OSDN Git Service

falling off the end of a function is ok with an unreachable instruction.
authorChris Lattner <sabre@nondot.org>
Sat, 14 Oct 2006 00:21:48 +0000 (00:21 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 14 Oct 2006 00:21:48 +0000 (00:21 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30950 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/BranchFolding.cpp

index dad23ea..7b5ee6c 100644 (file)
@@ -26,32 +26,30 @@ using namespace llvm;
 namespace {
   struct BranchFolder : public MachineFunctionPass {
     virtual bool runOnMachineFunction(MachineFunction &MF);
-    virtual const char *getPassName() const { return "Branch Folder"; }
+    virtual const char *getPassName() const { return "Control Flow Optimizer"; }
+    const TargetInstrInfo *TII;
+    bool MadeChange;
   private:
-    bool OptimizeBlock(MachineFunction::iterator MBB,
-                       const TargetInstrInfo &TII);
-
-    bool isUncondBranch(const MachineInstr *MI, const TargetInstrInfo &TII) {
-      return TII.isBarrier(MI->getOpcode()) && TII.isBranch(MI->getOpcode());
-    }
-    bool isCondBranch(const MachineInstr *MI, const TargetInstrInfo &TII) {
-      return TII.isBranch(MI->getOpcode()) && !TII.isBarrier(MI->getOpcode());
-    }
+    void OptimizeBlock(MachineFunction::iterator MBB);
   };
 }
 
 FunctionPass *llvm::createBranchFoldingPass() { return new BranchFolder(); }
 
 bool BranchFolder::runOnMachineFunction(MachineFunction &MF) {
+  TII = MF.getTarget().getInstrInfo();
+  if (!TII) return false;
+
+  //MF.dump();
+  
   bool EverMadeChange = false;
-  bool MadeChange = true;
-  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
+  MadeChange = true;
   while (MadeChange) {
     MadeChange = false;
     for (MachineFunction::iterator MBB = ++MF.begin(), E = MF.end(); MBB != E;
          ++MBB)
-      MadeChange |= OptimizeBlock(MBB, TII);
-
+      OptimizeBlock(MBB);
+    
     // If branches were folded away somehow, do a quick scan and delete any dead
     // blocks.
     if (MadeChange) {
@@ -78,13 +76,13 @@ bool BranchFolder::runOnMachineFunction(MachineFunction &MF) {
 static void ReplaceUsesOfBlockWith(MachineBasicBlock *BB,
                                    MachineBasicBlock *Old,
                                    MachineBasicBlock *New,
-                                   const TargetInstrInfo &TII) {
+                                   const TargetInstrInfo *TII) {
   assert(Old != New && "Cannot replace self with self!");
 
   MachineBasicBlock::iterator I = BB->end();
   while (I != BB->begin()) {
     --I;
-    if (!TII.isTerminatorInstr(I->getOpcode())) break;
+    if (!TII->isTerminatorInstr(I->getOpcode())) break;
 
     // Scan the operands of this machine instruction, replacing any uses of Old
     // with New.
@@ -103,23 +101,55 @@ static void ReplaceUsesOfBlockWith(MachineBasicBlock *BB,
     }
 }
 
-
-bool BranchFolder::OptimizeBlock(MachineFunction::iterator MBB,
-                                 const TargetInstrInfo &TII) {
+/// OptimizeBlock - Analyze and optimize control flow related to the specified
+/// block.  This is never called on the entry block.
+void BranchFolder::OptimizeBlock(MachineFunction::iterator MBB) {
   // If this block is empty, make everyone use its fall-through, not the block
   // explicitly.
   if (MBB->empty()) {
-    if (MBB->pred_empty()) return false;
-    MachineFunction::iterator FallThrough =next(MBB);
-    assert(FallThrough != MBB->getParent()->end() &&
-           "Fell off the end of the function!");
-    while (!MBB->pred_empty()) {
-      MachineBasicBlock *Pred = *(MBB->pred_end()-1);
-      ReplaceUsesOfBlockWith(Pred, MBB, FallThrough, TII);
+    if (MBB->pred_empty()) return;  // dead block?  Leave for cleanup later.
+    
+    MachineFunction::iterator FallThrough = next(MBB);
+    
+    if (FallThrough != MBB->getParent()->end()) {
+      while (!MBB->pred_empty()) {
+        MachineBasicBlock *Pred = *(MBB->pred_end()-1);
+        ReplaceUsesOfBlockWith(Pred, MBB, FallThrough, TII);
+      }
+      MadeChange = true;
     }
-    return true;
+    // TODO: CHANGE STUFF TO NOT BRANCH HERE!
+    return;
   }
 
+  // Check to see if we can simplify the terminator of the block before this
+  // one.
+#if 0
+  MachineBasicBlock *PriorTBB = 0, *PriorFBB = 0;
+  std::vector<MachineOperand> PriorCond;
+  if (!TII->AnalyzeBranch(*prior(MBB), PriorTBB, PriorFBB, PriorCond)) {
+    // If the previous branch is conditional and both conditions go to the same
+    // destination, remove the branch, replacing it with an unconditional one.
+    if (PriorTBB && PriorTBB == PriorFBB) {
+      TII->RemoveBranch(*prior(MBB));
+      PriorCond.clear(); 
+      if (PriorTBB != &*MBB)
+        TII->InsertBranch(*prior(MBB), PriorTBB, 0, PriorCond);
+      MadeChange = true;
+      return OptimizeBlock(MBB);
+    }
+    
+    // If the previous branch *only* branches to *this* block (conditional or
+    // not) remove the branch.
+    if (PriorTBB == &*MBB && PriorFBB == 0) {
+      TII->RemoveBranch(*prior(MBB));
+      MadeChange = true;
+      return OptimizeBlock(MBB);
+    }
+  }
+#endif
+  
+  
 #if 0
 
   if (MBB->pred_size() == 1) {
@@ -235,5 +265,4 @@ bool BranchFolder::OptimizeBlock(MachineFunction::iterator MBB,
     }
   }
 #endif
-  return false;
 }