Index: include/llvm/Analysis/TargetTransformInfo.h =================================================================== --- include/llvm/Analysis/TargetTransformInfo.h +++ include/llvm/Analysis/TargetTransformInfo.h @@ -356,6 +356,11 @@ /// target. bool shouldBuildLookupTables() const; + /// \brief Return true if the switch instruction should be lowered and false + /// if the target has a better lowering for this kind of switches that is not + /// what the default lower switch pass can do. + bool shouldLowerSwitch(const SwitchInst *SI) const; + /// \brief Don't restrict interleaved unrolling to small loops. bool enableAggressiveInterleaving(bool LoopHasReductions) const; @@ -614,6 +619,7 @@ virtual unsigned getJumpBufAlignment() = 0; virtual unsigned getJumpBufSize() = 0; virtual bool shouldBuildLookupTables() = 0; + virtual bool shouldLowerSwitch(const SwitchInst *SI) = 0; virtual bool enableAggressiveInterleaving(bool LoopHasReductions) = 0; virtual bool enableInterleavedAccessVectorization() = 0; virtual PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) = 0; @@ -766,6 +772,9 @@ bool shouldBuildLookupTables() override { return Impl.shouldBuildLookupTables(); } + bool shouldLowerSwitch(const SwitchInst *SI) override { + return Impl.shouldLowerSwitch(SI); + } bool enableAggressiveInterleaving(bool LoopHasReductions) override { return Impl.enableAggressiveInterleaving(LoopHasReductions); } Index: include/llvm/Analysis/TargetTransformInfoImpl.h =================================================================== --- include/llvm/Analysis/TargetTransformInfoImpl.h +++ include/llvm/Analysis/TargetTransformInfoImpl.h @@ -236,6 +236,8 @@ bool shouldBuildLookupTables() { return true; } + bool shouldLowerSwitch(const SwitchInst *SI) { return true; } + bool enableAggressiveInterleaving(bool LoopHasReductions) { return false; } bool enableInterleavedAccessVectorization() { return false; } Index: lib/Analysis/TargetTransformInfo.cpp =================================================================== --- lib/Analysis/TargetTransformInfo.cpp +++ lib/Analysis/TargetTransformInfo.cpp @@ -164,6 +164,10 @@ return TTIImpl->shouldBuildLookupTables(); } +bool TargetTransformInfo::shouldLowerSwitch(const SwitchInst *SI) const { + return TTIImpl->shouldLowerSwitch(SI); +} + bool TargetTransformInfo::enableAggressiveInterleaving(bool LoopHasReductions) const { return TTIImpl->enableAggressiveInterleaving(LoopHasReductions); } Index: lib/Transforms/Utils/LowerSwitch.cpp =================================================================== --- lib/Transforms/Utils/LowerSwitch.cpp +++ lib/Transforms/Utils/LowerSwitch.cpp @@ -15,6 +15,7 @@ #include "llvm/Transforms/Scalar.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/IR/CFG.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" @@ -63,6 +64,7 @@ // This is a cluster of orthogonal Transforms AU.addPreserved(); AU.addPreservedID(LowerInvokePassID); + AU.addRequired(); } struct CaseRange { @@ -103,9 +105,11 @@ } char LowerSwitch::ID = 0; -INITIALIZE_PASS(LowerSwitch, "lowerswitch", - "Lower SwitchInst's to branches", false, false) - +INITIALIZE_PASS_BEGIN(LowerSwitch, "lowerswitch", + "Lower SwitchInst's to branches", false, false) +INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) +INITIALIZE_PASS_END(LowerSwitch, "lowerswitch", + "Lower SwitchInst's to branches", false, false) // Publicly exposed interface to pass... char &llvm::LowerSwitchID = LowerSwitch::ID; // createLowerSwitchPass - Interface to this file... @@ -114,6 +118,8 @@ } bool LowerSwitch::runOnFunction(Function &F) { + const TargetTransformInfo &TTI = + getAnalysis().getTTI(F); bool Changed = false; SmallPtrSet DeleteList; @@ -126,8 +132,10 @@ continue; if (SwitchInst *SI = dyn_cast(Cur->getTerminator())) { - Changed = true; - processSwitchInst(SI, DeleteList); + if (TTI.shouldLowerSwitch(SI)) { + Changed = true; + processSwitchInst(SI, DeleteList); + } } }