Fix a pruning heuristic which implicitly assumed that SmallPtrSet is

deterministically sorted.

llvm-svn: 96071
This commit is contained in:
Dan Gohman 2010-02-13 02:06:02 +00:00
parent 6eb7ff5bbf
commit 25722fd3fc

View File

@ -579,6 +579,10 @@ private:
SmallPtrSet<const SCEV *, 16> &Regs, SmallPtrSet<const SCEV *, 16> &Regs,
const Loop *L, const Loop *L,
ScalarEvolution &SE, DominatorTree &DT); ScalarEvolution &SE, DominatorTree &DT);
void RatePrimaryRegister(const SCEV *Reg,
SmallPtrSet<const SCEV *, 16> &Regs,
const Loop *L,
ScalarEvolution &SE, DominatorTree &DT);
}; };
} }
@ -588,7 +592,6 @@ void Cost::RateRegister(const SCEV *Reg,
SmallPtrSet<const SCEV *, 16> &Regs, SmallPtrSet<const SCEV *, 16> &Regs,
const Loop *L, const Loop *L,
ScalarEvolution &SE, DominatorTree &DT) { ScalarEvolution &SE, DominatorTree &DT) {
if (Regs.insert(Reg)) {
if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(Reg)) { if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(Reg)) {
if (AR->getLoop() == L) if (AR->getLoop() == L)
AddRecCost += 1; /// TODO: This should be a function of the stride. AddRecCost += 1; /// TODO: This should be a function of the stride.
@ -606,17 +609,20 @@ void Cost::RateRegister(const SCEV *Reg,
(SE.getEffectiveSCEVType(PN->getType()) == (SE.getEffectiveSCEVType(PN->getType()) ==
SE.getEffectiveSCEVType(AR->getType())) && SE.getEffectiveSCEVType(AR->getType())) &&
SE.getSCEV(PN) == AR) SE.getSCEV(PN) == AR)
goto no_cost; return;
// If this isn't one of the addrecs that the loop already has, it // If this isn't one of the addrecs that the loop already has, it
// would require a costly new phi and add. // would require a costly new phi and add. TODO: This isn't
// precisely modeled right now.
++NumBaseAdds; ++NumBaseAdds;
if (!Regs.count(AR->getStart()))
RateRegister(AR->getStart(), Regs, L, SE, DT); RateRegister(AR->getStart(), Regs, L, SE, DT);
} }
// Add the step value register, if it needs one. // Add the step value register, if it needs one.
// TODO: The non-affine case isn't precisely modeled here. // TODO: The non-affine case isn't precisely modeled here.
if (!AR->isAffine() || !isa<SCEVConstant>(AR->getOperand(1))) if (!AR->isAffine() || !isa<SCEVConstant>(AR->getOperand(1)))
if (!Regs.count(AR->getStart()))
RateRegister(AR->getOperand(1), Regs, L, SE, DT); RateRegister(AR->getOperand(1), Regs, L, SE, DT);
} }
++NumRegs; ++NumRegs;
@ -629,8 +635,16 @@ void Cost::RateRegister(const SCEV *Reg,
(isa<SCEVUnknown>(cast<SCEVAddRecExpr>(Reg)->getStart()) || (isa<SCEVUnknown>(cast<SCEVAddRecExpr>(Reg)->getStart()) ||
isa<SCEVConstant>(cast<SCEVAddRecExpr>(Reg)->getStart())))) isa<SCEVConstant>(cast<SCEVAddRecExpr>(Reg)->getStart()))))
++SetupCost; ++SetupCost;
no_cost:;
} }
/// RatePrimaryRegister - Record this register in the set. If we haven't seen it
/// before, rate it.
void Cost::RatePrimaryRegister(const SCEV *Reg,
SmallPtrSet<const SCEV *, 16> &Regs,
const Loop *L,
ScalarEvolution &SE, DominatorTree &DT) {
if (Regs.insert(Reg))
RateRegister(Reg, Regs, L, SE, DT);
} }
void Cost::RateFormula(const Formula &F, void Cost::RateFormula(const Formula &F,
@ -645,7 +659,7 @@ void Cost::RateFormula(const Formula &F,
Loose(); Loose();
return; return;
} }
RateRegister(ScaledReg, Regs, L, SE, DT); RatePrimaryRegister(ScaledReg, Regs, L, SE, DT);
} }
for (SmallVectorImpl<const SCEV *>::const_iterator I = F.BaseRegs.begin(), for (SmallVectorImpl<const SCEV *>::const_iterator I = F.BaseRegs.begin(),
E = F.BaseRegs.end(); I != E; ++I) { E = F.BaseRegs.end(); I != E; ++I) {
@ -654,7 +668,7 @@ void Cost::RateFormula(const Formula &F,
Loose(); Loose();
return; return;
} }
RateRegister(BaseReg, Regs, L, SE, DT); RatePrimaryRegister(BaseReg, Regs, L, SE, DT);
NumIVMuls += isa<SCEVMulExpr>(BaseReg) && NumIVMuls += isa<SCEVMulExpr>(BaseReg) &&
BaseReg->hasComputableLoopEvolution(L); BaseReg->hasComputableLoopEvolution(L);
@ -2493,7 +2507,8 @@ void LSRInstance::FilterOutUndesirableDedicatedRegisters() {
} }
DEBUG(if (Changed) { DEBUG(if (Changed) {
dbgs() << "After filtering out undesirable candidates:\n"; dbgs() << "\n"
"After filtering out undesirable candidates:\n";
print_uses(dbgs()); print_uses(dbgs());
}); });
} }
@ -2610,13 +2625,13 @@ void LSRInstance::SolveRecurse(SmallVectorImpl<const Formula *> &Solution,
SmallSetVector<const SCEV *, 4> ReqRegs; SmallSetVector<const SCEV *, 4> ReqRegs;
for (SmallPtrSet<const SCEV *, 16>::const_iterator I = CurRegs.begin(), for (SmallPtrSet<const SCEV *, 16>::const_iterator I = CurRegs.begin(),
E = CurRegs.end(); I != E; ++I) E = CurRegs.end(); I != E; ++I)
if (LU.Regs.count(*I)) { if (LU.Regs.count(*I))
ReqRegs.insert(*I); ReqRegs.insert(*I);
break;
}
bool AnySatisfiedReqRegs = false;
SmallPtrSet<const SCEV *, 16> NewRegs; SmallPtrSet<const SCEV *, 16> NewRegs;
Cost NewCost; Cost NewCost;
retry:
for (SmallVectorImpl<Formula>::const_iterator I = LU.Formulae.begin(), for (SmallVectorImpl<Formula>::const_iterator I = LU.Formulae.begin(),
E = LU.Formulae.end(); I != E; ++I) { E = LU.Formulae.end(); I != E; ++I) {
const Formula &F = *I; const Formula &F = *I;
@ -2630,6 +2645,7 @@ void LSRInstance::SolveRecurse(SmallVectorImpl<const Formula *> &Solution,
F.BaseRegs.end()) F.BaseRegs.end())
goto skip; goto skip;
} }
AnySatisfiedReqRegs = true;
// Evaluate the cost of the current formula. If it's already worse than // Evaluate the cost of the current formula. If it's already worse than
// the current best, prune the search at that point. // the current best, prune the search at that point.
@ -2658,6 +2674,13 @@ void LSRInstance::SolveRecurse(SmallVectorImpl<const Formula *> &Solution,
} }
skip:; skip:;
} }
// If none of the formulae had all of the required registers, relax the
// constraint so that we don't exclude all formulae.
if (!AnySatisfiedReqRegs) {
ReqRegs.clear();
goto retry;
}
} }
void LSRInstance::Solve(SmallVectorImpl<const Formula *> &Solution) const { void LSRInstance::Solve(SmallVectorImpl<const Formula *> &Solution) const {