mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-02 00:37:09 +00:00
Revert "Initial implementation of optimization bisect support."
This reverts commit r267022, due to an ASan failure: http://lab.llvm.org:8080/green/job/clang-stage2-cmake-RgSan_check/1549 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@267115 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6a025fe5e2
commit
8866d94a61
@ -77,21 +77,15 @@ public:
|
||||
/// the call graph. If the derived class implements this method, it should
|
||||
/// always explicitly call the implementation here.
|
||||
void getAnalysisUsage(AnalysisUsage &Info) const override;
|
||||
|
||||
protected:
|
||||
/// Optional passes call this function to check whether the pass should be
|
||||
/// skipped. This is the case when optimization bisect is over the limit.
|
||||
bool skipSCC(CallGraphSCC &SCC) const;
|
||||
};
|
||||
|
||||
/// CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on.
|
||||
class CallGraphSCC {
|
||||
const CallGraph &CG; // The call graph for this SCC.
|
||||
void *Context; // The CGPassManager object that is vending this.
|
||||
std::vector<CallGraphNode*> Nodes;
|
||||
|
||||
public:
|
||||
CallGraphSCC(CallGraph &cg, void *context) : CG(cg), Context(context) {}
|
||||
CallGraphSCC(void *context) : Context(context) {}
|
||||
|
||||
void initialize(CallGraphNode *const *I, CallGraphNode *const *E) {
|
||||
Nodes.assign(I, E);
|
||||
@ -107,8 +101,6 @@ public:
|
||||
typedef std::vector<CallGraphNode *>::const_iterator iterator;
|
||||
iterator begin() const { return Nodes.begin(); }
|
||||
iterator end() const { return Nodes.end(); }
|
||||
|
||||
const CallGraph &getCallGraph() { return CG; }
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
@ -923,15 +923,6 @@ public:
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
};
|
||||
|
||||
/// Check with the OptBisect object to determine whether the described pass
|
||||
/// should be skipped.
|
||||
///
|
||||
/// This is a helper function which abstracts the details of accessing OptBisect
|
||||
/// through an LLVMContext obtained from an SCC.
|
||||
bool skipPassForSCC(const StringRef PassName, const LazyCallGraph::SCC &SCC);
|
||||
// This function is implemented in OptBisect.cpp but must be declared
|
||||
// here to avoid include file dependency problems.
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -88,10 +88,9 @@ public:
|
||||
virtual void deleteAnalysisLoop(Loop *L) {}
|
||||
|
||||
protected:
|
||||
/// Optional passes call this function to check whether the pass should be
|
||||
/// skipped. This is the case when Attribute::OptimizeNone is set or when
|
||||
/// optimization bisect is over the limit.
|
||||
bool skipLoop(const Loop *L) const;
|
||||
/// skipOptnoneFunction - Containing function has Attribute::OptimizeNone
|
||||
/// and most transformation passes should skip it.
|
||||
bool skipOptnoneFunction(const Loop *L) const;
|
||||
};
|
||||
|
||||
class LPPassManager : public FunctionPass, public PMDataManager {
|
||||
|
@ -32,7 +32,6 @@ class DiagnosticInfo;
|
||||
template <typename T> class SmallVectorImpl;
|
||||
class Function;
|
||||
class DebugLoc;
|
||||
class OptBisect;
|
||||
|
||||
/// This is an important class for using LLVM in a threaded context. It
|
||||
/// (opaquely) owns and manages the core "global" data of LLVM's core
|
||||
@ -227,9 +226,6 @@ public:
|
||||
return OptionRegistry::instance().template get<ValT, Base, Mem>();
|
||||
}
|
||||
|
||||
/// \brief Access the object which manages optimization bisection for failure
|
||||
/// analysis.
|
||||
OptBisect &getOptBisect();
|
||||
private:
|
||||
LLVMContext(LLVMContext&) = delete;
|
||||
void operator=(LLVMContext&) = delete;
|
||||
|
@ -1,139 +0,0 @@
|
||||
//===----------- llvm/IR/OptBisect.h - LLVM Bisect support -------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// This file declares the interface for bisecting optimizations.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_IR_OPTBISECT_H
|
||||
#define LLVM_IR_OPTBISECT_H
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class Pass;
|
||||
class StringRef;
|
||||
class Twine;
|
||||
|
||||
/// This class implements a mechanism to disable passes and individual
|
||||
/// optimizations at compile time based on a command line option
|
||||
/// (-opt-bisect-limit) in order to perform a bisecting search for
|
||||
/// optimization-related problems.
|
||||
class OptBisect {
|
||||
public:
|
||||
/// \brief Default constructor, initializes the OptBisect state based on the
|
||||
/// -opt-bisect-limit command line argument.
|
||||
///
|
||||
/// By default, bisection is disabled.
|
||||
///
|
||||
/// Clients should not instantiate this class directly. All access should go
|
||||
/// through LLVMContext.
|
||||
OptBisect();
|
||||
|
||||
/// Checks the bisect limit to determine if the specified pass should run.
|
||||
///
|
||||
/// This function will immediate return true if bisection is disabled. If the
|
||||
/// bisect limit is set to -1, the function will print a message describing
|
||||
/// the pass and the bisect number assigned to it and return true. Otherwise,
|
||||
/// the function will print a message with the bisect number assigned to the
|
||||
/// pass and indicating whether or not the pass will be run and return true if
|
||||
/// the bisect limit has not yet been exceded or false if it has.
|
||||
///
|
||||
/// Most passes should not call this routine directly. Instead, it is called
|
||||
/// through a helper routine provided by the pass base class. For instance,
|
||||
/// function passes should call FunctionPass::skipFunction().
|
||||
template <class UnitT>
|
||||
bool shouldRunPass(const Pass *P, const UnitT &U);
|
||||
|
||||
/// Checks the bisect limit to determine if the specified pass should run.
|
||||
///
|
||||
/// This function will immediate return true if bisection is disabled. If the
|
||||
/// bisect limit is set to -1, the function will print a message describing
|
||||
/// the pass and the bisect number assigned to it and return true. Otherwise,
|
||||
/// the function will print a message with the bisect number assigned to the
|
||||
/// pass and indicating whether or not the pass will be run and return true if
|
||||
/// the bisect limit has not yet been exceded or false if it has.
|
||||
///
|
||||
/// In order to avoid duplicating the code necessary to access OptBisect
|
||||
/// through the LLVMContext class, passes may call one of the helper
|
||||
/// functions that get the context from an IR object. For instance,
|
||||
/// function passes may call skipPassForFunction().
|
||||
template <class UnitT>
|
||||
bool shouldRunPass(const StringRef PassName, const UnitT &U);
|
||||
|
||||
/// Checks the bisect limit to determine if the optimization described by the
|
||||
/// /p Desc argument should run.
|
||||
///
|
||||
/// This function will immediate return true if bisection is disabled. If the
|
||||
/// bisect limit is set to -1, the function will print a message with the
|
||||
/// bisect number assigned to the optimization along with the /p Desc
|
||||
/// description and return true. Otherwise, the function will print a message
|
||||
/// with the bisect number assigned to the optimization and indicating whether
|
||||
/// or not the pass will be run and return true if the bisect limit has not
|
||||
/// yet been exceded or false if it has.
|
||||
///
|
||||
/// Passes may call this function to provide more fine grained control over
|
||||
/// individual optimizations performed by the pass. Passes which cannot be
|
||||
/// skipped entirely (such as non-optional code generation passes) may still
|
||||
/// call this function to control whether or not individual optional
|
||||
/// transformations are performed.
|
||||
bool shouldRunCase(const Twine &Desc);
|
||||
|
||||
private:
|
||||
bool checkPass(const StringRef PassName, const StringRef TargetDesc);
|
||||
|
||||
bool BisectEnabled = false;
|
||||
unsigned LastBisectNum = 0;
|
||||
};
|
||||
|
||||
// Access to OptBisect should go through LLVMContext, but for the
|
||||
// new pass manager there is no single base class from which a
|
||||
// helper function to abstract the messy details can be provided.
|
||||
// Instead, we provide standalone helper functions for each IR
|
||||
// type that must be handled.
|
||||
|
||||
class Module;
|
||||
class Function;
|
||||
//class BasicBlock;
|
||||
//class Loop;
|
||||
|
||||
/// Check with the OptBisect object to determine whether the described pass
|
||||
/// should be skipped.
|
||||
///
|
||||
/// This is a helper function which abstracts the details of accessing OptBisect
|
||||
/// through an LLVMContext obtained from a Module.
|
||||
bool skipPassForModule(const StringRef PassName, const Module &M);
|
||||
|
||||
/// Check with the OptBisect object to determine whether the described pass
|
||||
/// should be skipped.
|
||||
///
|
||||
/// This is a helper function which abstracts the details of accessing OptBisect
|
||||
/// through an LLVMContext obtained from a Function.
|
||||
bool skipPassForFunction(const StringRef PassName, const Function &F);
|
||||
#if 0
|
||||
/// Check with the OptBisect object to determine whether the described pass
|
||||
/// should be skipped.
|
||||
///
|
||||
/// This is a helper function which abstracts the details of accessing OptBisect
|
||||
/// through an LLVMContext obtained from a BasicBlock.
|
||||
bool skipPassForBasicBlock(const StringRef PassName, const BasicBlock &BB);
|
||||
|
||||
/// Check with the OptBisect object to determine whether the described pass
|
||||
/// should be skipped.
|
||||
///
|
||||
/// This is a helper function which abstracts the details of accessing OptBisect
|
||||
/// through an LLVMContext obtained from a Loop.
|
||||
bool skipPassForLoop(const StringRef PassName, const Loop &L);
|
||||
#endif
|
||||
// skiPassForSCC is declared in LazyCallGraph.h because of include file
|
||||
// dependency issues related to LazyCallGraph::SCC being nested.
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_IR_OPTBISECT_H
|
@ -251,11 +251,6 @@ public:
|
||||
explicit ModulePass(char &pid) : Pass(PT_Module, pid) {}
|
||||
// Force out-of-line virtual method.
|
||||
~ModulePass() override;
|
||||
|
||||
protected:
|
||||
/// Optional passes call this function to check whether the pass should be
|
||||
/// skipped. This is the case when optimization bisect is over the limit.
|
||||
bool skipModule(Module &M) const;
|
||||
};
|
||||
|
||||
|
||||
@ -315,10 +310,9 @@ public:
|
||||
PassManagerType getPotentialPassManagerType() const override;
|
||||
|
||||
protected:
|
||||
/// Optional passes call this function to check whether the pass should be
|
||||
/// skipped. This is the case when Attribute::OptimizeNone is set or when
|
||||
/// optimization bisect is over the limit.
|
||||
bool skipFunction(const Function &F) const;
|
||||
/// skipOptnoneFunction - This function has Attribute::OptimizeNone
|
||||
/// and most transformation passes should skip it.
|
||||
bool skipOptnoneFunction(const Function &F) const;
|
||||
};
|
||||
|
||||
|
||||
@ -365,10 +359,9 @@ public:
|
||||
PassManagerType getPotentialPassManagerType() const override;
|
||||
|
||||
protected:
|
||||
/// Optional passes call this function to check whether the pass should be
|
||||
/// skipped. This is the case when Attribute::OptimizeNone is set or when
|
||||
/// optimization bisect is over the limit.
|
||||
bool skipBasicBlock(const BasicBlock &BB) const;
|
||||
/// skipOptnoneFunction - Containing function has Attribute::OptimizeNone
|
||||
/// and most transformation passes should skip it.
|
||||
bool skipOptnoneFunction(const BasicBlock &BB) const;
|
||||
};
|
||||
|
||||
/// If the user specifies the -time-passes argument on an LLVM tool command line
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include "llvm/IR/IntrinsicInst.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/LegacyPassManagers.h"
|
||||
#include "llvm/IR/OptBisect.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/Timer.h"
|
||||
@ -445,7 +444,7 @@ bool CGPassManager::runOnModule(Module &M) {
|
||||
// Walk the callgraph in bottom-up SCC order.
|
||||
scc_iterator<CallGraph*> CGI = scc_begin(&CG);
|
||||
|
||||
CallGraphSCC CurSCC(CG, &CGI);
|
||||
CallGraphSCC CurSCC(&CGI);
|
||||
while (!CGI.isAtEnd()) {
|
||||
// Copy the current SCC and increment past it so that the pass can hack
|
||||
// on the SCC if it wants to without invalidating our iterator.
|
||||
@ -632,9 +631,3 @@ Pass *CallGraphSCCPass::createPrinterPass(raw_ostream &O,
|
||||
return new PrintCallGraphPass(Banner, O);
|
||||
}
|
||||
|
||||
bool CallGraphSCCPass::skipSCC(CallGraphSCC &SCC) const {
|
||||
return !SCC.getCallGraph().getModule()
|
||||
.getContext()
|
||||
.getOptBisect()
|
||||
.shouldRunPass(this, SCC);
|
||||
}
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "llvm/Analysis/LoopPass.h"
|
||||
#include "llvm/IR/IRPrintingPasses.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/OptBisect.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/Timer.h"
|
||||
@ -336,16 +335,11 @@ void LoopPass::assignPassManager(PMStack &PMS,
|
||||
LPPM->add(this);
|
||||
}
|
||||
|
||||
bool LoopPass::skipLoop(const Loop *L) const {
|
||||
// Containing function has Attribute::OptimizeNone and transformation
|
||||
// passes should skip it.
|
||||
bool LoopPass::skipOptnoneFunction(const Loop *L) const {
|
||||
const Function *F = L->getHeader()->getParent();
|
||||
if (!F)
|
||||
return false;
|
||||
// Check the opt bisect limit.
|
||||
LLVMContext &Context = F->getContext();
|
||||
if (!Context.getOptBisect().shouldRunPass(this, *L))
|
||||
return true;
|
||||
// Check for the OptimizeNone attribute.
|
||||
if (F->hasFnAttribute(Attribute::OptimizeNone)) {
|
||||
if (F && F->hasFnAttribute(Attribute::OptimizeNone)) {
|
||||
// FIXME: Report this to dbgs() only once per function.
|
||||
DEBUG(dbgs() << "Skipping pass '" << getPassName()
|
||||
<< "' in function " << F->getName() << "\n");
|
||||
|
@ -90,7 +90,7 @@ INITIALIZE_PASS(BranchFolderPass, "branch-folder",
|
||||
"Control Flow Optimizer", false, false)
|
||||
|
||||
bool BranchFolderPass::runOnMachineFunction(MachineFunction &MF) {
|
||||
if (skipFunction(*MF.getFunction()))
|
||||
if (skipOptnoneFunction(*MF.getFunction()))
|
||||
return false;
|
||||
|
||||
TargetPassConfig *PassConfig = &getAnalysis<TargetPassConfig>();
|
||||
|
@ -211,7 +211,7 @@ FunctionPass *llvm::createCodeGenPreparePass(const TargetMachine *TM) {
|
||||
}
|
||||
|
||||
bool CodeGenPrepare::runOnFunction(Function &F) {
|
||||
if (skipFunction(F))
|
||||
if (skipOptnoneFunction(F))
|
||||
return false;
|
||||
|
||||
DL = &F.getParent()->getDataLayout();
|
||||
|
@ -90,7 +90,7 @@ bool DeadMachineInstructionElim::isDead(const MachineInstr *MI) const {
|
||||
}
|
||||
|
||||
bool DeadMachineInstructionElim::runOnMachineFunction(MachineFunction &MF) {
|
||||
if (skipFunction(*MF.getFunction()))
|
||||
if (skipOptnoneFunction(*MF.getFunction()))
|
||||
return false;
|
||||
|
||||
bool AnyChanges = false;
|
||||
|
@ -63,9 +63,6 @@ ModulePass *llvm::createLowerEmuTLSPass(const TargetMachine *TM) {
|
||||
}
|
||||
|
||||
bool LowerEmuTLS::runOnModule(Module &M) {
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
if (!TM || !TM->Options.EmulatedTLS)
|
||||
return false;
|
||||
|
||||
|
@ -1430,7 +1430,7 @@ bool MachineBlockPlacement::runOnMachineFunction(MachineFunction &F) {
|
||||
if (std::next(F.begin()) == F.end())
|
||||
return false;
|
||||
|
||||
if (skipFunction(*F.getFunction()))
|
||||
if (skipOptnoneFunction(*F.getFunction()))
|
||||
return false;
|
||||
|
||||
MBPI = &getAnalysis<MachineBranchProbabilityInfo>();
|
||||
|
@ -704,7 +704,7 @@ bool MachineCSE::PerformCSE(MachineDomTreeNode *Node) {
|
||||
}
|
||||
|
||||
bool MachineCSE::runOnMachineFunction(MachineFunction &MF) {
|
||||
if (skipFunction(*MF.getFunction()))
|
||||
if (skipOptnoneFunction(*MF.getFunction()))
|
||||
return false;
|
||||
|
||||
TII = MF.getSubtarget().getInstrInfo();
|
||||
|
@ -349,7 +349,7 @@ void MachineCopyPropagation::CopyPropagateBlock(MachineBasicBlock &MBB) {
|
||||
}
|
||||
|
||||
bool MachineCopyPropagation::runOnMachineFunction(MachineFunction &MF) {
|
||||
if (skipFunction(*MF.getFunction()))
|
||||
if (skipOptnoneFunction(*MF.getFunction()))
|
||||
return false;
|
||||
|
||||
Changed = false;
|
||||
|
@ -260,7 +260,7 @@ static bool LoopIsOuterMostWithPredecessor(MachineLoop *CurLoop) {
|
||||
}
|
||||
|
||||
bool MachineLICM::runOnMachineFunction(MachineFunction &MF) {
|
||||
if (skipFunction(*MF.getFunction()))
|
||||
if (skipOptnoneFunction(*MF.getFunction()))
|
||||
return false;
|
||||
|
||||
Changed = FirstInLoop = false;
|
||||
|
@ -319,7 +319,7 @@ ScheduleDAGInstrs *PostMachineScheduler::createPostMachineScheduler() {
|
||||
/// design would be to split blocks at scheduling boundaries, but LLVM has a
|
||||
/// general bias against block splitting purely for implementation simplicity.
|
||||
bool MachineScheduler::runOnMachineFunction(MachineFunction &mf) {
|
||||
if (skipFunction(*mf.getFunction()))
|
||||
if (skipOptnoneFunction(*mf.getFunction()))
|
||||
return false;
|
||||
|
||||
if (EnableMachineSched.getNumOccurrences()) {
|
||||
@ -357,7 +357,7 @@ bool MachineScheduler::runOnMachineFunction(MachineFunction &mf) {
|
||||
}
|
||||
|
||||
bool PostMachineScheduler::runOnMachineFunction(MachineFunction &mf) {
|
||||
if (skipFunction(*mf.getFunction()))
|
||||
if (skipOptnoneFunction(*mf.getFunction()))
|
||||
return false;
|
||||
|
||||
if (EnablePostRAMachineSched.getNumOccurrences()) {
|
||||
|
@ -257,7 +257,7 @@ MachineSinking::AllUsesDominatedByBlock(unsigned Reg,
|
||||
}
|
||||
|
||||
bool MachineSinking::runOnMachineFunction(MachineFunction &MF) {
|
||||
if (skipFunction(*MF.getFunction()))
|
||||
if (skipOptnoneFunction(*MF.getFunction()))
|
||||
return false;
|
||||
|
||||
DEBUG(dbgs() << "******** Machine Sinking ********\n");
|
||||
|
@ -63,7 +63,7 @@ INITIALIZE_PASS(OptimizePHIs, "opt-phis",
|
||||
"Optimize machine instruction PHIs", false, false)
|
||||
|
||||
bool OptimizePHIs::runOnMachineFunction(MachineFunction &Fn) {
|
||||
if (skipFunction(*Fn.getFunction()))
|
||||
if (skipOptnoneFunction(*Fn.getFunction()))
|
||||
return false;
|
||||
|
||||
MRI = &Fn.getRegInfo();
|
||||
|
@ -1471,7 +1471,7 @@ bool PeepholeOptimizer::foldRedundantNAPhysCopy(
|
||||
}
|
||||
|
||||
bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) {
|
||||
if (skipFunction(*MF.getFunction()))
|
||||
if (skipOptnoneFunction(*MF.getFunction()))
|
||||
return false;
|
||||
|
||||
DEBUG(dbgs() << "********** PEEPHOLE OPTIMIZER **********\n");
|
||||
|
@ -273,7 +273,7 @@ bool PostRAScheduler::enablePostRAScheduler(
|
||||
}
|
||||
|
||||
bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) {
|
||||
if (skipFunction(*Fn.getFunction()))
|
||||
if (skipOptnoneFunction(*Fn.getFunction()))
|
||||
return false;
|
||||
|
||||
TII = Fn.getSubtarget().getInstrInfo();
|
||||
|
@ -657,7 +657,7 @@ void StackColoring::expungeSlotMap(DenseMap<int, int> &SlotRemap,
|
||||
}
|
||||
|
||||
bool StackColoring::runOnMachineFunction(MachineFunction &Func) {
|
||||
if (skipFunction(*Func.getFunction()))
|
||||
if (skipOptnoneFunction(*Func.getFunction()))
|
||||
return false;
|
||||
|
||||
DEBUG(dbgs() << "********** Stack Coloring **********\n"
|
||||
|
@ -44,7 +44,7 @@ INITIALIZE_PASS(TailDuplicatePass, "tailduplication", "Tail Duplication", false,
|
||||
false)
|
||||
|
||||
bool TailDuplicatePass::runOnMachineFunction(MachineFunction &MF) {
|
||||
if (skipFunction(*MF.getFunction()))
|
||||
if (skipOptnoneFunction(*MF.getFunction()))
|
||||
return false;
|
||||
|
||||
auto MMI = getAnalysisIfAvailable<MachineModuleInfo>();
|
||||
|
@ -39,7 +39,6 @@ add_llvm_library(LLVMCore
|
||||
Module.cpp
|
||||
ModuleSummaryIndex.cpp
|
||||
Operator.cpp
|
||||
OptBisect.cpp
|
||||
Pass.cpp
|
||||
PassManager.cpp
|
||||
PassRegistry.cpp
|
||||
|
@ -325,7 +325,3 @@ void LLVMContext::disableDebugTypeODRUniquing() { pImpl->DITypeMap.reset(); }
|
||||
void LLVMContext::setDiscardValueNames(bool Discard) {
|
||||
pImpl->DiscardValueNames = Discard;
|
||||
}
|
||||
|
||||
OptBisect &LLVMContext::getOptBisect() {
|
||||
return pImpl->getOptBisect();
|
||||
}
|
||||
|
@ -16,8 +16,6 @@
|
||||
#include "llvm/IR/Attributes.h"
|
||||
#include "llvm/IR/DiagnosticInfo.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/OptBisect.h"
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
#include <algorithm>
|
||||
using namespace llvm;
|
||||
|
||||
@ -234,19 +232,3 @@ void GetElementPtrConstantExpr::anchor() { }
|
||||
|
||||
void CompareConstantExpr::anchor() { }
|
||||
|
||||
/// Singleton instance of the OptBisect class.
|
||||
///
|
||||
/// This singleton is accessed via the LLVMContext::getOptBisect() function. It
|
||||
/// provides a mechanism to disable passes and individual optimizations at
|
||||
/// compile time based on a command line option (-opt-bisect-limit) in order to
|
||||
/// perform a bisecting search for optimization-related problems.
|
||||
///
|
||||
/// Even if multiple LLVMContext objects are created, they will all return the
|
||||
/// same instance of OptBisect in order to provide a single bisect count. Any
|
||||
/// code that uses the OptBisect object should be serialized when bisection is
|
||||
/// enabled in order to enable a consistent bisect count.
|
||||
static ManagedStatic<OptBisect> OptBisector;
|
||||
|
||||
OptBisect &LLVMContextImpl::getOptBisect() {
|
||||
return *OptBisector;
|
||||
}
|
||||
|
@ -1133,10 +1133,6 @@ public:
|
||||
|
||||
/// Destroy the ConstantArrays if they are not used.
|
||||
void dropTriviallyDeadConstantArrays();
|
||||
|
||||
/// \brief Access the object which manages optimization bisection for failure
|
||||
/// analysis.
|
||||
OptBisect &getOptBisect();
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,176 +0,0 @@
|
||||
//===------- llvm/IR/OptBisect/Bisect.cpp - LLVM Bisect support --------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// This file implements support for a bisecting optimizations based on a
|
||||
/// command line option.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Analysis/CallGraphSCCPass.h"
|
||||
#include "llvm/Analysis/LazyCallGraph.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/OptBisect.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
static cl::opt<int> OptBisectLimit("opt-bisect-limit", cl::Hidden,
|
||||
cl::init(INT_MAX), cl::Optional,
|
||||
cl::desc("Maximum optimization to perform"));
|
||||
|
||||
OptBisect::OptBisect() {
|
||||
BisectEnabled = OptBisectLimit != INT_MAX;
|
||||
}
|
||||
|
||||
static void printPassMessage(const StringRef &Name, int PassNum,
|
||||
StringRef TargetDesc, bool Running) {
|
||||
StringRef Status = Running ? "" : "NOT ";
|
||||
errs() << "BISECT: " << Status << "running pass "
|
||||
<< "(" << PassNum << ") " << Name << " on " << TargetDesc << "\n";
|
||||
}
|
||||
|
||||
static void printCaseMessage(int CaseNum, StringRef Msg, bool Running) {
|
||||
if (Running)
|
||||
errs() << "BISECT: running case (";
|
||||
else
|
||||
errs() << "BISECT: NOT running case (";
|
||||
errs() << CaseNum << "): " << Msg << "\n";
|
||||
}
|
||||
|
||||
static std::string getDescription(const Module &M) {
|
||||
return "module (" + M.getName().str() + ")";
|
||||
}
|
||||
|
||||
static std::string getDescription(const Function &F) {
|
||||
return "function (" + F.getName().str() + ")";
|
||||
}
|
||||
|
||||
static std::string getDescription(const BasicBlock &BB) {
|
||||
return "basic block (" + BB.getName().str() + ") in function (" +
|
||||
BB.getParent()->getName().str() + ")";
|
||||
}
|
||||
|
||||
static std::string getDescription(const Loop &L) {
|
||||
// FIXME: I'd like to be able to provide a better description here, but
|
||||
// calling L->getHeader() would introduce a new dependency on the
|
||||
// LLVMCore library.
|
||||
return "loop";
|
||||
}
|
||||
|
||||
static std::string getDescription(const CallGraphSCC &SCC) {
|
||||
std::string Desc = "SCC (";
|
||||
bool First = true;
|
||||
for (CallGraphNode *CGN : SCC) {
|
||||
if (First)
|
||||
First = false;
|
||||
else
|
||||
Desc += ", ";
|
||||
Function *F = CGN->getFunction();
|
||||
if (F)
|
||||
Desc += F->getName();
|
||||
else
|
||||
Desc += "<<null function>>";
|
||||
}
|
||||
Desc += ")";
|
||||
return Desc;
|
||||
}
|
||||
|
||||
static std::string getDescription(const LazyCallGraph::SCC &SCC) {
|
||||
std::string Desc = "SCC (";
|
||||
bool First = true;
|
||||
for (LazyCallGraph::Node &CGN : SCC) {
|
||||
if (First)
|
||||
First = false;
|
||||
else
|
||||
Desc += ", ";
|
||||
Function &F = CGN.getFunction();
|
||||
Desc += F.getName();
|
||||
}
|
||||
Desc += ")";
|
||||
return Desc;
|
||||
}
|
||||
|
||||
// Force instantiations.
|
||||
template bool OptBisect::shouldRunPass(const Pass *, const Module &);
|
||||
template bool OptBisect::shouldRunPass(const Pass *, const Function &);
|
||||
template bool OptBisect::shouldRunPass(const Pass *, const BasicBlock &);
|
||||
template bool OptBisect::shouldRunPass(const Pass *, const Loop &);
|
||||
template bool OptBisect::shouldRunPass(const Pass *, const CallGraphSCC &);
|
||||
template bool OptBisect::shouldRunPass(const StringRef PassName,
|
||||
const Module &);
|
||||
template bool OptBisect::shouldRunPass(const StringRef PassName,
|
||||
const Function &);
|
||||
template bool OptBisect::shouldRunPass(const StringRef PassName,
|
||||
const BasicBlock &);
|
||||
template bool OptBisect::shouldRunPass(const StringRef PassName, const Loop &);
|
||||
template bool OptBisect::shouldRunPass(const StringRef PassName,
|
||||
const LazyCallGraph::SCC &);
|
||||
|
||||
template <class UnitT>
|
||||
bool OptBisect::shouldRunPass(const Pass *P, const UnitT &U) {
|
||||
if (!BisectEnabled)
|
||||
return true;
|
||||
return checkPass(P->getPassName(), getDescription(U));
|
||||
}
|
||||
|
||||
// Interface function for the new pass manager.
|
||||
template <class UnitT>
|
||||
bool OptBisect::shouldRunPass(const StringRef PassName, const UnitT &U) {
|
||||
if (!BisectEnabled)
|
||||
return true;
|
||||
return checkPass(PassName, getDescription(U));
|
||||
}
|
||||
|
||||
bool OptBisect::checkPass(const StringRef PassName,
|
||||
const StringRef TargetDesc) {
|
||||
assert(BisectEnabled);
|
||||
|
||||
int CurBisectNum = ++LastBisectNum;
|
||||
bool ShouldRun = (OptBisectLimit == -1 || CurBisectNum <= OptBisectLimit);
|
||||
printPassMessage(PassName, CurBisectNum, TargetDesc, ShouldRun);
|
||||
return ShouldRun;
|
||||
}
|
||||
|
||||
bool OptBisect::shouldRunCase(const Twine &Msg) {
|
||||
if (!BisectEnabled)
|
||||
return true;
|
||||
int CurFuelNum = ++LastBisectNum;
|
||||
bool ShouldRun = (OptBisectLimit == -1 || CurFuelNum <= OptBisectLimit);
|
||||
printCaseMessage(CurFuelNum, Msg.str(), ShouldRun);
|
||||
return ShouldRun;
|
||||
}
|
||||
|
||||
bool llvm::skipPassForModule(const StringRef PassName, const Module &M) {
|
||||
return !M.getContext().getOptBisect().shouldRunPass(PassName, M);
|
||||
}
|
||||
|
||||
bool llvm::skipPassForFunction(const StringRef PassName, const Function &F) {
|
||||
return !F.getContext().getOptBisect().shouldRunPass(PassName, F);
|
||||
}
|
||||
#if 0
|
||||
bool llvm::skipPassForBasicBlock(const StringRef PassName, const BasicBlock &BB) {
|
||||
return !BB.getContext().getOptBisect().shouldRunPass(PassName, BB);
|
||||
}
|
||||
|
||||
bool llvm::skipPassForLoop(const StringRef PassName, const Loop &L) {
|
||||
const Function *F = L.getHeader()->getParent();
|
||||
if (!F)
|
||||
return false;
|
||||
return !F->getContext().getOptBisect().shouldRunPass(PassName, L);
|
||||
}
|
||||
#endif
|
||||
bool llvm::skipPassForSCC(const StringRef PassName, const LazyCallGraph::SCC &SCC) {
|
||||
LLVMContext &Context = SCC.begin()->getFunction().getContext();
|
||||
return !Context.getOptBisect().shouldRunPass(PassName, SCC);
|
||||
}
|
||||
|
@ -17,8 +17,6 @@
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/IRPrintingPasses.h"
|
||||
#include "llvm/IR/LegacyPassNameParser.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/OptBisect.h"
|
||||
#include "llvm/PassRegistry.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
@ -47,10 +45,6 @@ PassManagerType ModulePass::getPotentialPassManagerType() const {
|
||||
return PMT_ModulePassManager;
|
||||
}
|
||||
|
||||
bool ModulePass::skipModule(Module &M) const {
|
||||
return !M.getContext().getOptBisect().shouldRunPass(this, M);
|
||||
}
|
||||
|
||||
bool Pass::mustPreserveAnalysisID(char &AID) const {
|
||||
return Resolver->getAnalysisIfAvailable(&AID, true) != nullptr;
|
||||
}
|
||||
@ -146,13 +140,10 @@ PassManagerType FunctionPass::getPotentialPassManagerType() const {
|
||||
return PMT_FunctionPassManager;
|
||||
}
|
||||
|
||||
bool FunctionPass::skipFunction(const Function &F) const {
|
||||
if (!F.getContext().getOptBisect().shouldRunPass(this, F))
|
||||
return true;
|
||||
|
||||
bool FunctionPass::skipOptnoneFunction(const Function &F) const {
|
||||
if (F.hasFnAttribute(Attribute::OptimizeNone)) {
|
||||
DEBUG(dbgs() << "Skipping pass '" << getPassName() << "' on function "
|
||||
<< F.getName() << "\n");
|
||||
DEBUG(dbgs() << "Skipping pass '" << getPassName()
|
||||
<< "' on function " << F.getName() << "\n");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -177,13 +168,9 @@ bool BasicBlockPass::doFinalization(Function &) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BasicBlockPass::skipBasicBlock(const BasicBlock &BB) const {
|
||||
bool BasicBlockPass::skipOptnoneFunction(const BasicBlock &BB) const {
|
||||
const Function *F = BB.getParent();
|
||||
if (!F)
|
||||
return false;
|
||||
if (!F->getContext().getOptBisect().shouldRunPass(this, BB))
|
||||
return true;
|
||||
if (F->hasFnAttribute(Attribute::OptimizeNone)) {
|
||||
if (F && F->hasFnAttribute(Attribute::OptimizeNone)) {
|
||||
// Report this only once per function.
|
||||
if (&BB == &F->getEntryBlock())
|
||||
DEBUG(dbgs() << "Skipping pass '" << getPassName()
|
||||
|
@ -114,9 +114,6 @@ Pass *llvm::createArgumentPromotionPass(unsigned maxElements) {
|
||||
}
|
||||
|
||||
bool ArgPromotion::runOnSCC(CallGraphSCC &SCC) {
|
||||
if (skipSCC(SCC))
|
||||
return false;
|
||||
|
||||
bool Changed = false, LocalChange;
|
||||
|
||||
do { // Iterate until we stop promoting from this SCC.
|
||||
|
@ -96,8 +96,6 @@ unsigned ConstantMerge::getAlignment(GlobalVariable *GV) const {
|
||||
}
|
||||
|
||||
bool ConstantMerge::runOnModule(Module &M) {
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
// Find all the globals that are marked "used". These cannot be merged.
|
||||
SmallPtrSet<const GlobalValue*, 8> UsedGlobals;
|
||||
|
@ -158,9 +158,6 @@ void CrossDSOCFI::buildCFICheck() {
|
||||
}
|
||||
|
||||
bool CrossDSOCFI::runOnModule(Module &M) {
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
if (M.getModuleFlag("Cross-DSO CFI") == nullptr)
|
||||
return false;
|
||||
buildCFICheck();
|
||||
|
@ -1092,9 +1092,6 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
|
||||
}
|
||||
|
||||
bool DAE::runOnModule(Module &M) {
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
bool Changed = false;
|
||||
|
||||
// First pass: Do a simple check to see if any functions can have their "..."
|
||||
|
@ -50,9 +50,6 @@ ModulePass *llvm::createEliminateAvailableExternallyPass() {
|
||||
}
|
||||
|
||||
bool EliminateAvailableExternally::runOnModule(Module &M) {
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
bool Changed = false;
|
||||
|
||||
// Drop initializers of available externally global variables.
|
||||
|
@ -68,9 +68,6 @@ namespace {
|
||||
: ModulePass(ID), Named(GVs.begin(), GVs.end()), deleteStuff(deleteS) {}
|
||||
|
||||
bool runOnModule(Module &M) override {
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
// Visit the global inline asm.
|
||||
if (!deleteStuff)
|
||||
M.setModuleInlineAsm("");
|
||||
|
@ -987,9 +987,6 @@ static bool addNoRecurseAttrs(const SCCNodeSet &SCCNodes) {
|
||||
|
||||
PreservedAnalyses PostOrderFunctionAttrsPass::run(LazyCallGraph::SCC &C,
|
||||
CGSCCAnalysisManager &AM) {
|
||||
if (skipPassForSCC(name(), C))
|
||||
return PreservedAnalyses::all();
|
||||
|
||||
Module &M = *C.begin()->getFunction().getParent();
|
||||
const ModuleAnalysisManager &MAM =
|
||||
AM.getResult<ModuleAnalysisManagerCGSCCProxy>(C).getManager();
|
||||
@ -1084,9 +1081,6 @@ INITIALIZE_PASS_END(PostOrderFunctionAttrsLegacyPass, "functionattrs",
|
||||
Pass *llvm::createPostOrderFunctionAttrsLegacyPass() { return new PostOrderFunctionAttrsLegacyPass(); }
|
||||
|
||||
bool PostOrderFunctionAttrsLegacyPass::runOnSCC(CallGraphSCC &SCC) {
|
||||
if (skipSCC(SCC))
|
||||
return false;
|
||||
|
||||
TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
|
||||
bool Changed = false;
|
||||
|
||||
@ -1201,9 +1195,6 @@ static bool addNoRecurseAttrsTopDown(Function &F) {
|
||||
}
|
||||
|
||||
bool ReversePostOrderFunctionAttrs::runOnModule(Module &M) {
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
// We only have a post-order SCC traversal (because SCCs are inherently
|
||||
// discovered in post-order), so we accumulate them in a vector and then walk
|
||||
// it in reverse. This is simpler than using the RPO iterator infrastructure
|
||||
|
@ -499,9 +499,6 @@ public:
|
||||
: ModulePass(ID), Index(Index) {}
|
||||
|
||||
bool runOnModule(Module &M) override {
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
if (SummaryFile.empty() && !Index)
|
||||
report_fatal_error("error: -function-import requires -summary-file or "
|
||||
"file from frontend\n");
|
||||
|
@ -75,9 +75,6 @@ INITIALIZE_PASS(GlobalDCE, "globaldce",
|
||||
ModulePass *llvm::createGlobalDCEPass() { return new GlobalDCE(); }
|
||||
|
||||
bool GlobalDCE::runOnModule(Module &M) {
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
bool Changed = false;
|
||||
|
||||
// Remove empty functions from the global ctors list.
|
||||
|
@ -2528,9 +2528,6 @@ bool GlobalOpt::OptimizeEmptyGlobalCXXDtors(Function *CXAAtExitFn) {
|
||||
}
|
||||
|
||||
bool GlobalOpt::runOnModule(Module &M) {
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
bool Changed = false;
|
||||
|
||||
auto &DL = M.getDataLayout();
|
||||
|
@ -54,9 +54,6 @@ INITIALIZE_PASS(IPCP, "ipconstprop",
|
||||
ModulePass *llvm::createIPConstantPropagationPass() { return new IPCP(); }
|
||||
|
||||
bool IPCP::runOnModule(Module &M) {
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
bool Changed = false;
|
||||
bool LocalChange = true;
|
||||
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/OptBisect.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace llvm;
|
||||
@ -956,9 +955,6 @@ static bool inferAllPrototypeAttributes(Module &M,
|
||||
|
||||
PreservedAnalyses InferFunctionAttrsPass::run(Module &M,
|
||||
AnalysisManager<Module> &AM) {
|
||||
if (skipPassForModule(name(), M))
|
||||
return PreservedAnalyses::all();
|
||||
|
||||
auto &TLI = AM.getResult<TargetLibraryAnalysis>(M);
|
||||
|
||||
if (!inferAllPrototypeAttributes(M, TLI))
|
||||
@ -983,9 +979,6 @@ struct InferFunctionAttrsLegacyPass : public ModulePass {
|
||||
}
|
||||
|
||||
bool runOnModule(Module &M) override {
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
|
||||
return inferAllPrototypeAttributes(M, TLI);
|
||||
}
|
||||
|
@ -356,9 +356,6 @@ static bool InlineHistoryIncludes(Function *F, int InlineHistoryID,
|
||||
}
|
||||
|
||||
bool Inliner::runOnSCC(CallGraphSCC &SCC) {
|
||||
if (skipSCC(SCC))
|
||||
return false;
|
||||
|
||||
CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();
|
||||
ACT = &getAnalysis<AssumptionCacheTracker>();
|
||||
auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
|
||||
|
@ -105,9 +105,6 @@ public:
|
||||
}
|
||||
|
||||
bool runOnModule(Module &M) override {
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
CallGraphWrapperPass *CGPass =
|
||||
getAnalysisIfAvailable<CallGraphWrapperPass>();
|
||||
CallGraph *CG = CGPass ? &CGPass->getCallGraph() : nullptr;
|
||||
|
@ -81,7 +81,7 @@ INITIALIZE_PASS(SingleLoopExtractor, "loop-extract-single",
|
||||
Pass *llvm::createLoopExtractorPass() { return new LoopExtractor(); }
|
||||
|
||||
bool LoopExtractor::runOnLoop(Loop *L, LPPassManager &) {
|
||||
if (skipLoop(L))
|
||||
if (skipOptnoneFunction(L))
|
||||
return false;
|
||||
|
||||
// Only visit top-level loops.
|
||||
@ -249,9 +249,6 @@ void BlockExtractorPass::SplitLandingPadPreds(Function *F) {
|
||||
}
|
||||
|
||||
bool BlockExtractorPass::runOnModule(Module &M) {
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
std::set<BasicBlock*> TranslatedBlocksToNotExtract;
|
||||
for (unsigned i = 0, e = BlocksToNotExtract.size(); i != e; ++i) {
|
||||
BasicBlock *BB = BlocksToNotExtract[i];
|
||||
|
@ -1051,9 +1051,6 @@ bool LowerBitSets::eraseBitSetMetadata() {
|
||||
}
|
||||
|
||||
bool LowerBitSets::runOnModule(Module &M) {
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
bool Changed = buildBitSets();
|
||||
Changed |= eraseBitSetMetadata();
|
||||
return Changed;
|
||||
|
@ -1525,9 +1525,6 @@ bool MergeFunctions::doSanityCheck(std::vector<WeakVH> &Worklist) {
|
||||
}
|
||||
|
||||
bool MergeFunctions::runOnModule(Module &M) {
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
bool Changed = false;
|
||||
|
||||
// All functions in the module, ordered by hash. Functions with a unique
|
||||
|
@ -149,9 +149,6 @@ Function* PartialInliner::unswitchFunction(Function* F) {
|
||||
}
|
||||
|
||||
bool PartialInliner::runOnModule(Module& M) {
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
std::vector<Function*> worklist;
|
||||
worklist.reserve(M.size());
|
||||
for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI)
|
||||
|
@ -63,9 +63,6 @@ Pass *llvm::createPruneEHPass() { return new PruneEH(); }
|
||||
|
||||
|
||||
bool PruneEH::runOnSCC(CallGraphSCC &SCC) {
|
||||
if (skipSCC(SCC))
|
||||
return false;
|
||||
|
||||
SmallPtrSet<CallGraphNode *, 8> SCCNodes;
|
||||
CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();
|
||||
bool MadeChange = false;
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "llvm/Transforms/IPO/StripDeadPrototypes.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/OptBisect.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Transforms/IPO.h"
|
||||
|
||||
@ -55,9 +54,6 @@ static bool stripDeadPrototypes(Module &M) {
|
||||
}
|
||||
|
||||
PreservedAnalyses StripDeadPrototypesPass::run(Module &M) {
|
||||
if (skipPassForModule(name(), M))
|
||||
return PreservedAnalyses::all();
|
||||
|
||||
if (stripDeadPrototypes(M))
|
||||
return PreservedAnalyses::none();
|
||||
return PreservedAnalyses::all();
|
||||
@ -73,9 +69,6 @@ public:
|
||||
*PassRegistry::getPassRegistry());
|
||||
}
|
||||
bool runOnModule(Module &M) override {
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
return stripDeadPrototypes(M);
|
||||
}
|
||||
};
|
||||
|
@ -229,9 +229,6 @@ static bool StripSymbolNames(Module &M, bool PreserveDbgInfo) {
|
||||
}
|
||||
|
||||
bool StripSymbols::runOnModule(Module &M) {
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
bool Changed = false;
|
||||
Changed |= StripDebugInfo(M);
|
||||
if (!OnlyDebugInfo)
|
||||
@ -240,15 +237,10 @@ bool StripSymbols::runOnModule(Module &M) {
|
||||
}
|
||||
|
||||
bool StripNonDebugSymbols::runOnModule(Module &M) {
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
return StripSymbolNames(M, true);
|
||||
}
|
||||
|
||||
bool StripDebugDeclare::runOnModule(Module &M) {
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
Function *Declare = M.getFunction("llvm.dbg.declare");
|
||||
std::vector<Constant*> DeadConstants;
|
||||
@ -294,9 +286,6 @@ bool StripDebugDeclare::runOnModule(Module &M) {
|
||||
/// optimized away by the optimizer. This special pass removes debug info for
|
||||
/// such symbols.
|
||||
bool StripDeadDebugInfo::runOnModule(Module &M) {
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
bool Changed = false;
|
||||
|
||||
LLVMContext &C = M.getContext();
|
||||
|
@ -265,12 +265,7 @@ struct WholeProgramDevirt : public ModulePass {
|
||||
WholeProgramDevirt() : ModulePass(ID) {
|
||||
initializeWholeProgramDevirtPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
bool runOnModule(Module &M) {
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
return DevirtModule(M).run();
|
||||
}
|
||||
bool runOnModule(Module &M) { return DevirtModule(M).run(); }
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
@ -56,7 +56,6 @@
|
||||
#include "llvm/IR/Dominators.h"
|
||||
#include "llvm/IR/GetElementPtrTypeIterator.h"
|
||||
#include "llvm/IR/IntrinsicInst.h"
|
||||
#include "llvm/IR/OptBisect.h"
|
||||
#include "llvm/IR/PatternMatch.h"
|
||||
#include "llvm/IR/ValueHandle.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
@ -3102,9 +3101,6 @@ combineInstructionsOverFunction(Function &F, InstCombineWorklist &Worklist,
|
||||
|
||||
PreservedAnalyses InstCombinePass::run(Function &F,
|
||||
AnalysisManager<Function> &AM) {
|
||||
if (skipPassForFunction(name(), F))
|
||||
return PreservedAnalyses::all();
|
||||
|
||||
auto &AC = AM.getResult<AssumptionAnalysis>(F);
|
||||
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
|
||||
auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
|
||||
@ -3137,7 +3133,7 @@ void InstructionCombiningPass::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
}
|
||||
|
||||
bool InstructionCombiningPass::runOnFunction(Function &F) {
|
||||
if (skipFunction(F))
|
||||
if (skipOptnoneFunction(F))
|
||||
return false;
|
||||
|
||||
// Required analyses.
|
||||
|
@ -778,9 +778,6 @@ static void createIRLevelProfileFlagVariable(Module &M) {
|
||||
}
|
||||
|
||||
bool PGOInstrumentationGen::runOnModule(Module &M) {
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
createIRLevelProfileFlagVariable(M);
|
||||
for (auto &F : M) {
|
||||
if (F.isDeclaration())
|
||||
@ -804,9 +801,6 @@ static void setPGOCountOnFunc(PGOUseFunc &Func,
|
||||
}
|
||||
|
||||
bool PGOInstrumentationUse::runOnModule(Module &M) {
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
DEBUG(dbgs() << "Read in profile counters: ");
|
||||
auto &Ctx = M.getContext();
|
||||
// Read the counter array from file.
|
||||
|
@ -132,9 +132,6 @@ bool ObjCARCAPElim::runOnModule(Module &M) {
|
||||
if (!ModuleHasARC(M))
|
||||
return false;
|
||||
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
// Find the llvm.global_ctors variable, as the first step in
|
||||
// identifying the global constructors. In theory, unnecessary autorelease
|
||||
// pools could occur anywhere, but in practice it's pretty rare. Global
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include "llvm/IR/InstIterator.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/IntrinsicInst.h"
|
||||
#include "llvm/IR/OptBisect.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/ProfileData/InstrProf.h"
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
@ -147,9 +146,6 @@ static bool aggressiveDCE(Function& F) {
|
||||
}
|
||||
|
||||
PreservedAnalyses ADCEPass::run(Function &F) {
|
||||
if (skipPassForFunction(name(), F))
|
||||
return PreservedAnalyses::all();
|
||||
|
||||
if (aggressiveDCE(F))
|
||||
return PreservedAnalyses::none();
|
||||
return PreservedAnalyses::all();
|
||||
@ -163,7 +159,7 @@ struct ADCELegacyPass : public FunctionPass {
|
||||
}
|
||||
|
||||
bool runOnFunction(Function& F) override {
|
||||
if (skipFunction(F))
|
||||
if (skipOptnoneFunction(F))
|
||||
return false;
|
||||
return aggressiveDCE(F);
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ INITIALIZE_PASS_END(BDCE, "bdce", "Bit-Tracking Dead Code Elimination",
|
||||
false, false)
|
||||
|
||||
bool BDCE::runOnFunction(Function& F) {
|
||||
if (skipFunction(F))
|
||||
if (skipOptnoneFunction(F))
|
||||
return false;
|
||||
auto &DB = getAnalysis<DemandedBitsWrapperPass>().getDemandedBits();
|
||||
|
||||
|
@ -187,7 +187,7 @@ FunctionPass *llvm::createConstantHoistingPass() {
|
||||
|
||||
/// \brief Perform the constant hoisting optimization for the given function.
|
||||
bool ConstantHoisting::runOnFunction(Function &Fn) {
|
||||
if (skipFunction(Fn))
|
||||
if (skipOptnoneFunction(Fn))
|
||||
return false;
|
||||
|
||||
DEBUG(dbgs() << "********** Begin Constant Hoisting **********\n");
|
||||
|
@ -399,7 +399,7 @@ Constant *CorrelatedValuePropagation::getConstantAt(Value *V, Instruction *At) {
|
||||
}
|
||||
|
||||
bool CorrelatedValuePropagation::runOnFunction(Function &F) {
|
||||
if (skipFunction(F))
|
||||
if (skipOptnoneFunction(F))
|
||||
return false;
|
||||
|
||||
LVI = &getAnalysis<LazyValueInfo>();
|
||||
|
@ -41,7 +41,7 @@ namespace {
|
||||
initializeDeadInstEliminationPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
bool runOnBasicBlock(BasicBlock &BB) override {
|
||||
if (skipBasicBlock(BB))
|
||||
if (skipOptnoneFunction(BB))
|
||||
return false;
|
||||
auto *TLIP = getAnalysisIfAvailable<TargetLibraryInfoWrapperPass>();
|
||||
TargetLibraryInfo *TLI = TLIP ? &TLIP->getTLI() : nullptr;
|
||||
@ -122,7 +122,7 @@ static bool DCEInstruction(Instruction *I,
|
||||
}
|
||||
|
||||
bool DCE::runOnFunction(Function &F) {
|
||||
if (skipFunction(F))
|
||||
if (skipOptnoneFunction(F))
|
||||
return false;
|
||||
|
||||
auto *TLIP = getAnalysisIfAvailable<TargetLibraryInfoWrapperPass>();
|
||||
|
@ -58,7 +58,7 @@ namespace {
|
||||
}
|
||||
|
||||
bool runOnFunction(Function &F) override {
|
||||
if (skipFunction(F))
|
||||
if (skipOptnoneFunction(F))
|
||||
return false;
|
||||
|
||||
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include "llvm/IR/Dominators.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/IntrinsicInst.h"
|
||||
#include "llvm/IR/OptBisect.h"
|
||||
#include "llvm/IR/PatternMatch.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
@ -813,9 +812,6 @@ bool EarlyCSE::run() {
|
||||
|
||||
PreservedAnalyses EarlyCSEPass::run(Function &F,
|
||||
AnalysisManager<Function> &AM) {
|
||||
if (skipPassForFunction(name(), F))
|
||||
return PreservedAnalyses::all();
|
||||
|
||||
auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
|
||||
auto &TTI = AM.getResult<TargetIRAnalysis>(F);
|
||||
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
|
||||
@ -850,7 +846,7 @@ public:
|
||||
}
|
||||
|
||||
bool runOnFunction(Function &F) override {
|
||||
if (skipFunction(F))
|
||||
if (skipOptnoneFunction(F))
|
||||
return false;
|
||||
|
||||
auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
|
||||
|
@ -516,7 +516,7 @@ void Float2Int::cleanup() {
|
||||
}
|
||||
|
||||
bool Float2Int::runOnFunction(Function &F) {
|
||||
if (skipFunction(F))
|
||||
if (skipOptnoneFunction(F))
|
||||
return false;
|
||||
|
||||
DEBUG(dbgs() << "F2I: Looking at function " << F.getName() << "\n");
|
||||
|
@ -43,7 +43,6 @@
|
||||
#include "llvm/IR/IntrinsicInst.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/Metadata.h"
|
||||
#include "llvm/IR/OptBisect.h"
|
||||
#include "llvm/IR/PatternMatch.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
@ -585,9 +584,6 @@ void GVN::ValueTable::verifyRemoved(const Value *V) const {
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
PreservedAnalyses GVN::run(Function &F, AnalysisManager<Function> &AM) {
|
||||
if (skipPassForFunction(name(), F))
|
||||
return PreservedAnalyses::all();
|
||||
|
||||
// FIXME: The order of evaluation of these 'getResult' calls is very
|
||||
// significant! Re-ordering these variables will cause GVN when run alone to
|
||||
// be less effective! We should fix memdep and basic-aa to not exhibit this
|
||||
@ -2678,7 +2674,7 @@ public:
|
||||
}
|
||||
|
||||
bool runOnFunction(Function &F) override {
|
||||
if (skipFunction(F))
|
||||
if (skipOptnoneFunction(F))
|
||||
return false;
|
||||
|
||||
return Impl.runImpl(
|
||||
|
@ -2122,7 +2122,7 @@ void IndVarSimplify::sinkUnusedInvariants(Loop *L) {
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
|
||||
if (skipLoop(L))
|
||||
if (skipOptnoneFunction(L))
|
||||
return false;
|
||||
|
||||
// If LoopSimplify form is not available, stay out of trouble. Some notes:
|
||||
|
@ -187,7 +187,7 @@ FunctionPass *llvm::createJumpThreadingPass(int Threshold) { return new JumpThre
|
||||
/// runOnFunction - Top level algorithm.
|
||||
///
|
||||
bool JumpThreading::runOnFunction(Function &F) {
|
||||
if (skipFunction(F))
|
||||
if (skipOptnoneFunction(F))
|
||||
return false;
|
||||
|
||||
DEBUG(dbgs() << "Jump threading on function '" << F.getName() << "'\n");
|
||||
|
@ -174,7 +174,7 @@ Pass *llvm::createLICMPass() { return new LICM(); }
|
||||
/// times on one loop.
|
||||
///
|
||||
bool LICM::runOnLoop(Loop *L, LPPassManager &LPM) {
|
||||
if (skipLoop(L))
|
||||
if (skipOptnoneFunction(L))
|
||||
return false;
|
||||
|
||||
Changed = false;
|
||||
|
@ -221,7 +221,7 @@ bool LoadCombine::combineLoads(SmallVectorImpl<LoadPOPPair> &Loads) {
|
||||
}
|
||||
|
||||
bool LoadCombine::runOnBasicBlock(BasicBlock &BB) {
|
||||
if (skipBasicBlock(BB))
|
||||
if (skipOptnoneFunction(BB))
|
||||
return false;
|
||||
|
||||
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
|
||||
|
@ -119,7 +119,7 @@ bool LoopDeletion::isLoopDead(Loop *L,
|
||||
/// NOTE: This entire process relies pretty heavily on LoopSimplify and LCSSA
|
||||
/// in order to make various safety checks work.
|
||||
bool LoopDeletion::runOnLoop(Loop *L, LPPassManager &) {
|
||||
if (skipLoop(L))
|
||||
if (skipOptnoneFunction(L))
|
||||
return false;
|
||||
|
||||
DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
|
@ -169,7 +169,7 @@ static void deleteDeadInstruction(Instruction *I,
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
bool LoopIdiomRecognize::runOnLoop(Loop *L, LPPassManager &LPM) {
|
||||
if (skipLoop(L))
|
||||
if (skipOptnoneFunction(L))
|
||||
return false;
|
||||
|
||||
CurLoop = L;
|
||||
|
@ -65,7 +65,7 @@ Pass *llvm::createLoopInstSimplifyPass() {
|
||||
}
|
||||
|
||||
bool LoopInstSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
|
||||
if (skipLoop(L))
|
||||
if (skipOptnoneFunction(L))
|
||||
return false;
|
||||
|
||||
DominatorTreeWrapperPass *DTWP =
|
||||
|
@ -531,9 +531,6 @@ public:
|
||||
}
|
||||
|
||||
bool runOnFunction(Function &F) override {
|
||||
if (skipFunction(F))
|
||||
return false;
|
||||
|
||||
auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
|
||||
auto *LAA = &getAnalysis<LoopAccessAnalysis>();
|
||||
auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
|
@ -1536,7 +1536,7 @@ bool LoopReroll::reroll(Instruction *IV, Loop *L, BasicBlock *Header,
|
||||
}
|
||||
|
||||
bool LoopReroll::runOnLoop(Loop *L, LPPassManager &LPM) {
|
||||
if (skipLoop(L))
|
||||
if (skipOptnoneFunction(L))
|
||||
return false;
|
||||
|
||||
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
|
||||
|
@ -585,7 +585,7 @@ public:
|
||||
}
|
||||
|
||||
bool runOnLoop(Loop *L, LPPassManager &LPM) override {
|
||||
if (skipLoop(L))
|
||||
if (skipOptnoneFunction(L))
|
||||
return false;
|
||||
Function &F = *L->getHeader()->getParent();
|
||||
|
||||
|
@ -91,7 +91,7 @@ static bool simplifyLoopCFG(Loop *L, DominatorTree *DT, LoopInfo *LI) {
|
||||
/// runOnLoop - Perform basic CFG simplifications to assist other loop passes.
|
||||
/// For now, this only attempts to merge blocks in the trivial case.
|
||||
bool LoopSimplifyCFG::runOnLoop(Loop *L, LPPassManager &) {
|
||||
if (skipLoop(L))
|
||||
if (skipOptnoneFunction(L))
|
||||
return false;
|
||||
|
||||
DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
|
@ -5002,7 +5002,7 @@ void LoopStrengthReduce::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
}
|
||||
|
||||
bool LoopStrengthReduce::runOnLoop(Loop *L, LPPassManager & /*LPM*/) {
|
||||
if (skipLoop(L))
|
||||
if (skipOptnoneFunction(L))
|
||||
return false;
|
||||
|
||||
auto &IU = getAnalysis<IVUsers>();
|
||||
|
@ -787,7 +787,7 @@ public:
|
||||
Optional<bool> ProvidedRuntime;
|
||||
|
||||
bool runOnLoop(Loop *L, LPPassManager &) override {
|
||||
if (skipLoop(L))
|
||||
if (skipOptnoneFunction(L))
|
||||
return false;
|
||||
|
||||
Function &F = *L->getHeader()->getParent();
|
||||
|
@ -420,7 +420,7 @@ static Value *FindLIVLoopCondition(Value *Cond, Loop *L, bool &Changed) {
|
||||
}
|
||||
|
||||
bool LoopUnswitch::runOnLoop(Loop *L, LPPassManager &LPM_Ref) {
|
||||
if (skipLoop(L))
|
||||
if (skipOptnoneFunction(L))
|
||||
return false;
|
||||
|
||||
AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
|
||||
|
@ -531,7 +531,7 @@ void LoopVersioningLICM::setNoAliasToLoop(Loop *VerLoop) {
|
||||
}
|
||||
|
||||
bool LoopVersioningLICM::runOnLoop(Loop *L, LPPassManager &LPM) {
|
||||
if (skipLoop(L))
|
||||
if (skipOptnoneFunction(L))
|
||||
return false;
|
||||
Changed = false;
|
||||
// Get Analysis information.
|
||||
|
@ -116,7 +116,7 @@ namespace {
|
||||
initializeLowerAtomicPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
bool runOnBasicBlock(BasicBlock &BB) override {
|
||||
if (skipBasicBlock(BB))
|
||||
if (skipOptnoneFunction(BB))
|
||||
return false;
|
||||
bool Changed = false;
|
||||
for (BasicBlock::iterator DI = BB.begin(), DE = BB.end(); DI != DE; ) {
|
||||
|
@ -1361,7 +1361,7 @@ bool MemCpyOpt::iterateOnFunction(Function &F) {
|
||||
|
||||
/// This is the main transformation entry point for a function.
|
||||
bool MemCpyOpt::runOnFunction(Function &F) {
|
||||
if (skipFunction(F))
|
||||
if (skipOptnoneFunction(F))
|
||||
return false;
|
||||
|
||||
bool MadeChange = false;
|
||||
|
@ -560,9 +560,6 @@ bool MergedLoadStoreMotion::mergeStores(BasicBlock *T) {
|
||||
/// \brief Run the transformation for each function
|
||||
///
|
||||
bool MergedLoadStoreMotion::runOnFunction(Function &F) {
|
||||
if (skipFunction(F))
|
||||
return false;
|
||||
|
||||
auto *MDWP = getAnalysisIfAvailable<MemoryDependenceWrapperPass>();
|
||||
MD = MDWP ? &MDWP->getMemDep() : nullptr;
|
||||
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
|
||||
|
@ -208,7 +208,7 @@ FunctionPass *llvm::createNaryReassociatePass() {
|
||||
}
|
||||
|
||||
bool NaryReassociate::runOnFunction(Function &F) {
|
||||
if (skipFunction(F))
|
||||
if (skipOptnoneFunction(F))
|
||||
return false;
|
||||
|
||||
AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
||||
|
@ -2257,7 +2257,7 @@ void Reassociate::ReassociateExpression(BinaryOperator *I) {
|
||||
}
|
||||
|
||||
bool Reassociate::runOnFunction(Function &F) {
|
||||
if (skipFunction(F))
|
||||
if (skipOptnoneFunction(F))
|
||||
return false;
|
||||
|
||||
// Reassociate needs for each instruction to have its operands already
|
||||
|
@ -1568,7 +1568,7 @@ FunctionPass *llvm::createSCCPPass() {
|
||||
// and return true if the function was modified.
|
||||
//
|
||||
bool SCCP::runOnFunction(Function &F) {
|
||||
if (skipFunction(F))
|
||||
if (skipOptnoneFunction(F))
|
||||
return false;
|
||||
|
||||
DEBUG(dbgs() << "SCCP on function '" << F.getName() << "'\n");
|
||||
@ -1705,9 +1705,6 @@ static bool AddressIsTaken(const GlobalValue *GV) {
|
||||
}
|
||||
|
||||
bool IPSCCP::runOnModule(Module &M) {
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
const DataLayout &DL = M.getDataLayout();
|
||||
const TargetLibraryInfo *TLI =
|
||||
&getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
|
||||
|
@ -43,7 +43,6 @@
|
||||
#include "llvm/IR/IntrinsicInst.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/Operator.h"
|
||||
#include "llvm/IR/OptBisect.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
@ -4230,9 +4229,6 @@ PreservedAnalyses SROA::runImpl(Function &F, DominatorTree &RunDT,
|
||||
}
|
||||
|
||||
PreservedAnalyses SROA::run(Function &F, AnalysisManager<Function> &AM) {
|
||||
if (skipPassForFunction(name(), F))
|
||||
return PreservedAnalyses::all();
|
||||
|
||||
return runImpl(F, AM.getResult<DominatorTreeAnalysis>(F),
|
||||
AM.getResult<AssumptionAnalysis>(F));
|
||||
}
|
||||
@ -4250,7 +4246,7 @@ public:
|
||||
initializeSROALegacyPassPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
bool runOnFunction(Function &F) override {
|
||||
if (skipFunction(F))
|
||||
if (skipOptnoneFunction(F))
|
||||
return false;
|
||||
|
||||
auto PA = Impl.runImpl(
|
||||
|
@ -1026,7 +1026,7 @@ ConvertScalar_InsertValue(Value *SV, Value *Old,
|
||||
|
||||
|
||||
bool SROA::runOnFunction(Function &F) {
|
||||
if (skipFunction(F))
|
||||
if (skipOptnoneFunction(F))
|
||||
return false;
|
||||
|
||||
bool Changed = performPromotion(F);
|
||||
|
@ -1064,7 +1064,7 @@ bool SeparateConstOffsetFromGEP::splitGEP(GetElementPtrInst *GEP) {
|
||||
}
|
||||
|
||||
bool SeparateConstOffsetFromGEP::runOnFunction(Function &F) {
|
||||
if (skipFunction(F))
|
||||
if (skipOptnoneFunction(F))
|
||||
return false;
|
||||
|
||||
if (DisableSeparateConstOffsetFromGEP)
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/IntrinsicInst.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/OptBisect.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Transforms/Utils/Local.h"
|
||||
@ -188,9 +187,6 @@ SimplifyCFGPass::SimplifyCFGPass(int BonusInstThreshold)
|
||||
|
||||
PreservedAnalyses SimplifyCFGPass::run(Function &F,
|
||||
AnalysisManager<Function> &AM) {
|
||||
if (skipPassForFunction(name(), F))
|
||||
return PreservedAnalyses::all();
|
||||
|
||||
auto &TTI = AM.getResult<TargetIRAnalysis>(F);
|
||||
auto &AC = AM.getResult<AssumptionAnalysis>(F);
|
||||
|
||||
@ -216,7 +212,7 @@ struct CFGSimplifyPass : public FunctionPass {
|
||||
if (PredicateFtor && !PredicateFtor(F))
|
||||
return false;
|
||||
|
||||
if (skipFunction(F))
|
||||
if (skipOptnoneFunction(F))
|
||||
return false;
|
||||
|
||||
AssumptionCache *AC =
|
||||
|
@ -141,7 +141,7 @@ void SpeculativeExecution::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
}
|
||||
|
||||
bool SpeculativeExecution::runOnFunction(Function &F) {
|
||||
if (skipFunction(F))
|
||||
if (skipOptnoneFunction(F))
|
||||
return false;
|
||||
|
||||
TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
|
||||
|
@ -682,7 +682,7 @@ void StraightLineStrengthReduce::rewriteCandidateWithBasis(
|
||||
}
|
||||
|
||||
bool StraightLineStrengthReduce::runOnFunction(Function &F) {
|
||||
if (skipFunction(F))
|
||||
if (skipOptnoneFunction(F))
|
||||
return false;
|
||||
|
||||
TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
|
||||
|
@ -157,7 +157,7 @@ static bool CanTRE(Function &F) {
|
||||
}
|
||||
|
||||
bool TailCallElim::runOnFunction(Function &F) {
|
||||
if (skipFunction(F))
|
||||
if (skipOptnoneFunction(F))
|
||||
return false;
|
||||
|
||||
if (F.getFnAttribute("disable-tail-calls").getValueAsString() == "true")
|
||||
|
@ -59,13 +59,13 @@ INITIALIZE_PASS_END(PromotePass, "mem2reg", "Promote Memory to Register",
|
||||
false, false)
|
||||
|
||||
bool PromotePass::runOnFunction(Function &F) {
|
||||
if (skipFunction(F))
|
||||
return false;
|
||||
|
||||
std::vector<AllocaInst*> Allocas;
|
||||
|
||||
BasicBlock &BB = F.getEntryBlock(); // Get the entry node for the function
|
||||
|
||||
if (F.hasFnAttribute(Attribute::OptimizeNone))
|
||||
return false;
|
||||
|
||||
bool Changed = false;
|
||||
|
||||
DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
|
@ -397,7 +397,7 @@ namespace {
|
||||
Instruction *I, Instruction *J);
|
||||
|
||||
bool vectorizeBB(BasicBlock &BB) {
|
||||
if (skipBasicBlock(BB))
|
||||
if (skipOptnoneFunction(BB))
|
||||
return false;
|
||||
if (!DT->isReachableFromEntry(&BB)) {
|
||||
DEBUG(dbgs() << "BBV: skipping unreachable " << BB.getName() <<
|
||||
|
@ -1707,9 +1707,6 @@ struct LoopVectorize : public FunctionPass {
|
||||
BlockFrequency ColdEntryFreq;
|
||||
|
||||
bool runOnFunction(Function &F) override {
|
||||
if (skipFunction(F))
|
||||
return false;
|
||||
|
||||
SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
|
||||
LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
|
||||
TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
|
||||
|
@ -3396,7 +3396,7 @@ struct SLPVectorizer : public FunctionPass {
|
||||
}
|
||||
|
||||
bool runOnFunction(Function &F) override {
|
||||
if (skipFunction(F))
|
||||
if (skipOptnoneFunction(F))
|
||||
return false;
|
||||
|
||||
SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
|
||||
|
@ -1,39 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import subprocess
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument('--start', type=int, default=0)
|
||||
parser.add_argument('--end', type=int, default=(1 << 32))
|
||||
parser.add_argument('--optcmd', default=("opt"))
|
||||
parser.add_argument('--filecheckcmd', default=("FileCheck"))
|
||||
parser.add_argument('--prefix', default=("CHECK-BISECT"))
|
||||
parser.add_argument('--test', default=(""))
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
start = args.start
|
||||
end = args.end
|
||||
|
||||
opt_command = [args.optcmd, "-O2", "-opt-bisect-limit=%(count)s", "-S", args.test]
|
||||
check_command = [args.filecheckcmd, args.test, "--check-prefix=%s" % args.prefix]
|
||||
last = None
|
||||
while start != end and start != end-1:
|
||||
count = int(round(start + (end - start)/2))
|
||||
cmd = [x % {'count':count} for x in opt_command]
|
||||
print("opt: " + str(cmd))
|
||||
opt_result = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
filecheck_result = subprocess.Popen(check_command, stdin=opt_result.stdout)
|
||||
opt_result.stdout.close()
|
||||
opt_result.stderr.close()
|
||||
filecheck_result.wait()
|
||||
if filecheck_result.returncode == 0:
|
||||
start = count
|
||||
else:
|
||||
end = count
|
||||
|
||||
print("Last good count: %d" % start)
|
@ -1,148 +0,0 @@
|
||||
; This file verifies the behavior of the OptBisect class, which is used to
|
||||
; diagnose optimization related failures. The tests check various
|
||||
; invocations that result in different sets of optimization passes that
|
||||
; are run in different ways.
|
||||
;
|
||||
; This set of tests exercises the legacy pass manager interface to the OptBisect
|
||||
; class. Because the exact set of optimizations that will be run may
|
||||
; change over time, these tests are written in a more general manner than the
|
||||
; corresponding tests for the new pass manager.
|
||||
;
|
||||
; Don't use NEXT checks or hard-code pass numbering so that this won't fail if
|
||||
; new passes are inserted.
|
||||
|
||||
|
||||
; Verify that the file can be compiled to an object file at -O3 with all
|
||||
; skippable passes skipped.
|
||||
|
||||
; RUN: opt -O3 -opt-bisect-limit=0 < %s | llc -O3 -opt-bisect-limit=0
|
||||
|
||||
|
||||
; Verify that no skippable passes are run with -opt-bisect-limit=0.
|
||||
|
||||
; RUN: opt -disable-output -disable-verify -O3 -opt-bisect-limit=0 %s 2>&1 \
|
||||
; RUN: | FileCheck %s --check-prefix=CHECK-SKIP-ALL
|
||||
; CHECK-SKIP-ALL: BISECT: NOT running pass ({{[0-9]+}})
|
||||
; CHECK-SKIP-ALL-NOT: BISECT: running pass ({{[0-9]+}})
|
||||
|
||||
|
||||
; Verify that we can use the opt-bisect-helper.py script (derived from
|
||||
; utils/bisect) to locate the optimization that inlines the call to
|
||||
; f2() in f3().
|
||||
|
||||
; RUN: %python %S/opt-bisect-helper.py --start=0 --end=256 --optcmd=opt \
|
||||
; RUN: --filecheckcmd=FileCheck --test=%s \
|
||||
; RUN: --prefix=CHECK-BISECT-INLINE-HELPER \
|
||||
; RUN: | FileCheck %s --check-prefix=CHECK-BISECT-INLINE-RESULT
|
||||
; The helper script uses this to find the optimization that inlines the call.
|
||||
; CHECK-BISECT-INLINE-HELPER: call i32 @f2()
|
||||
; These checks verifies that the optimization was found.
|
||||
; CHECK-BISECT-INLINE-RESULT-NOT: Last good count: 0
|
||||
; CHECK-BISECT-INLINE-RESULT: Last good count: {{[0-9]+}}
|
||||
|
||||
|
||||
; Test a module pass.
|
||||
|
||||
; RUN: opt -disable-output -disable-verify -deadargelim -opt-bisect-limit=-1 %s \
|
||||
; RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-DEADARG
|
||||
; CHECK-DEADARG: BISECT: running pass ({{[0-9]+}}) Dead Argument Elimination on module
|
||||
|
||||
; RUN: opt -disable-output -disable-verify -deadargelim -opt-bisect-limit=0 %s \
|
||||
; RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-NOT-DEADARG
|
||||
; CHECK-NOT-DEADARG: BISECT: NOT running pass ({{[0-9]+}}) Dead Argument Elimination on module
|
||||
|
||||
|
||||
; Test an SCC pass.
|
||||
|
||||
; RUN: opt -disable-output -disable-verify -inline -opt-bisect-limit=-1 %s \
|
||||
; RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-INLINE
|
||||
; CHECK-INLINE: BISECT: running pass ({{[0-9]+}}) Function Integration/Inlining on SCC (<<null function>>)
|
||||
; CHECK-INLINE: BISECT: running pass ({{[0-9]+}}) Function Integration/Inlining on SCC (g)
|
||||
; CHECK-INLINE: BISECT: running pass ({{[0-9]+}}) Function Integration/Inlining on SCC (f1)
|
||||
; CHECK-INLINE: BISECT: running pass ({{[0-9]+}}) Function Integration/Inlining on SCC (f2)
|
||||
; CHECK-INLINE: BISECT: running pass ({{[0-9]+}}) Function Integration/Inlining on SCC (f3)
|
||||
; CHECK-INLINE: BISECT: running pass ({{[0-9]+}}) Function Integration/Inlining on SCC (<<null function>>)
|
||||
|
||||
; RUN: opt -disable-output -disable-verify -inline -opt-bisect-limit=0 %s \
|
||||
; RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-NOT-INLINE
|
||||
; CHECK-NOT-INLINE: BISECT: NOT running pass ({{[0-9]+}}) Function Integration/Inlining on SCC (<<null function>>)
|
||||
; CHECK-NOT-INLINE: BISECT: NOT running pass ({{[0-9]+}}) Function Integration/Inlining on SCC (g)
|
||||
; CHECK-NOT-INLINE: BISECT: NOT running pass ({{[0-9]+}}) Function Integration/Inlining on SCC (f1)
|
||||
; CHECK-NOT-INLINE: BISECT: NOT running pass ({{[0-9]+}}) Function Integration/Inlining on SCC (f2)
|
||||
; CHECK-NOT-INLINE: BISECT: NOT running pass ({{[0-9]+}}) Function Integration/Inlining on SCC (f3)
|
||||
; CHECK-NOT-INLINE: BISECT: NOT running pass ({{[0-9]+}}) Function Integration/Inlining on SCC (<<null function>>)
|
||||
|
||||
|
||||
; Test a function pass.
|
||||
|
||||
; RUN: opt -disable-output -disable-verify -early-cse -opt-bisect-limit=-1 \
|
||||
; RUN: %s 2>&1 | FileCheck %s --check-prefix=CHECK-EARLY-CSE
|
||||
; CHECK-EARLY-CSE: BISECT: running pass ({{[0-9]+}}) Early CSE on function (f1)
|
||||
; CHECK-EARLY-CSE: BISECT: running pass ({{[0-9]+}}) Early CSE on function (f2)
|
||||
; CHECK-EARLY-CSE: BISECT: running pass ({{[0-9]+}}) Early CSE on function (f3)
|
||||
|
||||
; RUN: opt -disable-output -disable-verify -early-cse -opt-bisect-limit=0 %s \
|
||||
; RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-NOT-EARLY-CSE
|
||||
; CHECK-NOT-EARLY-CSE: BISECT: NOT running pass ({{[0-9]+}}) Early CSE on function (f1)
|
||||
; CHECK-NOT-EARLY-CSE: BISECT: NOT running pass ({{[0-9]+}}) Early CSE on function (f2)
|
||||
; CHECK-NOT-EARLY-CSE: BISECT: NOT running pass ({{[0-9]+}}) Early CSE on function (f3)
|
||||
|
||||
|
||||
; Test a loop pass.
|
||||
|
||||
; RUN: opt -disable-output -disable-verify -loop-reduce -opt-bisect-limit=-1 \
|
||||
; RUN: %s 2>&1 | FileCheck %s --check-prefix=CHECK-LOOP-REDUCE
|
||||
; CHECK-LOOP-REDUCE: BISECT: running pass ({{[0-9]+}}) Loop Strength Reduction on loop
|
||||
; CHECK-LOOP-REDUCE: BISECT: running pass ({{[0-9]+}}) Loop Strength Reduction on loop
|
||||
; CHECK-LOOP-REDUCE: BISECT: running pass ({{[0-9]+}}) Loop Strength Reduction on loop
|
||||
; CHECK-LOOP-REDUCE: BISECT: running pass ({{[0-9]+}}) Loop Strength Reduction on loop
|
||||
; CHECK-LOOP-REDUCE: BISECT: running pass ({{[0-9]+}}) Loop Strength Reduction on loop
|
||||
|
||||
; RUN: opt -disable-output -disable-verify -loop-reduce -opt-bisect-limit=0 \
|
||||
; RUN: %s 2>&1 | FileCheck %s --check-prefix=CHECK-NOT-LOOP-REDUCE
|
||||
; CHECK-NOT-LOOP-REDUCE: BISECT: NOT running pass ({{[0-9]+}}) Loop Strength Reduction on loop
|
||||
; CHECK-NOT-LOOP-REDUCE: BISECT: NOT running pass ({{[0-9]+}}) Loop Strength Reduction on loop
|
||||
; CHECK-NOT-LOOP-REDUCE: BISECT: NOT running pass ({{[0-9]+}}) Loop Strength Reduction on loop
|
||||
; CHECK-NOT-LOOP-REDUCE: BISECT: NOT running pass ({{[0-9]+}}) Loop Strength Reduction on loop
|
||||
; CHECK-NOT-LOOP-REDUCE: BISECT: NOT running pass ({{[0-9]+}}) Loop Strength Reduction on loop
|
||||
|
||||
|
||||
declare i32 @g()
|
||||
|
||||
define void @f1() {
|
||||
entry:
|
||||
br label %loop.0
|
||||
loop.0:
|
||||
br i1 undef, label %loop.0.0, label %loop.1
|
||||
loop.0.0:
|
||||
br i1 undef, label %loop.0.0, label %loop.0.1
|
||||
loop.0.1:
|
||||
br i1 undef, label %loop.0.1, label %loop.0
|
||||
loop.1:
|
||||
br i1 undef, label %loop.1, label %loop.1.bb1
|
||||
loop.1.bb1:
|
||||
br i1 undef, label %loop.1, label %loop.1.bb2
|
||||
loop.1.bb2:
|
||||
br i1 undef, label %end, label %loop.1.0
|
||||
loop.1.0:
|
||||
br i1 undef, label %loop.1.0, label %loop.1
|
||||
end:
|
||||
ret void
|
||||
}
|
||||
|
||||
define i32 @f2() {
|
||||
entry:
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
define i32 @f3() {
|
||||
entry:
|
||||
%temp = call i32 @g()
|
||||
%icmp = icmp ugt i32 %temp, 2
|
||||
br i1 %icmp, label %bb.true, label %bb.false
|
||||
bb.true:
|
||||
%temp2 = call i32 @f2()
|
||||
ret i32 %temp2
|
||||
bb.false:
|
||||
ret i32 0
|
||||
}
|
@ -1,109 +0,0 @@
|
||||
; This file verifies the behavior of the OptBisect class, which is used to
|
||||
; diagnose optimization related failures. The tests check various
|
||||
; invocations that result in different sets of optimization passes that
|
||||
; are run in different ways.
|
||||
;
|
||||
; Because the exact set of optimizations that will be run is expected to
|
||||
; change over time, the checks for disabling passes are written in a
|
||||
; conservative way that avoids assumptions about which specific passes
|
||||
; will be disabled.
|
||||
|
||||
; RUN: opt -disable-output -disable-verify \
|
||||
; RUN: -passes=inferattrs -opt-bisect-limit=-1 %s 2>&1 \
|
||||
; RUN: | FileCheck %s --check-prefix=CHECK-MODULE-PASS
|
||||
; CHECK-MODULE-PASS: BISECT: running pass (1) InferFunctionAttrsPass on module
|
||||
|
||||
; RUN: opt -disable-output -disable-verify \
|
||||
; RUN: -passes=inferattrs -opt-bisect-limit=0 %s 2>&1 \
|
||||
; RUN: | FileCheck %s --check-prefix=CHECK-LIMIT-MODULE-PASS
|
||||
; CHECK-LIMIT-MODULE-PASS: BISECT: NOT running pass (1) InferFunctionAttrsPass on module
|
||||
|
||||
; RUN: opt -disable-output -disable-verify \
|
||||
; RUN: -passes=early-cse -opt-bisect-limit=-1 %s 2>&1 \
|
||||
; RUN: | FileCheck %s --check-prefix=CHECK-FUNCTION-PASS
|
||||
; CHECK-FUNCTION-PASS: BISECT: running pass (1) EarlyCSEPass on function (f1)
|
||||
; CHECK-FUNCTION-PASS: BISECT: running pass (2) EarlyCSEPass on function (f2)
|
||||
; CHECK-FUNCTION-PASS: BISECT: running pass (3) EarlyCSEPass on function (f3)
|
||||
|
||||
; RUN: opt -disable-output -disable-verify \
|
||||
; RUN: -passes=early-cse -opt-bisect-limit=2 %s 2>&1 \
|
||||
; RUN: | FileCheck %s --check-prefix=CHECK-LIMIT-FUNCTION-PASS
|
||||
; CHECK-LIMIT-FUNCTION-PASS: BISECT: running pass (1) EarlyCSEPass on function (f1)
|
||||
; CHECK-LIMIT-FUNCTION-PASS: BISECT: running pass (2) EarlyCSEPass on function (f2)
|
||||
; CHECK-LIMIT-FUNCTION-PASS: BISECT: NOT running pass (3) EarlyCSEPass on function (f3)
|
||||
|
||||
; RUN: opt -disable-output -disable-verify \
|
||||
; RUN: -passes=function-attrs -opt-bisect-limit=-1 %s 2>&1 \
|
||||
; RUN: | FileCheck %s --check-prefix=CHECK-CGSCC-PASS
|
||||
; CHECK-CGSCC-PASS: BISECT: running pass (1) PostOrderFunctionAttrsPass on SCC (f2)
|
||||
; CHECK-CGSCC-PASS: BISECT: running pass (2) PostOrderFunctionAttrsPass on SCC (f3)
|
||||
; CHECK-CGSCC-PASS: BISECT: running pass (3) PostOrderFunctionAttrsPass on SCC (f1)
|
||||
|
||||
; RUN: opt -disable-output -disable-verify \
|
||||
; RUN: -passes=function-attrs -opt-bisect-limit=2 %s 2>&1 \
|
||||
; RUN: | FileCheck %s --check-prefix=CHECK-LIMIT-CGSCC-PASS
|
||||
; CHECK-LIMIT-CGSCC-PASS: BISECT: running pass (1) PostOrderFunctionAttrsPass on SCC (f2)
|
||||
; CHECK-LIMIT-CGSCC-PASS: BISECT: running pass (2) PostOrderFunctionAttrsPass on SCC (f3)
|
||||
; CHECK-LIMIT-CGSCC-PASS: BISECT: NOT running pass (3) PostOrderFunctionAttrsPass on SCC (f1)
|
||||
|
||||
; RUN: opt -disable-output -disable-verify -opt-bisect-limit=-1 \
|
||||
; RUN: -passes='inferattrs,cgscc(function-attrs,function(early-cse))' %s 2>&1 \
|
||||
; RUN: | FileCheck %s --check-prefix=CHECK-MULTI-PASS
|
||||
; CHECK-MULTI-PASS: BISECT: running pass (1) InferFunctionAttrsPass on module
|
||||
; CHECK-MULTI-PASS: BISECT: running pass (2) PostOrderFunctionAttrsPass on SCC (f2)
|
||||
; CHECK-MULTI-PASS: BISECT: running pass (3) EarlyCSEPass on function (f2)
|
||||
; CHECK-MULTI-PASS: BISECT: running pass (4) PostOrderFunctionAttrsPass on SCC (f3)
|
||||
; CHECK-MULTI-PASS: BISECT: running pass (5) EarlyCSEPass on function (f3)
|
||||
; CHECK-MULTI-PASS: BISECT: running pass (6) PostOrderFunctionAttrsPass on SCC (f1)
|
||||
; CHECK-MULTI-PASS: BISECT: running pass (7) EarlyCSEPass on function (f1)
|
||||
|
||||
; RUN: opt -disable-output -disable-verify -opt-bisect-limit=5 \
|
||||
; RUN: -passes='inferattrs,cgscc(function-attrs,function(early-cse))' %s 2>&1 \
|
||||
; RUN: | FileCheck %s --check-prefix=CHECK-LIMIT-MULTI-PASS
|
||||
; CHECK-LIMIT-MULTI-PASS: BISECT: running pass (1) InferFunctionAttrsPass on module
|
||||
; CHECK-LIMIT-MULTI-PASS: BISECT: running pass (2) PostOrderFunctionAttrsPass on SCC (f2)
|
||||
; CHECK-LIMIT-MULTI-PASS: BISECT: running pass (3) EarlyCSEPass on function (f2)
|
||||
; CHECK-LIMIT-MULTI-PASS: BISECT: running pass (4) PostOrderFunctionAttrsPass on SCC (f3)
|
||||
; CHECK-LIMIT-MULTI-PASS: BISECT: running pass (5) EarlyCSEPass on function (f3)
|
||||
; CHECK-LIMIT-MULTI-PASS: BISECT: NOT running pass (6) PostOrderFunctionAttrsPass on SCC (f1)
|
||||
; CHECK-LIMIT-MULTI-PASS: BISECT: NOT running pass (7) EarlyCSEPass on function (f1)
|
||||
|
||||
declare i32 @g()
|
||||
|
||||
define void @f1() {
|
||||
entry:
|
||||
br label %loop.0
|
||||
loop.0:
|
||||
br i1 undef, label %loop.0.0, label %loop.1
|
||||
loop.0.0:
|
||||
br i1 undef, label %loop.0.0, label %loop.0.1
|
||||
loop.0.1:
|
||||
br i1 undef, label %loop.0.1, label %loop.0
|
||||
loop.1:
|
||||
br i1 undef, label %loop.1, label %loop.1.bb1
|
||||
loop.1.bb1:
|
||||
br i1 undef, label %loop.1, label %loop.1.bb2
|
||||
loop.1.bb2:
|
||||
br i1 undef, label %end, label %loop.1.0
|
||||
loop.1.0:
|
||||
br i1 undef, label %loop.1.0, label %loop.1
|
||||
end:
|
||||
ret void
|
||||
}
|
||||
|
||||
define i32 @f2() {
|
||||
entry:
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
define i32 @f3() {
|
||||
entry:
|
||||
%temp = call i32 @g()
|
||||
%icmp = icmp ugt i32 %temp, 2
|
||||
br i1 %icmp, label %bb.true, label %bb.false
|
||||
bb.true:
|
||||
%temp2 = call i32 @f2()
|
||||
ret i32 %temp2
|
||||
bb.false:
|
||||
ret i32 0
|
||||
}
|
Loading…
Reference in New Issue
Block a user