Skip to content

Commit 18e1928

Browse files
committed
[SelectionDAG] Split sd_use_iterator into sd_user_iterator and sd_use_iterator.
sd_use_iterator now returns an SDUse& when dereferenced. sd_user_iterator returns SDNode*.a SDNode::use_begin/use_end/uses work on sd_use_iterator. SDNode::user_begin/user_end/users work on sd_user_iterator. This allows us to write range based for loops using SDUse& and SDNode::uses(). I've converted many of these in this patch. I didn't update loops that have additional variables updated in their for statement. Some loops use sd_use_iterator::getOperandNo() which also prevents using range based for loops. I plan to move this into SDUse in a follow up patch.
1 parent e389492 commit 18e1928

18 files changed

+248
-234
lines changed

llvm/include/llvm/CodeGen/SelectionDAGNodes.h

Lines changed: 61 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -750,7 +750,7 @@ END_TWO_BYTE_PACK()
750750
bool use_empty() const { return UseList == nullptr; }
751751

752752
/// Return true if there is exactly one use of this node.
753-
bool hasOneUse() const { return hasSingleElement(users()); }
753+
bool hasOneUse() const { return hasSingleElement(uses()); }
754754

755755
/// Return the number of uses of this node. This method takes
756756
/// time proportional to the number of uses.
@@ -821,14 +821,12 @@ END_TWO_BYTE_PACK()
821821
}
822822

823823
/// Retrieve a pointer to the current user node.
824-
SDNode *operator*() const {
824+
SDUse &operator*() const {
825825
assert(Op && "Cannot dereference end iterator!");
826-
return Op->getUser();
826+
return *Op;
827827
}
828828

829-
SDNode *operator->() const { return operator*(); }
830-
831-
SDUse &getUse() const { return *Op; }
829+
SDUse *operator->() const { return &operator*(); }
832830

833831
/// Retrieve the operand # of this use in its user.
834832
unsigned getOperandNo() const {
@@ -837,29 +835,72 @@ END_TWO_BYTE_PACK()
837835
}
838836
};
839837

838+
class user_iterator {
839+
friend class SDNode;
840+
use_iterator UI;
841+
842+
explicit user_iterator(SDUse *op) : UI(op) {};
843+
844+
public:
845+
using iterator_category = std::forward_iterator_tag;
846+
using value_type = SDNode *;
847+
using difference_type = std::ptrdiff_t;
848+
using pointer = value_type *;
849+
using reference = value_type &;
850+
851+
user_iterator() = default;
852+
853+
bool operator==(const user_iterator &x) const { return UI == x.UI; }
854+
bool operator!=(const user_iterator &x) const { return !operator==(x); }
855+
856+
// /// Return true if this iterator is at the end of the uses list.
857+
bool atEnd() const { return *this == user_iterator(); }
858+
859+
user_iterator &operator++() { // Preincrement
860+
++UI;
861+
return *this;
862+
}
863+
864+
user_iterator operator++(int) { // Postincrement
865+
auto tmp = *this;
866+
++*this;
867+
return tmp;
868+
}
869+
870+
// Retrieve a pointer to the current User.
871+
SDNode *operator*() const { return UI->getUser(); }
872+
873+
SDNode *operator->() const { return operator*(); }
874+
875+
SDUse &getUse() const { return *UI; }
876+
};
877+
840878
/// Provide iteration support to walk over all uses of an SDNode.
841879
use_iterator use_begin() const {
842880
return use_iterator(UseList);
843881
}
844882

845883
static use_iterator use_end() { return use_iterator(nullptr); }
846884

