#include "llvm/Transforms/Scalar.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
+#include "llvm/IntrinsicInst.h"
#include "llvm/Instructions.h"
-#include "llvm/LLVMContext.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopPass.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"
"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() {
///
void HoistRegion(DomTreeNode *N);
+ // Cleanup debug information (remove stoppoints with no coressponding
+ // instructions).
+ void CleanupDbgInfoRegion(DomTreeNode *N);
+
/// inSubLoop - Little predicate that returns true if the specified basic
/// block is in a subloop of the current one, not the current one itself.
///
//
SinkRegion(DT->getNode(L->getHeader()));
HoistRegion(DT->getNode(L->getHeader()));
+ CleanupDbgInfoRegion(DT->getNode(L->getHeader()));
// Now that all loop invariants have been removed from the loop, promote any
// memory references to scalars that we can...
}
}
+void LICM::CleanupDbgInfoRegion(DomTreeNode *N) {
+ BasicBlock *BB = N->getBlock();
+
+ // If this subregion is not in the top level loop at all, exit.
+ if (!CurLoop->contains(BB)) return;
+
+ // We are processing blocks in reverse dfo, so process children first...
+ const std::vector<DomTreeNode*> &Children = N->getChildren();
+ for (unsigned i = 0, e = Children.size(); i != e; ++i)
+ CleanupDbgInfoRegion(Children[i]);
+
+ // Only need to process the contents of this block if it is not part of a
+ // subloop (which would already have been processed).
+ if (inSubLoop(BB)) return;
+
+ // We modify the basicblock, so don't cache end()
+ for (BasicBlock::iterator I=BB->begin(); I != BB->end();) {
+ Instruction *Last = 0;
+ // Remove consecutive dbgstoppoints, leave only last
+ do {
+ if (Last) {
+ Last->eraseFromParent();
+ Changed = true;
+ }
+ Last = I;
+ ++I;
+ } while (isa<DbgStopPointInst>(Last) && isa<DbgStopPointInst>(I));
+ }
+}
/// 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
Size = AA->getTypeStoreSize(LI->getType());
return !pointerInvalidatedByLoop(LI->getOperand(0), Size);
} else if (CallInst *CI = dyn_cast<CallInst>(&I)) {
+ if (isa<DbgStopPointInst>(CI)) {
+ // Don't hoist/sink dbgstoppoints, we handle them separately
+ return false;
+ }
// Handle obvious cases efficiently.
AliasAnalysis::ModRefBehavior Behavior = AA->getModRefBehavior(CI);
if (Behavior == AliasAnalysis::DoesNotAccessMemory)
/// 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(errs() << "LICM sinking instruction: " << I);
SmallVector<BasicBlock*, 8> ExitBlocks;
CurLoop->getExitBlocks(ExitBlocks);
++NumSunk;
Changed = true;
- LLVMContext &Context = I.getContext();
-
// The case where there is only a single exit node of this loop is common
// enough that we handle it as a special (more efficient) case. It is more
// efficient to handle because there are no PHI nodes that need to be placed.
// Instruction is not used, just delete it.
CurAST->deleteValue(&I);
if (!I.use_empty()) // If I has users in unreachable blocks, eliminate.
- I.replaceAllUsesWith(Context.getUndef(I.getType()));
+ 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);
}
// 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.
- I.replaceAllUsesWith(Context.getUndef(I.getType()));
+ I.replaceAllUsesWith(UndefValue::get(I.getType()));
I.eraseFromParent();
} else {
// Otherwise, if we have multiple exits, use the PromoteMem2Reg function to
// Firstly, we create a stack object to hold the value...
AllocaInst *AI = 0;
- if (I.getType() != Type::VoidTy) {
+ if (I.getType() != Type::getVoidTy(I.getContext())) {
AI = new AllocaInst(I.getType(), 0, I.getName(),
I.getParent()->getParent()->getEntryBlock().begin());
CurAST->add(AI);
ExitBlock->getInstList().insert(InsertPt, &I);
New = &I;
} else {
- New = I.clone(Context);
+ New = I.clone();
CurAST->copyValue(&I, New);
if (!I.getName().empty())
New->setName(I.getName()+".le");
if (AI) {
std::vector<AllocaInst*> Allocas;
Allocas.push_back(AI);
- PromoteMemToReg(Allocas, *DT, *DF, Context, CurAST);
+ PromoteMemToReg(Allocas, *DT, *DF, AI->getContext(), CurAST);
}
}
}
for (AliasSet::iterator I = AS.begin(), E = AS.end(); I != E; ++I)
ValueToAllocaMap.insert(std::make_pair(I->getValue(), AI));
- DOUT << "LICM: Promoting value: " << *V << "\n";
+ DEBUG(errs() << "LICM: Promoting value: " << *V << "\n");
}
}