Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit 36b699f

Browse files
committed
[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. =] git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203364 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent b033b03 commit 36b699f

File tree

100 files changed

+920
-1075
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

100 files changed

+920
-1075
lines changed

include/llvm/IR/CFG.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ class PredIterator : public std::iterator<std::forward_iterator_tag,
4444
typedef typename super::reference reference;
4545

4646
PredIterator() {}
47-
explicit inline PredIterator(Ptr *bb) : It(bb->use_begin()) {
47+
explicit inline PredIterator(Ptr *bb) : It(bb->user_begin()) {
4848
advancePastNonTerminators();
4949
}
50-
inline PredIterator(Ptr *bb, bool) : It(bb->use_end()) {}
50+
inline PredIterator(Ptr *bb, bool) : It(bb->user_end()) {}
5151

5252
inline bool operator==(const Self& x) const { return It == x.It; }
5353
inline bool operator!=(const Self& x) const { return !operator==(x); }
@@ -81,9 +81,9 @@ class PredIterator : public std::iterator<std::forward_iterator_tag,
8181
}
8282
};
8383

84-
typedef PredIterator<BasicBlock, Value::use_iterator> pred_iterator;
84+
typedef PredIterator<BasicBlock, Value::user_iterator> pred_iterator;
8585
typedef PredIterator<const BasicBlock,
86-
Value::const_use_iterator> const_pred_iterator;
86+
Value::const_user_iterator> const_pred_iterator;
8787

