X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTransforms%2FScalar%2FSink.cpp;h=7c0ac7aa6faec4225547e3d1c8b56b0510ad9e5e;hb=cdbb6a49e2f29b3cb3354810a36d240f6a64a972;hp=7348c45c5d37be8d65b4dc48e62fcfeab33bd25c;hpb=db77b82ed5afdc87000bc3b85bfb5398f183a8b3;p=oota-llvm.git diff --git a/lib/Transforms/Scalar/Sink.cpp b/lib/Transforms/Scalar/Sink.cpp index 7348c45c5d3..7c0ac7aa6fa 100644 --- a/lib/Transforms/Scalar/Sink.cpp +++ b/lib/Transforms/Scalar/Sink.cpp @@ -21,6 +21,7 @@ #include "llvm/IR/DataLayout.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -35,7 +36,6 @@ namespace { DominatorTree *DT; LoopInfo *LI; AliasAnalysis *AA; - const DataLayout *DL; public: static char ID; // Pass identification @@ -48,15 +48,15 @@ namespace { void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); FunctionPass::getAnalysisUsage(AU); - AU.addRequired(); + AU.addRequired(); AU.addRequired(); - AU.addRequired(); + AU.addRequired(); AU.addPreserved(); - AU.addPreserved(); + AU.addPreserved(); } private: bool ProcessBlock(BasicBlock &BB); - bool SinkInstruction(Instruction *I, SmallPtrSet &Stores); + bool SinkInstruction(Instruction *I, SmallPtrSetImpl &Stores); bool AllUsesDominatedByBlock(Instruction *Inst, BasicBlock *BB) const; bool IsAcceptableTarget(Instruction *Inst, BasicBlock *SuccToSinkTo) const; }; @@ -64,9 +64,9 @@ namespace { char Sinking::ID = 0; INITIALIZE_PASS_BEGIN(Sinking, "sink", "Code sinking", false, false) -INITIALIZE_PASS_DEPENDENCY(LoopInfo) +INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) -INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_END(Sinking, "sink", "Code sinking", false, false) FunctionPass *llvm::createSinkingPass() { return new Sinking(); } @@ -98,10 +98,8 @@ bool Sinking::AllUsesDominatedByBlock(Instruction *Inst, bool Sinking::runOnFunction(Function &F) { DT = &getAnalysis().getDomTree(); - LI = &getAnalysis(); - AA = &getAnalysis(); - DataLayoutPass *DLP = getAnalysisIfAvailable(); - DL = DLP ? &DLP->getDataLayout() : nullptr; + LI = &getAnalysis().getLoopInfo(); + AA = &getAnalysis().getAAResults(); bool MadeChange, EverMadeChange = false; @@ -121,7 +119,7 @@ bool Sinking::runOnFunction(Function &F) { bool Sinking::ProcessBlock(BasicBlock &BB) { // Can't sink anything out of a block that has less than two successors. - if (BB.getTerminator()->getNumSuccessors() <= 1 || BB.empty()) return false; + if (BB.getTerminator()->getNumSuccessors() <= 1) return false; // Don't bother sinking code out of unreachable blocks. In addition to being // unprofitable, it can also lead to infinite looping, because in an @@ -136,7 +134,7 @@ bool Sinking::ProcessBlock(BasicBlock &BB) { bool ProcessedBegin = false; SmallPtrSet Stores; do { - Instruction *Inst = I; // The instruction to sink. + Instruction *Inst = &*I; // The instruction to sink. // Predecrement I (if it's not begin) so that it isn't invalidated by // sinking. @@ -157,7 +155,7 @@ bool Sinking::ProcessBlock(BasicBlock &BB) { } static bool isSafeToMove(Instruction *Inst, AliasAnalysis *AA, - SmallPtrSet &Stores) { + SmallPtrSetImpl &Stores) { if (Inst->mayWriteToMemory()) { Stores.insert(Inst); @@ -165,16 +163,22 @@ static bool isSafeToMove(Instruction *Inst, AliasAnalysis *AA, } if (LoadInst *L = dyn_cast(Inst)) { - AliasAnalysis::Location Loc = AA->getLocation(L); - for (SmallPtrSet::iterator I = Stores.begin(), - E = Stores.end(); I != E; ++I) - if (AA->getModRefInfo(*I, Loc) & AliasAnalysis::Mod) + MemoryLocation Loc = MemoryLocation::get(L); + for (Instruction *S : Stores) + if (AA->getModRefInfo(S, Loc) & MRI_Mod) return false; } - if (isa(Inst) || isa(Inst)) + if (isa(Inst) || isa(Inst) || Inst->isEHPad()) return false; + // Convergent operations cannot be made control-dependent on additional + // values. + if (auto CS = CallSite(Inst)) { + if (CS.hasFnAttr(Attribute::Convergent)) + return false; + } + return true; } @@ -197,7 +201,7 @@ bool Sinking::IsAcceptableTarget(Instruction *Inst, if (SuccToSinkTo->getUniquePredecessor() != Inst->getParent()) { // We cannot sink a load across a critical edge - there may be stores in // other code paths. - if (!isSafeToSpeculativelyExecute(Inst, DL)) + if (!isSafeToSpeculativelyExecute(Inst)) return false; // We don't want to sink across a critical edge if we don't dominate the @@ -220,7 +224,7 @@ bool Sinking::IsAcceptableTarget(Instruction *Inst, /// SinkInstruction - Determine whether it is safe to sink the specified machine /// instruction out of its current block into a successor. bool Sinking::SinkInstruction(Instruction *Inst, - SmallPtrSet &Stores) { + SmallPtrSetImpl &Stores) { // Don't sink static alloca instructions. CodeGen assumes allocas outside the // entry block are dynamically sized stack objects. @@ -275,6 +279,6 @@ bool Sinking::SinkInstruction(Instruction *Inst, dbgs() << ")\n"); // Move the instruction. - Inst->moveBefore(SuccToSinkTo->getFirstInsertionPt()); + Inst->moveBefore(&*SuccToSinkTo->getFirstInsertionPt()); return true; }