mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-12 15:51:35 +00:00
[TargetPassConfig] Feature generic options to setup start/stop-after/before
This patch refactors the code used in llc such that all the users of the addPassesToEmitFile API have access to a homogeneous way of handling start/stop-after/before options right out of the box. In particular, just invoking addPassesToEmitFile will set the proper pipeline without additional effort (modulo parsing a .mir file if the start-before/after options are used. NFC. Differential Revision: https://reviews.llvm.org/D30913 llvm-svn: 309599
This commit is contained in:
parent
222d912f69
commit
6d5f774fb6
@ -108,6 +108,18 @@ private:
|
||||
bool Stopped = false;
|
||||
bool AddingMachinePasses = false;
|
||||
|
||||
/// Set the StartAfter, StartBefore and StopAfter passes to allow running only
|
||||
/// a portion of the normal code-gen pass sequence.
|
||||
///
|
||||
/// If the StartAfter and StartBefore pass ID is zero, then compilation will
|
||||
/// begin at the normal point; otherwise, clear the Started flag to indicate
|
||||
/// that passes should not be added until the starting pass is seen. If the
|
||||
/// Stop pass ID is zero, then compilation will continue to the end.
|
||||
///
|
||||
/// This function expects that at least one of the StartAfter or the
|
||||
/// StartBefore pass IDs is null.
|
||||
void setStartStopPasses();
|
||||
|
||||
protected:
|
||||
LLVMTargetMachine *TM;
|
||||
PassConfigImpl *Impl = nullptr; // Internal data structures
|
||||
@ -147,27 +159,25 @@ public:
|
||||
|
||||
CodeGenOpt::Level getOptLevel() const;
|
||||
|
||||
/// Set the StartAfter, StartBefore and StopAfter passes to allow running only
|
||||
/// a portion of the normal code-gen pass sequence.
|
||||
///
|
||||
/// If the StartAfter and StartBefore pass ID is zero, then compilation will
|
||||
/// begin at the normal point; otherwise, clear the Started flag to indicate
|
||||
/// that passes should not be added until the starting pass is seen. If the
|
||||
/// Stop pass ID is zero, then compilation will continue to the end.
|
||||
///
|
||||
/// This function expects that at least one of the StartAfter or the
|
||||
/// StartBefore pass IDs is null.
|
||||
void setStartStopPasses(AnalysisID StartBefore, AnalysisID StartAfter,
|
||||
AnalysisID StopBefore, AnalysisID StopAfter) {
|
||||
assert(!(StartBefore && StartAfter) &&
|
||||
"Start after and start before passes are given");
|
||||
assert(!(StopBefore && StopAfter) &&
|
||||
"Stop after and stop before passed are given");
|
||||
this->StartBefore = StartBefore;
|
||||
this->StartAfter = StartAfter;
|
||||
this->StopBefore = StopBefore;
|
||||
this->StopAfter = StopAfter;
|
||||
Started = (StartAfter == nullptr) && (StartBefore == nullptr);
|
||||
/// Describe the status of the codegen
|
||||
/// pipeline set by this target pass config.
|
||||
/// Having a limited codegen pipeline means that options
|
||||
/// have been used to restrict what codegen is doing.
|
||||
/// In particular, that means that codegen won't emit
|
||||
/// assembly code.
|
||||
bool hasLimitedCodeGenPipeline() const;
|
||||
|
||||
/// If hasLimitedCodeGenPipeline is true, this method
|
||||
/// returns a string with the name of the options, separated
|
||||
/// by \p Separator that caused this pipeline to be limited.
|
||||
std::string
|
||||
getLimitedCodeGenPipelineReason(const char *Separator = "/") const;
|
||||
|
||||
/// Check if the codegen pipeline is limited in such a way that it
|
||||
/// won't be complete. When the codegen pipeline is not complete,
|
||||
/// this means it may not be possible to generate assembly from it.
|
||||
bool willCompleteCodeGenPipeline() const {
|
||||
return !hasLimitedCodeGenPipeline() || (!StopAfter && !StopBefore);
|
||||
}
|
||||
|
||||
void setDisableVerify(bool Disable) { setOpt(DisableVerify, Disable); }
|
||||
|
@ -25,6 +25,7 @@
|
||||
namespace llvm {
|
||||
|
||||
class GlobalValue;
|
||||
class MachineModuleInfo;
|
||||
class Mangler;
|
||||
class MCAsmInfo;
|
||||
class MCContext;
|
||||
@ -222,11 +223,12 @@ public:
|
||||
/// emitted. Typically this will involve several steps of code generation.
|
||||
/// This method should return true if emission of this file type is not
|
||||
/// supported, or false on success.
|
||||
virtual bool addPassesToEmitFile(
|
||||
PassManagerBase &, raw_pwrite_stream &, CodeGenFileType,
|
||||
bool /*DisableVerify*/ = true, AnalysisID /*StartBefore*/ = nullptr,
|
||||
AnalysisID /*StartAfter*/ = nullptr, AnalysisID /*StopBefore*/ = nullptr,
|
||||
AnalysisID /*StopAfter*/ = nullptr) {
|
||||
/// \p MMI is an optional parameter that, if set to non-nullptr,
|
||||
/// will be used to set the MachineModuloInfo for this PM.
|
||||
virtual bool addPassesToEmitFile(PassManagerBase &, raw_pwrite_stream &,
|
||||
CodeGenFileType,
|
||||
bool /*DisableVerify*/ = true,
|
||||
MachineModuleInfo *MMI = nullptr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -270,6 +272,7 @@ protected: // Can only create subclasses.
|
||||
CodeModel::Model CM, CodeGenOpt::Level OL);
|
||||
|
||||
void initAsmInfo();
|
||||
|
||||
public:
|
||||
/// \brief Get a TargetIRAnalysis implementation for the target.
|
||||
///
|
||||
@ -283,11 +286,11 @@ public:
|
||||
|
||||
/// Add passes to the specified pass manager to get the specified file
|
||||
/// emitted. Typically this will involve several steps of code generation.
|
||||
bool addPassesToEmitFile(
|
||||
PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType,
|
||||
bool DisableVerify = true, AnalysisID StartBefore = nullptr,
|
||||
AnalysisID StartAfter = nullptr, AnalysisID StopBefore = nullptr,
|
||||
AnalysisID StopAfter = nullptr) override;
|
||||
/// \p MMI is an optional parameter that, if set to non-nullptr,
|
||||
/// will be used to set the MachineModuloInfofor this PM.
|
||||
bool addPassesToEmitFile(PassManagerBase &PM, raw_pwrite_stream &Out,
|
||||
CodeGenFileType FileType, bool DisableVerify = true,
|
||||
MachineModuleInfo *MMI = nullptr) override;
|
||||
|
||||
/// Add passes to the specified pass manager to get machine code emitted with
|
||||
/// the MCJIT. This method returns true if machine code is not supported. It
|
||||
|
@ -92,24 +92,25 @@ TargetIRAnalysis LLVMTargetMachine::getTargetIRAnalysis() {
|
||||
/// addPassesToX helper drives creation and initialization of TargetPassConfig.
|
||||
static MCContext *
|
||||
addPassesToGenerateCode(LLVMTargetMachine *TM, PassManagerBase &PM,
|
||||
bool DisableVerify, AnalysisID StartBefore,
|
||||
AnalysisID StartAfter, AnalysisID StopBefore,
|
||||
AnalysisID StopAfter) {
|
||||
bool DisableVerify, bool &WillCompleteCodeGenPipeline,
|
||||
raw_pwrite_stream &Out, MachineModuleInfo *MMI) {
|
||||
// Targets may override createPassConfig to provide a target-specific
|
||||
// subclass.
|
||||
TargetPassConfig *PassConfig = TM->createPassConfig(PM);
|
||||
PassConfig->setStartStopPasses(StartBefore, StartAfter, StopBefore,
|
||||
StopAfter);
|
||||
// Set PassConfig options provided by TargetMachine.
|
||||
PassConfig->setDisableVerify(DisableVerify);
|
||||
WillCompleteCodeGenPipeline = PassConfig->willCompleteCodeGenPipeline();
|
||||
PM.add(PassConfig);
|
||||
MachineModuleInfo *MMI = new MachineModuleInfo(TM);
|
||||
if (!MMI)
|
||||
MMI = new MachineModuleInfo(TM);
|
||||
PM.add(MMI);
|
||||
|
||||
if (PassConfig->addISelPasses())
|
||||
return nullptr;
|
||||
PassConfig->addMachinePasses();
|
||||
PassConfig->setInitialized();
|
||||
if (!WillCompleteCodeGenPipeline)
|
||||
PM.add(createPrintMIRPass(Out));
|
||||
|
||||
return &MMI->getContext();
|
||||
}
|
||||
@ -185,23 +186,20 @@ bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LLVMTargetMachine::addPassesToEmitFile(
|
||||
PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType,
|
||||
bool DisableVerify, AnalysisID StartBefore, AnalysisID StartAfter,
|
||||
AnalysisID StopBefore, AnalysisID StopAfter) {
|
||||
bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
|
||||
raw_pwrite_stream &Out,
|
||||
CodeGenFileType FileType,
|
||||
bool DisableVerify,
|
||||
MachineModuleInfo *MMI) {
|
||||
// Add common CodeGen passes.
|
||||
MCContext *Context =
|
||||
addPassesToGenerateCode(this, PM, DisableVerify, StartBefore, StartAfter,
|
||||
StopBefore, StopAfter);
|
||||
bool WillCompleteCodeGenPipeline = true;
|
||||
MCContext *Context = addPassesToGenerateCode(
|
||||
this, PM, DisableVerify, WillCompleteCodeGenPipeline, Out, MMI);
|
||||
if (!Context)
|
||||
return true;
|
||||
|
||||
if (StopBefore || StopAfter) {
|
||||
PM.add(createPrintMIRPass(Out));
|
||||
} else {
|
||||
if (addAsmPrinter(PM, Out, FileType, *Context))
|
||||
return true;
|
||||
}
|
||||
if (WillCompleteCodeGenPipeline && addAsmPrinter(PM, Out, FileType, *Context))
|
||||
return true;
|
||||
|
||||
PM.add(createFreeMachineFunctionPass());
|
||||
return false;
|
||||
@ -216,10 +214,13 @@ bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx,
|
||||
raw_pwrite_stream &Out,
|
||||
bool DisableVerify) {
|
||||
// Add common CodeGen passes.
|
||||
Ctx = addPassesToGenerateCode(this, PM, DisableVerify, nullptr, nullptr,
|
||||
nullptr, nullptr);
|
||||
bool WillCompleteCodeGenPipeline = true;
|
||||
Ctx = addPassesToGenerateCode(this, PM, DisableVerify,
|
||||
WillCompleteCodeGenPipeline, Out,
|
||||
/*MachineModuleInfo*/ nullptr);
|
||||
if (!Ctx)
|
||||
return true;
|
||||
assert(WillCompleteCodeGenPipeline && "CodeGen pipeline has been altered");
|
||||
|
||||
if (Options.MCOptions.MCSaveTempLabels)
|
||||
Ctx->setAllowTemporaryLabels(false);
|
||||
|
@ -153,6 +153,34 @@ static cl::opt<CFLAAType> UseCFLAA(
|
||||
clEnumValN(CFLAAType::Both, "both",
|
||||
"Enable both variants of CFL-AA")));
|
||||
|
||||
/// Option names for limiting the codegen pipeline.
|
||||
/// Those are used in error reporting and we didn't want
|
||||
/// to duplicate their names all over the place.
|
||||
const char *StartAfterOptName = "start-after";
|
||||
const char *StartBeforeOptName = "start-before";
|
||||
const char *StopAfterOptName = "stop-after";
|
||||
const char *StopBeforeOptName = "stop-before";
|
||||
|
||||
static cl::opt<std::string>
|
||||
StartAfterOpt(StringRef(StartAfterOptName),
|
||||
cl::desc("Resume compilation after a specific pass"),
|
||||
cl::value_desc("pass-name"), cl::init(""));
|
||||
|
||||
static cl::opt<std::string>
|
||||
StartBeforeOpt(StringRef(StartBeforeOptName),
|
||||
cl::desc("Resume compilation before a specific pass"),
|
||||
cl::value_desc("pass-name"), cl::init(""));
|
||||
|
||||
static cl::opt<std::string>
|
||||
StopAfterOpt(StringRef(StopAfterOptName),
|
||||
cl::desc("Stop compilation after a specific pass"),
|
||||
cl::value_desc("pass-name"), cl::init(""));
|
||||
|
||||
static cl::opt<std::string>
|
||||
StopBeforeOpt(StringRef(StopBeforeOptName),
|
||||
cl::desc("Stop compilation before a specific pass"),
|
||||
cl::value_desc("pass-name"), cl::init(""));
|
||||
|
||||
/// Allow standard passes to be disabled by command line options. This supports
|
||||
/// simple binary flags that either suppress the pass or do nothing.
|
||||
/// i.e. -disable-mypass=false has no effect.
|
||||
@ -282,6 +310,37 @@ TargetPassConfig::~TargetPassConfig() {
|
||||
delete Impl;
|
||||
}
|
||||
|
||||
static const PassInfo *getPassInfo(StringRef PassName) {
|
||||
if (PassName.empty())
|
||||
return nullptr;
|
||||
|
||||
const PassRegistry &PR = *PassRegistry::getPassRegistry();
|
||||
const PassInfo *PI = PR.getPassInfo(PassName);
|
||||
if (!PI)
|
||||
report_fatal_error(Twine('\"') + Twine(PassName) +
|
||||
Twine("\" pass is not registered."));
|
||||
return PI;
|
||||
}
|
||||
|
||||
static AnalysisID getPassIDFromName(StringRef PassName) {
|
||||
const PassInfo *PI = getPassInfo(PassName);
|
||||
return PI ? PI->getTypeInfo() : nullptr;
|
||||
}
|
||||
|
||||
void TargetPassConfig::setStartStopPasses() {
|
||||
StartBefore = getPassIDFromName(StartBeforeOpt);
|
||||
StartAfter = getPassIDFromName(StartAfterOpt);
|
||||
StopBefore = getPassIDFromName(StopBeforeOpt);
|
||||
StopAfter = getPassIDFromName(StopAfterOpt);
|
||||
if (StartBefore && StartAfter)
|
||||
report_fatal_error(Twine(StartBeforeOptName) + Twine(" and ") +
|
||||
Twine(StartAfterOptName) + Twine(" specified!"));
|
||||
if (StopBefore && StopAfter)
|
||||
report_fatal_error(Twine(StopBeforeOptName) + Twine(" and ") +
|
||||
Twine(StopAfterOptName) + Twine(" specified!"));
|
||||
Started = (StartAfter == nullptr) && (StartBefore == nullptr);
|
||||
}
|
||||
|
||||
// Out of line constructor provides default values for pass options and
|
||||
// registers all common codegen passes.
|
||||
TargetPassConfig::TargetPassConfig(LLVMTargetMachine &TM, PassManagerBase &pm)
|
||||
@ -305,6 +364,8 @@ TargetPassConfig::TargetPassConfig(LLVMTargetMachine &TM, PassManagerBase &pm)
|
||||
|
||||
if (TM.Options.EnableIPRA)
|
||||
setRequiresCodeGenSCCOrder();
|
||||
|
||||
setStartStopPasses();
|
||||
}
|
||||
|
||||
CodeGenOpt::Level TargetPassConfig::getOptLevel() const {
|
||||
@ -339,6 +400,30 @@ TargetPassConfig::TargetPassConfig()
|
||||
"triple set?");
|
||||
}
|
||||
|
||||
bool TargetPassConfig::hasLimitedCodeGenPipeline() const {
|
||||
return StartBefore || StartAfter || StopBefore || StopAfter;
|
||||
}
|
||||
|
||||
std::string
|
||||
TargetPassConfig::getLimitedCodeGenPipelineReason(const char *Separator) const {
|
||||
if (!hasLimitedCodeGenPipeline())
|
||||
return std::string();
|
||||
std::string Res;
|
||||
static cl::opt<std::string> *PassNames[] = {&StartAfterOpt, &StartBeforeOpt,
|
||||
&StopAfterOpt, &StopBeforeOpt};
|
||||
static const char *OptNames[] = {StartAfterOptName, StartBeforeOptName,
|
||||
StopAfterOptName, StopBeforeOptName};
|
||||
bool IsFirst = true;
|
||||
for (int Idx = 0; Idx < 4; ++Idx)
|
||||
if (!PassNames[Idx]->empty()) {
|
||||
if (!IsFirst)
|
||||
Res += Separator;
|
||||
IsFirst = false;
|
||||
Res += OptNames[Idx];
|
||||
}
|
||||
return Res;
|
||||
}
|
||||
|
||||
// Helper to verify the analysis is really immutable.
|
||||
void TargetPassConfig::setOpt(bool &Opt, bool Val) {
|
||||
assert(!Initialized && "PassConfig is immutable");
|
||||
|
@ -27,12 +27,12 @@
|
||||
; RUN: not llc < %s -stop-before=nonexistent -o /dev/null 2>&1 | FileCheck %s -check-prefix=NONEXISTENT-STOP-BEFORE
|
||||
; RUN: not llc < %s -start-after=nonexistent -o /dev/null 2>&1 | FileCheck %s -check-prefix=NONEXISTENT-START-AFTER
|
||||
; RUN: not llc < %s -stop-after=nonexistent -o /dev/null 2>&1 | FileCheck %s -check-prefix=NONEXISTENT-STOP-AFTER
|
||||
; NONEXISTENT-START-BEFORE: start-before pass is not registered.
|
||||
; NONEXISTENT-STOP-BEFORE: stop-before pass is not registered.
|
||||
; NONEXISTENT-START-AFTER: start-after pass is not registered.
|
||||
; NONEXISTENT-STOP-AFTER: stop-after pass is not registered.
|
||||
; NONEXISTENT-START-BEFORE: "nonexistent" pass is not registered.
|
||||
; NONEXISTENT-STOP-BEFORE: "nonexistent" pass is not registered.
|
||||
; NONEXISTENT-START-AFTER: "nonexistent" pass is not registered.
|
||||
; NONEXISTENT-STOP-AFTER: "nonexistent" pass is not registered.
|
||||
|
||||
; RUN: not llc < %s -start-before=loop-reduce -start-after=loop-reduce -o /dev/null 2>&1 | FileCheck %s -check-prefix=DOUBLE-START
|
||||
; RUN: not llc < %s -stop-before=loop-reduce -stop-after=loop-reduce -o /dev/null 2>&1 | FileCheck %s -check-prefix=DOUBLE-STOP
|
||||
; DOUBLE-START: -start-before and -start-after specified!
|
||||
; DOUBLE-STOP: -stop-before and -stop-after specified!
|
||||
; DOUBLE-START: start-before and start-after specified!
|
||||
; DOUBLE-STOP: stop-before and stop-after specified!
|
||||
|
@ -126,22 +126,6 @@ static cl::opt<bool> DiscardValueNames(
|
||||
cl::desc("Discard names from Value (other than GlobalValue)."),
|
||||
cl::init(false), cl::Hidden);
|
||||
|
||||
static cl::opt<std::string> StopBefore("stop-before",
|
||||
cl::desc("Stop compilation before a specific pass"),
|
||||
cl::value_desc("pass-name"), cl::init(""));
|
||||
|
||||
static cl::opt<std::string> StopAfter("stop-after",
|
||||
cl::desc("Stop compilation after a specific pass"),
|
||||
cl::value_desc("pass-name"), cl::init(""));
|
||||
|
||||
static cl::opt<std::string> StartBefore("start-before",
|
||||
cl::desc("Resume compilation before a specific pass"),
|
||||
cl::value_desc("pass-name"), cl::init(""));
|
||||
|
||||
static cl::opt<std::string> StartAfter("start-after",
|
||||
cl::desc("Resume compilation after a specific pass"),
|
||||
cl::value_desc("pass-name"), cl::init(""));
|
||||
|
||||
static cl::list<std::string> IncludeDirs("I", cl::desc("include search path"));
|
||||
|
||||
static cl::opt<bool> PassRemarksWithHotness(
|
||||
@ -389,20 +373,6 @@ static bool addPass(PassManagerBase &PM, const char *argv0,
|
||||
return false;
|
||||
}
|
||||
|
||||
static AnalysisID getPassID(const char *argv0, const char *OptionName,
|
||||
StringRef PassName) {
|
||||
if (PassName.empty())
|
||||
return nullptr;
|
||||
|
||||
const PassRegistry &PR = *PassRegistry::getPassRegistry();
|
||||
const PassInfo *PI = PR.getPassInfo(PassName);
|
||||
if (!PI) {
|
||||
errs() << argv0 << ": " << OptionName << " pass is not registered.\n";
|
||||
exit(1);
|
||||
}
|
||||
return PI->getTypeInfo();
|
||||
}
|
||||
|
||||
static int compileModule(char **argv, LLVMContext &Context) {
|
||||
// Load the module to be compiled...
|
||||
SMDiagnostic Err;
|
||||
@ -537,66 +507,44 @@ static int compileModule(char **argv, LLVMContext &Context) {
|
||||
}
|
||||
|
||||
const char *argv0 = argv[0];
|
||||
AnalysisID StartBeforeID = getPassID(argv0, "start-before", StartBefore);
|
||||
AnalysisID StartAfterID = getPassID(argv0, "start-after", StartAfter);
|
||||
AnalysisID StopAfterID = getPassID(argv0, "stop-after", StopAfter);
|
||||
AnalysisID StopBeforeID = getPassID(argv0, "stop-before", StopBefore);
|
||||
if (StartBeforeID && StartAfterID) {
|
||||
errs() << argv0 << ": -start-before and -start-after specified!\n";
|
||||
return 1;
|
||||
}
|
||||
if (StopBeforeID && StopAfterID) {
|
||||
errs() << argv0 << ": -stop-before and -stop-after specified!\n";
|
||||
LLVMTargetMachine &LLVMTM = static_cast<LLVMTargetMachine&>(*Target);
|
||||
MachineModuleInfo *MMI = new MachineModuleInfo(&LLVMTM);
|
||||
|
||||
// Construct a custom pass pipeline that starts after instruction
|
||||
// selection.
|
||||
if (!RunPassNames->empty()) {
|
||||
if (!MIR) {
|
||||
errs() << argv0 << ": run-pass is for .mir file only.\n";
|
||||
return 1;
|
||||
}
|
||||
TargetPassConfig &TPC = *LLVMTM.createPassConfig(PM);
|
||||
if (TPC.hasLimitedCodeGenPipeline()) {
|
||||
errs() << argv0 << ": run-pass cannot be used with "
|
||||
<< TPC.getLimitedCodeGenPipelineReason(" and ") << ".\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
TPC.setDisableVerify(NoVerify);
|
||||
PM.add(&TPC);
|
||||
PM.add(MMI);
|
||||
TPC.printAndVerify("");
|
||||
for (const std::string &RunPassName : *RunPassNames) {
|
||||
if (addPass(PM, argv0, RunPassName, TPC))
|
||||
return 1;
|
||||
}
|
||||
TPC.setInitialized();
|
||||
PM.add(createPrintMIRPass(*OS));
|
||||
PM.add(createFreeMachineFunctionPass());
|
||||
} else if (Target->addPassesToEmitFile(PM, *OS, FileType, NoVerify, MMI)) {
|
||||
errs() << argv0 << ": target does not support generation of this"
|
||||
<< " file type!\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (MIR) {
|
||||
// Construct a custom pass pipeline that starts after instruction
|
||||
// selection.
|
||||
LLVMTargetMachine &LLVMTM = static_cast<LLVMTargetMachine&>(*Target);
|
||||
TargetPassConfig &TPC = *LLVMTM.createPassConfig(PM);
|
||||
TPC.setDisableVerify(NoVerify);
|
||||
PM.add(&TPC);
|
||||
MachineModuleInfo *MMI = new MachineModuleInfo(&LLVMTM);
|
||||
assert(MMI && "addPassesToEmitFile didn't set MMI");
|
||||
if (MIR->parseMachineFunctions(*M, *MMI))
|
||||
return 1;
|
||||
PM.add(MMI);
|
||||
TPC.printAndVerify("");
|
||||
|
||||
if (!RunPassNames->empty()) {
|
||||
if (!StartAfter.empty() || !StopAfter.empty() || !StartBefore.empty() ||
|
||||
!StopBefore.empty()) {
|
||||
errs() << argv0 << ": start-after and/or stop-after passes are "
|
||||
"redundant when run-pass is specified.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (const std::string &RunPassName : *RunPassNames) {
|
||||
if (addPass(PM, argv0, RunPassName, TPC))
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
TPC.setStartStopPasses(StartBeforeID, StartAfterID, StopBeforeID,
|
||||
StopAfterID);
|
||||
TPC.addISelPasses();
|
||||
TPC.addMachinePasses();
|
||||
}
|
||||
TPC.setInitialized();
|
||||
|
||||
if (!StopBefore.empty() || !StopAfter.empty() || !RunPassNames->empty()) {
|
||||
PM.add(createPrintMIRPass(*OS));
|
||||
} else if (LLVMTM.addAsmPrinter(PM, *OS, FileType, MMI->getContext())) {
|
||||
errs() << argv0 << ": target does not support generation of this"
|
||||
<< " file type!\n";
|
||||
return 1;
|
||||
}
|
||||
PM.add(createFreeMachineFunctionPass());
|
||||
} else if (Target->addPassesToEmitFile(PM, *OS, FileType, NoVerify,
|
||||
StartBeforeID, StartAfterID,
|
||||
StopBeforeID, StopAfterID)) {
|
||||
errs() << argv0 << ": target does not support generation of this"
|
||||
<< " file type!\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Before executing passes, print the final values of the LLVM options.
|
||||
|
Loading…
x
Reference in New Issue
Block a user