diff --git a/llvm/include/llvm/Transforms/Scalar/ConstraintElimination.h b/llvm/include/llvm/Transforms/Scalar/ConstraintElimination.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/Transforms/Scalar/ConstraintElimination.h @@ -0,0 +1,24 @@ +//===- ConstraintElimination.h - Constraint elimination pass ----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_SCALAR_CONSTRAINTELIMINATION_H +#define LLVM_TRANSFORMS_SCALAR_CONSTRAINTELIMINATION_H + +#include "llvm/IR/PassManager.h" + +namespace llvm { + +class ConstraintEliminationPass + : public PassInfoMixin { +public: + PreservedAnalyses run(Function &F, FunctionAnalysisManager &); +}; + +} // end namespace llvm + +#endif // LLVM_TRANSFORMS_SCALAR_CONSTRAINTELIMINATION_H diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -130,6 +130,7 @@ #include "llvm/Transforms/Scalar/BDCE.h" #include "llvm/Transforms/Scalar/CallSiteSplitting.h" #include "llvm/Transforms/Scalar/ConstantHoisting.h" +#include "llvm/Transforms/Scalar/ConstraintElimination.h" #include "llvm/Transforms/Scalar/CorrelatedValuePropagation.h" #include "llvm/Transforms/Scalar/DCE.h" #include "llvm/Transforms/Scalar/DeadStoreElimination.h" @@ -284,6 +285,7 @@ CallGraphProfile = true; } +extern cl::opt EnableConstraintElimination; extern cl::opt EnableHotColdSplit; extern cl::opt EnableOrderFileInstrumentation; @@ -606,6 +608,9 @@ FPM.addPass(SimplifyCFGPass()); } + if (EnableConstraintElimination) + FPM.addPass(ConstraintEliminationPass()); + // Speculative execution if the target has divergent branches; otherwise nop. FPM.addPass(SpeculativeExecutionPass(/* OnlyIfDivergentTarget =*/true)); diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -188,6 +188,7 @@ FUNCTION_PASS("break-crit-edges", BreakCriticalEdgesPass()) FUNCTION_PASS("callsite-splitting", CallSiteSplittingPass()) FUNCTION_PASS("consthoist", ConstantHoistingPass()) +FUNCTION_PASS("constraint-elimination", ConstraintEliminationPass()) FUNCTION_PASS("chr", ControlHeightReductionPass()) FUNCTION_PASS("coro-early", CoroEarlyPass()) FUNCTION_PASS("coro-elide", CoroElidePass()) diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Transforms/Scalar/ConstraintElimination.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/ConstraintSystem.h" @@ -273,6 +274,19 @@ return Changed; } +PreservedAnalyses ConstraintEliminationPass::run(Function &F, + FunctionAnalysisManager &AM) { + auto &DT = AM.getResult(F); + if (!eliminateConstraints(F, DT)) + return PreservedAnalyses::all(); + + PreservedAnalyses PA; + PA.preserve(); + PA.preserve(); + PA.preserveSet(); + return PA; +} + namespace { class ConstraintElimination : public FunctionPass { diff --git a/llvm/test/Transforms/ConstraintElimination/dom.ll b/llvm/test/Transforms/ConstraintElimination/dom.ll --- a/llvm/test/Transforms/ConstraintElimination/dom.ll +++ b/llvm/test/Transforms/ConstraintElimination/dom.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -constraint-elimination -S %s | FileCheck %s +; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s ; Test cases where both the true and false successors reach the same block, ; dominated by one of them.