[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp

Chris Lattner lattner at cs.uiuc.edu
Wed Dec 8 15:44:12 PST 2004



Changes in directory llvm/lib/Transforms/Scalar:

InstructionCombining.cpp updated: 1.290 -> 1.291
---
Log message:

Do extremely simple sinking of instructions when they are only used in a
successor block.  This turns cases like this:

x = a op b
if (c) {
  use x
}

into:

if (c) {
  x = a op b
  use x
}

This triggers 3965 times in spec, and is tested by 
Regression/Transforms/InstCombine/sink_instruction.ll

This appears to expose a bug in the X86 backend for 177.mesa, which I'm 
looking in to.



---
Diffs of the changes:  (+52 -1)

Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.290 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.291
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.290	Wed Dec  8 17:10:30 2004
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp	Wed Dec  8 17:43:58 2004
@@ -43,12 +43,13 @@
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
 #include "llvm/Transforms/Utils/Local.h"
 #include "llvm/Support/CallSite.h"
+#include "llvm/Support/Debug.h"
 #include "llvm/Support/GetElementPtrTypeIterator.h"
 #include "llvm/Support/InstIterator.h"
 #include "llvm/Support/InstVisitor.h"
 #include "llvm/Support/PatternMatch.h"
-#include "llvm/Support/Debug.h"
 #include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/STLExtras.h"
 #include <algorithm>
 using namespace llvm;
 using namespace llvm::PatternMatch;
@@ -57,6 +58,7 @@
   Statistic<> NumCombined ("instcombine", "Number of insts combined");
   Statistic<> NumConstProp("instcombine", "Number of constant folds");
   Statistic<> NumDeadInst ("instcombine", "Number of dead inst eliminated");
+  Statistic<> NumSunkInst ("instcombine", "Number of instructions sunk");
 
   class InstCombiner : public FunctionPass,
                        public InstVisitor<InstCombiner, Instruction*> {
@@ -4189,6 +4191,32 @@
                  WorkList.end());
 }
 
+
+/// TryToSinkInstruction - Try to move the specified instruction from its
+/// current block into the beginning of DestBlock, which can only happen if it's
+/// safe to move the instruction past all of the instructions between it and the
+/// end of its block.
+static bool TryToSinkInstruction(Instruction *I, BasicBlock *DestBlock) {
+  assert(I->hasOneUse() && "Invariants didn't hold!");
+
+  // Cannot move control-flow-involving instructions.
+  if (isa<PHINode>(I) || isa<InvokeInst>(I) || isa<CallInst>(I)) return false;
+  
+  // Do not sink alloca instructions out of the entry block.
+  if (isa<AllocaInst>(I) && I->getParent() == &DestBlock->getParent()->front())
+    return false;
+
+  if (isa<LoadInst>(I)) return false;
+
+  BasicBlock::iterator InsertPos = DestBlock->begin();
+  while (isa<PHINode>(InsertPos)) ++InsertPos;
+
+  BasicBlock *SrcBlock = I->getParent();
+  DestBlock->getInstList().splice(InsertPos, SrcBlock->getInstList(), I);  
+  ++NumSunkInst;
+  return true;
+}
+
 bool InstCombiner::runOnFunction(Function &F) {
   bool Changed = false;
   TD = &getAnalysis<TargetData>();
@@ -4246,6 +4274,29 @@
       continue;
     }
 
+    // See if we can trivially sink this instruction to a successor basic block.
+    if (I->hasOneUse()) {
+      BasicBlock *BB = I->getParent();
+      BasicBlock *UserParent = cast<Instruction>(I->use_back())->getParent();
+      if (UserParent != BB) {
+        bool UserIsSuccessor = false;
+        // See if the user is one of our successors.
+        for (succ_iterator SI = succ_begin(BB), E = succ_end(BB); SI != E; ++SI)
+          if (*SI == UserParent) {
+            UserIsSuccessor = true;
+            break;
+          }
+
+        // If the user is one of our immediate successors, and if that successor
+        // only has us as a predecessors (we'd have to split the critical edge
+        // otherwise), we can keep going.
+        if (UserIsSuccessor && !isa<PHINode>(I->use_back()) &&
+            next(pred_begin(UserParent)) == pred_end(UserParent))
+          // Okay, the CFG is simple enough, try to sink this instruction.
+          Changed |= TryToSinkInstruction(I, UserParent);
+      }
+    }
+
     // Now that we have an instruction, try combining it to simplify it...
     if (Instruction *Result = visit(*I)) {
       ++NumCombined;






More information about the llvm-commits mailing list