diff options
author | Daniel Jasper <djasper@google.com> | 2015-01-20 19:43:33 +0000 |
---|---|---|
committer | Daniel Jasper <djasper@google.com> | 2015-01-20 19:43:33 +0000 |
commit | 6b77455f819dfd587bd6927b7e1c705a6d3df36d (patch) | |
tree | 6a751d08ecaca770ec719670c267a0dc272789a2 /llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | |
parent | be10ece5ed0eaad063cfef5d4669dea952fb1fa1 (diff) | |
download | bcm5719-llvm-6b77455f819dfd587bd6927b7e1c705a6d3df36d.tar.gz bcm5719-llvm-6b77455f819dfd587bd6927b7e1c705a6d3df36d.zip |
Prevent binary-tree deterioration in sparse switch statements.
This addresses part of llvm.org/PR22262. Specifically, it prevents
considering the densities of sub-ranges that have fewer than
TLI.getMinimumJumpTableEntries() elements. Those densities won't help
jump tables.
This is not a complete solution but works around the most pressing
issue.
Review: http://reviews.llvm.org/D7070
llvm-svn: 226600
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 2ee276fccbe..ea76bc68bd5 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -2420,6 +2420,7 @@ bool SelectionDAGBuilder::handleBTSplitSwitchCase(CaseRec& CR, DEBUG(dbgs() << "Selecting best pivot: \n" << "First: " << First << ", Last: " << Last <<'\n' << "LSize: " << LSize << ", RSize: " << RSize << '\n'); + const TargetLowering &TLI = DAG.getTargetLoweringInfo(); for (CaseItr I = CR.Range.first, J=I+1, E = CR.Range.second; J!=E; ++I, ++J) { const APInt &LEnd = cast<ConstantInt>(I->High)->getValue(); @@ -2429,10 +2430,16 @@ bool SelectionDAGBuilder::handleBTSplitSwitchCase(CaseRec& CR, "Invalid case distance"); // Use volatile double here to avoid excess precision issues on some hosts, // e.g. that use 80-bit X87 registers. + // Only consider the density of sub-ranges that actually have sufficient + // entries to be lowered as a jump table. volatile double LDensity = - LSize.roundToDouble() / (LEnd - First + 1ULL).roundToDouble(); + LSize.ult(TLI.getMinimumJumpTableEntries()) + ? 0.0 + : LSize.roundToDouble() / (LEnd - First + 1ULL).roundToDouble(); volatile double RDensity = - RSize.roundToDouble() / (Last - RBegin + 1ULL).roundToDouble(); + RSize.ult(TLI.getMinimumJumpTableEntries()) + ? 0.0 + : RSize.roundToDouble() / (Last - RBegin + 1ULL).roundToDouble(); volatile double Metric = Range.logBase2() * (LDensity + RDensity); // Should always split in some non-trivial place DEBUG(dbgs() <<"=>Step\n" @@ -2450,13 +2457,8 @@ bool SelectionDAGBuilder::handleBTSplitSwitchCase(CaseRec& CR, RSize -= J->size(); } - const TargetLowering &TLI = DAG.getTargetLoweringInfo(); - if (areJTsAllowed(TLI)) { - // If our case is dense we *really* should handle it earlier! - assert((FMetric > 0) && "Should handle dense range earlier!"); - } else { + if (FMetric == 0 || !areJTsAllowed(TLI)) Pivot = CR.Range.first + Size/2; - } splitSwitchCase(CR, Pivot, WorkList, SV, SwitchBB); return true; } |