llvm.org GIT mirror llvm / 301f71e
Switch lowering: improve partitioning of jump tables When there's a tie between partitionings of jump tables, consider also cases that result in no jump tables, but in one or a few cases. The motivation is that many contemporary processors typically perform case switches fairly quickly. Differential revision: https://reviews.llvm.org/D25212 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@285099 91177308-0d34-0410-b5e6-96231b3b80d8 Evandro Menezes 3 years ago
2 changed file(s) with 39 addition(s) and 23 deletion(s). Raw diff Collapse all Expand all
84328432
84338433 const int64_t N = Clusters.size();
84348434 const unsigned MinJumpTableEntries = TLI.getMinimumJumpTableEntries();
8435 const unsigned SmallNumberOfEntries = MinJumpTableEntries / 2;
84358436 const unsigned MaxJumpTableSize =
8436 OptForSize ? UINT_MAX : TLI.getMaximumJumpTableSize() ?
8437 TLI.getMaximumJumpTableSize() : UINT_MAX;
8437 OptForSize || TLI.getMaximumJumpTableSize() == 0
8438 ? UINT_MAX : TLI.getMaximumJumpTableSize();
84388439
84398440 if (N < 2 || N < MinJumpTableEntries)
84408441 return;
84588459 .getLimitedValue(UINT_MAX - 1) + 1;
84598460 if (JumpTableSize <= MaxJumpTableSize &&
84608461 isDense(Clusters, TotalCases, 0, N - 1, MinDensity)) {
8461
84628462 CaseCluster JTCluster;
84638463 if (buildJumpTable(Clusters, 0, N - 1, SI, DefaultMBB, JTCluster)) {
84648464 Clusters[0] = JTCluster;
84828482 SmallVector MinPartitions(N);
84838483 // LastElement[i] is the last element of the partition starting at i.
84848484 SmallVector LastElement(N);
8485 // NumTables[i]: nbr of >= MinJumpTableSize partitions from Clusters[i..N-1].
8486 SmallVector NumTables(N);
8485 // PartitionsScore[i] is used to break ties when choosing between two
8486 // partitionings resulting in the same number of partitions.
8487 SmallVector PartitionsScore(N);
8488 // For PartitionsScore, a small number of comparisons is considered as good as
8489 // a jump table and a single comparison is considered better than a jump
8490 // table.
8491 enum PartitionScores : unsigned {
8492 NoTable = 0,
8493 Table = 1,
8494 FewCases = 1,
8495 SingleCase = 2
8496 };
84878497
84888498 // Base case: There is only one way to partition Clusters[N-1].
84898499 MinPartitions[N - 1] = 1;
84908500 LastElement[N - 1] = N - 1;
8491 NumTables[N - 1] = 0;
8501 PartitionsScore[N - 1] = PartitionScores::SingleCase;
84928502
84938503 // Note: loop indexes are signed to avoid underflow.
84948504 for (int64_t i = N - 2; i >= 0; i--) {
84968506 // Baseline: Put Clusters[i] into a partition on its own.
84978507 MinPartitions[i] = MinPartitions[i + 1] + 1;
84988508 LastElement[i] = i;
8499 NumTables[i] = NumTables[i + 1];
8509 PartitionsScore[i] = PartitionsScore[i + 1] + PartitionScores::SingleCase;
85008510
85018511 // Search for a solution that results in fewer partitions.
85028512 for (int64_t j = N - 1; j > i; j--) {
85078517 if (JumpTableSize <= MaxJumpTableSize &&
85088518 isDense(Clusters, TotalCases, i, j, MinDensity)) {
85098519 unsigned NumPartitions = 1 + (j == N - 1 ? 0 : MinPartitions[j + 1]);
8510 bool IsTable = j - i + 1 >= MinJumpTableEntries;
8511 unsigned Tables = IsTable + (j == N - 1 ? 0 : NumTables[j + 1]);
8512
8513 // If this j leads to fewer partitions, or same number of partitions
8514 // with more lookup tables, it is a better partitioning.
8520 unsigned Score = j == N - 1 ? 0 : PartitionsScore[j + 1];
8521 int64_t NumEntries = j - i + 1;
8522
8523 if (NumEntries == 1)
8524 Score += PartitionScores::SingleCase;
8525 else if (NumEntries <= SmallNumberOfEntries)
8526 Score += PartitionScores::FewCases;
8527 else if (NumEntries >= MinJumpTableEntries)
8528 Score += PartitionScores::Table;
8529
8530 // If this leads to fewer partitions, or to the same number of
8531 // partitions with better score, it is a better partitioning.
85158532 if (NumPartitions < MinPartitions[i] ||
8516 (NumPartitions == MinPartitions[i] && Tables > NumTables[i])) {
8533 (NumPartitions == MinPartitions[i] && Score > PartitionsScore[i])) {
85178534 MinPartitions[i] = NumPartitions;
85188535 LastElement[i] = j;
8519 NumTables[i] = Tables;
8536 PartitionsScore[i] = Score;
85208537 }
85218538 }
85228539 }
None ; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -o - 2>%t; FileCheck %s --check-prefixes=CHECK,CHECK0 <%t
1 ; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -max-jump-table=4 -o - 2>%t; FileCheck %s --check-prefixes=CHECK,CHECK4 <%t
2 ; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -max-jump-table=8 -o - 2>%t; FileCheck %s --check-prefixes=CHECK,CHECK8 <%t
3 ; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -mcpu=exynos-m1 -o - 2>%t; FileCheck %s --check-prefixes=CHECK,CHECKM1 <%t
0 ; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECK0 < %t
1 ; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -max-jump-table=4 -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECK4 < %t
2 ; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -max-jump-table=8 -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECK8 < %t
3 ; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -mcpu=exynos-m1 -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECKM1 < %t
44
55 declare void @ext(i32)
66
2626 i32 17, label %bb17
2727 ]
2828 ; CHECK-LABEL: function jt1:
29 ; CHECK: Jump Tables:
29 ; CHECK-NEXT: Jump Tables:
3030 ; CHECK0-NEXT: jt#0:
3131 ; CHECK0-NOT: jt#1:
3232 ; CHECK4-NEXT: jt#0:
3636 ; CHECK4-NOT: jt#4:
3737 ; CHECK8-NEXT: jt#0:
3838 ; CHECK8-SAME: jt#1:
39 ; CHECK8-SAME: jt#2: BB#14 BB#15 BB#16 BB#17{{$}}
40 ; CHECK8-NOT: jt#3:
39 ; CHECK8-NOT: jt#2:
4140 ; CHECKM1-NEXT: jt#0:
42 ; CHECKM1-SAME: jt#1: BB#13 BB#14 BB#15 BB#16 BB#17{{$}}
41 ; CHECKM1-SAME: jt#1
4342 ; CHECKM1-NOT: jt#2:
4443 ; CHEC-NEXT: Function Live Ins:
4544
7675 i32 15, label %bb6
7776 ]
7877 ; CHECK-LABEL: function jt2:
79 ; CHECK: Jump Tables:
78 ; CHECK-NEXT: Jump Tables:
8079 ; CHECK0-NEXT: jt#0: BB#1 BB#2 BB#3 BB#4 BB#7 BB#7 BB#7 BB#7 BB#7 BB#7 BB#7 BB#7 BB#7 BB#5 BB#6{{$}}
8180 ; CHECK4-NEXT: jt#0: BB#1 BB#2 BB#3 BB#4{{$}}
8281 ; CHECK8-NEXT: jt#0: BB#1 BB#2 BB#3 BB#4{{$}}