summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorAyonam Ray <ayonam@rrlogic.co.in>2019-01-29 12:01:32 +0000
committerAyonam Ray <ayonam@rrlogic.co.in>2019-01-29 12:01:32 +0000
commit4272af9b3e7f55fc15e2ff704f46d76d69134d40 (patch)
tree46d03efb17d6dd0252b9ac38eb9c5a5a4c1e9fe2 /llvm/lib/CodeGen
parent2601aa54069256f89bffecf34f513fe75272b526 (diff)
downloadbcm5719-llvm-4272af9b3e7f55fc15e2ff704f46d76d69134d40.tar.gz
bcm5719-llvm-4272af9b3e7f55fc15e2ff704f46d76d69134d40.zip
[CodeGen] Omit range checks from jump tables when lowering switches with unreachable default
During the lowering of a switch that would result in the generation of a jump table, a range check is performed before indexing into the jump table, for the switch value being outside the jump table range and a conditional branch is inserted to jump to the default block. In case the default block is unreachable, this conditional jump can be omitted. This patch implements omitting this conditional branch for unreachable defaults. Review ID: D52002 Reviewers: Hans Wennborg, Eli Freidman, Roman Lebedev llvm-svn: 352484
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp75
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h5
2 files changed, 28 insertions, 52 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index d0caf3938a8..3c8f2e9f612 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -2176,24 +2176,31 @@ void SelectionDAGBuilder::visitJumpTableHeader(JumpTable &JT,
JumpTableReg, SwitchOp);
JT.Reg = JumpTableReg;
- // Emit the range check for the jump table, and branch to the default block
- // for the switch statement if the value being switched on exceeds the largest
- // case in the switch.
- SDValue CMP = DAG.getSetCC(
- dl, TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(),
- Sub.getValueType()),
- Sub, DAG.getConstant(JTH.Last - JTH.First, dl, VT), ISD::SETUGT);
-
- SDValue BrCond = DAG.getNode(ISD::BRCOND, dl,
- MVT::Other, CopyTo, CMP,
- DAG.getBasicBlock(JT.Default));
-
- // Avoid emitting unnecessary branches to the next block.
- if (JT.MBB != NextBlock(SwitchBB))
- BrCond = DAG.getNode(ISD::BR, dl, MVT::Other, BrCond,
- DAG.getBasicBlock(JT.MBB));
-
- DAG.setRoot(BrCond);
+ if (!JTH.OmitRangeCheck) {
+ // Emit the range check for the jump table, and branch to the default block
+ // for the switch statement if the value being switched on exceeds the
+ // largest case in the switch.
+ SDValue CMP = DAG.getSetCC(
+ dl, TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(),
+ Sub.getValueType()),
+ Sub, DAG.getConstant(JTH.Last - JTH.First, dl, VT), ISD::SETUGT);
+
+ SDValue BrCond = DAG.getNode(ISD::BRCOND, dl,
+ MVT::Other, CopyTo, CMP,
+ DAG.getBasicBlock(JT.Default));
+
+ // Avoid emitting unnecessary branches to the next block.
+ if (JT.MBB != NextBlock(SwitchBB))
+ BrCond = DAG.getNode(ISD::BR, dl, MVT::Other, BrCond,
+ DAG.getBasicBlock(JT.MBB));
+
+ DAG.setRoot(BrCond);
+ } else {
+ SDValue BrCond = DAG.getNode(ISD::BR, dl, MVT::Other, CopyTo,
+ DAG.getBasicBlock(JT.MBB));
+ DAG.setRoot(BrCond);
+ SwitchBB->removeSuccessor(JT.Default, true);
+ }
}
/// Create a LOAD_STACK_GUARD node, and let it carry the target specific global
@@ -10308,38 +10315,6 @@ void SelectionDAGBuilder::visitSwitch(const SwitchInst &SI) {
// if there are many clusters.
sortAndRangeify(Clusters);
- if (TM.getOptLevel() != CodeGenOpt::None) {
- // Replace an unreachable default with the most popular destination.
- // FIXME: Exploit unreachable default more aggressively.
- bool UnreachableDefault =
- isa<UnreachableInst>(SI.getDefaultDest()->getFirstNonPHIOrDbg());
- if (UnreachableDefault && !Clusters.empty()) {
- DenseMap<const BasicBlock *, unsigned> Popularity;
- unsigned MaxPop = 0;
- const BasicBlock *MaxBB = nullptr;
- for (auto I : SI.cases()) {
- const BasicBlock *BB = I.getCaseSuccessor();
- if (++Popularity[BB] > MaxPop) {
- MaxPop = Popularity[BB];
- MaxBB = BB;
- }
- }
- // Set new default.
- assert(MaxPop > 0 && MaxBB);
- DefaultMBB = FuncInfo.MBBMap[MaxBB];
-
- // Remove cases that were pointing to the destination that is now the
- // default.
- CaseClusterVector New;
- New.reserve(Clusters.size());
- for (CaseCluster &CC : Clusters) {
- if (CC.MBB != DefaultMBB)
- New.push_back(CC);
- }
- Clusters = std::move(New);
- }
- }
-
// The branch probablity of the peeled case.
BranchProbability PeeledCaseProb = BranchProbability::getZero();
MachineBasicBlock *PeeledSwitchMBB =
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
index 558266e485b..e075e886dd2 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
@@ -278,11 +278,12 @@ private:
const Value *SValue;
MachineBasicBlock *HeaderBB;
bool Emitted;
+ bool OmitRangeCheck;
JumpTableHeader(APInt F, APInt L, const Value *SV, MachineBasicBlock *H,
- bool E = false)
+ bool E = false, bool ORC = false)
: First(std::move(F)), Last(std::move(L)), SValue(SV), HeaderBB(H),
- Emitted(E) {}
+ Emitted(E), OmitRangeCheck(ORC) {}
};
using JumpTableBlock = std::pair<JumpTableHeader, JumpTable>;
OpenPOWER on IntegriCloud