@@ -215,17 +215,11 @@ void DependencyGraph::scanAndAddDeps(MemDGNode &DstN,
215215 }
216216}
217217
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 ());
227221 MemDGNode *LastMemN = dyn_cast<MemDGNode>(LastN);
228- for (Instruction &I : drop_begin (InstrInterval )) {
222+ for (Instruction &I : drop_begin (NewInterval )) {
229223 auto *N = getOrCreateNode (&I);
230224 // Build the Mem node chain.
231225 if (auto *MemN = dyn_cast<MemDGNode>(N)) {
@@ -235,16 +229,109 @@ Interval<Instruction> DependencyGraph::extend(ArrayRef<Instruction *> Instrs) {
235229 LastMemN = MemN;
236230 }
237231 }
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+
238281 // 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 ());
243314 scanAndAddDeps (DstN, SrcRange);
244315 }
245316 }
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+ }
246332
247- return InstrInterval;
333+ DAGInterval = Union;
334+ return NewInterval;
248335}
249336
250337#ifndef NDEBUG
0 commit comments