Fix Transforms/InstCombine/2007-02-01-LoadSinkAlloca.ll, a serious code
authorChris Lattner <sabre@nondot.org>
Thu, 1 Feb 2007 22:30:07 +0000 (22:30 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 1 Feb 2007 22:30:07 +0000 (22:30 +0000)
pessimization where instcombine can sink a load (good for code size) that
prevents an alloca from being promoted by mem2reg (bad for everything).

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

lib/Transforms/Scalar/InstructionCombining.cpp

index aec61ab07672d9d22a0ff055da638b10209d84c7..9fbcdc182db28ab9204ade3e259670fa62ca8b56 100644 (file)
@@ -7464,12 +7464,36 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) {
 /// of the block that defines it.  This means that it must be obvious the value
 /// of the load is not changed from the point of the load to the end of the
 /// block it is in.
+///
+/// Finally, it is safe, but not profitable, to sink a load targetting a
+/// non-address-taken alloca.  Doing so will cause us to not promote the alloca
+/// to a register.
 static bool isSafeToSinkLoad(LoadInst *L) {
   BasicBlock::iterator BBI = L, E = L->getParent()->end();
   
   for (++BBI; BBI != E; ++BBI)
     if (BBI->mayWriteToMemory())
       return false;
+  
+  // Check for non-address taken alloca.  If not address-taken already, it isn't
+  // profitable to do this xform.
+  if (AllocaInst *AI = dyn_cast<AllocaInst>(L->getOperand(0))) {
+    bool isAddressTaken = false;
+    for (Value::use_iterator UI = AI->use_begin(), E = AI->use_end();
+         UI != E; ++UI) {
+      if (isa<LoadInst>(UI)) continue;
+      if (StoreInst *SI = dyn_cast<StoreInst>(*UI)) {
+        // If storing TO the alloca, then the address isn't taken.
+        if (SI->getOperand(1) == AI) continue;
+      }
+      isAddressTaken = true;
+      break;
+    }
+    
+    if (!isAddressTaken)
+      return false;
+  }
+  
   return true;
 }