浏览代码

Avoid adding empty blocks while inserting an edge from finally block to early exit

When we add an edge from end of finally block to an early exit, we need not create additional blocks
if the Leave/LeaveNull at the end of finally was in a separate block preceeded by a Label.
Creating empty blocks like this can lead to issues with DelateLeaveChains later on, moreover we want to keep the IR clean.
Meghana Gupta 8 年之前
父节点
当前提交
5924ffa5a5
共有 1 个文件被更改,包括 21 次插入10 次删除
  1. 21 10
      lib/Backend/FlowGraph.cpp

+ 21 - 10
lib/Backend/FlowGraph.cpp

@@ -636,29 +636,40 @@ void FlowGraph::InsertEdgeFromFinallyToEarlyExit(BasicBlock *finallyEndBlock, IR
     IR::LabelInstr *leaveLabel = IR::LabelInstr::New(Js::OpCode::Label, this->func);
     lastInstr->InsertBefore(leaveLabel);
 
-    this->AddBlock(leaveLabel, lastInstr, finallyEndBlock->GetNext(), finallyEndBlock /*prevBlock*/);
+    this->AddBlock(leaveLabel, lastInstr, nextBB, finallyEndBlock /*prevBlock*/);
     leaveLabel->SetRegion(lastLabel->GetRegion());
 
     this->AddEdge(finallyEndBlock, leaveLabel->GetBasicBlock());
 
-    IR::LabelInstr *brLabel = IR::LabelInstr::New(Js::OpCode::Label, this->func);
-    leaveLabel->InsertBefore(brLabel);
+    // If the Leave/LeaveNull at the end of finally was not preceeded by a Label, we have to create a new block with BrOnException to early exit
+    if (!lastInstr->GetPrevRealInstrOrLabel()->IsLabelInstr())
+    {
+        IR::LabelInstr *brLabel = IR::LabelInstr::New(Js::OpCode::Label, this->func);
+        leaveLabel->InsertBefore(brLabel);
 
-    IR::BranchInstr *brToExit = IR::BranchInstr::New(Js::OpCode::BrOnException, exitLabel, this->func);
-    leaveLabel->InsertBefore(brToExit);
+        IR::BranchInstr *brToExit = IR::BranchInstr::New(Js::OpCode::BrOnException, exitLabel, this->func);
+        leaveLabel->InsertBefore(brToExit);
 
-    this->AddBlock(brLabel, brToExit, finallyEndBlock->GetNext(), finallyEndBlock /*prevBlock*/);
+        this->AddBlock(brLabel, brToExit, finallyEndBlock->GetNext(), finallyEndBlock /*prevBlock*/);
+        brLabel->SetRegion(lastLabel->GetRegion());
 
-    brLabel->SetRegion(lastLabel->GetRegion());
+        this->AddEdge(finallyEndBlock, brLabel->GetBasicBlock());
+    }
+    else
+    {
+        // If the Leave/LeaveNull at the end of finally was preceeded by a Label, we reuse the block inserting BrOnException to early exit in it
+        IR::BranchInstr *brToExit = IR::BranchInstr::New(Js::OpCode::BrOnException, exitLabel, this->func);
+        leaveLabel->InsertBefore(brToExit);
+        this->AddEdge(finallyEndBlock, exitLabel->GetBasicBlock());
+    }
 
-    // in case of throw/non-terminating loop, there maybe no edge to the next block
+    // In case of throw/non-terminating loop, there maybe no edge to the next block
     if (this->FindEdge(finallyEndBlock, nextBB))
     {
         finallyEndBlock->RemoveSucc(nextBB, this);
     }
-    this->AddEdge(finallyEndBlock, brLabel->GetBasicBlock());
 
-    this->regToFinallyEndMap->Item(lastLabel->GetRegion(), finallyEndBlock->next->next);
+    this->regToFinallyEndMap->Item(lastLabel->GetRegion(), leaveLabel->GetBasicBlock());
 }
 
 void