Fix PHIElimination optimization that uses MBB->getBasicBlock.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Fri, 13 Nov 2009 21:56:15 +0000 (21:56 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Fri, 13 Nov 2009 21:56:15 +0000 (21:56 +0000)
The BasicBlock associated with a MachineBasicBlock does not necessarily
correspond to the code in the MBB.

Don't insert a new IR BasicBlock when splitting critical edges. We are not
supposed to modify the IR during codegen, and we should be able to do just
fine with a NULL BB.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@88707 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/PHIElimination.cpp
lib/CodeGen/PHIElimination.h

index 58af9c54b7c0cfb210091b3ffcd1a01c8ec07f4a..3fe142465e3ba9726f6f20f639befe08a43c4523 100644 (file)
@@ -15,8 +15,6 @@
 
 #define DEBUG_TYPE "phielim"
 #include "PHIElimination.h"
-#include "llvm/BasicBlock.h"
-#include "llvm/Instructions.h"
 #include "llvm/CodeGen/LiveVariables.h"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
@@ -126,26 +124,28 @@ static bool isSourceDefinedByImplicitDef(const MachineInstr *MPhi,
   return true;
 }
 
-// FindCopyInsertPoint - Find a safe place in MBB to insert a copy from SrcReg.
-// This needs to be after any def or uses of SrcReg, but before any subsequent
-// point where control flow might jump out of the basic block.
+// FindCopyInsertPoint - Find a safe place in MBB to insert a copy from SrcReg
+// when following the CFG edge to SuccMBB. This needs to be after any def of
+// SrcReg, but before any subsequent point where control flow might jump out of
+// the basic block.
 MachineBasicBlock::iterator
 llvm::PHIElimination::FindCopyInsertPoint(MachineBasicBlock &MBB,
+                                          MachineBasicBlock &SuccMBB,
                                           unsigned SrcReg) {
   // Handle the trivial case trivially.
   if (MBB.empty())
     return MBB.begin();
 
-  // If this basic block does not contain an invoke, then control flow always
-  // reaches the end of it, so place the copy there.  The logic below works in
-  // this case too, but is more expensive.
-  if (!isa<InvokeInst>(MBB.getBasicBlock()->getTerminator()))
+  // Usually, we just want to insert the copy before the first terminator
+  // instruction. However, for the edge going to a landing pad, we must insert
+  // the copy before the call/invoke instruction.
+  if (!SuccMBB.isLandingPad())
     return MBB.getFirstTerminator();
 
-  // Discover any definition/uses in this basic block.
+  // Discover any definitions in this basic block.
   SmallPtrSet<MachineInstr*, 8> DefUsesInMBB;
-  for (MachineRegisterInfo::reg_iterator RI = MRI->reg_begin(SrcReg),
-       RE = MRI->reg_end(); RI != RE; ++RI) {
+  for (MachineRegisterInfo::def_iterator RI = MRI->def_begin(SrcReg),
+         RE = MRI->def_end(); RI != RE; ++RI) {
     MachineInstr *DefUseMI = &*RI;
     if (DefUseMI->getParent() == &MBB)
       DefUsesInMBB.insert(DefUseMI);
@@ -153,14 +153,14 @@ llvm::PHIElimination::FindCopyInsertPoint(MachineBasicBlock &MBB,
 
   MachineBasicBlock::iterator InsertPoint;
   if (DefUsesInMBB.empty()) {
-    // No def/uses.  Insert the copy at the start of the basic block.
+    // No defs.  Insert the copy at the start of the basic block.
     InsertPoint = MBB.begin();
   } else if (DefUsesInMBB.size() == 1) {
-    // Insert the copy immediately after the definition/use.
+    // Insert the copy immediately after the def.
     InsertPoint = *DefUsesInMBB.begin();
     ++InsertPoint;
   } else {
-    // Insert the copy immediately after the last definition/use.
+    // Insert the copy immediately after the last def.
     InsertPoint = MBB.end();
     while (!DefUsesInMBB.count(&*--InsertPoint)) {}
     ++InsertPoint;
@@ -272,7 +272,8 @@ void llvm::PHIElimination::LowerAtomicPHINode(
 
     // Find a safe location to insert the copy, this may be the first terminator
     // in the block (or end()).
-    MachineBasicBlock::iterator InsertPos = FindCopyInsertPoint(opBlock, SrcReg);
+    MachineBasicBlock::iterator InsertPos =
+      FindCopyInsertPoint(opBlock, MBB, SrcReg);
 
     // Insert the copy.
     TII->copyRegToReg(opBlock, InsertPos, IncomingReg, SrcReg, RC, RC);
@@ -427,21 +428,8 @@ MachineBasicBlock *PHIElimination::SplitCriticalEdge(MachineBasicBlock *A,
   assert(A && B && "Missing MBB end point");
   ++NumSplits;
 
-  BasicBlock *ABB = const_cast<BasicBlock*>(A->getBasicBlock());
-  BasicBlock *BBB = const_cast<BasicBlock*>(B->getBasicBlock());
-  assert(ABB && BBB && "End points must have a basic block");
-  BasicBlock *BB = BasicBlock::Create(BBB->getContext(),
-                                      ABB->getName() + "." + BBB->getName() +
-                                      "_phi_edge");
-  Function *F = ABB->getParent();
-  F->getBasicBlockList().insert(F->end(), BB);
-
-  BranchInst::Create(BBB, BB);
-  // We could do more here to produce correct IR, compare
-  // llvm::SplitCriticalEdge
-
   MachineFunction *MF = A->getParent();
-  MachineBasicBlock *NMBB = MF->CreateMachineBasicBlock(BB);
+  MachineBasicBlock *NMBB = MF->CreateMachineBasicBlock();
   MF->push_back(NMBB);
   DEBUG(errs() << "PHIElimination splitting critical edge:"
         " BB#" << A->getNumber()
index edc2d36670bf9ab9c4cb9422c5b151d8d76c3000..94716eef6c51ae943f66d9f06cd6278e42d9432f 100644 (file)
@@ -110,11 +110,12 @@ namespace llvm {
     MachineBasicBlock *SplitCriticalEdge(MachineBasicBlock *A,
                                          MachineBasicBlock *B);
 
-    // FindCopyInsertPoint - Find a safe place in MBB to insert a copy from
-    // SrcReg.  This needs to be after any def or uses of SrcReg, but before
-    // any subsequent point where control flow might jump out of the basic
-    // block.
+    /// FindCopyInsertPoint - Find a safe place in MBB to insert a copy from
+    /// SrcReg when following the CFG edge to SuccMBB. This needs to be after
+    /// any def of SrcReg, but before any subsequent point where control flow
+    /// might jump out of the basic block.
     MachineBasicBlock::iterator FindCopyInsertPoint(MachineBasicBlock &MBB,
+                                                    MachineBasicBlock &SuccMBB,
                                                     unsigned SrcReg);
 
     // SkipPHIsAndLabels - Copies need to be inserted after phi nodes and