void addLateLTOOptimizationPasses(legacy::PassManagerBase &PM);
void addPGOInstrPasses(legacy::PassManagerBase &MPM, bool IsCS);
void addFunctionSimplificationPasses(legacy::PassManagerBase &MPM);
- void addInstructionCombiningPass(legacy::PassManagerBase &MPM) const;
public:
/// populateFunctionPassManager - This fills in the function pass manager,
class InstCombinePass : public PassInfoMixin<InstCombinePass> {
InstCombineWorklist Worklist;
- const bool ExpensiveCombines;
const unsigned MaxIterations;
public:
static StringRef name() { return "InstCombinePass"; }
- explicit InstCombinePass(bool ExpensiveCombines = true);
- explicit InstCombinePass(bool ExpensiveCombines, unsigned MaxIterations);
+ explicit InstCombinePass();
+ explicit InstCombinePass(unsigned MaxIterations);
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
/// will try to combine all instructions in the function.
class InstructionCombiningPass : public FunctionPass {
InstCombineWorklist Worklist;
- const bool ExpensiveCombines;
const unsigned MaxIterations;
public:
static char ID; // Pass identification, replacement for typeid
- explicit InstructionCombiningPass(bool ExpensiveCombines = true);
- explicit InstructionCombiningPass(bool ExpensiveCombines,
- unsigned MaxIterations);
+ explicit InstructionCombiningPass();
+ explicit InstructionCombiningPass(unsigned MaxIterations);
void getAnalysisUsage(AnalysisUsage &AU) const override;
bool runOnFunction(Function &F) override;
// into:
// %Z = add int 2, %X
//
-FunctionPass *createInstructionCombiningPass(bool ExpensiveCombines = true);
-FunctionPass *createInstructionCombiningPass(bool ExpensiveCombines,
- unsigned MaxIterations);
+FunctionPass *createInstructionCombiningPass();
+FunctionPass *createInstructionCombiningPass(unsigned MaxIterations);
}
#endif
PM.add(createScopedNoAliasAAWrapperPass());
}
-void PassManagerBuilder::addInstructionCombiningPass(
- legacy::PassManagerBase &PM) const {
- bool ExpensiveCombines = OptLevel > 2;
- PM.add(createInstructionCombiningPass(ExpensiveCombines));
-}
-
void PassManagerBuilder::populateFunctionPassManager(
legacy::FunctionPassManager &FPM) {
addExtensionsToPM(EP_EarlyAsPossible, FPM);
// Combine silly seq's
if (OptLevel > 2)
MPM.add(createAggressiveInstCombinerPass());
- addInstructionCombiningPass(MPM);
+ MPM.add(createInstructionCombiningPass());
if (SizeLevel == 0 && !DisableLibCallsShrinkWrap)
MPM.add(createLibCallsShrinkWrapPass());
addExtensionsToPM(EP_Peephole, MPM);
// simplify-cfg. Eventually loop-simplifycfg should be enhanced to replace the
// need for this.
MPM.add(createCFGSimplificationPass());
- addInstructionCombiningPass(MPM);
+ MPM.add(createInstructionCombiningPass());
// We resume loop passes creating a second loop pipeline here.
MPM.add(createIndVarSimplifyPass()); // Canonicalize indvars
MPM.add(createLoopIdiomPass()); // Recognize idioms like memset.
// Run instcombine after redundancy elimination to exploit opportunities
// opened up by them.
- addInstructionCombiningPass(MPM);
+ MPM.add(createInstructionCombiningPass());
addExtensionsToPM(EP_Peephole, MPM);
if (OptLevel > 1) {
MPM.add(createJumpThreadingPass()); // Thread jumps
MPM.add(createAggressiveDCEPass()); // Delete dead instructions
MPM.add(createCFGSimplificationPass()); // Merge & remove BBs
// Clean up after everything.
- addInstructionCombiningPass(MPM);
+ MPM.add(createInstructionCombiningPass());
addExtensionsToPM(EP_Peephole, MPM);
if (EnableCHR && OptLevel >= 3 &&
MPM.add(createDeadArgEliminationPass()); // Dead argument elimination
- addInstructionCombiningPass(MPM); // Clean up after IPCP & DAE
+ MPM.add(createInstructionCombiningPass()); // Clean up after IPCP & DAE
addExtensionsToPM(EP_Peephole, MPM);
MPM.add(createCFGSimplificationPass()); // Clean up after IPCP & DAE
// on -O1 and no #pragma is found). Would be good to have these two passes
// as function calls, so that we can only pass them when the vectorizer
// changed the code.
- addInstructionCombiningPass(MPM);
+ MPM.add(createInstructionCombiningPass());
if (OptLevel > 1 && ExtraVectorizerPasses) {
// At higher optimization levels, try to clean up any runtime overlap and
// alignment checks inserted by the vectorizer. We want to track correllated
// and unswitch the runtime checks if possible. Once hoisted, we may have
// dead (or speculatable) control flows or more combining opportunities.
MPM.add(createCorrelatedValuePropagationPass());
- addInstructionCombiningPass(MPM);
+ MPM.add(createInstructionCombiningPass());
MPM.add(createLICMPass(LicmMssaOptCap, LicmMssaNoAccForPromotionCap));
MPM.add(createLoopUnswitchPass(SizeLevel || OptLevel < 3, DivergentTarget));
MPM.add(createCFGSimplificationPass());
- addInstructionCombiningPass(MPM);
+ MPM.add(createInstructionCombiningPass());
}
// Cleanup after loop vectorization, etc. Simplification passes like CVP and
}
addExtensionsToPM(EP_Peephole, MPM);
- addInstructionCombiningPass(MPM);
+ MPM.add(createInstructionCombiningPass());
if (EnableUnrollAndJam && !DisableUnrollLoops) {
// Unroll and Jam. We do this before unroll but need to be in a separate
if (!DisableUnrollLoops) {
// LoopUnroll may generate some redundency to cleanup.
- addInstructionCombiningPass(MPM);
+ MPM.add(createInstructionCombiningPass());
// Runtime unrolling will introduce runtime check in loop prologue. If the
// unrolled loop is a inner loop, then the prologue will be inside the
// calls, etc, so let instcombine do this.
if (OptLevel > 2)
PM.add(createAggressiveInstCombinerPass());
- addInstructionCombiningPass(PM);
+ PM.add(createInstructionCombiningPass());
addExtensionsToPM(EP_Peephole, PM);
// Inline small functions
PM.add(createArgumentPromotionPass());
// The IPO passes may leave cruft around. Clean up after them.
- addInstructionCombiningPass(PM);
+ PM.add(createInstructionCombiningPass());
addExtensionsToPM(EP_Peephole, PM);
PM.add(createJumpThreadingPass());
// we may have exposed more scalar opportunities. Run parts of the scalar
// optimizer again at this point.
PM.add(createVectorCombinePass());
- addInstructionCombiningPass(PM); // Initial cleanup
+ PM.add(createInstructionCombiningPass()); // Initial cleanup
PM.add(createCFGSimplificationPass()); // if-convert
PM.add(createSCCPPass()); // Propagate exposed constants
- addInstructionCombiningPass(PM); // Clean up again
+ PM.add(createInstructionCombiningPass()); // Clean up again
PM.add(createBitTrackingDCEPass());
// More scalar chains could be vectorized due to more alias information
PM.add(createAlignmentFromAssumptionsPass());
// Cleanup and simplify the code after the scalar optimizations.
- addInstructionCombiningPass(PM);
+ PM.add(createInstructionCombiningPass());
addExtensionsToPM(EP_Peephole, PM);
PM.add(createJumpThreadingPass());
// Mode in which we are running the combiner.
const bool MinimizeSize;
- /// Enable combines that trigger rarely but are costly in compiletime.
- const bool ExpensiveCombines;
-
AliasAnalysis *AA;
// Required analyses.
public:
InstCombiner(InstCombineWorklist &Worklist, BuilderTy &Builder,
- bool MinimizeSize, bool ExpensiveCombines, AliasAnalysis *AA,
+ bool MinimizeSize, AliasAnalysis *AA,
AssumptionCache &AC, TargetLibraryInfo &TLI, DominatorTree &DT,
OptimizationRemarkEmitter &ORE, BlockFrequencyInfo *BFI,
ProfileSummaryInfo *PSI, const DataLayout &DL, LoopInfo *LI)
: Worklist(Worklist), Builder(Builder), MinimizeSize(MinimizeSize),
- ExpensiveCombines(ExpensiveCombines), AA(AA), AC(AC), TLI(TLI), DT(DT),
+ AA(AA), AC(AC), TLI(TLI), DT(DT),
DL(DL), SQ(DL, &TLI, &DT, &AC), ORE(ORE), BFI(BFI), PSI(PSI), LI(LI) {}
/// Run the combiner over the entire worklist until it is empty.
EnableCodeSinking("instcombine-code-sinking", cl::desc("Enable code sinking"),
cl::init(true));
-// FIXME: This option is no longer used for anything and may be removed.
-static cl::opt<bool>
-EnableExpensiveCombines("expensive-combines",
- cl::desc("Enable expensive instruction combines"));
-
static cl::opt<unsigned> LimitMaxIterations(
"instcombine-max-iterations",
cl::desc("Limit the maximum number of instruction combining iterations"),
Function &F, InstCombineWorklist &Worklist, AliasAnalysis *AA,
AssumptionCache &AC, TargetLibraryInfo &TLI, DominatorTree &DT,
OptimizationRemarkEmitter &ORE, BlockFrequencyInfo *BFI,
- ProfileSummaryInfo *PSI, bool ExpensiveCombines, unsigned MaxIterations,
- LoopInfo *LI) {
+ ProfileSummaryInfo *PSI, unsigned MaxIterations, LoopInfo *LI) {
auto &DL = F.getParent()->getDataLayout();
- if (EnableExpensiveCombines.getNumOccurrences())
- ExpensiveCombines = EnableExpensiveCombines;
MaxIterations = std::min(MaxIterations, LimitMaxIterations.getValue());
/// Builder - This is an IRBuilder that automatically inserts new
MadeIRChange |= prepareICWorklistFromFunction(F, DL, &TLI, Worklist);
- InstCombiner IC(Worklist, Builder, F.hasMinSize(), ExpensiveCombines, AA,
+ InstCombiner IC(Worklist, Builder, F.hasMinSize(), AA,
AC, TLI, DT, ORE, BFI, PSI, DL, LI);
IC.MaxArraySizeForCombine = MaxArraySize;
return MadeIRChange;
}
-InstCombinePass::InstCombinePass(bool ExpensiveCombines)
- : ExpensiveCombines(ExpensiveCombines), MaxIterations(LimitMaxIterations) {}
+InstCombinePass::InstCombinePass() : MaxIterations(LimitMaxIterations) {}
-InstCombinePass::InstCombinePass(bool ExpensiveCombines, unsigned MaxIterations)
- : ExpensiveCombines(ExpensiveCombines), MaxIterations(MaxIterations) {}
+InstCombinePass::InstCombinePass(unsigned MaxIterations)
+ : MaxIterations(MaxIterations) {}
PreservedAnalyses InstCombinePass::run(Function &F,
FunctionAnalysisManager &AM) {
&AM.getResult<BlockFrequencyAnalysis>(F) : nullptr;
if (!combineInstructionsOverFunction(F, Worklist, AA, AC, TLI, DT, ORE, BFI,
- PSI, ExpensiveCombines, MaxIterations,
- LI))
+ PSI, MaxIterations, LI))
// No changes, all analyses are preserved.
return PreservedAnalyses::all();
nullptr;
return combineInstructionsOverFunction(F, Worklist, AA, AC, TLI, DT, ORE, BFI,
- PSI, ExpensiveCombines, MaxIterations,
- LI);
+ PSI, MaxIterations, LI);
}
char InstructionCombiningPass::ID = 0;
-InstructionCombiningPass::InstructionCombiningPass(bool ExpensiveCombines)
- : FunctionPass(ID), ExpensiveCombines(ExpensiveCombines),
- MaxIterations(InstCombineDefaultMaxIterations) {
+InstructionCombiningPass::InstructionCombiningPass()
+ : FunctionPass(ID), MaxIterations(InstCombineDefaultMaxIterations) {
initializeInstructionCombiningPassPass(*PassRegistry::getPassRegistry());
}
-InstructionCombiningPass::InstructionCombiningPass(bool ExpensiveCombines,
- unsigned MaxIterations)
- : FunctionPass(ID), ExpensiveCombines(ExpensiveCombines),
- MaxIterations(MaxIterations) {
+InstructionCombiningPass::InstructionCombiningPass(unsigned MaxIterations)
+ : FunctionPass(ID), MaxIterations(MaxIterations) {
initializeInstructionCombiningPassPass(*PassRegistry::getPassRegistry());
}
initializeInstructionCombiningPassPass(*unwrap(R));
}
-FunctionPass *llvm::createInstructionCombiningPass(bool ExpensiveCombines) {
- return new InstructionCombiningPass(ExpensiveCombines);
+FunctionPass *llvm::createInstructionCombiningPass() {
+ return new InstructionCombiningPass();
}
-FunctionPass *llvm::createInstructionCombiningPass(bool ExpensiveCombines,
- unsigned MaxIterations) {
- return new InstructionCombiningPass(ExpensiveCombines, MaxIterations);
+FunctionPass *llvm::createInstructionCombiningPass(unsigned MaxIterations) {
+ return new InstructionCombiningPass(MaxIterations);
}
void LLVMAddInstructionCombiningPass(LLVMPassManagerRef PM) {
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -instcombine -expensive-combines=0 < %s | FileCheck %s --check-prefixes=CHECK,EXPENSIVE-OFF
-; RUN: opt -S -instcombine -expensive-combines=1 < %s | FileCheck %s --check-prefixes=CHECK,EXPENSIVE-ON
+; RUN: opt -S -instcombine < %s | FileCheck %s
target datalayout = "E-m:e-i64:64-n32:64"
target triple = "powerpc64-unknown-linux-gnu"
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -instcombine -S | FileCheck %s --check-prefixes=CHECK,EXPENSIVE-ON
-; RUN: opt < %s -instcombine -expensive-combines=0 -S | FileCheck %s --check-prefixes=CHECK,EXPENSIVE-OFF
+; RUN: opt < %s -instcombine -S | FileCheck %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -instcombine -expensive-combines=0 < %s | FileCheck %s --check-prefixes=CHECK,EXPENSIVE-OFF
-; RUN: opt -S -instcombine -expensive-combines=1 < %s | FileCheck %s --check-prefixes=CHECK,EXPENSIVE-ON
+; RUN: opt -S -instcombine < %s | FileCheck %s
declare i32 @passthru_i32(i32 returned)
declare i8* @passthru_p8(i8* returned)
+++ /dev/null
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -instcombine < %s | FileCheck %s --check-prefix=DEFAULT
-; RUN: opt -S -instcombine -expensive-combines=1 < %s | FileCheck %s --check-prefix=EXPENSIVE-ON
-; RUN: opt -S -instcombine -expensive-combines=0 < %s | FileCheck %s --check-prefix=EXPENSIVE-OFF
-
-define void @test() {
-; DEFAULT-LABEL: @test(
-; DEFAULT-NEXT: [[CALL:%.*]] = call i32 @passthru(i32 0)
-; DEFAULT-NEXT: call void @sink(i32 0)
-; DEFAULT-NEXT: ret void
-;
-; EXPENSIVE-ON-LABEL: @test(
-; EXPENSIVE-ON-NEXT: [[CALL:%.*]] = call i32 @passthru(i32 0)
-; EXPENSIVE-ON-NEXT: call void @sink(i32 0)
-; EXPENSIVE-ON-NEXT: ret void
-;
-; EXPENSIVE-OFF-LABEL: @test(
-; EXPENSIVE-OFF-NEXT: [[CALL:%.*]] = call i32 @passthru(i32 0)
-; EXPENSIVE-OFF-NEXT: call void @sink(i32 0)
-; EXPENSIVE-OFF-NEXT: ret void
-;
- %call = call i32 @passthru(i32 0)
- call void @sink(i32 %call)
- ret void
-}
-
-declare i32 @passthru(i32 returned)
-declare void @sink(i32)
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -instcombine -expensive-combines=0 < %s | FileCheck %s --check-prefixes=CHECK,EXPENSIVE-OFF
-; RUN: opt -S -instcombine -expensive-combines=1 < %s | FileCheck %s --check-prefixes=CHECK,EXPENSIVE-ON
+; RUN: opt -S -instcombine < %s | FileCheck %s
define void @test_shl(i1 %x) {
; CHECK-LABEL: @test_shl(
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -instcombine -expensive-combines=0 -S | FileCheck %s --check-prefixes=CHECK,EXPENSIVE-OFF
-; RUN: opt < %s -instcombine -expensive-combines=1 -S | FileCheck %s --check-prefixes=CHECK,EXPENSIVE-ON
+; RUN: opt < %s -instcombine -S | FileCheck %s
; Result of left shifting a non-negative integer
; with nsw flag should also be non-negative
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -instcombine -expensive-combines=0 < %s | FileCheck %s --check-prefixes=CHECK,EXPENSIVE-OFF
-; RUN: opt -S -instcombine -expensive-combines=1 < %s | FileCheck %s --check-prefixes=CHECK,EXPENSIVE-ON
+; RUN: opt -S -instcombine < %s | FileCheck %s
; Check that we don't crash on unreasonable constant indexes
define i32 @test_out_of_bounds(i32 %a, i1 %x, i1 %y) {
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -instcombine -expensive-combines=0 < %s | FileCheck %s --check-prefixes=CHECK,EXPENSIVE-OFF
-; RUN: opt -S -instcombine -expensive-combines=1 < %s | FileCheck %s --check-prefixes=CHECK,EXPENSIVE-ON
+; RUN: opt -S -instcombine < %s | FileCheck %s
; OSS Fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=15217
define i64 @fuzz15217(i1 %cond, i8* %Ptr, i64 %Val) {
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -instcombine -expensive-combines=0 -instcombine-infinite-loop-threshold=2 < %s | FileCheck %s
+; RUN: opt -S -instcombine -instcombine-infinite-loop-threshold=2 < %s | FileCheck %s
; This test used to cause an infinite combine loop.