Simplification of trip counting machinery.

- make sure to check the indvar type before anything else (efficiency)
  - Make sure to insert the 'add' into the program, even though it'll be
    dead
  - Wrap code at 80 columns
  - Other minor cleanups to reduce indentation level


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@8434 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2003-09-10 14:51:49 +00:00
parent 1a51956d11
commit 44abf85ae7

View File

@ -155,7 +155,9 @@ InductionVariable::InductionVariable(PHINode *P, LoopInfo *LoopInfo): End(0) {
} }
Value* InductionVariable::getExecutionCount(LoopInfo *LoopInfo) { Value *InductionVariable::getExecutionCount(LoopInfo *LoopInfo) {
if (InductionType != Canonical) return 0;
DEBUG(std::cerr << "entering getExecutionCount\n"); DEBUG(std::cerr << "entering getExecutionCount\n");
// Don't recompute if already available // Don't recompute if already available
@ -167,111 +169,104 @@ Value* InductionVariable::getExecutionCount(LoopInfo *LoopInfo) {
const Loop *L = LoopInfo ? LoopInfo->getLoopFor(Phi->getParent()) : 0; const Loop *L = LoopInfo ? LoopInfo->getLoopFor(Phi->getParent()) : 0;
if (!L) { if (!L) {
DEBUG(std::cerr << "null loop. oops\n"); DEBUG(std::cerr << "null loop. oops\n");
return NULL; return 0;
} }
// >1 backedge => cannot predict number of iterations // >1 backedge => cannot predict number of iterations
if (Phi->getNumIncomingValues() != 2) { if (Phi->getNumIncomingValues() != 2) {
DEBUG(std::cerr << ">2 incoming values. oops\n"); DEBUG(std::cerr << ">2 incoming values. oops\n");
return NULL; return 0;
} }
// Find final node: predecesor of the loop header that's also an exit // Find final node: predecesor of the loop header that's also an exit
BasicBlock *terminator = 0; BasicBlock *terminator = 0;
BasicBlock *header = L->getHeader(); for (pred_iterator PI = pred_begin(L->getHeader()),
for (pred_iterator PI = pred_begin(header), PE = pred_end(header); PE = pred_end(L->getHeader()); PI != PE; ++PI)
PI != PE; ++PI) {
if (L->isLoopExit(*PI)) { if (L->isLoopExit(*PI)) {
terminator = *PI; terminator = *PI;
break; break;
} }
}
// Break in the loop => cannot predict number of iterations // Break in the loop => cannot predict number of iterations
// break: any block which is an exit node whose successor is not in loop, // break: any block which is an exit node whose successor is not in loop,
// and this block is not marked as the terminator // and this block is not marked as the terminator
// //
const std::vector<BasicBlock*> &blocks = L->getBlocks(); const std::vector<BasicBlock*> &blocks = L->getBlocks();
for (std::vector<BasicBlock*>::const_iterator i = blocks.begin(), e = blocks.end(); for (std::vector<BasicBlock*>::const_iterator I = blocks.begin(),
i != e; ++i) { e = blocks.end(); I != e; ++I)
if (L->isLoopExit(*i) && (*i != terminator)) { if (L->isLoopExit(*I) && *I != terminator)
for (succ_iterator SI = succ_begin(*i), SE = succ_end(*i); SI != SE; ++SI) { for (succ_iterator SI = succ_begin(*I), SE = succ_end(*I); SI != SE; ++SI)
if (! L->contains(*SI)) { if (!L->contains(*SI)) {
DEBUG(std::cerr << "break found in loop"); DEBUG(std::cerr << "break found in loop");
return NULL; return 0;
} }
}
}
}
BranchInst *B = dyn_cast<BranchInst>(terminator->getTerminator()); BranchInst *B = dyn_cast<BranchInst>(terminator->getTerminator());
if (!B) { if (!B) {
// this really should not happen DEBUG(std::cerr << "Terminator is not a cond branch!");
DEBUG(std::cerr << "no terminator instruction!"); return 0;
return NULL;
} }
SetCondInst *SCI = dyn_cast<SetCondInst>(B->getCondition()); SetCondInst *SCI = dyn_cast<SetCondInst>(B->getCondition());
if (!SCI) {
if (SCI && InductionType == Canonical) { DEBUG(std::cerr << "Not a cond branch on setcc!\n");
DEBUG(std::cerr << "sci:" << *SCI); return 0;
Value *condVal0 = SCI->getOperand(0); }
Value *condVal1 = SCI->getOperand(1);
Value *indVar = 0; DEBUG(std::cerr << "sci:" << *SCI);
Value *condVal0 = SCI->getOperand(0);
// the induction variable is the one coming from the backedge Value *condVal1 = SCI->getOperand(1);
if (L->contains(Phi->getIncomingBlock(0))) { Value *indVar = 0;
indVar = Phi->getIncomingValue(0);
} else { // the induction variable is the one coming from the backedge
indVar = Phi->getIncomingValue(1); indVar = Phi->getIncomingValue(L->contains(Phi->getIncomingBlock(1)));
}
// check to see if indVar is one of the parameters in SCI // Check to see if indVar is one of the parameters in SCI and if the other is
// and if the other is loop-invariant, it is the UB // loop-invariant, it is the UB
if (indVar == condVal0) { if (indVar == condVal0) {
if (isLoopInvariant(condVal1, L)) { if (isLoopInvariant(condVal1, L))
End = condVal1; End = condVal1;
} else { else {
DEBUG(std::cerr << "not loop invariant 1\n"); DEBUG(std::cerr << "not loop invariant 1\n");
} return 0;
} else if (indVar == condVal1) { }
if (isLoopInvariant(condVal0, L)) { } else if (indVar == condVal1) {
End = condVal0; if (isLoopInvariant(condVal0, L))
} else { End = condVal0;
DEBUG(std::cerr << "not loop invariant 0\n"); else {
} DEBUG(std::cerr << "not loop invariant 0\n");
} return 0;
}
if (End) { } else {
switch (SCI->getOpcode()) { DEBUG(std::cerr << "Loop condition doesn't directly uses indvar\n");
case Instruction::SetLT: return 0;
case Instruction::SetNE: break; // already done }
case Instruction::SetLE: {
// if compared to a constant int N, then predict N+1 iterations switch (SCI->getOpcode()) {
if (ConstantSInt *ubSigned = dyn_cast<ConstantSInt>(End)) { case Instruction::SetLT:
End = ConstantSInt::get(ubSigned->getType(), ubSigned->getValue()+1); case Instruction::SetNE: return End; // already done
DEBUG(std::cerr << "signed int constant\n"); case Instruction::SetLE:
} else if (ConstantUInt *ubUnsigned = dyn_cast<ConstantUInt>(End)) { // if compared to a constant int N, then predict N+1 iterations
End = ConstantUInt::get(ubUnsigned->getType(), if (ConstantSInt *ubSigned = dyn_cast<ConstantSInt>(End)) {
ubUnsigned->getValue()+1); DEBUG(std::cerr << "signed int constant\n");
DEBUG(std::cerr << "unsigned int constant\n"); return ConstantSInt::get(ubSigned->getType(), ubSigned->getValue()+1);
} else { } else if (ConstantUInt *ubUnsigned = dyn_cast<ConstantUInt>(End)) {
DEBUG(std::cerr << "symbolic bound\n"); DEBUG(std::cerr << "unsigned int constant\n");
//End = NULL; return ConstantUInt::get(ubUnsigned->getType(),
// new expression N+1 ubUnsigned->getValue()+1);
End = BinaryOperator::create(Instruction::Add, End, } else {
ConstantUInt::get(ubUnsigned->getType(), DEBUG(std::cerr << "symbolic bound\n");
1)); // new expression N+1, insert right before the SCI. FIXME: If End is loop
} // invariant, then so is this expression. We should insert it in the loop
break; // preheader if it exists.
} return BinaryOperator::create(Instruction::Add, End,
default: End = NULL; // cannot predict ConstantInt::get(End->getType(), 1),
} "tripcount", SCI);
} }
return End;
} else { default:
DEBUG(std::cerr << "SCI null or non-canonical ind var\n"); return 0; // cannot predict
} }
return NULL;
} }