@@ -40,6 +40,54 @@ enum class DGNodeID {
40
40
MemDGNode,
41
41
};
42
42
43
+ class DGNode ;
44
+ class MemDGNode ;
45
+ class DependencyGraph ;
46
+
47
+ // / While OpIt points to a Value that is not an Instruction keep incrementing
48
+ // / it. \Returns the first iterator that points to an Instruction, or end.
49
+ [[nodiscard]] static User::op_iterator skipNonInstr (User::op_iterator OpIt,
50
+ User::op_iterator OpItE) {
51
+ while (OpIt != OpItE && !isa<Instruction>((*OpIt).get ()))
52
+ ++OpIt;
53
+ return OpIt;
54
+ }
55
+
56
+ // / Iterate over both def-use and mem dependencies.
57
+ class PredIterator {
58
+ User::op_iterator OpIt;
59
+ User::op_iterator OpItE;
60
+ DenseSet<MemDGNode *>::iterator MemIt;
61
+ DGNode *N = nullptr ;
62
+ DependencyGraph *DAG = nullptr ;
63
+
64
+ PredIterator (const User::op_iterator &OpIt, const User::op_iterator &OpItE,
65
+ const DenseSet<MemDGNode *>::iterator &MemIt, DGNode *N,
66
+ DependencyGraph &DAG)
67
+ : OpIt(OpIt), OpItE(OpItE), MemIt(MemIt), N(N), DAG(&DAG) {}
68
+ PredIterator (const User::op_iterator &OpIt, const User::op_iterator &OpItE,
69
+ DGNode *N, DependencyGraph &DAG)
70
+ : OpIt(OpIt), OpItE(OpItE), N(N), DAG(&DAG) {}
71
+ friend class DGNode ; // For constructor
72
+ friend class MemDGNode ; // For constructor
73
+
74
+ public:
75
+ using difference_type = std::ptrdiff_t ;
76
+ using value_type = DGNode *;
77
+ using pointer = value_type *;
78
+ using reference = value_type &;
79
+ using iterator_category = std::input_iterator_tag;
80
+ value_type operator *();
81
+ PredIterator &operator ++();
82
+ PredIterator operator ++(int ) {
83
+ auto Copy = *this ;
84
+ ++(*this );
85
+ return Copy;
86
+ }
87
+ bool operator ==(const PredIterator &Other) const ;
88
+ bool operator !=(const PredIterator &Other) const { return !(*this == Other); }
89
+ };
90
+
43
91
// / A DependencyGraph Node that points to an Instruction and contains memory
44
92
// / dependency edges.
45
93
class DGNode {
@@ -63,6 +111,23 @@ class DGNode {
63
111
virtual ~DGNode () = default ;
64
112
// / \Returns true if this is before \p Other in program order.
65
113
bool comesBefore (const DGNode *Other) { return I->comesBefore (Other->I ); }
114
+ using iterator = PredIterator;
115
+ virtual iterator preds_begin (DependencyGraph &DAG) {
116
+ return PredIterator (skipNonInstr (I->op_begin (), I->op_end ()), I->op_end (),
117
+ this , DAG);
118
+ }
119
+ virtual iterator preds_end (DependencyGraph &DAG) {
120
+ return PredIterator (I->op_end (), I->op_end (), this , DAG);
121
+ }
122
+ iterator preds_begin (DependencyGraph &DAG) const {
123
+ return const_cast <DGNode *>(this )->preds_begin (DAG);
124
+ }
125
+ iterator preds_end (DependencyGraph &DAG) const {
126
+ return const_cast <DGNode *>(this )->preds_end (DAG);
127
+ }
128
+ iterator_range<iterator> preds (DependencyGraph &DAG) const {
129
+ return make_range (preds_begin (DAG), preds_end (DAG));
130
+ }
66
131
67
132
static bool isStackSaveOrRestoreIntrinsic (Instruction *I) {
68
133
if (auto *II = dyn_cast<IntrinsicInst>(I)) {
@@ -145,6 +210,14 @@ class MemDGNode final : public DGNode {
145
210
static bool classof (const DGNode *Other) {
146
211
return Other->SubclassID == DGNodeID::MemDGNode;
147
212
}
213
+ iterator preds_begin (DependencyGraph &DAG) override {
214
+ auto OpEndIt = I->op_end ();
215
+ return PredIterator (skipNonInstr (I->op_begin (), OpEndIt), OpEndIt,
216
+ MemPreds.begin (), this , DAG);
217
+ }
218
+ iterator preds_end (DependencyGraph &DAG) override {
219
+ return PredIterator (I->op_end (), I->op_end (), MemPreds.end (), this , DAG);
220
+ }
148
221
// / \Returns the previous Mem DGNode in instruction order.
149
222
MemDGNode *getPrevNode () const { return PrevMemN; }
150
223
// / \Returns the next Mem DGNode in instruction order.
0 commit comments