mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-16 23:38:40 +00:00
Add memoization for getSCEVAtScope results for instructions
which are not analyzed with SCEV techniques, which can require brute-forcing through a large number of instructions. This fixes a massive compile-time issue on 400.perlbench (in particular, the loop in MD5Transform). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@71259 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
66a7e857aa
commit
6bce643c36
@ -271,6 +271,11 @@ namespace llvm {
|
|||||||
/// exit value.
|
/// exit value.
|
||||||
std::map<PHINode*, Constant*> ConstantEvolutionLoopExitValue;
|
std::map<PHINode*, Constant*> ConstantEvolutionLoopExitValue;
|
||||||
|
|
||||||
|
/// ValuesAtScopes - This map contains entries for all the instructions
|
||||||
|
/// that we attempt to compute getSCEVAtScope information for without
|
||||||
|
/// using SCEV techniques, which can be expensive.
|
||||||
|
std::map<Instruction *, std::map<const Loop *, Constant *> > ValuesAtScopes;
|
||||||
|
|
||||||
/// createSCEV - We know that there is no SCEV for the specified value.
|
/// createSCEV - We know that there is no SCEV for the specified value.
|
||||||
/// Analyze the expression.
|
/// Analyze the expression.
|
||||||
SCEVHandle createSCEV(Value *V);
|
SCEVHandle createSCEV(Value *V);
|
||||||
|
@ -2766,6 +2766,13 @@ SCEVHandle ScalarEvolution::getSCEVAtScope(const SCEV *V, const Loop *L) {
|
|||||||
// the arguments into constants, and if so, try to constant propagate the
|
// the arguments into constants, and if so, try to constant propagate the
|
||||||
// result. This is particularly useful for computing loop exit values.
|
// result. This is particularly useful for computing loop exit values.
|
||||||
if (CanConstantFold(I)) {
|
if (CanConstantFold(I)) {
|
||||||
|
// Check to see if we've folded this instruction at this loop before.
|
||||||
|
std::map<const Loop *, Constant *> &Values = ValuesAtScopes[I];
|
||||||
|
std::pair<std::map<const Loop *, Constant *>::iterator, bool> Pair =
|
||||||
|
Values.insert(std::make_pair(L, static_cast<Constant *>(0)));
|
||||||
|
if (!Pair.second)
|
||||||
|
return Pair.first->second ? &*getUnknown(Pair.first->second) : V;
|
||||||
|
|
||||||
std::vector<Constant*> Operands;
|
std::vector<Constant*> Operands;
|
||||||
Operands.reserve(I->getNumOperands());
|
Operands.reserve(I->getNumOperands());
|
||||||
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
|
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
|
||||||
@ -2812,6 +2819,7 @@ SCEVHandle ScalarEvolution::getSCEVAtScope(const SCEV *V, const Loop *L) {
|
|||||||
else
|
else
|
||||||
C = ConstantFoldInstOperands(I->getOpcode(), I->getType(),
|
C = ConstantFoldInstOperands(I->getOpcode(), I->getType(),
|
||||||
&Operands[0], Operands.size());
|
&Operands[0], Operands.size());
|
||||||
|
Pair.first->second = C;
|
||||||
return getUnknown(C);
|
return getUnknown(C);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3473,6 +3481,8 @@ void SCEVCallbackVH::deleted() {
|
|||||||
assert(SE && "SCEVCallbackVH called with a non-null ScalarEvolution!");
|
assert(SE && "SCEVCallbackVH called with a non-null ScalarEvolution!");
|
||||||
if (PHINode *PN = dyn_cast<PHINode>(getValPtr()))
|
if (PHINode *PN = dyn_cast<PHINode>(getValPtr()))
|
||||||
SE->ConstantEvolutionLoopExitValue.erase(PN);
|
SE->ConstantEvolutionLoopExitValue.erase(PN);
|
||||||
|
if (Instruction *I = dyn_cast<Instruction>(getValPtr()))
|
||||||
|
SE->ValuesAtScopes.erase(I);
|
||||||
SE->Scalars.erase(getValPtr());
|
SE->Scalars.erase(getValPtr());
|
||||||
// this now dangles!
|
// this now dangles!
|
||||||
}
|
}
|
||||||
@ -3499,6 +3509,8 @@ void SCEVCallbackVH::allUsesReplacedWith(Value *) {
|
|||||||
}
|
}
|
||||||
if (PHINode *PN = dyn_cast<PHINode>(U))
|
if (PHINode *PN = dyn_cast<PHINode>(U))
|
||||||
SE->ConstantEvolutionLoopExitValue.erase(PN);
|
SE->ConstantEvolutionLoopExitValue.erase(PN);
|
||||||
|
if (Instruction *I = dyn_cast<Instruction>(U))
|
||||||
|
SE->ValuesAtScopes.erase(I);
|
||||||
if (SE->Scalars.erase(U))
|
if (SE->Scalars.erase(U))
|
||||||
for (Value::use_iterator UI = U->use_begin(), UE = U->use_end();
|
for (Value::use_iterator UI = U->use_begin(), UE = U->use_end();
|
||||||
UI != UE; ++UI)
|
UI != UE; ++UI)
|
||||||
@ -3507,6 +3519,8 @@ void SCEVCallbackVH::allUsesReplacedWith(Value *) {
|
|||||||
if (DeleteOld) {
|
if (DeleteOld) {
|
||||||
if (PHINode *PN = dyn_cast<PHINode>(Old))
|
if (PHINode *PN = dyn_cast<PHINode>(Old))
|
||||||
SE->ConstantEvolutionLoopExitValue.erase(PN);
|
SE->ConstantEvolutionLoopExitValue.erase(PN);
|
||||||
|
if (Instruction *I = dyn_cast<Instruction>(Old))
|
||||||
|
SE->ValuesAtScopes.erase(I);
|
||||||
SE->Scalars.erase(Old);
|
SE->Scalars.erase(Old);
|
||||||
// this now dangles!
|
// this now dangles!
|
||||||
}
|
}
|
||||||
@ -3535,6 +3549,7 @@ void ScalarEvolution::releaseMemory() {
|
|||||||
Scalars.clear();
|
Scalars.clear();
|
||||||
BackedgeTakenCounts.clear();
|
BackedgeTakenCounts.clear();
|
||||||
ConstantEvolutionLoopExitValue.clear();
|
ConstantEvolutionLoopExitValue.clear();
|
||||||
|
ValuesAtScopes.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScalarEvolution::getAnalysisUsage(AnalysisUsage &AU) const {
|
void ScalarEvolution::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user