8888
inline pred_iterator pred_begin(BasicBlock *BB) { return pred_iterator(BB); }
8989
inline const_pred_iterator pred_begin(const BasicBlock *BB) {

include/llvm/IR/CallSite.h

+14-6
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,13 @@ class CallSiteBase {
103103

104104
/// isCallee - Determine whether the passed iterator points to the
105105
/// callee operand's Use.
106-
///
107-
bool isCallee(Value::const_use_iterator UI) const {
108-
return getCallee() == &UI.getUse();
106+
bool isCallee(Value::const_user_iterator UI) const {
107+
return isCallee(&UI.getUse());
109108
}
110109

110+
/// Determine whether this Use is the callee operand's Use.
111+
bool isCallee(const Use *U) const { return getCallee() == U; }
112+
111113
ValTy *getArgument(unsigned ArgNo) const {
112114
assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!");
113115
return *(arg_begin() + ArgNo);
@@ -121,11 +123,17 @@ class CallSiteBase {
121123

122124
/// Given a value use iterator, returns the argument that corresponds to it.
123125
/// Iterator must actually correspond to an argument.
124-
unsigned getArgumentNo(Value::const_use_iterator I) const {
126+
unsigned getArgumentNo(Value::const_user_iterator I) const {
127+
return getArgumentNo(&I.getUse());
128+
}
129+
130+
/// Given a use for an argument, get the argument number that corresponds to
131+
/// it.
132+
unsigned getArgumentNo(const Use *U) const {
125133
assert(getInstruction() && "Not a call or invoke instruction!");
126-
assert(arg_begin() <= &I.getUse() && &I.getUse() < arg_end()
134+
assert(arg_begin() <= U && U < arg_end()
127135
&& "Argument # out of range!");
128-
return &I.getUse() - arg_begin();
136+
return U - arg_begin();
129137
}
130138

131139
/// arg_iterator - The type of iterator to use when looping over actual

include/llvm/IR/Instruction.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ class Instruction : public User, public ilist_node<Instruction> {
4545
// Out of line virtual method, so the vtable, etc has a home.
4646
~Instruction();
4747

48-
/// use_back - Specialize the methods defined in Value, as we know that an
48+
/// user_back - Specialize the methods defined in Value, as we know that an
4949
/// instruction can only be used by other instructions.
50-
Instruction *use_back() { return cast<Instruction>(*use_begin());}
51-
const Instruction *use_back() const { return cast<Instruction>(*use_begin());}
50+
Instruction *user_back() { return cast<Instruction>(*user_begin());}
51+
const Instruction *user_back() const { return cast<Instruction>(*user_begin());}
5252

5353
inline const BasicBlock *getParent() const { return Parent; }
5454
inline BasicBlock *getParent() { return Parent; }

include/llvm/IR/Instructions.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -2100,7 +2100,7 @@ class PHINode : public Instruction {
21002100
/// getIncomingBlock - Return incoming basic block corresponding
21012101
/// to value use iterator.
21022102
///
2103-
BasicBlock *getIncomingBlock(Value::const_use_iterator I) const {
2103+
BasicBlock *getIncomingBlock(Value::const_user_iterator I) const {
21042104
return getIncomingBlock(I.getUse());
21052105
}
21062106

include/llvm/IR/Value.h

+77-19
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#define LLVM_IR_VALUE_H
1616

1717
#include "llvm-c/Core.h"
18+
#include "llvm/ADT/iterator_range.h"
1819
#include "llvm/IR/Use.h"
1920
#include "llvm/Support/CBindingWrapping.h"
2021
#include "llvm/Support/Casting.h"
@@ -75,13 +76,54 @@ class Value {
7576
unsigned char SubclassOptionalData : 7;
7677

7778
private:
79+
template <typename UseT> // UseT == 'Use' or 'const Use'
80+
class use_iterator_impl
81+
: public std::iterator<std::forward_iterator_tag, UseT *, ptrdiff_t> {
82+
typedef std::iterator<std::forward_iterator_tag, UseT *, ptrdiff_t> super;
83+
84+
UseT *U;
85+
explicit use_iterator_impl(UseT *u) : U(u) {}
86+
friend class Value;
87+
88+
public:
89+
typedef typename super::reference reference;
90+
typedef typename super::pointer pointer;
91+
92+
use_iterator_impl() : U() {}
93+
94+
bool operator==(const use_iterator_impl &x) const { return U == x.U; }
95+
bool operator!=(const use_iterator_impl &x) const { return !operator==(x); }
96+
97+
use_iterator_impl &operator++() { // Preincrement
98+
assert(U && "Cannot increment end iterator!");
99+
U = U->getNext();
100+
return *this;
101+
}
102+
use_iterator_impl operator++(int) { // Postincrement
103+
auto tmp = *this;
104+
++*this;
105+
return tmp;
106+
}
107+
108+
UseT &operator*() const {
109+
assert(U && "Cannot dereference end iterator!");
110+
return *U;
111+
}
112+
113+
UseT *operator->() const { return &operator*(); }
114+
115+
operator use_iterator_impl<const UseT>() const {
116+
return use_iterator_impl<const UseT>(U);
117+
}
118+
};
119+
78120
template <typename UserTy> // UserTy == 'User' or 'const User'
79121
class user_iterator_impl
80122
: public std::iterator<std::forward_iterator_tag, UserTy *, ptrdiff_t> {
81123
typedef std::iterator<std::forward_iterator_tag, UserTy *, ptrdiff_t> super;
82124

83-
Use *U;
84-
explicit user_iterator_impl(Use *u) : U(u) {}
125+
use_iterator_impl<Use> UI;
126+
explicit user_iterator_impl(Use *U) : UI(U) {}
85127
friend class Value;
86128

87129
public:
@@ -90,16 +132,14 @@ class Value {
90132

91133
user_iterator_impl() {}
92134

93-
bool operator==(const user_iterator_impl &x) const { return U == x.U; }
135+
bool operator==(const user_iterator_impl &x) const { return UI == x.UI; }
94136
bool operator!=(const user_iterator_impl &x) const { return !operator==(x); }
95137

96-
/// \brief Returns true if this iterator is equal to use_end() on the value.
97-
bool atEnd() const { return U == 0; }
138+
/// \brief Returns true if this iterator is equal to user_end() on the value.
139+
bool atEnd() const { return *this == user_iterator_impl(); }
98140

99-
// Iterator traversal: forward iteration only
100141
user_iterator_impl &operator++() { // Preincrement
101-
assert(U && "Cannot increment end iterator!");
102-
U = U->getNext();
142+
++UI;
103143
return *this;
104144
}
105145
user_iterator_impl operator++(int) { // Postincrement
@@ -110,21 +150,20 @@ class Value {
110150

111151
// Retrieve a pointer to the current User.
112152
UserTy *operator*() const {
113-
assert(U && "Cannot dereference end iterator!");
114-
return U->getUser();
153+
return UI->getUser();
115154
}
116155

117156
UserTy *operator->() const { return operator*(); }
118157

119158
operator user_iterator_impl<const UserTy>() const {
120-
return user_iterator_impl<const UserTy>(U);
159+
return user_iterator_impl<const UserTy>(*UI);
121160
}
122161

123-
Use &getUse() const { return *U; }
162+
Use &getUse() const { return *UI; }
124163

125164
/// \brief Return the operand # of this use in its User.
126165
/// FIXME: Replace all callers with a direct call to Use::getOperandNo.
127-
unsigned getOperandNo() const { return U->getOperandNo(); }
166+
unsigned getOperandNo() const { return UI->getOperandNo(); }
128167
};
129168

130169
/// SubclassData - This member is defined by this class, but is not used for
@@ -205,14 +244,33 @@ class Value {
205244
//
206245
bool use_empty() const { return UseList == 0; }
207246

208-
typedef user_iterator_impl<User> use_iterator;
209-
typedef user_iterator_impl<const User> const_use_iterator;
247+
typedef use_iterator_impl<Use> use_iterator;
248+
typedef use_iterator_impl<const Use> const_use_iterator;
210249
use_iterator use_begin() { return use_iterator(UseList); }
211250
const_use_iterator use_begin() const { return const_use_iterator(UseList); }
212-
use_iterator use_end() { return use_iterator(0); }
213-
const_use_iterator use_end() const { return const_use_iterator(0); }
214-
User *use_back() { return *use_begin(); }
215-
const User *use_back() const { return *use_begin(); }
251+
use_iterator use_end() { return use_iterator(); }
252+
const_use_iterator use_end() const { return const_use_iterator(); }
253+
iterator_range<use_iterator> uses() {
254+
return iterator_range<use_iterator>(use_begin(), use_end());
255+
}
256+
iterator_range<const_use_iterator> uses() const {
257+
return iterator_range<const_use_iterator>(use_begin(), use_end());
258+
}
259+
260+
typedef user_iterator_impl<User> user_iterator;
261+
typedef user_iterator_impl<const User> const_user_iterator;
262+
user_iterator user_begin() { return user_iterator(UseList); }
263+
const_user_iterator user_begin() const { return const_user_iterator(UseList); }
264+
user_iterator user_end() { return user_iterator(); }
265+
const_user_iterator user_end() const { return const_user_iterator(); }
266+
User *user_back() { return *user_begin(); }
267+
const User *user_back() const { return *user_begin(); }
268+
iterator_range<user_iterator> users() {
269+
return iterator_range<user_iterator>(user_begin(), user_end());
270+
}
271+
iterator_range<const_user_iterator> users() const {
272+
return iterator_range<const_user_iterator>(user_begin(), user_end());
273+
}
216274

217275
/// hasOneUse - Return true if there is exactly one user of this value. This
218276
/// is specialized because it is a common request and does not require

lib/Analysis/CaptureTracking.cpp

+8-12
Original file line numberDiff line numberDiff line change
@@ -85,17 +85,15 @@ void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker) {
8585
SmallSet<const Use *, Threshold> Visited;
8686
int Count = 0;
8787

88-
for (Value::const_use_iterator UI = V->use_begin(), UE = V->use_end();
89-
UI != UE; ++UI) {
88+
for (const Use &U : V->uses()) {
9089
// If there are lots of uses, conservatively say that the value
9190
// is captured to avoid taking too much compile time.
9291
if (Count++ >= Threshold)
9392
return Tracker->tooManyUses();
9493

95-
Use *U = &UI.getUse();
96-
if (!Tracker->shouldExplore(U)) continue;
97-
Visited.insert(U);
98-
Worklist.push_back(U);
94+
if (!Tracker->shouldExplore(&U)) continue;
95+
Visited.insert(&U);
96+
Worklist.push_back(&U);
9997
}
10098

10199
while (!Worklist.empty()) {
@@ -148,17 +146,15 @@ void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker) {
148146
case Instruction::AddrSpaceCast:
149147
// The original value is not captured via this if the new value isn't.
150148
Count = 0;
151-
for (Instruction::use_iterator UI = I->use_begin(), UE = I->use_end();
152-
UI != UE; ++UI) {
149+
for (Use &UU : I->uses()) {
153150
// If there are lots of uses, conservatively say that the value
154151
// is captured to avoid taking too much compile time.
155152
if (Count++ >= Threshold)
156153
return Tracker->tooManyUses();
157154

158-
Use *U = &UI.getUse();
159-
if (Visited.insert(U))
160-
if (Tracker->shouldExplore(U))
161-
Worklist.push_back(U);
155+
if (Visited.insert(&UU))
156+
if (Tracker->shouldExplore(&UU))
157+
Worklist.push_back(&UU);
162158
}
163159
break;
164160
case Instruction::ICmp:

lib/Analysis/IPA/GlobalsModRef.cpp

+13-14
Original file line numberDiff line numberDiff line change
@@ -252,33 +252,33 @@ bool GlobalsModRef::AnalyzeUsesOfPointer(Value *V,
252252
GlobalValue *OkayStoreDest) {
253253
if (!V->getType()->isPointerTy()) return true;
254254

255-
for (Value::use_iterator UI = V->use_begin(), E=V->use_end(); UI != E; ++UI) {
256-
User *U = *UI;
257-
if (LoadInst *LI = dyn_cast<LoadInst>(U)) {
255+
for (Use &U : V->uses()) {
256+
User *I = U.getUser();
257+
if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
258258
Readers.push_back(LI->getParent()->getParent());
259-
} else if (StoreInst *SI = dyn_cast<StoreInst>(U)) {
259+
} else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
260260
if (V == SI->getOperand(1)) {
261261
Writers.push_back(SI->getParent()->getParent());
262262
} else if (SI->getOperand(1) != OkayStoreDest) {
263263
return true; // Storing the pointer
264264
}
265-
} else if (Operator::getOpcode(U) == Instruction::GetElementPtr) {
266-
if (AnalyzeUsesOfPointer(U, Readers, Writers))
265+
} else if (Operator::getOpcode(I) == Instruction::GetElementPtr) {
266+
if (AnalyzeUsesOfPointer(I, Readers, Writers))
267267
return true;
268-
} else if (Operator::getOpcode(U) == Instruction::BitCast) {
269-
if (AnalyzeUsesOfPointer(U, Readers, Writers, OkayStoreDest))
268+
} else if (Operator::getOpcode(I) == Instruction::BitCast) {
269+
if (AnalyzeUsesOfPointer(I, Readers, Writers, OkayStoreDest))
270270
return true;
271-
} else if (CallSite CS = U) {
271+
} else if (CallSite CS = I) {
272272
// Make sure that this is just the function being called, not that it is
273273
// passing into the function.
274-
if (!CS.isCallee(UI)) {
274+
if (!CS.isCallee(&U)) {
275275
// Detect calls to free.
276-
if (isFreeCall(U, TLI))
276+
if (isFreeCall(I, TLI))
277277
Writers.push_back(CS->getParent()->getParent());
278278
else
279279
return true; // Argument of an unknown call.
280280
}
281-
} else if (ICmpInst *ICI = dyn_cast<ICmpInst>(U)) {
281+
} else if (ICmpInst *ICI = dyn_cast<ICmpInst>(I)) {
282282
if (!isa<ConstantPointerNull>(ICI->getOperand(1)))
283283
return true; // Allow comparison against null.
284284
} else {
@@ -303,8 +303,7 @@ bool GlobalsModRef::AnalyzeIndirectGlobalMemory(GlobalValue *GV) {
303303

304304
// Walk the user list of the global. If we find anything other than a direct
305305
// load or store, bail out.
306-
for (Value::use_iterator I = GV->use_begin(), E = GV->use_end(); I != E; ++I){
307-
User *U = *I;
306+
for (User *U : GV->users()) {
308307
if (LoadInst *LI = dyn_cast<LoadInst>(U)) {
309308
// The pointer loaded from the global can only be used in simple ways:
310309
// we allow addressing of it and loading storing to it. We do *not* allow

lib/Analysis/IPA/InlineCost.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -1052,9 +1052,8 @@ bool CallAnalyzer::analyzeCall(CallSite CS) {
10521052

10531053
Function *Caller = CS.getInstruction()->getParent()->getParent();
10541054
// Check if the caller function is recursive itself.
1055-
for (Value::use_iterator U = Caller->use_begin(), E = Caller->use_end();
1056-
U != E; ++U) {
1057-
CallSite Site(cast<Value>(*U));
1055+
for (User *U : Caller->users()) {
1056+
CallSite Site(U);
10581057
if (!Site)
10591058
continue;
10601059
Instruction *I = Site.getInstruction();

lib/Analysis/IVUsers.cpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,8 @@ bool IVUsers::AddUsersImpl(Instruction *I,
142142
return false;
143143

144144
SmallPtrSet<Instruction *, 4> UniqueUsers;
145-
for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
146-
UI != E; ++UI) {
147-
Instruction *User = cast<Instruction>(*UI);
145+
for (Use &U : I->uses()) {
146+
Instruction *User = cast<Instruction>(U.getUser());
148147
if (!UniqueUsers.insert(User))
149148
continue;
150149

@@ -157,7 +156,7 @@ bool IVUsers::AddUsersImpl(Instruction *I,
157156
BasicBlock *UseBB = User->getParent();
158157
// A phi's use is live out of its predecessor block.
159158
if (PHINode *PHI = dyn_cast<PHINode>(User)) {
160-
unsigned OperandNo = UI.getOperandNo();
159+
unsigned OperandNo = U.getOperandNo();
161160
unsigned ValNo = PHINode::getIncomingValueNumForOperand(OperandNo);
162161
UseBB = PHI->getIncomingBlock(ValNo);
163162
}

lib/Analysis/InstructionSimplify.cpp

+5-7
Original file line numberDiff line numberDiff line change
@@ -3200,10 +3200,9 @@ static bool replaceAndRecursivelySimplifyImpl(Instruction *I, Value *SimpleV,
32003200
// If we have an explicit value to collapse to, do that round of the
32013201
// simplification loop by hand initially.
32023202
if (SimpleV) {
3203-
for (Value::use_iterator UI = I->use_begin(), UE = I->use_end(); UI != UE;
3204-
++UI)
3205-
if (*UI != I)
3206-
Worklist.insert(cast<Instruction>(*UI));
3203+
for (User *U : I->users())
3204+
if (U != I)
3205+
Worklist.insert(cast<Instruction>(U));
32073206

32083207
// Replace the instruction with its simplified value.
32093208
I->replaceAllUsesWith(SimpleV);
@@ -3230,9 +3229,8 @@ static bool replaceAndRecursivelySimplifyImpl(Instruction *I, Value *SimpleV,
32303229
// Stash away all the uses of the old instruction so we can check them for
32313230
// recursive simplifications after a RAUW. This is cheaper than checking all
32323231
// uses of To on the recursive step in most cases.
3233-
for (Value::use_iterator UI = I->use_begin(), UE = I->use_end(); UI != UE;
3234-
++UI)
3235-
Worklist.insert(cast<Instruction>(*UI));
3232+
for (User *U : I->users())
3233+
Worklist.insert(cast<Instruction>(U));
32363234

32373235
// Replace the instruction with its simplified value.
32383236
I->replaceAllUsesWith(SimpleV);

0 commit comments

Comments
 (0)