mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 05:01:59 +01:00
Switch lowering: enable whole-switch jump tables at -O0.
To same compile time, the analysis to find dense case-clusters in switches is not done at -O0. However, when the whole switch is dense enough, it is easy to turn it into a jump table, resulting in much faster code with no extra effort. llvm-svn: 240071
This commit is contained in:
parent
76c4baaac4
commit
e8d3ea5daa
@ -7504,6 +7504,31 @@ void SelectionDAGBuilder::findJumpTables(CaseClusterVector &Clusters,
|
||||
const int64_t N = Clusters.size();
|
||||
const unsigned MinJumpTableSize = TLI.getMinimumJumpTableEntries();
|
||||
|
||||
// TotalCases[i]: Total nbr of cases in Clusters[0..i].
|
||||
SmallVector<unsigned, 8> TotalCases(N);
|
||||
|
||||
for (unsigned i = 0; i < N; ++i) {
|
||||
APInt Hi = Clusters[i].High->getValue();
|
||||
APInt Lo = Clusters[i].Low->getValue();
|
||||
TotalCases[i] = (Hi - Lo).getLimitedValue() + 1;
|
||||
if (i != 0)
|
||||
TotalCases[i] += TotalCases[i - 1];
|
||||
}
|
||||
|
||||
if (N >= MinJumpTableSize && isDense(Clusters, &TotalCases[0], 0, N - 1)) {
|
||||
// Cheap case: the whole range might be suitable for jump table.
|
||||
CaseCluster JTCluster;
|
||||
if (buildJumpTable(Clusters, 0, N - 1, SI, DefaultMBB, JTCluster)) {
|
||||
Clusters[0] = JTCluster;
|
||||
Clusters.resize(1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// The algorithm below is not suitable for -O0.
|
||||
if (TM.getOptLevel() == CodeGenOpt::None)
|
||||
return;
|
||||
|
||||
// Split Clusters into minimum number of dense partitions. The algorithm uses
|
||||
// the same idea as Kannan & Proebsting "Correction to 'Producing Good Code
|
||||
// for the Case Statement'" (1994), but builds the MinPartitions array in
|
||||
@ -7517,16 +7542,6 @@ void SelectionDAGBuilder::findJumpTables(CaseClusterVector &Clusters,
|
||||
SmallVector<unsigned, 8> LastElement(N);
|
||||
// NumTables[i]: nbr of >= MinJumpTableSize partitions from Clusters[i..N-1].
|
||||
SmallVector<unsigned, 8> NumTables(N);
|
||||
// TotalCases[i]: Total nbr of cases in Clusters[0..i].
|
||||
SmallVector<unsigned, 8> TotalCases(N);
|
||||
|
||||
for (unsigned i = 0; i < N; ++i) {
|
||||
APInt Hi = Clusters[i].High->getValue();
|
||||
APInt Lo = Clusters[i].Low->getValue();
|
||||
TotalCases[i] = (Hi - Lo).getLimitedValue() + 1;
|
||||
if (i != 0)
|
||||
TotalCases[i] += TotalCases[i - 1];
|
||||
}
|
||||
|
||||
// Base case: There is only one way to partition Clusters[N-1].
|
||||
MinPartitions[N - 1] = 1;
|
||||
@ -7714,6 +7729,10 @@ void SelectionDAGBuilder::findBitTestClusters(CaseClusterVector &Clusters,
|
||||
assert(Clusters[i-1].High->getValue().slt(Clusters[i].Low->getValue()));
|
||||
#endif
|
||||
|
||||
// The algorithm below is not suitable for -O0.
|
||||
if (TM.getOptLevel() == CodeGenOpt::None)
|
||||
return;
|
||||
|
||||
// If target does not have legal shift left, do not emit bit tests at all.
|
||||
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
|
||||
EVT PTy = TLI.getPointerTy();
|
||||
@ -8129,11 +8148,8 @@ void SelectionDAGBuilder::visitSwitch(const SwitchInst &SI) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (TM.getOptLevel() != CodeGenOpt::None) {
|
||||
findJumpTables(Clusters, &SI, DefaultMBB);
|
||||
findBitTestClusters(Clusters, &SI);
|
||||
}
|
||||
|
||||
findJumpTables(Clusters, &SI, DefaultMBB);
|
||||
findBitTestClusters(Clusters, &SI);
|
||||
|
||||
DEBUG({
|
||||
dbgs() << "Case clusters: ";
|
||||
|
@ -16,23 +16,18 @@ bb1: tail call void @g(i32 1) br label %return
|
||||
bb2: tail call void @g(i32 1) br label %return
|
||||
return: ret void
|
||||
|
||||
; Should be lowered as straight compares in -O0 mode.
|
||||
; NOOPT-LABEL: basic
|
||||
; NOOPT: subl $1, %eax
|
||||
; NOOPT: je
|
||||
; NOOPT: subl $3, %eax
|
||||
; NOOPT: je
|
||||
; NOOPT: subl $4, %eax
|
||||
; NOOPT: je
|
||||
; NOOPT: subl $5, %eax
|
||||
; NOOPT: je
|
||||
|
||||
; Jump table otherwise.
|
||||
; Lowered as a jump table, both with and without optimization.
|
||||
; CHECK-LABEL: basic
|
||||
; CHECK: decl
|
||||
; CHECK: cmpl $4
|
||||
; CHECK: ja
|
||||
; CHECK: jmpq *.LJTI
|
||||
; NOOPT-LABEL: basic
|
||||
; NOOPT: decl
|
||||
; NOOPT: subl $4
|
||||
; NOOPT: ja
|
||||
; NOOPT: movq .LJTI
|
||||
; NOOPT: jmpq
|
||||
}
|
||||
|
||||
|
||||
@ -205,6 +200,21 @@ return: ret void
|
||||
; CHECK: leal -5
|
||||
; CHECK: cmpl $10
|
||||
; CHECK: jmpq *.LJTI
|
||||
|
||||
; At -O0, we don't build jump tables for only parts of a switch.
|
||||
; NOOPT-LABEL: optimal_jump_table1
|
||||
; NOOPT: testl %edi, %edi
|
||||
; NOOPT: je
|
||||
; NOOPT: subl $5, %eax
|
||||
; NOOPT: je
|
||||
; NOOPT: subl $6, %eax
|
||||
; NOOPT: je
|
||||
; NOOPT: subl $12, %eax
|
||||
; NOOPT: je
|
||||
; NOOPT: subl $13, %eax
|
||||
; NOOPT: je
|
||||
; NOOPT: subl $15, %eax
|
||||
; NOOPT: je
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user