[llvm] r285099 - Switch lowering: improve partitioning of jump tables
Evandro Menezes via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 25 12:11:43 PDT 2016
Author: evandro
Date: Tue Oct 25 14:11:43 2016
New Revision: 285099
URL: http://llvm.org/viewvc/llvm-project?rev=285099&view=rev
Log:
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
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
llvm/trunk/test/CodeGen/AArch64/max-jump-table.ll
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=285099&r1=285098&r2=285099&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Tue Oct 25 14:11:43 2016
@@ -8433,9 +8433,10 @@ void SelectionDAGBuilder::findJumpTables
const int64_t N = Clusters.size();
const unsigned MinJumpTableEntries = TLI.getMinimumJumpTableEntries();
+ const unsigned SmallNumberOfEntries = MinJumpTableEntries / 2;
const unsigned MaxJumpTableSize =
- OptForSize ? UINT_MAX : TLI.getMaximumJumpTableSize() ?
- TLI.getMaximumJumpTableSize() : UINT_MAX;
+ OptForSize || TLI.getMaximumJumpTableSize() == 0
+ ? UINT_MAX : TLI.getMaximumJumpTableSize();
if (N < 2 || N < MinJumpTableEntries)
return;
@@ -8459,7 +8460,6 @@ void SelectionDAGBuilder::findJumpTables
.getLimitedValue(UINT_MAX - 1) + 1;
if (JumpTableSize <= MaxJumpTableSize &&
isDense(Clusters, TotalCases, 0, N - 1, MinDensity)) {
-
CaseCluster JTCluster;
if (buildJumpTable(Clusters, 0, N - 1, SI, DefaultMBB, JTCluster)) {
Clusters[0] = JTCluster;
@@ -8483,13 +8483,23 @@ void SelectionDAGBuilder::findJumpTables
SmallVector<unsigned, 8> MinPartitions(N);
// LastElement[i] is the last element of the partition starting at i.
SmallVector<unsigned, 8> LastElement(N);
- // NumTables[i]: nbr of >= MinJumpTableSize partitions from Clusters[i..N-1].
- SmallVector<unsigned, 8> NumTables(N);
+ // PartitionsScore[i] is used to break ties when choosing between two
+ // partitionings resulting in the same number of partitions.
+ SmallVector<unsigned, 8> PartitionsScore(N);
+ // For PartitionsScore, a small number of comparisons is considered as good as
+ // a jump table and a single comparison is considered better than a jump
+ // table.
+ enum PartitionScores : unsigned {
+ NoTable = 0,
+ Table = 1,
+ FewCases = 1,
+ SingleCase = 2
+ };
// Base case: There is only one way to partition Clusters[N-1].
MinPartitions[N - 1] = 1;
LastElement[N - 1] = N - 1;
- NumTables[N - 1] = 0;
+ PartitionsScore[N - 1] = PartitionScores::SingleCase;
// Note: loop indexes are signed to avoid underflow.
for (int64_t i = N - 2; i >= 0; i--) {
@@ -8497,7 +8507,7 @@ void SelectionDAGBuilder::findJumpTables
// Baseline: Put Clusters[i] into a partition on its own.
MinPartitions[i] = MinPartitions[i + 1] + 1;
LastElement[i] = i;
- NumTables[i] = NumTables[i + 1];
+ PartitionsScore[i] = PartitionsScore[i + 1] + PartitionScores::SingleCase;
// Search for a solution that results in fewer partitions.
for (int64_t j = N - 1; j > i; j--) {
@@ -8508,16 +8518,23 @@ void SelectionDAGBuilder::findJumpTables
if (JumpTableSize <= MaxJumpTableSize &&
isDense(Clusters, TotalCases, i, j, MinDensity)) {
unsigned NumPartitions = 1 + (j == N - 1 ? 0 : MinPartitions[j + 1]);
- bool IsTable = j - i + 1 >= MinJumpTableEntries;
- unsigned Tables = IsTable + (j == N - 1 ? 0 : NumTables[j + 1]);
+ unsigned Score = j == N - 1 ? 0 : PartitionsScore[j + 1];
+ int64_t NumEntries = j - i + 1;
+
+ if (NumEntries == 1)
+ Score += PartitionScores::SingleCase;
+ else if (NumEntries <= SmallNumberOfEntries)
+ Score += PartitionScores::FewCases;
+ else if (NumEntries >= MinJumpTableEntries)
+ Score += PartitionScores::Table;
- // If this j leads to fewer partitions, or same number of partitions
- // with more lookup tables, it is a better partitioning.
+ // If this leads to fewer partitions, or to the same number of
+ // partitions with better score, it is a better partitioning.
if (NumPartitions < MinPartitions[i] ||
- (NumPartitions == MinPartitions[i] && Tables > NumTables[i])) {
+ (NumPartitions == MinPartitions[i] && Score > PartitionsScore[i])) {
MinPartitions[i] = NumPartitions;
LastElement[i] = j;
- NumTables[i] = Tables;
+ PartitionsScore[i] = Score;
}
}
}
Modified: llvm/trunk/test/CodeGen/AArch64/max-jump-table.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/max-jump-table.ll?rev=285099&r1=285098&r2=285099&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/max-jump-table.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/max-jump-table.ll Tue Oct 25 14:11:43 2016
@@ -1,7 +1,7 @@
-; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -o - 2>%t; FileCheck %s --check-prefixes=CHECK,CHECK0 <%t
-; 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
-; 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
-; 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
+; 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
+; 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
+; 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
+; 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
declare void @ext(i32)
@@ -27,7 +27,7 @@ entry:
i32 17, label %bb17
]
; CHECK-LABEL: function jt1:
-; CHECK: Jump Tables:
+; CHECK-NEXT: Jump Tables:
; CHECK0-NEXT: jt#0:
; CHECK0-NOT: jt#1:
; CHECK4-NEXT: jt#0:
@@ -37,10 +37,9 @@ entry:
; CHECK4-NOT: jt#4:
; CHECK8-NEXT: jt#0:
; CHECK8-SAME: jt#1:
-; CHECK8-SAME: jt#2: BB#14 BB#15 BB#16 BB#17{{$}}
-; CHECK8-NOT: jt#3:
+; CHECK8-NOT: jt#2:
; CHECKM1-NEXT: jt#0:
-; CHECKM1-SAME: jt#1: BB#13 BB#14 BB#15 BB#16 BB#17{{$}}
+; CHECKM1-SAME: jt#1
; CHECKM1-NOT: jt#2:
; CHEC-NEXT: Function Live Ins:
@@ -77,7 +76,7 @@ entry:
i32 15, label %bb6
]
; CHECK-LABEL: function jt2:
-; CHECK: Jump Tables:
+; CHECK-NEXT: Jump Tables:
; 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{{$}}
; CHECK4-NEXT: jt#0: BB#1 BB#2 BB#3 BB#4{{$}}
; CHECK8-NEXT: jt#0: BB#1 BB#2 BB#3 BB#4{{$}}
More information about the llvm-commits
mailing list