@@ -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,109 @@ 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
+ // TODO: Implement Interval::comesBefore() to replace this check.
235
+ bool NewIsAbove = NewInterval.bottom ()->comesBefore (DAGInterval.top ());
236
+ assert (
237
+ (NewIsAbove || DAGInterval.bottom ()->comesBefore (NewInterval.top ())) &&
238
+ " Expected NewInterval below DAGInterval." );
239
+ const auto &TopInterval = NewIsAbove ? NewInterval : DAGInterval;
240
+ const auto &BotInterval = NewIsAbove ? DAGInterval : NewInterval;
241
+ MemDGNode *LinkTopN =
242
+ MemDGNodeIntervalBuilder::getBotMemDGNode (TopInterval, *this );
243
+ MemDGNode *LinkBotN =
244
+ MemDGNodeIntervalBuilder::getTopMemDGNode (BotInterval, *this );
245
+ assert (LinkTopN->comesBefore (LinkBotN) && " Wrong order!" );
246
+ if (LinkTopN != nullptr && LinkBotN != nullptr ) {
247
+ LinkTopN->setNextNode (LinkBotN);
248
+ LinkBotN->setPrevNode (LinkTopN);
249
+ }
250
+ #ifndef NDEBUG
251
+ // TODO: Remove this once we've done enough testing.
252
+ // Check that the chain is well formed.
253
+ auto UnionIntvl = DAGInterval.getUnionInterval (NewInterval);
254
+ MemDGNode *ChainTopN =
255
+ MemDGNodeIntervalBuilder::getTopMemDGNode (UnionIntvl, *this );
256
+ MemDGNode *ChainBotN =
257
+ MemDGNodeIntervalBuilder::getBotMemDGNode (UnionIntvl, *this );
258
+ if (ChainTopN != nullptr && ChainBotN != nullptr ) {
259
+ for (auto *N = ChainTopN->getNextNode (), *LastN = ChainTopN; N != nullptr ;
260
+ LastN = N, N = N->getNextNode ()) {
261
+ assert (N == LastN->getNextNode () && " Bad chain!" );
262
+ assert (N->getPrevNode () == LastN && " Bad chain!" );
263
+ }
264
+ }
265
+ #endif // NDEBUG
266
+ }
267
+ }
268
+
269
+ Interval<Instruction> DependencyGraph::extend (ArrayRef<Instruction *> Instrs) {
270
+ if (Instrs.empty ())
271
+ return {};
272
+
273
+ Interval<Instruction> InstrsInterval (Instrs);
274
+ Interval<Instruction> Union = DAGInterval.getUnionInterval (InstrsInterval);
275
+ auto NewInterval = Union.getSingleDiff (DAGInterval);
276
+ if (NewInterval.empty ())
277
+ return {};
278
+
279
+ createNewNodes (NewInterval);
280
+
238
281
// 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 ());
282
+ //
283
+ // 1. DAGInterval empty 2. New is below Old 3. New is above old
284
+ // ------------------------ ------------------- -------------------
285
+ // Scan: DstN: Scan:
286
+ // +---+ -ScanTopN +---+DstTopN -ScanTopN
287
+ // | | | |New| |
288
+ // |Old| | +---+ -ScanBotN
289
+ // | | | +---+
290
+ // DstN: Scan: +---+DstN: | | |
291
+ // +---+DstTopN -ScanTopN +---+DstTopN | |Old|
292
+ // |New| | |New| | | |
293
+ // +---+DstBotN -ScanBotN +---+DstBotN -ScanBotN +---+DstBotN
294
+
295
+ // 1. This is a new DAG.
296
+ if (DAGInterval.empty ()) {
297
+ assert (NewInterval == InstrsInterval && " Expected empty DAGInterval!" );
298
+ auto DstRange = MemDGNodeIntervalBuilder::make (NewInterval, *this );
299
+ if (!DstRange.empty ()) {
300
+ for (MemDGNode &DstN : drop_begin (DstRange)) {
301
+ auto SrcRange = Interval<MemDGNode>(DstRange.top (), DstN.getPrevNode ());
302
+ scanAndAddDeps (DstN, SrcRange);
303
+ }
304
+ }
305
+ }
306
+ // 2. The new section is below the old section.
307
+ else if (DAGInterval.bottom ()->comesBefore (NewInterval.top ())) {
308
+ auto DstRange = MemDGNodeIntervalBuilder::make (NewInterval, *this );
309
+ auto SrcRangeFull = MemDGNodeIntervalBuilder::make (
310
+ DAGInterval.getUnionInterval (NewInterval), *this );
311
+ for (MemDGNode &DstN : DstRange) {
312
+ auto SrcRange =
313
+ Interval<MemDGNode>(SrcRangeFull.top (), DstN.getPrevNode ());
243
314
scanAndAddDeps (DstN, SrcRange);
244
315
}
245
316
}
317
+ // 3. The new section is above the old section.
318
+ else if (NewInterval.bottom ()->comesBefore (DAGInterval.top ())) {
319
+ auto DstRange = MemDGNodeIntervalBuilder::make (
320
+ NewInterval.getUnionInterval (DAGInterval), *this );
321
+ auto SrcRangeFull = MemDGNodeIntervalBuilder::make (NewInterval, *this );
322
+ if (!DstRange.empty ()) {
323
+ for (MemDGNode &DstN : drop_begin (DstRange)) {
324
+ auto SrcRange =
325
+ Interval<MemDGNode>(SrcRangeFull.top (), DstN.getPrevNode ());
326
+ scanAndAddDeps (DstN, SrcRange);
327
+ }
328
+ }
329
+ } else {
330
+ llvm_unreachable (" We don't expect extending in both directions!" );
331
+ }
246
332
247
- return InstrInterval;
333
+ DAGInterval = Union;
334
+ return NewInterval;
248
335
}
249
336
250
337
#ifndef NDEBUG
0 commit comments