#include "llvm/Transforms/Scalar.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
+#include "llvm/IntrinsicInst.h"
#include "llvm/Instructions.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Transforms/Utils/PromoteMemToReg.h"
#include "llvm/Support/CFG.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Debug.h"
#include "llvm/ADT/Statistic.h"
#include <algorithm>
DisablePromotion("disable-licm-promotion", cl::Hidden,
cl::desc("Disable memory promotion in LICM pass"));
-// This feature is currently disabled by default because CodeGen is not yet capable
-// of rematerializing these constants in PIC mode, so it can lead to degraded
-// performance. Compile test/CodeGen/X86/remat-constant.ll with
-// -relocation-model=pic to see an example of this.
-static cl::opt<bool>
-EnableLICMConstantMotion("enable-licm-constant-variables", cl::Hidden,
- cl::desc("Enable hoisting/sinking of constant "
- "global variables"));
-
namespace {
- struct VISIBILITY_HIDDEN LICM : public LoopPass {
+ struct LICM : public LoopPass {
static char ID; // Pass identification, replacement for typeid
LICM() : LoopPass(&ID) {}
AU.addRequired<AliasAnalysis>();
AU.addPreserved<ScalarEvolution>();
AU.addPreserved<DominanceFrontier>();
+ AU.addPreservedID(LoopSimplifyID);
}
bool doFinalization() {
// Because the exit block is not in the loop, we know we have to get _at
// least_ its immediate dominator.
- do {
- // Get next Immediate Dominator.
- IDom = IDom->getIDom();
-
+ IDom = IDom->getIDom();
+
+ while (IDom && IDom != BlockInLoopNode) {
// If we have got to the header of the loop, then the instructions block
// did not dominate the exit node, so we can't hoist it.
if (IDom->getBlock() == LoopHeader)
return false;
- } while (IDom != BlockInLoopNode);
+ // Get next Immediate Dominator.
+ IDom = IDom->getIDom();
+ };
return true;
}
// Get the preheader block to move instructions into...
Preheader = L->getLoopPreheader();
- assert(Preheader&&"Preheader insertion pass guarantees we have a preheader!");
// Loop over the body of this loop, looking for calls, invokes, and stores.
// Because subloops have already been incorporated into AST, we skip blocks in
// us to sink instructions in one pass, without iteration. After sinking
// instructions, we perform another pass to hoist them out of the loop.
//
- SinkRegion(DT->getNode(L->getHeader()));
- HoistRegion(DT->getNode(L->getHeader()));
+ if (L->hasDedicatedExits())
+ SinkRegion(DT->getNode(L->getHeader()));
+ if (Preheader)
+ HoistRegion(DT->getNode(L->getHeader()));
// Now that all loop invariants have been removed from the loop, promote any
// memory references to scalars that we can...
- if (!DisablePromotion)
+ if (!DisablePromotion && Preheader && L->hasDedicatedExits())
PromoteValuesInLoop();
// Clear out loops state information for the next iteration
}
}
-
/// HoistRegion - Walk the specified region of the CFG (defined by all blocks
/// dominated by the specified block, and that are in the current loop) in depth
/// first order w.r.t the DominatorTree. This allows us to visit definitions
// Loads from constant memory are always safe to move, even if they end up
// in the same alias set as something that ends up being modified.
- if (EnableLICMConstantMotion &&
- AA->pointsToConstantMemory(LI->getOperand(0)))
+ if (AA->pointsToConstantMemory(LI->getOperand(0)))
return true;
// Don't hoist loads which have may-aliased stores in loop.
unsigned Size = 0;
if (LI->getType()->isSized())
- Size = AA->getTargetData().getTypeStoreSize(LI->getType());
+ Size = AA->getTypeStoreSize(LI->getType());
return !pointerInvalidatedByLoop(LI->getOperand(0), Size);
} else if (CallInst *CI = dyn_cast<CallInst>(&I)) {
// Handle obvious cases efficiently.
if (PN->getIncomingValue(i) == &I)
if (CurLoop->contains(PN->getIncomingBlock(i)))
return false;
- } else if (CurLoop->contains(User->getParent())) {
+ } else if (CurLoop->contains(User)) {
return false;
}
}
/// position, and may either delete it or move it to outside of the loop.
///
void LICM::sink(Instruction &I) {
- DOUT << "LICM sinking instruction: " << I;
+ DEBUG(dbgs() << "LICM sinking instruction: " << I);
SmallVector<BasicBlock*, 8> ExitBlocks;
CurLoop->getExitBlocks(ExitBlocks);
if (!isExitBlockDominatedByBlockInLoop(ExitBlocks[0], I.getParent())) {
// Instruction is not used, just delete it.
CurAST->deleteValue(&I);
- if (!I.use_empty()) // If I has users in unreachable blocks, eliminate.
+ // If I has users in unreachable blocks, eliminate.
+ // If I is not void type then replaceAllUsesWith undef.
+ // This allows ValueHandlers and custom metadata to adjust itself.
+ if (!I.getType()->isVoidTy())
I.replaceAllUsesWith(UndefValue::get(I.getType()));
I.eraseFromParent();
} else {
// Move the instruction to the start of the exit block, after any PHI
// nodes in it.
I.removeFromParent();
-
BasicBlock::iterator InsertPt = ExitBlocks[0]->getFirstNonPHI();
ExitBlocks[0]->getInstList().insert(InsertPt, &I);
}
} else if (ExitBlocks.empty()) {
// The instruction is actually dead if there ARE NO exit blocks.
CurAST->deleteValue(&I);
- if (!I.use_empty()) // If I has users in unreachable blocks, eliminate.
+ // If I has users in unreachable blocks, eliminate.
+ // If I is not void type then replaceAllUsesWith undef.
+ // This allows ValueHandlers and custom metadata to adjust itself.
+ if (!I.getType()->isVoidTy())
I.replaceAllUsesWith(UndefValue::get(I.getType()));
I.eraseFromParent();
} else {
// Firstly, we create a stack object to hold the value...
AllocaInst *AI = 0;
- if (I.getType() != Type::VoidTy) {
+ if (!I.getType()->isVoidTy()) {
AI = new AllocaInst(I.getType(), 0, I.getName(),
I.getParent()->getParent()->getEntryBlock().begin());
CurAST->add(AI);
/// that is safe to hoist, this instruction is called to do the dirty work.
///
void LICM::hoist(Instruction &I) {
- DOUT << "LICM hoisting to " << Preheader->getName() << ": " << I;
+ DEBUG(dbgs() << "LICM hoisting to " << Preheader->getName() << ": "
+ << I << "\n");
// Remove the instruction from its current basic block... but don't delete the
// instruction.
///
bool LICM::isSafeToExecuteUnconditionally(Instruction &Inst) {
// If it is not a trapping instruction, it is always safe to hoist.
- if (!Inst.isTrapping()) return true;
+ if (Inst.isSafeToSpeculativelyExecute())
+ return true;
// Otherwise we have to check to make sure that the instruction dominates all
// of the exit blocks. If it doesn't, then there is a path out of the loop
if (Inst.getParent() == CurLoop->getHeader())
return true;
- // It's always safe to load from a global or alloca.
- if (isa<LoadInst>(Inst))
- if (isa<AllocationInst>(Inst.getOperand(0)) ||
- isa<GlobalVariable>(Inst.getOperand(0)))
- return true;
-
// Get the exit blocks for the current loop.
SmallVector<BasicBlock*, 8> ExitBlocks;
CurLoop->getExitBlocks(ExitBlocks);
// If we are promoting a pointer value, update alias information for the
// inserted load.
Value *LoadValue = 0;
- if (isa<PointerType>(cast<PointerType>(Ptr->getType())->getElementType())) {
+ if (cast<PointerType>(Ptr->getType())->getElementType()->isPointerTy()) {
// Locate a load or store through the pointer, and assign the same value
// to LI as we are loading or storing. Since we know that the value is
// stored in this loop, this will always succeed.
LoadInst *LI = new LoadInst(PromotedValues[i].first, "", InsertPos);
// If this is a pointer type, update alias info appropriately.
- if (isa<PointerType>(LI->getType()))
+ if (LI->getType()->isPointerTy())
CurAST->copyValue(PointerValueNumbers[PVN++], LI);
// Store into the memory we promoted.
std::map<Value*, AllocaInst*> &ValueToAllocaMap) {
Instruction *FnStart = CurLoop->getHeader()->getParent()->begin()->begin();
- SmallVector<BasicBlock*, 4> ExitingBlocks;
- CurLoop->getExitingBlocks(ExitingBlocks);
-
// Loop over all of the alias sets in the tracker object.
for (AliasSetTracker::iterator I = CurAST->begin(), E = CurAST->end();
I != E; ++I) {
// set, if the pointer is loop invariant, and if we are not eliminating any
// volatile loads or stores.
if (AS.isForwardingAliasSet() || !AS.isMod() || !AS.isMustAlias() ||
- AS.isVolatile() || !CurLoop->isLoopInvariant(AS.begin()->first))
+ AS.isVolatile() || !CurLoop->isLoopInvariant(AS.begin()->getValue()))
continue;
assert(!AS.empty() &&
"Must alias set should have at least one pointer element in it!");
- Value *V = AS.begin()->first;
+ Value *V = AS.begin()->getValue();
// Check that all of the pointers in the alias set have the same type. We
// cannot (yet) promote a memory location that is loaded and stored in
{
bool PointerOk = true;
for (AliasSet::iterator I = AS.begin(), E = AS.end(); I != E; ++I)
- if (V->getType() != I->first->getType()) {
+ if (V->getType() != I->getValue()->getType()) {
PointerOk = false;
break;
}
UI != UE; ++UI) {
// Ignore instructions not in this loop.
Instruction *Use = dyn_cast<Instruction>(*UI);
- if (!Use || !CurLoop->contains(Use->getParent()))
+ if (!Use || !CurLoop->contains(Use))
continue;
if (!isa<LoadInst>(Use) && !isa<StoreInst>(Use)) {
CurAST->copyValue(V, AI);
for (AliasSet::iterator I = AS.begin(), E = AS.end(); I != E; ++I)
- ValueToAllocaMap.insert(std::make_pair(I->first, AI));
+ ValueToAllocaMap.insert(std::make_pair(I->getValue(), AI));
- DOUT << "LICM: Promoting value: " << *V << "\n";
+ DEBUG(dbgs() << "LICM: Promoting value: " << *V << "\n");
}
}