Index: llvm/trunk/include/llvm/Transforms/Utils/BreakCriticalEdges.h =================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/BreakCriticalEdges.h +++ llvm/trunk/include/llvm/Transforms/Utils/BreakCriticalEdges.h @@ -0,0 +1,29 @@ +//===- BreakCriticalEdges.h - Critical Edge Elimination Pass --------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// BreakCriticalEdges pass - Break all of the critical edges in the CFG by +// inserting a dummy basic block. This pass may be "required" by passes that +// cannot deal with critical edges. For this usage, the structure type is +// forward declared. This pass obviously invalidates the CFG, but can update +// dominator trees. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_UTILS_BREAKCRITICALEDGES_H +#define LLVM_TRANSFORMS_UTILS_BREAKCRITICALEDGES_H + +#include "llvm/IR/Function.h" +#include "llvm/IR/PassManager.h" + +namespace llvm { +struct BreakCriticalEdgesPass : public PassInfoMixin { + PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); +}; +} // namespace llvm +#endif // LLVM_TRANSFORMS_UTILS_BREAKCRITICALEDGES_H Index: llvm/trunk/lib/Passes/PassBuilder.cpp =================================================================== --- llvm/trunk/lib/Passes/PassBuilder.cpp +++ llvm/trunk/lib/Passes/PassBuilder.cpp @@ -113,6 +113,7 @@ #include "llvm/Transforms/Scalar/Sink.h" #include "llvm/Transforms/Scalar/TailRecursionElimination.h" #include "llvm/Transforms/Utils/AddDiscriminators.h" +#include "llvm/Transforms/Utils/BreakCriticalEdges.h" #include "llvm/Transforms/Utils/LCSSA.h" #include "llvm/Transforms/Utils/LoopSimplify.h" #include "llvm/Transforms/Utils/Mem2Reg.h" Index: llvm/trunk/lib/Passes/PassRegistry.def =================================================================== --- llvm/trunk/lib/Passes/PassRegistry.def +++ llvm/trunk/lib/Passes/PassRegistry.def @@ -130,6 +130,7 @@ FUNCTION_PASS("add-discriminators", AddDiscriminatorsPass()) FUNCTION_PASS("alignment-from-assumptions", AlignmentFromAssumptionsPass()) FUNCTION_PASS("bdce", BDCEPass()) +FUNCTION_PASS("break-crit-edges", BreakCriticalEdgesPass()) FUNCTION_PASS("consthoist", ConstantHoistingPass()) FUNCTION_PASS("correlated-propagation", CorrelatedValuePropagationPass()) FUNCTION_PASS("dce", DCEPass()) Index: llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp +++ llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp @@ -15,7 +15,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Utils/BreakCriticalEdges.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" @@ -23,10 +23,10 @@ #include "llvm/Analysis/LoopInfo.h" #include "llvm/IR/CFG.h" #include "llvm/IR/Dominators.h" -#include "llvm/IR/Function.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Type.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" using namespace llvm; @@ -72,6 +72,20 @@ return new BreakCriticalEdges(); } +PreservedAnalyses BreakCriticalEdgesPass::run(Function &F, + FunctionAnalysisManager &AM) { + auto *DT = AM.getCachedResult(F); + auto *LI = AM.getCachedResult(F); + unsigned N = SplitAllCriticalEdges(F, CriticalEdgeSplittingOptions(DT, LI)); + NumBroken += N; + if (N == 0) + return PreservedAnalyses::all(); + PreservedAnalyses PA; + PA.preserve(); + PA.preserve(); + return PA; +} + //===----------------------------------------------------------------------===// // Implementation of the external critical edge manipulation functions //===----------------------------------------------------------------------===// Index: llvm/trunk/test/Analysis/Dominators/2006-10-02-BreakCritEdges.ll =================================================================== --- llvm/trunk/test/Analysis/Dominators/2006-10-02-BreakCritEdges.ll +++ llvm/trunk/test/Analysis/Dominators/2006-10-02-BreakCritEdges.ll @@ -1,4 +1,5 @@ ; RUN: opt < %s -domtree -break-crit-edges -analyze -domtree | FileCheck %s +; RUN: opt < %s -passes='require,break-crit-edges,print' -disable-output 2>&1| FileCheck %s ; PR932 ; CHECK: [3] %brtrue {1,2} Index: llvm/trunk/test/Analysis/Dominators/2007-01-14-BreakCritEdges.ll =================================================================== --- llvm/trunk/test/Analysis/Dominators/2007-01-14-BreakCritEdges.ll +++ llvm/trunk/test/Analysis/Dominators/2007-01-14-BreakCritEdges.ll @@ -1,4 +1,5 @@ ; RUN: opt < %s -domtree -break-crit-edges -domtree -disable-output +; RUN: opt < %s -passes='require,break-crit-edges,require' -disable-output ; PR1110 %struct.OggVorbis_File = type { i8*, i32, i64, i64, %struct.ogg_sync_state, i32, i64*, i64*, i32*, i64*, %struct.vorbis_info*, %struct.vorbis_comment*, i64, i32, i32, i32, double, double, %struct.ogg_stream_state, %struct.vorbis_dsp_state, %struct.vorbis_block, %struct.ov_callbacks }