static const bool ViewISelDAGs = 0, ViewSchedDAGs = 0;
#endif
-// Scheduling heuristics
-enum SchedHeuristics {
- defaultScheduling, // Let the target specify its preference.
- noScheduling, // No scheduling, emit breadth first sequence.
- simpleScheduling, // Two pass, min. critical path, max. utilization.
- simpleNoItinScheduling, // Same as above exact using generic latency.
- listSchedulingBURR, // Bottom up reg reduction list scheduling.
- listSchedulingTD // Top-down list scheduler.
-};
-
namespace {
- cl::opt<SchedHeuristics>
+ cl::opt<ScheduleDAG::SchedHeuristics>
ISHeuristic(
"sched",
cl::desc("Choose scheduling style"),
- cl::init(defaultScheduling),
+ cl::init(ScheduleDAG::defaultScheduling),
cl::values(
- clEnumValN(defaultScheduling, "default",
+ clEnumValN(ScheduleDAG::defaultScheduling, "default",
"Target preferred scheduling style"),
- clEnumValN(noScheduling, "none",
+ clEnumValN(ScheduleDAG::noScheduling, "none",
"No scheduling: breadth first sequencing"),
- clEnumValN(simpleScheduling, "simple",
+ clEnumValN(ScheduleDAG::simpleScheduling, "simple",
"Simple two pass scheduling: minimize critical path "
"and maximize processor utilization"),
- clEnumValN(simpleNoItinScheduling, "simple-noitin",
+ clEnumValN(ScheduleDAG::simpleNoItinScheduling, "simple-noitin",
"Simple two pass scheduling: Same as simple "
"except using generic latency"),
- clEnumValN(listSchedulingBURR, "list-burr",
- "Bottom up register reduction list scheduling"),
- clEnumValN(listSchedulingTD, "list-td",
+ clEnumValN(ScheduleDAG::listSchedulingBURR, "list-burr",
+ "Bottom-up register reduction list scheduling"),
+ clEnumValN(ScheduleDAG::listSchedulingTDRR, "list-tdrr",
+ "Top-down register reduction list scheduling"),
+ clEnumValN(ScheduleDAG::listSchedulingTD, "list-td",
"Top-down list scheduler"),
clEnumValEnd));
} // namespace
const BasicBlock *LLVMBB = CurMBB->getBasicBlock();
Reloc::Model Relocs = TLI.getTargetMachine().getRelocationModel();
- // If the switch has more than 5 blocks, and at least 75% dense, then emit a
- // jump table rather than lowering the switch to a binary tree of conditional
- // branches.
+ // If the switch has more than 5 blocks, and at least 31.25% dense, and the
+ // target supports indirect branches, then emit a jump table rather than
+ // lowering the switch to a binary tree of conditional branches.
// FIXME: Make this work with PIC code
if (TLI.isOperationLegal(ISD::BRIND, TLI.getPointerTy()) &&
(Relocs == Reloc::Static || Relocs == Reloc::DynamicNoPIC) &&
uint64_t Last = cast<ConstantIntegral>(Cases.back().first)->getRawValue();
double Density = (double)Cases.size() / (double)((Last - First) + 1ULL);
- if (Density >= 0.75) {
+ if (Density >= 0.3125) {
// Create a new basic block to hold the code for loading the address
// of the jump table, and jumping to it. Update successor information;
// we will either branch to the default case for the switch, or the jump
/// InsertGEPComputeCode - Insert code into BB to compute Ptr+PtrOffset,
/// casting to the type of GEPI.
-static Value *InsertGEPComputeCode(Value *&V, BasicBlock *BB, Instruction *GEPI,
- Value *Ptr, Value *PtrOffset) {
+static Instruction *InsertGEPComputeCode(Instruction *&V, BasicBlock *BB,
+ Instruction *GEPI, Value *Ptr,
+ Value *PtrOffset) {
if (V) return V; // Already computed.
BasicBlock::iterator InsertPt;
// Add the offset, cast it to the right type.
Ptr = BinaryOperator::createAdd(Ptr, PtrOffset, "", InsertPt);
- Ptr = new CastInst(Ptr, GEPI->getType(), "", InsertPt);
- return V = Ptr;
+ return V = new CastInst(Ptr, GEPI->getType(), "", InsertPt);
}
/// ReplaceUsesOfGEPInst - Replace all uses of RepPtr with inserted code to
static void ReplaceUsesOfGEPInst(Instruction *RepPtr, Value *Ptr,
Constant *PtrOffset, BasicBlock *DefBB,
GetElementPtrInst *GEPI,
- std::map<BasicBlock*,Value*> &InsertedExprs) {
+ std::map<BasicBlock*,Instruction*> &InsertedExprs) {
while (!RepPtr->use_empty()) {
Instruction *User = cast<Instruction>(RepPtr->use_back());
// If this is a load of the pointer, or a store through the pointer, emit
// the increment into the load/store block.
- Value *NewVal;
+ Instruction *NewVal;
if (isa<LoadInst>(User) ||
(isa<StoreInst>(User) && User->getOperand(0) != RepPtr)) {
NewVal = InsertGEPComputeCode(InsertedExprs[User->getParent()],
Ptr, PtrOffset);
}
- if (GEPI->getType() != RepPtr->getType())
- NewVal = new CastInst(NewVal, RepPtr->getType(), "", User);
+ if (GEPI->getType() != RepPtr->getType()) {
+ BasicBlock::iterator IP = NewVal;
+ ++IP;
+ NewVal = new CastInst(NewVal, RepPtr->getType(), "", IP);
+ }
User->replaceUsesOfWith(RepPtr, NewVal);
}
}
// block, otherwise we use a canonical version right next to the gep (these
// won't be foldable as addresses, so we might as well share the computation).
- std::map<BasicBlock*,Value*> InsertedExprs;
+ std::map<BasicBlock*,Instruction*> InsertedExprs;
ReplaceUsesOfGEPInst(GEPI, Ptr, PtrOffset, DefBB, GEPI, InsertedExprs);
// Finally, the GEP is dead, remove it.
switch (ISHeuristic) {
default: assert(0 && "Unrecognized scheduling heuristic");
- case defaultScheduling:
+ case ScheduleDAG::defaultScheduling:
if (TLI.getSchedulingPreference() == TargetLowering::SchedulingForLatency)
SL = createTDListDAGScheduler(DAG, BB, CreateTargetHazardRecognizer());
else {
SL = createBURRListDAGScheduler(DAG, BB);
}
break;
- case noScheduling:
+ case ScheduleDAG::noScheduling:
SL = createBFS_DAGScheduler(DAG, BB);
break;
- case simpleScheduling:
+ case ScheduleDAG::simpleScheduling:
SL = createSimpleDAGScheduler(false, DAG, BB);
break;
- case simpleNoItinScheduling:
+ case ScheduleDAG::simpleNoItinScheduling:
SL = createSimpleDAGScheduler(true, DAG, BB);
break;
- case listSchedulingBURR:
+ case ScheduleDAG::listSchedulingBURR:
SL = createBURRListDAGScheduler(DAG, BB);
break;
- case listSchedulingTD:
+ case ScheduleDAG::listSchedulingTDRR:
+ SL = createTDRRListDAGScheduler(DAG, BB);
+ break;
+ case ScheduleDAG::listSchedulingTD:
SL = createTDListDAGScheduler(DAG, BB, CreateTargetHazardRecognizer());
break;
}