Skip to content

Commit 746f507

Browse files
committed
Use a O(N) algorithm with a conservative tradeoff
1 parent d6513e1 commit 746f507

File tree

1 file changed

+30
-13
lines changed

1 file changed

+30
-13
lines changed

mlir/lib/Transforms/Utils/RegionUtils.cpp

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -701,23 +701,40 @@ static SmallVector<SmallVector<Value, 8>, 2> pruneRedundantArguments(
701701
// idxToReplacement[3] = 0
702702
llvm::DenseMap<unsigned, unsigned> idxToReplacement;
703703

704+
// This is a useful data structure to track the first appearance of a Value
705+
// on a given list of arguments
706+
DenseMap<Value, unsigned> firstValueToIdx;
707+
for (unsigned j = 0; j < numArgs; ++j) {
708+
Value newArg = newArguments[0][j];
709+
if (!firstValueToIdx.contains(newArg))
710+
firstValueToIdx[newArg] = j;
711+
}
712+
704713
// Go through the first list of arguments (list 0).
705714
for (unsigned j = 0; j < numArgs; ++j) {
706715
bool shouldReplaceJ = false;
707716
unsigned replacement = 0;
708-
// Look back to see if there are possible redundancies in
709-
// list 0.
710-
for (unsigned k = 0; k < j; k++) {
711-
if (newArguments[0][k] == newArguments[0][j]) {
712-
shouldReplaceJ = true;
713-
replacement = k;
714-
// If a possible redundancy is found, then scan the other lists: we
715-
// can prune the arguments if and only if they are redundant in every
716-
// list.
717-
for (unsigned i = 1; i < numLists; ++i)
718-
shouldReplaceJ =
719-
shouldReplaceJ && (newArguments[i][k] == newArguments[i][j]);
720-
}
717+
// Look back to see if there are possible redundancies in list 0. Please
718+
// note that we are using a map to annotate when an argument was seen first
719+
// to avoid a O(N^2) algorithm. This has the drawback that if we have two
720+
// lists like:
721+
// list0: [%a, %a, %a]
722+
// list1: [%c, %b, %b]
723+
// We cannot simplify it, because firstVlaueToIdx[%a] = 0, but we cannot
724+
// point list1[1](==%b) or list1[2](==%b) to list1[0](==%c). However, since
725+
// the number of arguments can be potentially unbounded we cannot afford a
726+
// O(N^2) algorithm (to search to all the possible pairs) and we need to
727+
// accept the trade-off.
728+
unsigned k = firstValueToIdx[newArguments[0][j]];
729+
if (k != j) {
730+
shouldReplaceJ = true;
731+
replacement = k;
732+
// If a possible redundancy is found, then scan the other lists: we
733+
// can prune the arguments if and only if they are redundant in every
734+
// list.
735+
for (unsigned i = 1; i < numLists; ++i)
736+
shouldReplaceJ =
737+
shouldReplaceJ && (newArguments[i][k] == newArguments[i][j]);
721738
}
722739
// Save the replacement.
723740
if (shouldReplaceJ)

0 commit comments

Comments
 (0)