847-
/// Provide iteration support to walk over all users of an SDNode.
848-
/// For now, this should only be used to get a pointer to the first user.
849-
/// FIXME: Rename use_iterator to user_iterator. Add user_end().
850-
use_iterator user_begin() const { return use_iterator(UseList); }
851-
852-
// Dereferencing use_iterator returns the user SDNode* making it closer to a
853-
// user_iterator thus this function is called users() to reflect that.
854-
// FIXME: Rename to user_iterator and introduce a use_iterator that returns
855-
// SDUse*.
856-
inline iterator_range<use_iterator> users() {
885+
inline iterator_range<use_iterator> uses() {
857886
return make_range(use_begin(), use_end());
858887
}
859-
inline iterator_range<use_iterator> users() const {
888+
inline iterator_range<use_iterator> uses() const {
860889
return make_range(use_begin(), use_end());
861890
}
862891

892+
/// Provide iteration support to walk over all users of an SDNode.
893+
user_iterator user_begin() const { return user_iterator(UseList); }
894+
895+
static user_iterator user_end() { return user_iterator(nullptr); }
896+
897+
inline iterator_range<user_iterator> users() {
898+
return make_range(user_begin(), user_end());
899+
}
900+
inline iterator_range<user_iterator> users() const {
901+
return make_range(user_begin(), user_end());
902+
}
903+
863904
/// Return true if there are exactly NUSES uses of the indicated value.
864905
/// This method ignores uses of other values defined by this operation.
865906
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const;
@@ -1019,9 +1060,9 @@ END_TWO_BYTE_PACK()
10191060
/// If this node has a glue value with a user, return
10201061
/// the user (there is at most one). Otherwise return NULL.
10211062
SDNode *getGluedUser() const {
1022-
for (use_iterator UI = use_begin(), UE = use_end(); UI != UE; ++UI)
1023-
if (UI.getUse().get().getValueType() == MVT::Glue)
1024-
return *UI;
1063+
for (SDUse &U : uses())
1064+
if (U.getValueType() == MVT::Glue)
1065+
return U.getUser();
10251066
return nullptr;
10261067
}
10271068

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13229,12 +13229,11 @@ static bool ExtendUsesToFormExtLoad(EVT VT, SDNode *N, SDValue N0,
1322913229
const TargetLowering &TLI) {
1323013230
bool HasCopyToRegUses = false;
1323113231
bool isTruncFree = TLI.isTruncateFree(VT, N0.getValueType());
13232-
for (SDNode::use_iterator UI = N0->use_begin(), UE = N0->use_end(); UI != UE;
13233-
++UI) {
13234-
SDNode *User = *UI;
13232+
for (SDUse &Use : N0->uses()) {
13233+
SDNode *User = Use.getUser();
1323513234
if (User == N)
1323613235
continue;
13237-
if (UI.getUse().getResNo() != N0.getResNo())
13236+
if (Use.getResNo() != N0.getResNo())
1323813237
continue;
1323913238
// FIXME: Only extend SETCC N, N and SETCC N, c for now.
1324013239
if (ExtOpc != ISD::ANY_EXTEND && User->getOpcode() == ISD::SETCC) {
@@ -13266,9 +13265,7 @@ static bool ExtendUsesToFormExtLoad(EVT VT, SDNode *N, SDValue N0,
1326613265

1326713266
if (HasCopyToRegUses) {
1326813267
bool BothLiveOut = false;
13269-
for (SDNode::use_iterator UI = N->use_begin(), UE = N->use_end();
13270-
UI != UE; ++UI) {
13271-
SDUse &Use = UI.getUse();
13268+
for (SDUse &Use : N->uses()) {
1327213269
if (Use.getResNo() == 0 && Use.getUser()->getOpcode() == ISD::CopyToReg) {
1327313270
BothLiveOut = true;
1327413271
break;
@@ -13780,11 +13777,10 @@ SDValue DAGCombiner::foldSextSetcc(SDNode *N) {
1378013777

1378113778
// Non-chain users of this value must either be the setcc in this
1378213779
// sequence or extends that can be folded into the new {z/s}ext-load.
13783-
for (SDNode::use_iterator UI = V->use_begin(), UE = V->use_end();
13784-
UI != UE; ++UI) {
13780+
for (SDUse &Use : V->uses()) {
1378513781
// Skip uses of the chain and the setcc.
13786-
SDNode *User = *UI;
13787-
if (UI.getUse().getResNo() != 0 || User == N0.getNode())
13782+
SDNode *User = Use.getUser();
13783+
if (Use.getResNo() != 0 || User == N0.getNode())
1378813784
continue;
1378913785
// Extra users must have exactly the same cast we are about to create.
1379013786
// TODO: This restriction could be eased if ExtendUsesToFormExtLoad()
@@ -18928,7 +18924,7 @@ bool DAGCombiner::CombineToPreIndexedLoadStore(SDNode *N) {
1892818924
for (SDNode::use_iterator UI = BasePtr->use_begin(),
1892918925
UE = BasePtr->use_end();
1893018926
UI != UE; ++UI) {
18931-
SDUse &Use = UI.getUse();
18927+
SDUse &Use = *UI;
1893218928
// Skip the use that is Ptr and uses of other results from BasePtr's
1893318929
// node (important for nodes that return multiple results).
1893418930
if (Use.getUser() == Ptr.getNode() || Use != BasePtr)
@@ -20056,13 +20052,12 @@ bool DAGCombiner::SliceUpLoad(SDNode *N) {
2005620052
// Check if this load is used as several smaller chunks of bits.
2005720053
// Basically, look for uses in trunc or trunc(lshr) and record a new chain
2005820054
// of computation for each trunc.
20059-
for (SDNode::use_iterator UI = LD->use_begin(), UIEnd = LD->use_end();
20060-
UI != UIEnd; ++UI) {
20055+
for (SDUse &U : LD->uses()) {
2006120056
// Skip the uses of the chain.
20062-
if (UI.getUse().getResNo() != 0)
20057+
if (U.getResNo() != 0)
2006320058
continue;
2006420059

20065-
SDNode *User = *UI;
20060+
SDNode *User = U.getUser();
2006620061
unsigned Shift = 0;
2006720062

2006820063
// Check if this is a trunc(lshr).
@@ -20940,7 +20935,7 @@ DAGCombiner::getStoreMergeCandidates(StoreSDNode *St,
2094020935
// This must be a chain use.
2094120936
if (UseIter.getOperandNo() != 0)
2094220937
return;
20943-
if (auto *OtherStore = dyn_cast<StoreSDNode>(*UseIter)) {
20938+
if (auto *OtherStore = dyn_cast<StoreSDNode>(UseIter->getUser())) {
2094420939
BaseIndexOffset Ptr;
2094520940
int64_t PtrDiff;
2094620941
if (CandidateMatch(OtherStore, Ptr, PtrDiff) &&
@@ -20958,12 +20953,13 @@ DAGCombiner::getStoreMergeCandidates(StoreSDNode *St,
2095820953
return nullptr;
2095920954
for (auto I = RootNode->use_begin(), E = RootNode->use_end();
2096020955
I != E && NumNodesExplored < MaxSearchNodes; ++I, ++NumNodesExplored) {
20961-
if (I.getOperandNo() == 0 && isa<LoadSDNode>(*I)) { // walk down chain
20962-
for (auto I2 = (*I)->use_begin(), E2 = (*I)->use_end(); I2 != E2; ++I2)
20956+
SDNode *User = I->getUser();
20957+
if (I.getOperandNo() == 0 && isa<LoadSDNode>(User)) { // walk down chain
20958+
for (auto I2 = User->use_begin(), E2 = User->use_end(); I2 != E2; ++I2)
2096320959
TryToAddCandidate(I2);
2096420960
}
2096520961
// Check stores that depend on the root (e.g. Store 3 in the chart above).
20966-
if (I.getOperandNo() == 0 && isa<StoreSDNode>(*I)) {
20962+
if (I.getOperandNo() == 0 && isa<StoreSDNode>(User)) {
2096720963
TryToAddCandidate(I);
2096820964
}
2096920965
}
@@ -27320,8 +27316,7 @@ SDValue DAGCombiner::visitGET_FPENV_MEM(SDNode *N) {
2732027316

2732127317
// Check if the loaded value is used only in a store operation.
2732227318
StoreSDNode *StNode = nullptr;
27323-
for (auto I = LdNode->use_begin(), E = LdNode->use_end(); I != E; ++I) {
27324-
SDUse &U = I.getUse();
27319+
for (SDUse &U : LdNode->uses()) {
2732527320
if (U.getResNo() == 0) {
2732627321
if (auto *St = dyn_cast<StoreSDNode>(U.getUser())) {
2732727322
if (StNode)

llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,9 @@ void DAGTypeLegalizer::PerformExpensiveChecks() {
8888
if (I != ReplacedValues.end()) {
8989
Mapped |= 1;
9090
// Check that remapped values are only used by nodes marked NewNode.
91-
for (SDNode::use_iterator UI = Node.use_begin(), UE = Node.use_end();
92-
UI != UE; ++UI)
93-
if (UI.getUse().getResNo() == i)
94-
assert(UI->getNodeId() == NewNode &&
91+
for (SDUse &U : Node.uses())
92+
if (U.getResNo() == i)
93+
assert(U.getUser()->getNodeId() == NewNode &&
9594
"Remapped value has non-trivial use!");
9695

9796
// Check that the final result of applying ReplacedValues is not

llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ void ScheduleDAGSDNodes::ClusterNeighboringLoads(SDNode *Node) {
236236
// This algorithm requires a reasonably low use count before finding a match
237237
// to avoid uselessly blowing up compile time in large blocks.
238238
unsigned UseCount = 0;
239-
for (SDNode::use_iterator I = Chain->use_begin(), E = Chain->use_end();
239+
for (SDNode::user_iterator I = Chain->user_begin(), E = Chain->user_end();
240240
I != E && UseCount < 100; ++I, ++UseCount) {
241241
if (I.getUse().getResNo() != Chain.getResNo())
242242
continue;

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11611,7 +11611,7 @@ class RAUWUpdateListener : public SelectionDAG::DAGUpdateListener {
1161111611

1161211612
void NodeDeleted(SDNode *N, SDNode *E) override {
1161311613
// Increment the iterator as needed.
11614-
while (UI != UE && N == *UI)
11614+
while (UI != UE && N == UI->getUser())
1161511615
++UI;
1161611616
}
1161711617

@@ -11650,7 +11650,7 @@ void SelectionDAG::ReplaceAllUsesWith(SDValue FromN, SDValue To) {
1165011650
SDNode::use_iterator UI = From->use_begin(), UE = From->use_end();
1165111651
RAUWUpdateListener Listener(*this, UI, UE);
1165211652
while (UI != UE) {
11653-
SDNode *User = *UI;
11653+
SDNode *User = UI->getUser();
1165411654

1165511655
// This node is about to morph, remove its old self from the CSE maps.
1165611656
RemoveNodeFromCSEMaps(User);
@@ -11660,12 +11660,12 @@ void SelectionDAG::ReplaceAllUsesWith(SDValue FromN, SDValue To) {
1166011660
// To help reduce the number of CSE recomputations, process all
1166111661
// the uses of this user that we can find this way.
1166211662
do {
11663-
SDUse &Use = UI.getUse();
11663+
SDUse &Use = *UI;
1166411664
++UI;
1166511665
Use.set(To);
1166611666
if (To->isDivergent() != From->isDivergent())
1166711667
updateDivergence(User);
11668-
} while (UI != UE && *UI == User);
11668+
} while (UI != UE && UI->getUser() == User);
1166911669
// Now that we have modified User, add it back to the CSE maps. If it
1167011670
// already exists there, recursively merge the results together.
1167111671
AddModifiedNodeToCSEMaps(User);
@@ -11708,7 +11708,7 @@ void SelectionDAG::ReplaceAllUsesWith(SDNode *From, SDNode *To) {
1170811708
SDNode::use_iterator UI = From->use_begin(), UE = From->use_end();
1170911709
RAUWUpdateListener Listener(*this, UI, UE);
1171011710
while (UI != UE) {
11711-
SDNode *User = *UI;
11711+
SDNode *User = UI->getUser();
1171211712

1171311713
// This node is about to morph, remove its old self from the CSE maps.
1171411714
RemoveNodeFromCSEMaps(User);
@@ -11718,12 +11718,12 @@ void SelectionDAG::ReplaceAllUsesWith(SDNode *From, SDNode *To) {
1171811718
// To help reduce the number of CSE recomputations, process all
1171911719
// the uses of this user that we can find this way.
1172011720
do {
11721-
SDUse &Use = UI.getUse();
11721+
SDUse &Use = *UI;
1172211722
++UI;
1172311723
Use.setNode(To);
1172411724
if (To->isDivergent() != From->isDivergent())
1172511725
updateDivergence(User);
11726-
} while (UI != UE && *UI == User);
11726+
} while (UI != UE && UI->getUser() == User);
1172711727

1172811728
// Now that we have modified User, add it back to the CSE maps. If it
1172911729
// already exists there, recursively merge the results together.
@@ -11756,7 +11756,7 @@ void SelectionDAG::ReplaceAllUsesWith(SDNode *From, const SDValue *To) {
1175611756
SDNode::use_iterator UI = From->use_begin(), UE = From->use_end();
1175711757
RAUWUpdateListener Listener(*this, UI, UE);
1175811758
while (UI != UE) {
11759-
SDNode *User = *UI;
11759+
SDNode *User = UI->getUser();
1176011760

1176111761
// This node is about to morph, remove its old self from the CSE maps.
1176211762
RemoveNodeFromCSEMaps(User);
@@ -11767,12 +11767,12 @@ void SelectionDAG::ReplaceAllUsesWith(SDNode *From, const SDValue *To) {
1176711767
// user that we can find this way.
1176811768
bool To_IsDivergent = false;
1176911769
do {
11770-
SDUse &Use = UI.getUse();
11770+
SDUse &Use = *UI;
1177111771
const SDValue &ToOp = To[Use.getResNo()];
1177211772
++UI;
1177311773
Use.set(ToOp);
1177411774
To_IsDivergent |= ToOp->isDivergent();
11775-
} while (UI != UE && *UI == User);
11775+
} while (UI != UE && UI->getUser() == User);
1177611776

1177711777
if (To_IsDivergent != From->isDivergent())
1177811778
updateDivergence(User);
@@ -11810,15 +11810,15 @@ void SelectionDAG::ReplaceAllUsesOfValueWith(SDValue From, SDValue To){
1181011810
UE = From.getNode()->use_end();
1181111811
RAUWUpdateListener Listener(*this, UI, UE);
1181211812
while (UI != UE) {
11813-
SDNode *User = *UI;
11813+
SDNode *User = UI->getUser();
1181411814
bool UserRemovedFromCSEMaps = false;
1181511815

1181611816
// A user can appear in a use list multiple times, and when this
1181711817
// happens the uses are usually next to each other in the list.
1181811818
// To help reduce the number of CSE recomputations, process all
1181911819
// the uses of this user that we can find this way.
1182011820
do {
11821-
SDUse &Use = UI.getUse();
11821+
SDUse &Use = *UI;
1182211822

1182311823
// Skip uses of different values from the same node.
1182411824
if (Use.getResNo() != From.getResNo()) {
@@ -11837,7 +11837,7 @@ void SelectionDAG::ReplaceAllUsesOfValueWith(SDValue From, SDValue To){
1183711837
Use.set(To);
1183811838
if (To->isDivergent() != From->isDivergent())
1183911839
updateDivergence(User);
11840-
} while (UI != UE && *UI == User);
11840+
} while (UI != UE && UI->getUser() == User);
1184111841
// We are iterating over all uses of the From node, so if a use
1184211842
// doesn't use the specific value, no changes are made.
1184311843
if (!UserRemovedFromCSEMaps)
@@ -11982,11 +11982,9 @@ void SelectionDAG::ReplaceAllUsesOfValuesWith(const SDValue *From,
1198211982
for (unsigned i = 0; i != Num; ++i) {
1198311983
unsigned FromResNo = From[i].getResNo();
1198411984
SDNode *FromNode = From[i].getNode();
11985-
for (SDNode::use_iterator UI = FromNode->use_begin(),
11986-
E = FromNode->use_end(); UI != E; ++UI) {
11987-
SDUse &Use = UI.getUse();
11985+
for (SDUse &Use : FromNode->uses()) {
1198811986
if (Use.getResNo() == FromResNo) {
11989-
UseMemo Memo = { *UI, i, &Use };
11987+
UseMemo Memo = {Use.getUser(), i, &Use};
1199011988
Uses.push_back(Memo);
1199111989
}
1199211990
}
@@ -12462,8 +12460,8 @@ bool SDNode::hasNUsesOfValue(unsigned NUses, unsigned Value) const {
1246212460
assert(Value < getNumValues() && "Bad value!");
1246312461

1246412462
// TODO: Only iterate over uses of a given value of the node
12465-
for (SDNode::use_iterator UI = use_begin(), E = use_end(); UI != E; ++UI) {
12466-
if (UI.getUse().getResNo() == Value) {
12463+
for (SDUse &U : uses()) {
12464+
if (U.getResNo() == Value) {
1246712465
if (NUses == 0)
1246812466
return false;
1246912467
--NUses;
@@ -12479,8 +12477,8 @@ bool SDNode::hasNUsesOfValue(unsigned NUses, unsigned Value) const {
1247912477
bool SDNode::hasAnyUseOfValue(unsigned Value) const {
1248012478
assert(Value < getNumValues() && "Bad value!");
1248112479

12482-
for (SDNode::use_iterator UI = use_begin(), E = use_end(); UI != E; ++UI)
12483-
if (UI.getUse().getResNo() == Value)
12480+
for (SDUse &U : uses())
12481+
if (U.getResNo() == Value)
1248412482
return true;
1248512483

1248612484
return false;

0 commit comments

Comments
 (0)