mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-29 10:32:47 +00:00
Add Loop contains utility methods for testing whether a loop
contains another loop, or an instruction. The loop form is substantially more efficient on large loops than the typical code it replaces. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@91654 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3ca735450d
commit
92329c7fbe
@ -93,12 +93,28 @@ public:
|
||||
BlockT *getHeader() const { return Blocks.front(); }
|
||||
LoopT *getParentLoop() const { return ParentLoop; }
|
||||
|
||||
/// contains - Return true if the specified basic block is in this loop
|
||||
/// contains - Return true if the specified loop is contained within in
|
||||
/// this loop.
|
||||
///
|
||||
bool contains(const LoopT *L) const {
|
||||
if (L == this) return true;
|
||||
if (L == 0) return false;
|
||||
return contains(L->getParentLoop());
|
||||
}
|
||||
|
||||
/// contains - Return true if the specified basic block is in this loop.
|
||||
///
|
||||
bool contains(const BlockT *BB) const {
|
||||
return std::find(block_begin(), block_end(), BB) != block_end();
|
||||
}
|
||||
|
||||
/// contains - Return true if the specified instruction is in this loop.
|
||||
///
|
||||
template<class InstT>
|
||||
bool contains(const InstT *Inst) const {
|
||||
return contains(Inst->getParent());
|
||||
}
|
||||
|
||||
/// iterator/begin/end - Return the loops contained entirely within this loop.
|
||||
///
|
||||
const std::vector<LoopT *> &getSubLoops() const { return SubLoops; }
|
||||
|
@ -53,7 +53,7 @@ static bool containsAddRecFromDifferentLoop(const SCEV *S, Loop *L) {
|
||||
if (newLoop == L)
|
||||
return false;
|
||||
// if newLoop is an outer loop of L, this is OK.
|
||||
if (newLoop->contains(L->getHeader()))
|
||||
if (newLoop->contains(L))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -148,7 +148,7 @@ static bool IVUseShouldUsePostIncValue(Instruction *User, Instruction *IV,
|
||||
Loop *L, LoopInfo *LI, DominatorTree *DT,
|
||||
Pass *P) {
|
||||
// If the user is in the loop, use the preinc value.
|
||||
if (L->contains(User->getParent())) return false;
|
||||
if (L->contains(User)) return false;
|
||||
|
||||
BasicBlock *LatchBlock = L->getLoopLatch();
|
||||
if (!LatchBlock)
|
||||
@ -209,7 +209,7 @@ bool IVUsers::AddUsersIfInteresting(Instruction *I) {
|
||||
return false; // Non-reducible symbolic expression, bail out.
|
||||
|
||||
// Keep things simple. Don't touch loop-variant strides.
|
||||
if (!Stride->isLoopInvariant(L) && L->contains(I->getParent()))
|
||||
if (!Stride->isLoopInvariant(L) && L->contains(I))
|
||||
return false;
|
||||
|
||||
SmallPtrSet<Instruction *, 4> UniqueUsers;
|
||||
@ -324,7 +324,7 @@ const SCEV *IVUsers::getReplacementExpr(const IVStrideUse &U) const {
|
||||
if (U.isUseOfPostIncrementedValue())
|
||||
RetVal = SE->getAddExpr(RetVal, U.getParent()->Stride);
|
||||
// Evaluate the expression out of the loop, if possible.
|
||||
if (!L->contains(U.getUser()->getParent())) {
|
||||
if (!L->contains(U.getUser())) {
|
||||
const SCEV *ExitVal = SE->getSCEVAtScope(RetVal, L->getParentLoop());
|
||||
if (ExitVal->isLoopInvariant(L))
|
||||
RetVal = ExitVal;
|
||||
|
@ -56,7 +56,7 @@ bool Loop::isLoopInvariant(Value *V) const {
|
||||
/// loop-invariant.
|
||||
///
|
||||
bool Loop::isLoopInvariant(Instruction *I) const {
|
||||
return !contains(I->getParent());
|
||||
return !contains(I);
|
||||
}
|
||||
|
||||
/// makeLoopInvariant - If the given value is an instruciton inside of the
|
||||
|
@ -298,7 +298,7 @@ bool SCEVAddRecExpr::isLoopInvariant(const Loop *QueryLoop) const {
|
||||
return false;
|
||||
|
||||
// This recurrence is variant w.r.t. QueryLoop if QueryLoop contains L.
|
||||
if (QueryLoop->contains(L->getHeader()))
|
||||
if (QueryLoop->contains(L))
|
||||
return false;
|
||||
|
||||
// This recurrence is variant w.r.t. QueryLoop if any of its operands
|
||||
@ -333,7 +333,7 @@ bool SCEVUnknown::isLoopInvariant(const Loop *L) const {
|
||||
// Instructions are never considered invariant in the function body
|
||||
// (null loop) because they are defined within the "loop".
|
||||
if (Instruction *I = dyn_cast<Instruction>(V))
|
||||
return L && !L->contains(I->getParent());
|
||||
return L && !L->contains(I);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3774,7 +3774,7 @@ static PHINode *getConstantEvolvingPHI(Value *V, const Loop *L) {
|
||||
// If this is not an instruction, or if this is an instruction outside of the
|
||||
// loop, it can't be derived from a loop PHI.
|
||||
Instruction *I = dyn_cast<Instruction>(V);
|
||||
if (I == 0 || !L->contains(I->getParent())) return 0;
|
||||
if (I == 0 || !L->contains(I)) return 0;
|
||||
|
||||
if (PHINode *PN = dyn_cast<PHINode>(I)) {
|
||||
if (L->getHeader() == I->getParent())
|
||||
@ -4091,7 +4091,7 @@ const SCEV *ScalarEvolution::computeSCEVAtScope(const SCEV *V, const Loop *L) {
|
||||
// If this is a loop recurrence for a loop that does not contain L, then we
|
||||
// are dealing with the final value computed by the loop.
|
||||
if (const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(V)) {
|
||||
if (!L || !AddRec->getLoop()->contains(L->getHeader())) {
|
||||
if (!L || !AddRec->getLoop()->contains(L)) {
|
||||
// To evaluate this recurrence, we need to know how many times the AddRec
|
||||
// loop iterates. Compute this now.
|
||||
const SCEV *BackedgeTakenCount = getBackedgeTakenCount(AddRec->getLoop());
|
||||
|
@ -322,7 +322,7 @@ bool MachineLICM::IsLoopInvariantInst(MachineInstr &I) {
|
||||
|
||||
// If the loop contains the definition of an operand, then the instruction
|
||||
// isn't loop invariant.
|
||||
if (CurLoop->contains(RegInfo->getVRegDef(Reg)->getParent()))
|
||||
if (CurLoop->contains(RegInfo->getVRegDef(Reg)))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -258,7 +258,7 @@ void IndVarSimplify::RewriteLoopExitValues(Loop *L,
|
||||
|
||||
// Check that InVal is defined in the loop.
|
||||
Instruction *Inst = cast<Instruction>(InVal);
|
||||
if (!L->contains(Inst->getParent()))
|
||||
if (!L->contains(Inst))
|
||||
continue;
|
||||
|
||||
// Okay, this instruction has a user outside of the current loop
|
||||
|
@ -433,7 +433,7 @@ bool LICM::isNotUsedInLoop(Instruction &I) {
|
||||
if (PN->getIncomingValue(i) == &I)
|
||||
if (CurLoop->contains(PN->getIncomingBlock(i)))
|
||||
return false;
|
||||
} else if (CurLoop->contains(User->getParent())) {
|
||||
} else if (CurLoop->contains(User)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -831,7 +831,7 @@ void LICM::FindPromotableValuesInLoop(
|
||||
UI != UE; ++UI) {
|
||||
// Ignore instructions not in this loop.
|
||||
Instruction *Use = dyn_cast<Instruction>(*UI);
|
||||
if (!Use || !CurLoop->contains(Use->getParent()))
|
||||
if (!Use || !CurLoop->contains(Use))
|
||||
continue;
|
||||
|
||||
if (!isa<LoadInst>(Use) && !isa<StoreInst>(Use)) {
|
||||
|
@ -288,7 +288,7 @@ bool LoopIndexSplit::runOnLoop(Loop *IncomingLoop, LPPassManager &LPM_Ref) {
|
||||
// isUsedOutsideLoop - Returns true iff V is used outside the loop L.
|
||||
static bool isUsedOutsideLoop(Value *V, Loop *L) {
|
||||
for(Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ++UI)
|
||||
if (!L->contains(cast<Instruction>(*UI)->getParent()))
|
||||
if (!L->contains(cast<Instruction>(*UI)))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@ -842,7 +842,7 @@ void LoopIndexSplit::updatePHINodes(BasicBlock *ExitBB, BasicBlock *Latch,
|
||||
for (Value::use_iterator UI = PHV->use_begin(), E = PHV->use_end();
|
||||
UI != E; ++UI)
|
||||
if (PHINode *U = dyn_cast<PHINode>(*UI))
|
||||
if (LP->contains(U->getParent())) {
|
||||
if (LP->contains(U)) {
|
||||
NewV = U;
|
||||
break;
|
||||
}
|
||||
|
@ -388,7 +388,7 @@ void BasedUser::RewriteInstructionToUseNewBase(const SCEV *NewBase,
|
||||
// If this is a use outside the loop (which means after, since it is based
|
||||
// on a loop indvar) we use the post-incremented value, so that we don't
|
||||
// artificially make the preinc value live out the bottom of the loop.
|
||||
if (!isUseOfPostIncrementedValue && L->contains(Inst->getParent())) {
|
||||
if (!isUseOfPostIncrementedValue && L->contains(Inst)) {
|
||||
if (NewBasePt && isa<PHINode>(OperandValToReplace)) {
|
||||
InsertPt = NewBasePt;
|
||||
++InsertPt;
|
||||
@ -429,7 +429,7 @@ void BasedUser::RewriteInstructionToUseNewBase(const SCEV *NewBase,
|
||||
// that case(?).
|
||||
Instruction *OldLoc = dyn_cast<Instruction>(OperandValToReplace);
|
||||
BasicBlock *PHIPred = PN->getIncomingBlock(i);
|
||||
if (L->contains(OldLoc->getParent())) {
|
||||
if (L->contains(OldLoc)) {
|
||||
// If this is a critical edge, split the edge so that we do not insert
|
||||
// the code on all predecessor/successor paths. We do this unless this
|
||||
// is the canonical backedge for this loop, as this can make some
|
||||
@ -446,7 +446,7 @@ void BasedUser::RewriteInstructionToUseNewBase(const SCEV *NewBase,
|
||||
// is outside of the loop, and PredTI is in the loop, we want to
|
||||
// move the block to be immediately before the PHI block, not
|
||||
// immediately after PredTI.
|
||||
if (L->contains(PHIPred) && !L->contains(PN->getParent()))
|
||||
if (L->contains(PHIPred) && !L->contains(PN))
|
||||
NewBB->moveBefore(PN->getParent());
|
||||
|
||||
// Splitting the edge can reduce the number of PHI entries we have.
|
||||
@ -458,7 +458,7 @@ void BasedUser::RewriteInstructionToUseNewBase(const SCEV *NewBase,
|
||||
Value *&Code = InsertedCode[PHIPred];
|
||||
if (!Code) {
|
||||
// Insert the code into the end of the predecessor block.
|
||||
Instruction *InsertPt = (L->contains(OldLoc->getParent())) ?
|
||||
Instruction *InsertPt = (L->contains(OldLoc)) ?
|
||||
PHIPred->getTerminator() :
|
||||
OldLoc->getParent()->getTerminator();
|
||||
Code = InsertCodeForBaseAtPosition(NewBase, PN->getType(),
|
||||
@ -697,7 +697,7 @@ RemoveCommonExpressionsFromUseBases(std::vector<BasedUser> &Uses,
|
||||
// it is clearly shared across all the IV's. If the use is outside the loop
|
||||
// (which means after it) we don't want to factor anything *into* the loop,
|
||||
// so just use 0 as the base.
|
||||
if (L->contains(Uses[0].Inst->getParent()))
|
||||
if (L->contains(Uses[0].Inst))
|
||||
std::swap(Result, Uses[0].Base);
|
||||
return Result;
|
||||
}
|
||||
@ -722,7 +722,7 @@ RemoveCommonExpressionsFromUseBases(std::vector<BasedUser> &Uses,
|
||||
// after the loop to affect base computation of values *inside* the loop,
|
||||
// because we can always add their offsets to the result IV after the loop
|
||||
// is done, ensuring we get good code inside the loop.
|
||||
if (!L->contains(Uses[i].Inst->getParent()))
|
||||
if (!L->contains(Uses[i].Inst))
|
||||
continue;
|
||||
NumUsesInsideLoop++;
|
||||
|
||||
@ -778,7 +778,7 @@ RemoveCommonExpressionsFromUseBases(std::vector<BasedUser> &Uses,
|
||||
// and a Result in the same instruction (for example because it would
|
||||
// require too many registers). Check this.
|
||||
for (unsigned i=0; i<NumUses; ++i) {
|
||||
if (!L->contains(Uses[i].Inst->getParent()))
|
||||
if (!L->contains(Uses[i].Inst))
|
||||
continue;
|
||||
// We know this is an addressing mode use; if there are any uses that
|
||||
// are not, FreeResult would be Zero.
|
||||
@ -814,7 +814,7 @@ RemoveCommonExpressionsFromUseBases(std::vector<BasedUser> &Uses,
|
||||
// the final IV value coming into those uses does. Instead of trying to
|
||||
// remove the pieces of the common base, which might not be there,
|
||||
// subtract off the base to compensate for this.
|
||||
if (!L->contains(Uses[i].Inst->getParent())) {
|
||||
if (!L->contains(Uses[i].Inst)) {
|
||||
Uses[i].Base = SE->getMinusSCEV(Uses[i].Base, Result);
|
||||
continue;
|
||||
}
|
||||
@ -1109,7 +1109,7 @@ const SCEV *LoopStrengthReduce::CollectIVUsers(const SCEV *Stride,
|
||||
// If the user is not in the current loop, this means it is using the exit
|
||||
// value of the IV. Do not put anything in the base, make sure it's all in
|
||||
// the immediate field to allow as much factoring as possible.
|
||||
if (!L->contains(UsersToProcess[i].Inst->getParent())) {
|
||||
if (!L->contains(UsersToProcess[i].Inst)) {
|
||||
UsersToProcess[i].Imm = SE->getAddExpr(UsersToProcess[i].Imm,
|
||||
UsersToProcess[i].Base);
|
||||
UsersToProcess[i].Base =
|
||||
@ -1353,7 +1353,7 @@ static Instruction *FindIVIncInsertPt(std::vector<BasedUser> &UsersToProcess,
|
||||
const Loop *L) {
|
||||
if (UsersToProcess.size() == 1 &&
|
||||
UsersToProcess[0].isUseOfPostIncrementedValue &&
|
||||
L->contains(UsersToProcess[0].Inst->getParent()))
|
||||
L->contains(UsersToProcess[0].Inst))
|
||||
return UsersToProcess[0].Inst;
|
||||
return L->getLoopLatch()->getTerminator();
|
||||
}
|
||||
@ -1626,7 +1626,7 @@ LoopStrengthReduce::StrengthReduceIVUsersOfStride(const SCEV *Stride,
|
||||
// loop to ensure it is dominated by the increment. In case it's the
|
||||
// only use of the iv, the increment instruction is already before the
|
||||
// use.
|
||||
if (L->contains(User.Inst->getParent()) && User.Inst != IVIncInsertPt)
|
||||
if (L->contains(User.Inst) && User.Inst != IVIncInsertPt)
|
||||
User.Inst->moveBefore(IVIncInsertPt);
|
||||
}
|
||||
|
||||
@ -1688,7 +1688,7 @@ LoopStrengthReduce::StrengthReduceIVUsersOfStride(const SCEV *Stride,
|
||||
// common base, and are adding it back here. Use the same expression
|
||||
// as before, rather than CommonBaseV, so DAGCombiner will zap it.
|
||||
if (!CommonExprs->isZero()) {
|
||||
if (L->contains(User.Inst->getParent()))
|
||||
if (L->contains(User.Inst))
|
||||
RewriteExpr = SE->getAddExpr(RewriteExpr,
|
||||
SE->getUnknown(CommonBaseV));
|
||||
else
|
||||
@ -2363,7 +2363,7 @@ static bool isUsedByExitBranch(ICmpInst *Cond, Loop *L) {
|
||||
static bool ShouldCountToZero(ICmpInst *Cond, IVStrideUse* &CondUse,
|
||||
ScalarEvolution *SE, Loop *L,
|
||||
const TargetLowering *TLI = 0) {
|
||||
if (!L->contains(Cond->getParent()))
|
||||
if (!L->contains(Cond))
|
||||
return false;
|
||||
|
||||
if (!isa<SCEVConstant>(CondUse->getOffset()))
|
||||
|
@ -877,7 +877,7 @@ void LoopUnswitch::RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC,
|
||||
|
||||
for (unsigned i = 0, e = Users.size(); i != e; ++i)
|
||||
if (Instruction *U = cast<Instruction>(Users[i])) {
|
||||
if (!L->contains(U->getParent()))
|
||||
if (!L->contains(U))
|
||||
continue;
|
||||
U->replaceUsesOfWith(LIC, Replacement);
|
||||
Worklist.push_back(U);
|
||||
@ -888,7 +888,7 @@ void LoopUnswitch::RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC,
|
||||
// can. This case occurs when we unswitch switch statements.
|
||||
for (unsigned i = 0, e = Users.size(); i != e; ++i)
|
||||
if (Instruction *U = cast<Instruction>(Users[i])) {
|
||||
if (!L->contains(U->getParent()))
|
||||
if (!L->contains(U))
|
||||
continue;
|
||||
|
||||
Worklist.push_back(U);
|
||||
|
@ -309,10 +309,10 @@ BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,
|
||||
if (TIL == DestLoop) {
|
||||
// Both in the same loop, the NewBB joins loop.
|
||||
DestLoop->addBasicBlockToLoop(NewBB, LI->getBase());
|
||||
} else if (TIL->contains(DestLoop->getHeader())) {
|
||||
} else if (TIL->contains(DestLoop)) {
|
||||
// Edge from an outer loop to an inner loop. Add to the outer loop.
|
||||
TIL->addBasicBlockToLoop(NewBB, LI->getBase());
|
||||
} else if (DestLoop->contains(TIL->getHeader())) {
|
||||
} else if (DestLoop->contains(TIL)) {
|
||||
// Edge from an inner loop to an outer loop. Add to the outer loop.
|
||||
DestLoop->addBasicBlockToLoop(NewBB, LI->getBase());
|
||||
} else {
|
||||
|
@ -194,7 +194,7 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, LoopInfo* LI, LPPassManager* LPM)
|
||||
OrigPHINode.push_back(PN);
|
||||
if (Instruction *I =
|
||||
dyn_cast<Instruction>(PN->getIncomingValueForBlock(LatchBlock)))
|
||||
if (L->contains(I->getParent()))
|
||||
if (L->contains(I))
|
||||
LastValueMap[I] = I;
|
||||
}
|
||||
|
||||
@ -222,7 +222,7 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, LoopInfo* LI, LPPassManager* LPM)
|
||||
PHINode *NewPHI = cast<PHINode>(ValueMap[OrigPHINode[i]]);
|
||||
Value *InVal = NewPHI->getIncomingValueForBlock(LatchBlock);
|
||||
if (Instruction *InValI = dyn_cast<Instruction>(InVal))
|
||||
if (It > 1 && L->contains(InValI->getParent()))
|
||||
if (It > 1 && L->contains(InValI))
|
||||
InVal = LastValueMap[InValI];
|
||||
ValueMap[OrigPHINode[i]] = InVal;
|
||||
New->getInstList().erase(NewPHI);
|
||||
@ -244,7 +244,7 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, LoopInfo* LI, LPPassManager* LPM)
|
||||
UI != UE;) {
|
||||
Instruction *UseInst = cast<Instruction>(*UI);
|
||||
++UI;
|
||||
if (isa<PHINode>(UseInst) && !L->contains(UseInst->getParent())) {
|
||||
if (isa<PHINode>(UseInst) && !L->contains(UseInst)) {
|
||||
PHINode *phi = cast<PHINode>(UseInst);
|
||||
Value *Incoming = phi->getIncomingValueForBlock(*BB);
|
||||
phi->addIncoming(Incoming, New);
|
||||
@ -295,7 +295,7 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, LoopInfo* LI, LPPassManager* LPM)
|
||||
// If this value was defined in the loop, take the value defined by the
|
||||
// last iteration of the loop.
|
||||
if (Instruction *InValI = dyn_cast<Instruction>(InVal)) {
|
||||
if (L->contains(InValI->getParent()))
|
||||
if (L->contains(InValI))
|
||||
InVal = LastValueMap[InVal];
|
||||
}
|
||||
PN->addIncoming(InVal, LastIterationBB);
|
||||
|
Loading…
Reference in New Issue
Block a user