Skip to content

Commit e6b2495

Browse files
authored
[SelectionDAG] Split SDNode::use_iterator into user_iterator and use_iterator. (#120531)
SDNode::use_iterator now returns an SDUse& when dereferenced. SDNode::user_iterator returns SDNode*. SDNode::use_begin/use_end/uses work on use_iterator. SDNode::user_begin/user_end/users work on user_iterator. We can now 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 SDNode::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 f8bcd93 commit e6b2495

18 files changed

+245
-237
lines changed

llvm/include/llvm/CodeGen/SelectionDAGNodes.h

Lines changed: 58 additions & 23 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.
@@ -806,9 +806,6 @@ END_TWO_BYTE_PACK()
806806
return !operator==(x);
807807
}
808808

809-
/// Return true if this iterator is at the end of uses list.
810-
bool atEnd() const { return Op == nullptr; }
811-
812809
// Iterator traversal: forward iteration only.
813810
use_iterator &operator++() { // Preincrement
814811
assert(Op && "Cannot increment end iterator!");
@@ -821,14 +818,12 @@ END_TWO_BYTE_PACK()
821818
}
822819

823820
/// Retrieve a pointer to the current user node.
824-
SDNode *operator*() const {
821+
SDUse &operator*() const {
825822
assert(Op && "Cannot dereference end iterator!");
826-
return Op->getUser();
823+
return *Op;
827824
}
828825

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

833828
/// Retrieve the operand # of this use in its user.
834829
unsigned getOperandNo() const {
@@ -837,29 +832,69 @@ END_TWO_BYTE_PACK()
837832
}
838833
};
839834

835+
class user_iterator {
836+
friend class SDNode;
837+
use_iterator UI;
838+
839+
explicit user_iterator(SDUse *op) : UI(op) {};
840+
841+
public:
842+
using iterator_category = std::forward_iterator_tag;
843+
using value_type = SDNode *;
844+
using difference_type = std::ptrdiff_t;
845+
using pointer = value_type *;
846+
using reference = value_type &;
847+
848+
user_iterator() = default;
849+
850+
bool operator==(const user_iterator &x) const { return UI == x.UI; }
851+
bool operator!=(const user_iterator &x) const { return !operator==(x); }
852+
853+
user_iterator &operator++() { // Preincrement
854+
++UI;
855+
return *this;
856+
}
857+
858+
user_iterator operator++(int) { // Postincrement
859+
auto tmp = *this;
860+
++*this;
861+
return tmp;
862+
}
863+
864+
// Retrieve a pointer to the current User.
865+
SDNode *operator*() const { return UI->getUser(); }
866+
867+
SDNode *operator->() const { return operator*(); }
868+
869+
SDUse &getUse() const { return *UI; }
870+
};
871+
840872
/// Provide iteration support to walk over all uses of an SDNode.
841873
use_iterator use_begin() const {
842874
return use_iterator(UseList);
843875
}
844876

845877
static use_iterator use_end() { return use_iterator(nullptr); }
846878

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() {
879+
inline iterator_range<use_iterator> uses() {
857880
return make_range(use_begin(), use_end());
858881
}
859-
inline iterator_range<use_iterator> users() const {
882+
inline iterator_range<use_iterator> uses() const {
860883
return make_range(use_begin(), use_end());
861884
}
862885

886+
/// Provide iteration support to walk over all users of an SDNode.
887+
user_iterator user_begin() const { return user_iterator(UseList); }
888+
889+
static user_iterator user_end() { return user_iterator(nullptr); }
890+
891+
inline iterator_range<user_iterator> users() {
892+
return make_range(user_begin(), user_end());
893+
}
894+
inline iterator_range<user_iterator> users() const {
895+
return make_range(user_begin(), user_end());
896+
}
897+
863898
/// Return true if there are exactly NUSES uses of the indicated value.
864899
/// This method ignores uses of other values defined by this operation.
865900
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const;
@@ -1019,9 +1054,9 @@ END_TWO_BYTE_PACK()
10191054
/// If this node has a glue value with a user, return
10201055
/// the user (there is at most one). Otherwise return NULL.
10211056
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;
1057+
for (SDUse &U : uses())
1058+
if (U.getValueType() == MVT::Glue)
1059+
return U.getUser();
10251060
return nullptr;
10261061
}
10271062

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;

0 commit comments

Comments
 (0)