mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-27 14:34:58 +00:00
Make the code that updates ScalarEvolution's internal state in response
to a loop deletion more thorough. Don't prune the def-use tree search at instructions that don't have SCEVs computed, because an instruction with a user that has a computed SCEV may itself lack a computed SCEV. Also, remove loop-related values from the ValuesAtScopes and ConstantEvolutionLoopExitValues maps as well. This fixes a regression in 483.xalancbmk. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75030 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
85ebb0f66c
commit
59ae6b9987
@ -346,11 +346,6 @@ namespace llvm {
|
||||
Constant *getConstantEvolutionLoopExitValue(PHINode *PN, const APInt& BEs,
|
||||
const Loop *L);
|
||||
|
||||
/// forgetLoopPHIs - Delete the memoized SCEVs associated with the
|
||||
/// PHI nodes in the given loop. This is used when the trip count of
|
||||
/// the loop may have changed.
|
||||
void forgetLoopPHIs(const Loop *L);
|
||||
|
||||
public:
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
ScalarEvolution();
|
||||
|
@ -81,6 +81,7 @@
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include <algorithm>
|
||||
using namespace llvm;
|
||||
|
||||
@ -2856,6 +2857,29 @@ const SCEV *ScalarEvolution::getMaxBackedgeTakenCount(const Loop *L) {
|
||||
return getBackedgeTakenInfo(L).Max;
|
||||
}
|
||||
|
||||
/// PushLoopPHIs - Push PHI nodes in the header of the given loop
|
||||
/// onto the given Worklist.
|
||||
static void
|
||||
PushLoopPHIs(const Loop *L, SmallVectorImpl<Instruction *> &Worklist) {
|
||||
BasicBlock *Header = L->getHeader();
|
||||
|
||||
// Push all Loop-header PHIs onto the Worklist stack.
|
||||
for (BasicBlock::iterator I = Header->begin();
|
||||
PHINode *PN = dyn_cast<PHINode>(I); ++I)
|
||||
Worklist.push_back(PN);
|
||||
}
|
||||
|
||||
/// PushDefUseChildren - Push users of the given Instruction
|
||||
/// onto the given Worklist.
|
||||
static void
|
||||
PushDefUseChildren(Instruction *I,
|
||||
SmallVectorImpl<Instruction *> &Worklist) {
|
||||
// Push the def-use children onto the Worklist stack.
|
||||
for (Value::use_iterator UI = I->use_begin(), UE = I->use_end();
|
||||
UI != UE; ++UI)
|
||||
Worklist.push_back(cast<Instruction>(UI));
|
||||
}
|
||||
|
||||
const ScalarEvolution::BackedgeTakenInfo &
|
||||
ScalarEvolution::getBackedgeTakenInfo(const Loop *L) {
|
||||
// Initially insert a CouldNotCompute for this loop. If the insertion
|
||||
@ -2886,10 +2910,38 @@ ScalarEvolution::getBackedgeTakenInfo(const Loop *L) {
|
||||
|
||||
// Now that we know more about the trip count for this loop, forget any
|
||||
// existing SCEV values for PHI nodes in this loop since they are only
|
||||
// conservative estimates made without the benefit
|
||||
// of trip count information.
|
||||
if (ItCount.hasAnyInfo())
|
||||
forgetLoopPHIs(L);
|
||||
// conservative estimates made without the benefit of trip count
|
||||
// information. This is similar to the code in
|
||||
// forgetLoopBackedgeTakenCount, except that it handles SCEVUnknown PHI
|
||||
// nodes specially.
|
||||
if (ItCount.hasAnyInfo()) {
|
||||
SmallVector<Instruction *, 16> Worklist;
|
||||
PushLoopPHIs(L, Worklist);
|
||||
|
||||
SmallPtrSet<Instruction *, 8> Visited;
|
||||
while (!Worklist.empty()) {
|
||||
Instruction *I = Worklist.pop_back_val();
|
||||
if (!Visited.insert(I)) continue;
|
||||
|
||||
std::map<SCEVCallbackVH, const SCEV*>::iterator It =
|
||||
Scalars.find(static_cast<Value *>(I));
|
||||
if (It != Scalars.end()) {
|
||||
// SCEVUnknown for a PHI either means that it has an unrecognized
|
||||
// structure, or it's a PHI that's in the progress of being computed
|
||||
// by createNodeForPHI. In the former case, additional loop trip count
|
||||
// information isn't going to change anything. In the later case,
|
||||
// createNodeForPHI will perform the necessary updates on its own when
|
||||
// it gets to that point.
|
||||
if (!isa<PHINode>(I) || !isa<SCEVUnknown>(It->second))
|
||||
Scalars.erase(It);
|
||||
ValuesAtScopes.erase(I);
|
||||
if (PHINode *PN = dyn_cast<PHINode>(I))
|
||||
ConstantEvolutionLoopExitValue.erase(PN);
|
||||
}
|
||||
|
||||
PushDefUseChildren(I, Worklist);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Pair.first->second;
|
||||
}
|
||||
@ -2900,37 +2952,25 @@ ScalarEvolution::getBackedgeTakenInfo(const Loop *L) {
|
||||
/// is deleted.
|
||||
void ScalarEvolution::forgetLoopBackedgeTakenCount(const Loop *L) {
|
||||
BackedgeTakenCounts.erase(L);
|
||||
forgetLoopPHIs(L);
|
||||
}
|
||||
|
||||
/// forgetLoopPHIs - Delete the memoized SCEVs associated with the
|
||||
/// PHI nodes in the given loop. This is used when the trip count of
|
||||
/// the loop may have changed.
|
||||
void ScalarEvolution::forgetLoopPHIs(const Loop *L) {
|
||||
BasicBlock *Header = L->getHeader();
|
||||
|
||||
// Push all Loop-header PHIs onto the Worklist stack, except those
|
||||
// that are presently represented via a SCEVUnknown. SCEVUnknown for
|
||||
// a PHI either means that it has an unrecognized structure, or it's
|
||||
// a PHI that's in the progress of being computed by createNodeForPHI.
|
||||
// In the former case, additional loop trip count information isn't
|
||||
// going to change anything. In the later case, createNodeForPHI will
|
||||
// perform the necessary updates on its own when it gets to that point.
|
||||
SmallVector<Instruction *, 16> Worklist;
|
||||
for (BasicBlock::iterator I = Header->begin();
|
||||
PHINode *PN = dyn_cast<PHINode>(I); ++I) {
|
||||
std::map<SCEVCallbackVH, const SCEV *>::iterator It =
|
||||
Scalars.find((Value*)I);
|
||||
if (It != Scalars.end() && !isa<SCEVUnknown>(It->second))
|
||||
Worklist.push_back(PN);
|
||||
}
|
||||
PushLoopPHIs(L, Worklist);
|
||||
|
||||
SmallPtrSet<Instruction *, 8> Visited;
|
||||
while (!Worklist.empty()) {
|
||||
Instruction *I = Worklist.pop_back_val();
|
||||
if (Scalars.erase(I))
|
||||
for (Value::use_iterator UI = I->use_begin(), UE = I->use_end();
|
||||
UI != UE; ++UI)
|
||||
Worklist.push_back(cast<Instruction>(UI));
|
||||
if (!Visited.insert(I)) continue;
|
||||
|
||||
std::map<SCEVCallbackVH, const SCEV*>::iterator It =
|
||||
Scalars.find(static_cast<Value *>(I));
|
||||
if (It != Scalars.end()) {
|
||||
Scalars.erase(It);
|
||||
ValuesAtScopes.erase(I);
|
||||
if (PHINode *PN = dyn_cast<PHINode>(I))
|
||||
ConstantEvolutionLoopExitValue.erase(PN);
|
||||
}
|
||||
|
||||
PushDefUseChildren(I, Worklist);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user