X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTransforms%2FScalar%2FSink.cpp;h=7c0ac7aa6faec4225547e3d1c8b56b0510ad9e5e;hb=cdbb6a49e2f29b3cb3354810a36d240f6a64a972;hp=e500c3b24e71434bb00620d954df68d154b50b16;hpb=7f2eff792a2e18758a25956abdac2440ee18dd7f;p=oota-llvm.git diff --git a/lib/Transforms/Scalar/Sink.cpp b/lib/Transforms/Scalar/Sink.cpp index e500c3b24e7..7c0ac7aa6fa 100644 --- a/lib/Transforms/Scalar/Sink.cpp +++ b/lib/Transforms/Scalar/Sink.cpp @@ -12,19 +12,22 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "sink" #include "llvm/Transforms/Scalar.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/ValueTracking.h" +#include "llvm/IR/CFG.h" +#include "llvm/IR/DataLayout.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/IntrinsicInst.h" -#include "llvm/Support/CFG.h" +#include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; +#define DEBUG_TYPE "sink" + STATISTIC(NumSunk, "Number of instructions sunk"); STATISTIC(NumSinkIter, "Number of sinking iterations"); @@ -40,20 +43,20 @@ namespace { initializeSinkingPass(*PassRegistry::getPassRegistry()); } - virtual bool runOnFunction(Function &F); + bool runOnFunction(Function &F) override; - virtual void getAnalysisUsage(AnalysisUsage &AU) const { + 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; }; @@ -61,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(); } @@ -76,15 +79,14 @@ bool Sinking::AllUsesDominatedByBlock(Instruction *Inst, // This may leave a referencing dbg_value in the original block, before // the definition of the vreg. Dwarf generator handles this although the // user might not get the right info at runtime. - for (Value::use_iterator I = Inst->use_begin(), - E = Inst->use_end(); I != E; ++I) { + for (Use &U : Inst->uses()) { // Determine the block of the use. - Instruction *UseInst = cast(*I); + Instruction *UseInst = cast(U.getUser()); BasicBlock *UseBlock = UseInst->getParent(); if (PHINode *PN = dyn_cast(UseInst)) { // PHI nodes use the operand in the predecessor block, not the block with // the PHI. - unsigned Num = PHINode::getIncomingValueNumForOperand(I.getOperandNo()); + unsigned Num = PHINode::getIncomingValueNumForOperand(U.getOperandNo()); UseBlock = PN->getIncomingBlock(Num); } // Check that it dominates. @@ -96,8 +98,8 @@ bool Sinking::AllUsesDominatedByBlock(Instruction *Inst, bool Sinking::runOnFunction(Function &F) { DT = &getAnalysis().getDomTree(); - LI = &getAnalysis(); - AA = &getAnalysis(); + LI = &getAnalysis().getLoopInfo(); + AA = &getAnalysis().getAAResults(); bool MadeChange, EverMadeChange = false; @@ -117,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 @@ -132,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. @@ -153,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); @@ -161,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; } @@ -204,7 +212,7 @@ bool Sinking::IsAcceptableTarget(Instruction *Inst, // Don't sink instructions into a loop. Loop *succ = LI->getLoopFor(SuccToSinkTo); Loop *cur = LI->getLoopFor(Inst->getParent()); - if (succ != 0 && succ != cur) + if (succ != nullptr && succ != cur) return false; } @@ -216,7 +224,14 @@ 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. + if (AllocaInst *AI = dyn_cast(Inst)) + if (AI->isStaticAlloca()) + return false; + // Check if it's safe to move the instruction. if (!isSafeToMove(Inst, AA, Stores)) return false; @@ -231,14 +246,14 @@ bool Sinking::SinkInstruction(Instruction *Inst, // SuccToSinkTo - This is the successor to sink this instruction to, once we // decide. - BasicBlock *SuccToSinkTo = 0; + BasicBlock *SuccToSinkTo = nullptr; // Instructions can only be sunk if all their uses are in blocks // dominated by one of the successors. // Look at all the postdominators and see if we can sink it in one. DomTreeNode *DTN = DT->getNode(Inst->getParent()); for (DomTreeNode::iterator I = DTN->begin(), E = DTN->end(); - I != E && SuccToSinkTo == 0; ++I) { + I != E && SuccToSinkTo == nullptr; ++I) { BasicBlock *Candidate = (*I)->getBlock(); if ((*I)->getIDom()->getBlock() == Inst->getParent() && IsAcceptableTarget(Inst, Candidate)) @@ -248,13 +263,13 @@ bool Sinking::SinkInstruction(Instruction *Inst, // If no suitable postdominator was found, look at all the successors and // decide which one we should sink to, if any. for (succ_iterator I = succ_begin(Inst->getParent()), - E = succ_end(Inst->getParent()); I != E && SuccToSinkTo == 0; ++I) { + E = succ_end(Inst->getParent()); I != E && !SuccToSinkTo; ++I) { if (IsAcceptableTarget(Inst, *I)) SuccToSinkTo = *I; } // If we couldn't find a block to sink to, ignore this instruction. - if (SuccToSinkTo == 0) + if (!SuccToSinkTo) return false; DEBUG(dbgs() << "Sink" << *Inst << " ("; @@ -264,6 +279,6 @@ bool Sinking::SinkInstruction(Instruction *Inst, dbgs() << ")\n"); // Move the instruction. - Inst->moveBefore(SuccToSinkTo->getFirstInsertionPt()); + Inst->moveBefore(&*SuccToSinkTo->getFirstInsertionPt()); return true; }