[C++11] Add range based accessors for the Use-Def chain of a Value.
This requires a number of steps. 1) Move value_use_iterator into the Value class as an implementation detail 2) Change it to actually be a *Use* iterator rather than a *User* iterator. 3) Add an adaptor which is a User iterator that always looks through the Use to the User. 4) Wrap these in Value::use_iterator and Value::user_iterator typedefs. 5) Add the range adaptors as Value::uses() and Value::users(). 6) Update *all* of the callers to correctly distinguish between whether they wanted a use_iterator (and to explicitly dig out the User when needed), or a user_iterator which makes the Use itself totally opaque. Because #6 requires churning essentially everything that walked the Use-Def chains, I went ahead and added all of the range adaptors and switched them to range-based loops where appropriate. Also because the renaming requires at least churning every line of code, it didn't make any sense to split these up into multiple commits -- all of which would touch all of the same lies of code. The result is still not quite optimal. The Value::use_iterator is a nice regular iterator, but Value::user_iterator is an iterator over User*s rather than over the User objects themselves. As a consequence, it fits a bit awkwardly into the range-based world and it has the weird extra-dereferencing 'operator->' that so many of our iterators have. I think this could be fixed by providing something which transforms a range of T&s into a range of T*s, but that *can* be separated into another patch, and it isn't yet 100% clear whether this is the right move. However, this change gets us most of the benefit and cleans up a substantial amount of code around Use and User. =] llvm-svn: 203364
This commit is contained in:
@@ -3344,12 +3344,11 @@ static bool hasOutsideLoopUser(const Loop *TheLoop, Instruction *Inst,
|
||||
// instructions must not have external users.
|
||||
if (!Reductions.count(Inst))
|
||||
//Check that all of the users of the loop are inside the BB.
|
||||
for (Value::use_iterator I = Inst->use_begin(), E = Inst->use_end();
|
||||
I != E; ++I) {
|
||||
Instruction *U = cast<Instruction>(*I);
|
||||
for (User *U : Inst->users()) {
|
||||
Instruction *UI = cast<Instruction>(U);
|
||||
// This user may be a reduction exit value.
|
||||
if (!TheLoop->contains(U)) {
|
||||
DEBUG(dbgs() << "LV: Found an outside user for : " << *U << '\n');
|
||||
if (!TheLoop->contains(UI)) {
|
||||
DEBUG(dbgs() << "LV: Found an outside user for : " << *UI << '\n');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -3545,9 +3544,8 @@ static Value *stripGetElementPtr(Value *Ptr, ScalarEvolution *SE,
|
||||
///\brief Look for a cast use of the passed value.
|
||||
static Value *getUniqueCastUse(Value *Ptr, Loop *Lp, Type *Ty) {
|
||||
Value *UniqueCast = 0;
|
||||
for (Value::use_iterator UI = Ptr->use_begin(), UE = Ptr->use_end(); UI != UE;
|
||||
++UI) {
|
||||
CastInst *CI = dyn_cast<CastInst>(*UI);
|
||||
for (User *U : Ptr->users()) {
|
||||
CastInst *CI = dyn_cast<CastInst>(U);
|
||||
if (CI && CI->getType() == Ty) {
|
||||
if (!UniqueCast)
|
||||
UniqueCast = CI;
|
||||
@@ -4714,12 +4712,11 @@ bool LoopVectorizationLegality::AddReductionVar(PHINode *Phi,
|
||||
// nodes once we get to them.
|
||||
SmallVector<Instruction *, 8> NonPHIs;
|
||||
SmallVector<Instruction *, 8> PHIs;
|
||||
for (Value::use_iterator UI = Cur->use_begin(), E = Cur->use_end(); UI != E;
|
||||
++UI) {
|
||||
Instruction *Usr = cast<Instruction>(*UI);
|
||||
for (User *U : Cur->users()) {
|
||||
Instruction *UI = cast<Instruction>(U);
|
||||
|
||||
// Check if we found the exit user.
|
||||
BasicBlock *Parent = Usr->getParent();
|
||||
BasicBlock *Parent = UI->getParent();
|
||||
if (!TheLoop->contains(Parent)) {
|
||||
// Exit if you find multiple outside users or if the header phi node is
|
||||
// being used. In this case the user uses the value of the previous
|
||||
@@ -4742,20 +4739,20 @@ bool LoopVectorizationLegality::AddReductionVar(PHINode *Phi,
|
||||
// value must only be used once, except by phi nodes and min/max
|
||||
// reductions which are represented as a cmp followed by a select.
|
||||
ReductionInstDesc IgnoredVal(false, 0);
|
||||
if (VisitedInsts.insert(Usr)) {
|
||||
if (isa<PHINode>(Usr))
|
||||
PHIs.push_back(Usr);
|
||||
if (VisitedInsts.insert(UI)) {
|
||||
if (isa<PHINode>(UI))
|
||||
PHIs.push_back(UI);
|
||||
else
|
||||
NonPHIs.push_back(Usr);
|
||||
} else if (!isa<PHINode>(Usr) &&
|
||||
((!isa<FCmpInst>(Usr) &&
|
||||
!isa<ICmpInst>(Usr) &&
|
||||
!isa<SelectInst>(Usr)) ||
|
||||
!isMinMaxSelectCmpPattern(Usr, IgnoredVal).IsReduction))
|
||||
NonPHIs.push_back(UI);
|
||||
} else if (!isa<PHINode>(UI) &&
|
||||
((!isa<FCmpInst>(UI) &&
|
||||
!isa<ICmpInst>(UI) &&
|
||||
!isa<SelectInst>(UI)) ||
|
||||
!isMinMaxSelectCmpPattern(UI, IgnoredVal).IsReduction))
|
||||
return false;
|
||||
|
||||
// Remember that we completed the cycle.
|
||||
if (Usr == Phi)
|
||||
if (UI == Phi)
|
||||
FoundStartPHI = true;
|
||||
}
|
||||
Worklist.append(PHIs.begin(), PHIs.end());
|
||||
@@ -4801,7 +4798,7 @@ LoopVectorizationLegality::isMinMaxSelectCmpPattern(Instruction *I,
|
||||
// We must handle the select(cmp()) as a single instruction. Advance to the
|
||||
// select.
|
||||
if ((Cmp = dyn_cast<ICmpInst>(I)) || (Cmp = dyn_cast<FCmpInst>(I))) {
|
||||
if (!Cmp->hasOneUse() || !(Select = dyn_cast<SelectInst>(*I->use_begin())))
|
||||
if (!Cmp->hasOneUse() || !(Select = dyn_cast<SelectInst>(*I->user_begin())))
|
||||
return ReductionInstDesc(false, I);
|
||||
return ReductionInstDesc(Select, Prev.MinMaxKind);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user