@@ -40,6 +40,54 @@ enum class DGNodeID {
4040 MemDGNode,
4141};
4242
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+
4391// / A DependencyGraph Node that points to an Instruction and contains memory
4492// / dependency edges.
4593class DGNode {
@@ -63,6 +111,23 @@ class DGNode {
63111 virtual ~DGNode () = default ;
64112 // / \Returns true if this is before \p Other in program order.
65113 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+ }
66131
67132 static bool isStackSaveOrRestoreIntrinsic (Instruction *I) {
68133 if (auto *II = dyn_cast<IntrinsicInst>(I)) {
@@ -145,6 +210,14 @@ class MemDGNode final : public DGNode {
145210 static bool classof (const DGNode *Other) {
146211 return Other->SubclassID == DGNodeID::MemDGNode;
147212 }
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+ }
148221 // / \Returns the previous Mem DGNode in instruction order.
149222 MemDGNode *getPrevNode () const { return PrevMemN; }
150223 // / \Returns the next Mem DGNode in instruction order.
0 commit comments