mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-08 21:10:35 +00:00
CodeGen/LLVMTargetMachine: Refactor ISel pass construction; NFCI
- Move ISel (and pre-isel) pass construction into TargetPassConfig - Extract AsmPrinter construction into a helper function Putting the ISel code into TargetPassConfig seems a lot more natural and both changes together make make it easier to build custom pipelines involving .mir in an upcoming commit. This moves MachineModuleInfo to an earlier place in the pass pipeline which shouldn't have any effect. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304754 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2c200794df
commit
516023ae81
@ -119,6 +119,10 @@ protected:
|
||||
/// callers.
|
||||
bool RequireCodeGenSCCOrder;
|
||||
|
||||
/// Add the actual instruction selection passes. This does not include
|
||||
/// preparation passes on IR.
|
||||
bool addCoreISelPasses();
|
||||
|
||||
public:
|
||||
TargetPassConfig(LLVMTargetMachine &TM, PassManagerBase &pm);
|
||||
// Dummy constructor.
|
||||
@ -206,6 +210,13 @@ public:
|
||||
/// has not be overriden on the command line with '-regalloc=...'
|
||||
bool usingDefaultRegAlloc() const;
|
||||
|
||||
/// High level function that adds all passes necessary to go from llvm IR
|
||||
/// representation to the MI representation.
|
||||
/// Adds IR based lowering and target specific optimization passes and finally
|
||||
/// the core instruction selection passes.
|
||||
/// \returns true if an error occured, false otherwise.
|
||||
bool addISelPasses();
|
||||
|
||||
/// Add common target configurable passes that perform LLVM IR to IR
|
||||
/// transforms following machine independent optimization.
|
||||
virtual void addIRPasses();
|
||||
|
@ -305,6 +305,11 @@ public:
|
||||
/// remove this at some point and always enable the verifier when
|
||||
/// EXPENSIVE_CHECKS is enabled.
|
||||
virtual bool isMachineVerifierClean() const { return true; }
|
||||
|
||||
/// \brief Adds an AsmPrinter pass to the pipeline that prints assembly or
|
||||
/// machine code from the MI representation.
|
||||
bool addAsmPrinter(PassManagerBase &PM, raw_pwrite_stream &Out,
|
||||
CodeGenFileType FileTYpe, MCContext &Context);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
@ -35,17 +35,6 @@
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
using namespace llvm;
|
||||
|
||||
// Enable or disable FastISel. Both options are needed, because
|
||||
// FastISel is enabled by default with -fast, and we wish to be
|
||||
// able to enable or disable fast-isel independently from -O0.
|
||||
static cl::opt<cl::boolOrDefault>
|
||||
EnableFastISelOption("fast-isel", cl::Hidden,
|
||||
cl::desc("Enable the \"fast\" instruction selector"));
|
||||
|
||||
static cl::opt<cl::boolOrDefault>
|
||||
EnableGlobalISel("global-isel", cl::Hidden,
|
||||
cl::desc("Enable the \"global\" instruction selector"));
|
||||
|
||||
void LLVMTargetMachine::initAsmInfo() {
|
||||
MRI = TheTarget.createMCRegInfo(getTargetTriple().str());
|
||||
MII = TheTarget.createMCInstrInfo();
|
||||
@ -117,99 +106,23 @@ addPassesToGenerateCode(LLVMTargetMachine *TM, PassManagerBase &PM,
|
||||
// Set PassConfig options provided by TargetMachine.
|
||||
PassConfig->setDisableVerify(DisableVerify);
|
||||
PM.add(PassConfig);
|
||||
|
||||
// When in emulated TLS mode, add the LowerEmuTLS pass.
|
||||
if (TM->Options.EmulatedTLS)
|
||||
PM.add(createLowerEmuTLSPass());
|
||||
|
||||
PM.add(createPreISelIntrinsicLoweringPass());
|
||||
|
||||
// Add internal analysis passes from the target machine.
|
||||
PM.add(createTargetTransformInfoWrapperPass(TM->getTargetIRAnalysis()));
|
||||
|
||||
PassConfig->addIRPasses();
|
||||
|
||||
PassConfig->addCodeGenPrepare();
|
||||
|
||||
PassConfig->addPassesToHandleExceptions();
|
||||
|
||||
PassConfig->addISelPrepare();
|
||||
|
||||
MachineModuleInfo *MMI = new MachineModuleInfo(TM);
|
||||
MMI->setMachineFunctionInitializer(MFInitializer);
|
||||
PM.add(MMI);
|
||||
|
||||
// Enable FastISel with -fast, but allow that to be overridden.
|
||||
TM->setO0WantsFastISel(EnableFastISelOption != cl::BOU_FALSE);
|
||||
if (EnableFastISelOption == cl::BOU_TRUE ||
|
||||
(TM->getOptLevel() == CodeGenOpt::None &&
|
||||
TM->getO0WantsFastISel()))
|
||||
TM->setFastISel(true);
|
||||
|
||||
// Ask the target for an isel.
|
||||
// Enable GlobalISel if the target wants to, but allow that to be overriden.
|
||||
if (EnableGlobalISel == cl::BOU_TRUE || (EnableGlobalISel == cl::BOU_UNSET &&
|
||||
PassConfig->isGlobalISelEnabled())) {
|
||||
if (PassConfig->addIRTranslator())
|
||||
return nullptr;
|
||||
|
||||
PassConfig->addPreLegalizeMachineIR();
|
||||
|
||||
if (PassConfig->addLegalizeMachineIR())
|
||||
return nullptr;
|
||||
|
||||
// Before running the register bank selector, ask the target if it
|
||||
// wants to run some passes.
|
||||
PassConfig->addPreRegBankSelect();
|
||||
|
||||
if (PassConfig->addRegBankSelect())
|
||||
return nullptr;
|
||||
|
||||
PassConfig->addPreGlobalInstructionSelect();
|
||||
|
||||
if (PassConfig->addGlobalInstructionSelect())
|
||||
return nullptr;
|
||||
|
||||
// Pass to reset the MachineFunction if the ISel failed.
|
||||
PM.add(createResetMachineFunctionPass(
|
||||
PassConfig->reportDiagnosticWhenGlobalISelFallback(),
|
||||
PassConfig->isGlobalISelAbortEnabled()));
|
||||
|
||||
// Provide a fallback path when we do not want to abort on
|
||||
// not-yet-supported input.
|
||||
if (!PassConfig->isGlobalISelAbortEnabled() &&
|
||||
PassConfig->addInstSelector())
|
||||
return nullptr;
|
||||
|
||||
} else if (PassConfig->addInstSelector())
|
||||
if (PassConfig->addISelPasses())
|
||||
return nullptr;
|
||||
|
||||
PassConfig->addMachinePasses();
|
||||
|
||||
PassConfig->setInitialized();
|
||||
|
||||
return &MMI->getContext();
|
||||
}
|
||||
|
||||
bool LLVMTargetMachine::addPassesToEmitFile(
|
||||
PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType,
|
||||
bool DisableVerify, AnalysisID StartBefore, AnalysisID StartAfter,
|
||||
AnalysisID StopBefore, AnalysisID StopAfter,
|
||||
MachineFunctionInitializer *MFInitializer) {
|
||||
// Add common CodeGen passes.
|
||||
MCContext *Context =
|
||||
addPassesToGenerateCode(this, PM, DisableVerify, StartBefore, StartAfter,
|
||||
StopBefore, StopAfter, MFInitializer);
|
||||
if (!Context)
|
||||
return true;
|
||||
|
||||
if (StopBefore || StopAfter) {
|
||||
PM.add(createPrintMIRPass(Out));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM,
|
||||
raw_pwrite_stream &Out, CodeGenFileType FileType,
|
||||
MCContext &Context) {
|
||||
if (Options.MCOptions.MCSaveTempLabels)
|
||||
Context->setAllowTemporaryLabels(false);
|
||||
Context.setAllowTemporaryLabels(false);
|
||||
|
||||
const MCSubtargetInfo &STI = *getMCSubtargetInfo();
|
||||
const MCAsmInfo &MAI = *getMCAsmInfo();
|
||||
@ -226,14 +139,14 @@ bool LLVMTargetMachine::addPassesToEmitFile(
|
||||
// Create a code emitter if asked to show the encoding.
|
||||
MCCodeEmitter *MCE = nullptr;
|
||||
if (Options.MCOptions.ShowMCEncoding)
|
||||
MCE = getTarget().createMCCodeEmitter(MII, MRI, *Context);
|
||||
MCE = getTarget().createMCCodeEmitter(MII, MRI, Context);
|
||||
|
||||
MCAsmBackend *MAB =
|
||||
getTarget().createMCAsmBackend(MRI, getTargetTriple().str(), TargetCPU,
|
||||
Options.MCOptions);
|
||||
auto FOut = llvm::make_unique<formatted_raw_ostream>(Out);
|
||||
MCStreamer *S = getTarget().createAsmStreamer(
|
||||
*Context, std::move(FOut), Options.MCOptions.AsmVerbose,
|
||||
Context, std::move(FOut), Options.MCOptions.AsmVerbose,
|
||||
Options.MCOptions.MCUseDwarfDirectory, InstPrinter, MCE, MAB,
|
||||
Options.MCOptions.ShowMCInst);
|
||||
AsmStreamer.reset(S);
|
||||
@ -242,7 +155,7 @@ bool LLVMTargetMachine::addPassesToEmitFile(
|
||||
case CGFT_ObjectFile: {
|
||||
// Create the code emitter for the target if it exists. If not, .o file
|
||||
// emission fails.
|
||||
MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, MRI, *Context);
|
||||
MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, MRI, Context);
|
||||
MCAsmBackend *MAB =
|
||||
getTarget().createMCAsmBackend(MRI, getTargetTriple().str(), TargetCPU,
|
||||
Options.MCOptions);
|
||||
@ -250,11 +163,11 @@ bool LLVMTargetMachine::addPassesToEmitFile(
|
||||
return true;
|
||||
|
||||
// Don't waste memory on names of temp labels.
|
||||
Context->setUseNamesOnTempLabels(false);
|
||||
Context.setUseNamesOnTempLabels(false);
|
||||
|
||||
Triple T(getTargetTriple().str());
|
||||
AsmStreamer.reset(getTarget().createMCObjectStreamer(
|
||||
T, *Context, *MAB, Out, MCE, STI, Options.MCOptions.MCRelaxAll,
|
||||
T, Context, *MAB, Out, MCE, STI, Options.MCOptions.MCRelaxAll,
|
||||
Options.MCOptions.MCIncrementalLinkerCompatible,
|
||||
/*DWARFMustBeAtTheEnd*/ true));
|
||||
break;
|
||||
@ -262,7 +175,7 @@ bool LLVMTargetMachine::addPassesToEmitFile(
|
||||
case CGFT_Null:
|
||||
// The Null output is intended for use for performance analysis and testing,
|
||||
// not real users.
|
||||
AsmStreamer.reset(getTarget().createNullStreamer(*Context));
|
||||
AsmStreamer.reset(getTarget().createNullStreamer(Context));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -273,8 +186,29 @@ bool LLVMTargetMachine::addPassesToEmitFile(
|
||||
return true;
|
||||
|
||||
PM.add(Printer);
|
||||
PM.add(createFreeMachineFunctionPass());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LLVMTargetMachine::addPassesToEmitFile(
|
||||
PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType,
|
||||
bool DisableVerify, AnalysisID StartBefore, AnalysisID StartAfter,
|
||||
AnalysisID StopBefore, AnalysisID StopAfter,
|
||||
MachineFunctionInitializer *MFInitializer) {
|
||||
// Add common CodeGen passes.
|
||||
MCContext *Context =
|
||||
addPassesToGenerateCode(this, PM, DisableVerify, StartBefore, StartAfter,
|
||||
StopBefore, StopAfter, MFInitializer);
|
||||
if (!Context)
|
||||
return true;
|
||||
|
||||
if (StopBefore || StopAfter) {
|
||||
PM.add(createPrintMIRPass(Out));
|
||||
} else {
|
||||
if (addAsmPrinter(PM, Out, FileType, *Context))
|
||||
return true;
|
||||
}
|
||||
|
||||
PM.add(createFreeMachineFunctionPass());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "llvm/Analysis/CallGraphSCCPass.h"
|
||||
#include "llvm/Analysis/Passes.h"
|
||||
#include "llvm/Analysis/ScopedNoAliasAA.h"
|
||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||
#include "llvm/Analysis/TypeBasedAliasAnalysis.h"
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/CodeGen/RegAllocRegistry.h"
|
||||
@ -95,6 +96,16 @@ static cl::opt<bool> VerifyMachineCode("verify-machineinstrs", cl::Hidden,
|
||||
static cl::opt<bool> EnableMachineOutliner("enable-machine-outliner",
|
||||
cl::Hidden,
|
||||
cl::desc("Enable machine outliner"));
|
||||
// Enable or disable FastISel. Both options are needed, because
|
||||
// FastISel is enabled by default with -fast, and we wish to be
|
||||
// able to enable or disable fast-isel independently from -O0.
|
||||
static cl::opt<cl::boolOrDefault>
|
||||
EnableFastISelOption("fast-isel", cl::Hidden,
|
||||
cl::desc("Enable the \"fast\" instruction selector"));
|
||||
|
||||
static cl::opt<cl::boolOrDefault>
|
||||
EnableGlobalISel("global-isel", cl::Hidden,
|
||||
cl::desc("Enable the \"global\" instruction selector"));
|
||||
|
||||
static cl::opt<std::string>
|
||||
PrintMachineInstrs("print-machineinstrs", cl::ValueOptional,
|
||||
@ -571,6 +582,66 @@ void TargetPassConfig::addISelPrepare() {
|
||||
addPass(createVerifierPass());
|
||||
}
|
||||
|
||||
bool TargetPassConfig::addCoreISelPasses() {
|
||||
// Enable FastISel with -fast, but allow that to be overridden.
|
||||
TM->setO0WantsFastISel(EnableFastISelOption != cl::BOU_FALSE);
|
||||
if (EnableFastISelOption == cl::BOU_TRUE ||
|
||||
(TM->getOptLevel() == CodeGenOpt::None && TM->getO0WantsFastISel()))
|
||||
TM->setFastISel(true);
|
||||
|
||||
// Ask the target for an isel.
|
||||
// Enable GlobalISel if the target wants to, but allow that to be overriden.
|
||||
if (EnableGlobalISel == cl::BOU_TRUE ||
|
||||
(EnableGlobalISel == cl::BOU_UNSET && isGlobalISelEnabled())) {
|
||||
if (addIRTranslator())
|
||||
return true;
|
||||
|
||||
addPreLegalizeMachineIR();
|
||||
|
||||
if (addLegalizeMachineIR())
|
||||
return true;
|
||||
|
||||
// Before running the register bank selector, ask the target if it
|
||||
// wants to run some passes.
|
||||
addPreRegBankSelect();
|
||||
|
||||
if (addRegBankSelect())
|
||||
return true;
|
||||
|
||||
addPreGlobalInstructionSelect();
|
||||
|
||||
if (addGlobalInstructionSelect())
|
||||
return true;
|
||||
|
||||
// Pass to reset the MachineFunction if the ISel failed.
|
||||
addPass(createResetMachineFunctionPass(
|
||||
reportDiagnosticWhenGlobalISelFallback(), isGlobalISelAbortEnabled()));
|
||||
|
||||
// Provide a fallback path when we do not want to abort on
|
||||
// not-yet-supported input.
|
||||
if (!isGlobalISelAbortEnabled() && addInstSelector())
|
||||
return true;
|
||||
|
||||
} else if (addInstSelector())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TargetPassConfig::addISelPasses() {
|
||||
if (TM->Options.EmulatedTLS)
|
||||
addPass(createLowerEmuTLSPass());
|
||||
|
||||
addPass(createPreISelIntrinsicLoweringPass());
|
||||
addPass(createTargetTransformInfoWrapperPass(TM->getTargetIRAnalysis()));
|
||||
addIRPasses();
|
||||
addCodeGenPrepare();
|
||||
addPassesToHandleExceptions();
|
||||
addISelPrepare();
|
||||
|
||||
return addCoreISelPasses();
|
||||
}
|
||||
|
||||
/// -regalloc=... command line option.
|
||||
static FunctionPass *useDefaultRegisterAllocator() { return nullptr; }
|
||||
static cl::opt<RegisterRegAlloc::FunctionPassCtor, false,
|
||||
|
@ -10,12 +10,12 @@
|
||||
; STOP-BEFORE-NOT: Loop Strength Reduction
|
||||
|
||||
; RUN: llc < %s -debug-pass=Structure -start-after=loop-reduce -o /dev/null 2>&1 | FileCheck %s -check-prefix=START-AFTER
|
||||
; START-AFTER: -machine-branch-prob -pre-isel-intrinsic-lowering
|
||||
; START-AFTER: -machine-branch-prob -gc-lowering
|
||||
; START-AFTER: FunctionPass Manager
|
||||
; START-AFTER-NEXT: Lower Garbage Collection Instructions
|
||||
|
||||
; RUN: llc < %s -debug-pass=Structure -start-before=loop-reduce -o /dev/null 2>&1 | FileCheck %s -check-prefix=START-BEFORE
|
||||
; START-BEFORE: -machine-branch-prob -pre-isel-intrinsic-lowering
|
||||
; START-BEFORE: -machine-branch-prob -domtree
|
||||
; START-BEFORE: FunctionPass Manager
|
||||
; START-BEFORE: Loop Strength Reduction
|
||||
; START-BEFORE-NEXT: Lower Garbage Collection Instructions
|
||||
|
@ -5,12 +5,12 @@
|
||||
; CHECK-LABEL: Pass Arguments:
|
||||
; CHECK-NEXT: Target Library Information
|
||||
; CHECK-NEXT: Target Pass Configuration
|
||||
; CHECK-NEXT: Machine Module Information
|
||||
; CHECK-NEXT: Target Transform Information
|
||||
; CHECK-NEXT: Type-Based Alias Analysis
|
||||
; CHECK-NEXT: Scoped NoAlias Alias Analysis
|
||||
; CHECK-NEXT: Assumption Cache Tracker
|
||||
; CHECK-NEXT: Create Garbage Collector Module Metadata
|
||||
; CHECK-NEXT: Machine Module Information
|
||||
; CHECK-NEXT: Machine Branch Probability Analysis
|
||||
; CHECK-NEXT: ModulePass Manager
|
||||
; CHECK-NEXT: Pre-ISel Intrinsic Lowering
|
||||
|
Loading…
Reference in New Issue
Block a user