@@ -701,23 +701,40 @@ static SmallVector<SmallVector<Value, 8>, 2> pruneRedundantArguments(
701
701
// idxToReplacement[3] = 0
702
702
llvm::DenseMap<unsigned , unsigned > idxToReplacement;
703
703
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
+
704
713
// Go through the first list of arguments (list 0).
705
714
for (unsigned j = 0 ; j < numArgs; ++j) {
706
715
bool shouldReplaceJ = false ;
707
716
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]);
721
738
}
722
739
// Save the replacement.
723
740
if (shouldReplaceJ)
0 commit comments