diff options
author | Chris Lattner <sabre@nondot.org> | 2007-02-01 22:30:07 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-02-01 22:30:07 +0000 |
commit | fd905caa77fc77bbc6414d98c03fb6ee8035694b (patch) | |
tree | d55577fe9cbb790c09cb4a6378de71a4e8c0a0fe | |
parent | 5c70a012c77d63e4d09c7540abba930a4aa03df8 (diff) |
Fix Transforms/InstCombine/2007-02-01-LoadSinkAlloca.ll, a serious code
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
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index aec61ab076..9fbcdc182d 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -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; } |