DEBUG(std::cerr << "LICM sinking instruction: " << I);
const std::vector<BasicBlock*> &ExitBlocks = CurLoop->getExitBlocks();
-
+ std::vector<Value*> Operands(I.op_begin(), I.op_end());
+
+ if (isa<LoadInst>(I)) ++NumMovedLoads;
+ ++NumSunk;
+ Changed = true;
+
// 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.
} else if (ExitBlocks.size() == 0) {
// The instruction is actually dead if there ARE NO exit blocks.
I.getParent()->getInstList().erase(&I);
- return; // Don't count this as a sunk instruction, don't check operands.
} else {
// Otherwise, if we have multiple exits, use the PromoteMem2Reg function to
// do all of the hard work of inserting PHI nodes as necessary. We convert
BasicBlock *ExitBlock = ExitBlocks[i];
if (isExitBlockDominatedByBlockInLoop(ExitBlock, InstOrigBB)) {
- std::set<BasicBlock*>::iterator SI =
- InsertedBlocks.lower_bound(ExitBlock);
// If we haven't already processed this exit block, do so now.
- if (SI == InsertedBlocks.end() || *SI != ExitBlock) {
+ if (InsertedBlocks.insert(ExitBlock).second) {
// Insert the code after the last PHI node...
BasicBlock::iterator InsertPt = ExitBlock->begin();
while (isa<PHINode>(InsertPt)) ++InsertPt;
// instruction, otherwise clone the original instruction and insert
// the copy.
Instruction *New;
- if (InsertedBlocks.empty()) {
+ if (InsertedBlocks.size() == 1) {
I.getParent()->getInstList().remove(&I);
ExitBlock->getInstList().insert(InsertPt, &I);
New = &I;
// Now that we have inserted the instruction, store it into the alloca
new StoreInst(New, AI, InsertPt);
-
- // Remember we processed this block
- InsertedBlocks.insert(SI, ExitBlock);
}
}
}
PromoteMemToReg(Allocas, *DT, *DF, AA->getTargetData());
}
- if (isa<LoadInst>(I)) ++NumMovedLoads;
- ++NumSunk;
- Changed = true;
-
// Since we just sunk an instruction, check to see if any other instructions
// used by this instruction are now sinkable. If so, sink them too.
- for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
- if (Instruction *OpI = dyn_cast<Instruction>(I.getOperand(i)))
+ for (unsigned i = 0, e = Operands.size(); i != e; ++i)
+ if (Instruction *OpI = dyn_cast<Instruction>(Operands[i]))
if (CurLoop->contains(OpI->getParent()) && canSinkOrHoistInst(*OpI) &&
- isNotUsedInLoop(*OpI) &&
- isSafeToExecuteUnconditionally(*OpI))
+ isNotUsedInLoop(*OpI) && isSafeToExecuteUnconditionally(*OpI))
sink(*OpI);
}
const std::vector<BasicBlock*> &ExitBlocks = CurLoop->getExitBlocks();
for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i)
- if (!ProcessedBlocks.count(ExitBlocks[i])) {
- ProcessedBlocks.insert(ExitBlocks[i]);
-
+ if (ProcessedBlocks.insert(ExitBlocks[i]).second) {
// Copy all of the allocas into their memory locations...
BasicBlock::iterator BI = ExitBlocks[i]->begin();
while (isa<PHINode>(*BI))