@@ -215,17 +215,11 @@ void DependencyGraph::scanAndAddDeps(MemDGNode &DstN,
215
215
}
216
216
}
217
217
218
- Interval<Instruction> DependencyGraph::extend (ArrayRef<Instruction *> Instrs) {
219
- if (Instrs.empty ())
220
- return {};
221
-
222
- Interval<Instruction> InstrInterval (Instrs);
223
-
224
- DGNode *LastN = getOrCreateNode (InstrInterval.top ());
225
- // Create DGNodes for all instrs in Interval to avoid future Instruction to
226
- // DGNode lookups.
218
+ void DependencyGraph::createNewNodes (const Interval<Instruction> &NewInterval) {
219
+ // Create Nodes only for the new sections of the DAG.
220
+ DGNode *LastN = getOrCreateNode (NewInterval.top ());
227
221
MemDGNode *LastMemN = dyn_cast<MemDGNode>(LastN);
228
- for (Instruction &I : drop_begin (InstrInterval )) {
222
+ for (Instruction &I : drop_begin (NewInterval )) {
229
223
auto *N = getOrCreateNode (&I);
230
224
// Build the Mem node chain.
231
225
if (auto *MemN = dyn_cast<MemDGNode>(N)) {
@@ -235,16 +229,105 @@ Interval<Instruction> DependencyGraph::extend(ArrayRef<Instruction *> Instrs) {
235
229
LastMemN = MemN;
236
230
}
237
231
}
232
+ // Link new MemDGNode chain with the old one, if any.
233
+ if (!DAGInterval.empty ()) {
234
+ bool NewIsAbove = NewInterval.bottom ()->comesBefore (DAGInterval.bottom ());
235
+ const auto &TopInterval = NewIsAbove ? NewInterval : DAGInterval;
236
+ const auto &BotInterval = NewIsAbove ? DAGInterval : NewInterval;
237
+ MemDGNode *LinkTopN =
238
+ MemDGNodeIntervalBuilder::getBotMemDGNode (TopInterval, *this );
239
+ MemDGNode *LinkBotN =
240
+ MemDGNodeIntervalBuilder::getTopMemDGNode (BotInterval, *this );
241
+ assert (LinkTopN->comesBefore (LinkBotN) && " Wrong order!" );
242
+ if (LinkTopN != nullptr && LinkBotN != nullptr ) {
243
+ LinkTopN->setNextNode (LinkBotN);
244
+ LinkBotN->setPrevNode (LinkTopN);
245
+ }
246
+ #ifndef NDEBUG
247
+ // TODO: Remove this once we've done enough testing.
248
+ // Check that the chain is well formed.
249
+ auto UnionIntvl = DAGInterval.getUnionInterval (NewInterval);
250
+ MemDGNode *ChainTopN =
251
+ MemDGNodeIntervalBuilder::getTopMemDGNode (UnionIntvl, *this );
252
+ MemDGNode *ChainBotN =
253
+ MemDGNodeIntervalBuilder::getBotMemDGNode (UnionIntvl, *this );
254
+ if (ChainTopN != nullptr && ChainBotN != nullptr ) {
255
+ for (auto *N = ChainTopN->getNextNode (), *LastN = ChainTopN; N != nullptr ;
256
+ LastN = N, N = N->getNextNode ()) {
257
+ assert (N == LastN->getNextNode () && " Bad chain!" );
258
+ assert (N->getPrevNode () == LastN && " Bad chain!" );
259
+ }
260
+ }
261
+ #endif // NDEBUG
262
+ }
263
+ }
264
+
265
+ Interval<Instruction> DependencyGraph::extend (ArrayRef<Instruction *> Instrs) {
266
+ if (Instrs.empty ())
267
+ return {};
268
+
269
+ Interval<Instruction> InstrsInterval (Instrs);
270
+ Interval<Instruction> Union = DAGInterval.getUnionInterval (InstrsInterval);
271
+ auto NewInterval = Union.getSingleDiff (DAGInterval);
272
+ if (NewInterval.empty ())
273
+ return {};
274
+
275
+ createNewNodes (NewInterval);
276
+
238
277
// Create the dependencies.
239
- auto DstRange = MemDGNodeIntervalBuilder::make (InstrInterval, *this );
240
- if (!DstRange.empty ()) {
241
- for (MemDGNode &DstN : drop_begin (DstRange)) {
242
- auto SrcRange = Interval<MemDGNode>(DstRange.top (), DstN.getPrevNode ());
278
+ //
279
+ // 1. DAGInterval empty 2. New is below Old 3. New is above old
280
+ // ------------------------ ------------------- -------------------
281
+ // Scan: DstN: Scan:
282
+ // +---+ -ScanTopN +---+DstTopN -ScanTopN
283
+ // | | | |New| |
284
+ // |Old| | +---+ -ScanBotN
285
+ // | | | +---+
286
+ // DstN: Scan: +---+DstN: | | |
287
+ // +---+DstTopN -ScanTopN +---+DstTopN | |Old|
288
+ // |New| | |New| | | |
289
+ // +---+DstBotN -ScanBotN +---+DstBotN -ScanBotN +---+DstBotN
290
+
291
+ // 1. This is a new DAG.
292
+ if (DAGInterval.empty ()) {
293
+ assert (NewInterval == InstrsInterval && " Expected empty DAGInterval!" );
294
+ auto DstRange = MemDGNodeIntervalBuilder::make (NewInterval, *this );
295
+ if (!DstRange.empty ()) {
296
+ for (MemDGNode &DstN : drop_begin (DstRange)) {
297
+ auto SrcRange = Interval<MemDGNode>(DstRange.top (), DstN.getPrevNode ());
298
+ scanAndAddDeps (DstN, SrcRange);
299
+ }
300
+ }
301
+ }
302
+ // 2. The new section is below the old section.
303
+ else if (DAGInterval.bottom ()->comesBefore (NewInterval.top ())) {
304
+ auto DstRange = MemDGNodeIntervalBuilder::make (NewInterval, *this );
305
+ auto SrcRangeFull = MemDGNodeIntervalBuilder::make (
306
+ DAGInterval.getUnionInterval (NewInterval), *this );
307
+ for (MemDGNode &DstN : DstRange) {
308
+ auto SrcRange =
309
+ Interval<MemDGNode>(SrcRangeFull.top (), DstN.getPrevNode ());
243
310
scanAndAddDeps (DstN, SrcRange);
244
311
}
245
312
}
313
+ // 3. The new section is above the old section.
314
+ else if (NewInterval.bottom ()->comesBefore (DAGInterval.top ())) {
315
+ auto DstRange = MemDGNodeIntervalBuilder::make (
316
+ NewInterval.getUnionInterval (DAGInterval), *this );
317
+ auto SrcRangeFull = MemDGNodeIntervalBuilder::make (NewInterval, *this );
318
+ if (!DstRange.empty ()) {
319
+ for (MemDGNode &DstN : drop_begin (DstRange)) {
320
+ auto SrcRange =
321
+ Interval<MemDGNode>(SrcRangeFull.top (), DstN.getPrevNode ());
322
+ scanAndAddDeps (DstN, SrcRange);
323
+ }
324
+ }
325
+ } else {
326
+ llvm_unreachable (" We don't expect extending in both directions!" );
327
+ }
246
328
247
- return InstrInterval;
329
+ DAGInterval = Union;
330
+ return NewInterval;
248
331
}
249
332
250
333
#ifndef NDEBUG
0 commit comments