@@ -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,105 @@ 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+ 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+
238277 // 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 ());
243310 scanAndAddDeps (DstN, SrcRange);
244311 }
245312 }
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+ }
246328
247- return InstrInterval;
329+ DAGInterval = Union;
330+ return NewInterval;
248331}
249332
250333#ifndef NDEBUG
0 commit comments