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
llvm-svn: 8434
			
			
This commit is contained in:
		
							parent
							
								
									732ae94521
								
							
						
					
					
						commit
						960a857dac
					
				| 
						 | 
					@ -156,6 +156,8 @@ 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) {
 | 
				
			||||||
 | 
					    DEBUG(std::cerr << "Not a cond branch on setcc!\n");
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (SCI && InductionType == Canonical) {
 | 
					 | 
				
			||||||
  DEBUG(std::cerr << "sci:" << *SCI);
 | 
					  DEBUG(std::cerr << "sci:" << *SCI);
 | 
				
			||||||
  Value *condVal0 = SCI->getOperand(0);
 | 
					  Value *condVal0 = SCI->getOperand(0);
 | 
				
			||||||
  Value *condVal1 = SCI->getOperand(1);
 | 
					  Value *condVal1 = SCI->getOperand(1);
 | 
				
			||||||
  Value *indVar = 0;
 | 
					  Value *indVar = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // the induction variable is the one coming from the backedge
 | 
					  // the induction variable is the one coming from the backedge
 | 
				
			||||||
    if (L->contains(Phi->getIncomingBlock(0))) {
 | 
					  indVar = Phi->getIncomingValue(L->contains(Phi->getIncomingBlock(1)));
 | 
				
			||||||
      indVar = Phi->getIncomingValue(0);
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      indVar = Phi->getIncomingValue(1);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // check to see if indVar is one of the parameters in SCI
 | 
					
 | 
				
			||||||
    // and if the other is loop-invariant, it is the UB
 | 
					  // Check to see if indVar is one of the parameters in SCI and if the other is
 | 
				
			||||||
 | 
					  // 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) {
 | 
					  } else if (indVar == condVal1) {
 | 
				
			||||||
      if (isLoopInvariant(condVal0, L)) {
 | 
					    if (isLoopInvariant(condVal0, L))
 | 
				
			||||||
      End = condVal0;
 | 
					      End = condVal0;
 | 
				
			||||||
      } else {
 | 
					    else {
 | 
				
			||||||
      DEBUG(std::cerr << "not loop invariant 0\n");
 | 
					      DEBUG(std::cerr << "not loop invariant 0\n");
 | 
				
			||||||
 | 
					      return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    DEBUG(std::cerr << "Loop condition doesn't directly uses indvar\n");
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (End) {
 | 
					 | 
				
			||||||
  switch (SCI->getOpcode()) {
 | 
					  switch (SCI->getOpcode()) {
 | 
				
			||||||
  case Instruction::SetLT:
 | 
					  case Instruction::SetLT:
 | 
				
			||||||
      case Instruction::SetNE: break; // already done
 | 
					  case Instruction::SetNE: return End; // already done
 | 
				
			||||||
      case Instruction::SetLE: {
 | 
					  case Instruction::SetLE:
 | 
				
			||||||
    // if compared to a constant int N, then predict N+1 iterations
 | 
					    // if compared to a constant int N, then predict N+1 iterations
 | 
				
			||||||
    if (ConstantSInt *ubSigned = dyn_cast<ConstantSInt>(End)) {
 | 
					    if (ConstantSInt *ubSigned = dyn_cast<ConstantSInt>(End)) {
 | 
				
			||||||
          End = ConstantSInt::get(ubSigned->getType(), ubSigned->getValue()+1);
 | 
					 | 
				
			||||||
      DEBUG(std::cerr << "signed int constant\n");
 | 
					      DEBUG(std::cerr << "signed int constant\n");
 | 
				
			||||||
 | 
					      return ConstantSInt::get(ubSigned->getType(), ubSigned->getValue()+1);
 | 
				
			||||||
    } else if (ConstantUInt *ubUnsigned = dyn_cast<ConstantUInt>(End)) {
 | 
					    } else if (ConstantUInt *ubUnsigned = dyn_cast<ConstantUInt>(End)) {
 | 
				
			||||||
          End = ConstantUInt::get(ubUnsigned->getType(),
 | 
					 | 
				
			||||||
                                  ubUnsigned->getValue()+1);
 | 
					 | 
				
			||||||
      DEBUG(std::cerr << "unsigned int constant\n");
 | 
					      DEBUG(std::cerr << "unsigned int constant\n");
 | 
				
			||||||
 | 
					      return ConstantUInt::get(ubUnsigned->getType(),
 | 
				
			||||||
 | 
					                               ubUnsigned->getValue()+1);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      DEBUG(std::cerr << "symbolic bound\n");
 | 
					      DEBUG(std::cerr << "symbolic bound\n");
 | 
				
			||||||
          //End = NULL;
 | 
					      // new expression N+1, insert right before the SCI.  FIXME: If End is loop
 | 
				
			||||||
          // new expression N+1
 | 
					      // invariant, then so is this expression.  We should insert it in the loop
 | 
				
			||||||
          End = BinaryOperator::create(Instruction::Add, End, 
 | 
					      // preheader if it exists.
 | 
				
			||||||
                                       ConstantUInt::get(ubUnsigned->getType(),
 | 
					      return BinaryOperator::create(Instruction::Add, End, 
 | 
				
			||||||
                                                         1));
 | 
					                                    ConstantInt::get(End->getType(), 1),
 | 
				
			||||||
 | 
					                                    "tripcount", SCI);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
        break;
 | 
					
 | 
				
			||||||
 | 
					  default:
 | 
				
			||||||
 | 
					    return 0; // cannot predict
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
      default: End = NULL; // cannot predict
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return End;
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    DEBUG(std::cerr << "SCI null or non-canonical ind var\n");
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return NULL;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue