Skip to content

Commit 08bfc9b

Browse files
authored
[SandboxVec][DAG] Avoid unnecessary dependency scan and improve description (#112057)
When NewInterval is below DAGInterval we used to revisit instructions already visited. This patch fixes this by separating the scan in two: 1. The full scan of the NewInterval, and 2. The cross-interval scan for DAGInterval. This is further explained in the new description.
1 parent 66723a0 commit 08bfc9b

File tree

1 file changed

+63
-26
lines changed

1 file changed

+63
-26
lines changed

llvm/lib/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.cpp

Lines changed: 63 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -276,30 +276,44 @@ Interval<Instruction> DependencyGraph::extend(ArrayRef<Instruction *> Instrs) {
276276

277277
// Create the dependencies.
278278
//
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);
279+
// 1. This is a new DAG, DAGInterval is empty. Fully scan the whole interval.
280+
// +---+ - -
281+
// | | SrcN | |
282+
// | | | | SrcRange |
283+
// |New| v | | DstRange
284+
// | | DstN - |
285+
// | | |
286+
// +---+ -
287+
// We are scanning for deps with destination in NewInterval and sources in
288+
// NewInterval until DstN, for each DstN.
289+
auto FullScan = [this](const Interval<Instruction> Intvl) {
290+
auto DstRange = MemDGNodeIntervalBuilder::make(Intvl, *this);
295291
if (!DstRange.empty()) {
296292
for (MemDGNode &DstN : drop_begin(DstRange)) {
297293
auto SrcRange = Interval<MemDGNode>(DstRange.top(), DstN.getPrevNode());
298294
scanAndAddDeps(DstN, SrcRange);
299295
}
300296
}
297+
};
298+
if (DAGInterval.empty()) {
299+
assert(NewInterval == InstrsInterval && "Expected empty DAGInterval!");
300+
FullScan(NewInterval);
301301
}
302302
// 2. The new section is below the old section.
303+
// +---+ -
304+
// | | |
305+
// |Old| SrcN |
306+
// | | | |
307+
// +---+ | | SrcRange
308+
// +---+ | | -
309+
// | | | | |
310+
// |New| v | | DstRange
311+
// | | DstN - |
312+
// | | |
313+
// +---+ -
314+
// We are scanning for deps with destination in NewInterval because the deps
315+
// in DAGInterval have already been computed. We consider sources in the whole
316+
// range including both NewInterval and DAGInterval until DstN, for each DstN.
303317
else if (DAGInterval.bottom()->comesBefore(NewInterval.top())) {
304318
auto DstRange = MemDGNodeIntervalBuilder::make(NewInterval, *this);
305319
auto SrcRangeFull = MemDGNodeIntervalBuilder::make(
@@ -312,16 +326,39 @@ Interval<Instruction> DependencyGraph::extend(ArrayRef<Instruction *> Instrs) {
312326
}
313327
// 3. The new section is above the old section.
314328
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-
}
329+
// +---+ - -
330+
// | | SrcN | |
331+
// |New| | | SrcRange | DstRange
332+
// | | v | |
333+
// | | DstN - |
334+
// | | |
335+
// +---+ -
336+
// +---+
337+
// |Old|
338+
// | |
339+
// +---+
340+
// When scanning for deps with destination in NewInterval we need to fully
341+
// scan the interval. This is the same as the scanning for a new DAG.
342+
FullScan(NewInterval);
343+
344+
// +---+ -
345+
// | | |
346+
// |New| SrcN | SrcRange
347+
// | | | |
348+
// | | | |
349+
// | | | |
350+
// +---+ | -
351+
// +---+ | -
352+
// |Old| v | DstRange
353+
// | | DstN |
354+
// +---+ -
355+
// When scanning for deps with destination in DAGInterval we need to
356+
// consider sources from the NewInterval only, because all intra-DAGInterval
357+
// dependencies have already been created.
358+
auto DstRangeOld = MemDGNodeIntervalBuilder::make(DAGInterval, *this);
359+
auto SrcRange = MemDGNodeIntervalBuilder::make(NewInterval, *this);
360+
for (MemDGNode &DstN : DstRangeOld)
361+
scanAndAddDeps(DstN, SrcRange);
325362
} else {
326363
llvm_unreachable("We don't expect extending in both directions!");
327364
}

0 commit comments

Comments
 (0)