forked from OSchip/llvm-project
[NewPM][CodeGen] Introduce CodeGenPassBuilder to help build codegen pipeline
Following up on D67687. Please refer to the RFC here http://lists.llvm.org/pipermail/llvm-dev/2020-July/143309.html `CodeGenPassBuilder` is the NPM counterpart of `TargetPassConfig` with below differences. - Debugging features (MIR print/verify, disable pass, start/stop-before/after, etc.) living in `TargetPassConfig` are moved to use PassInstrument as much as possible. (Implementation also lives in `TargetPassConfig.cpp`) - `TargetPassConfig` is a polymorphic base (virtual inheritance) to build the target-dependent pipeline whereas `CodeGenPassBuilder` is the CRTP base/helper to implement the target-dependent pipeline. The motivation is flexibility for targets to customize the pipeline, inlining opportunity, and fits the overall NPM value semantics design. - `TargetPassConfig` is a legacy immutable pass to declare hooks for targets to customize some target-independent codegen layer behavior. This is partially ported to TargetMachine::options. The rest, such as `createMachineScheduler/createPostMachineScheduler`, are left out for now. They should be implemented in LLVMTargetMachine in the future. Reviewed By: arsenm, aeubanks Differential Revision: https://reviews.llvm.org/D83608
This commit is contained in:
parent
f782d5ea86
commit
4646de5d75
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,197 @@
|
|||
//===- MachinePassRegistry.def - Registry of passes -------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file is used as the registry of passes that are for target-independent
|
||||
// code generator.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// NOTE: NO INCLUDE GUARD DESIRED!
|
||||
|
||||
#ifndef MODULE_ANALYSIS
|
||||
#define MODULE_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)
|
||||
#endif
|
||||
MODULE_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis, (PIC))
|
||||
#undef MODULE_ANALYSIS
|
||||
|
||||
#ifndef MODULE_PASS
|
||||
#define MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)
|
||||
#endif
|
||||
MODULE_PASS("pre-isel-intrinsic-lowering", PreISelIntrinsicLoweringPass, ())
|
||||
#undef MODULE_PASS
|
||||
|
||||
#ifndef FUNCTION_ANALYSIS
|
||||
#define FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)
|
||||
#endif
|
||||
FUNCTION_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis, (PIC))
|
||||
FUNCTION_ANALYSIS("targetir", TargetIRAnalysis, (std::move(TM.getTargetIRAnalysis())))
|
||||
#undef FUNCTION_ANALYSIS
|
||||
|
||||
#ifndef FUNCTION_PASS
|
||||
#define FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)
|
||||
#endif
|
||||
FUNCTION_PASS("mergeicmps", MergeICmpsPass, ())
|
||||
FUNCTION_PASS("lower-constant-intrinsics", LowerConstantIntrinsicsPass, ())
|
||||
FUNCTION_PASS("unreachableblockelim", UnreachableBlockElimPass, ())
|
||||
FUNCTION_PASS("consthoist", ConstantHoistingPass, ())
|
||||
FUNCTION_PASS("partially-inline-libcalls", PartiallyInlineLibCallsPass, ())
|
||||
FUNCTION_PASS("ee-instrument", EntryExitInstrumenterPass, (false))
|
||||
FUNCTION_PASS("post-inline-ee-instrument", EntryExitInstrumenterPass, (true))
|
||||
FUNCTION_PASS("expand-reductions", ExpandReductionsPass, ())
|
||||
FUNCTION_PASS("lowerinvoke", LowerInvokePass, ())
|
||||
FUNCTION_PASS("verify", VerifierPass, ())
|
||||
#undef FUNCTION_PASS
|
||||
|
||||
#ifndef LOOP_PASS
|
||||
#define LOOP_PASS(NAME, PASS_NAME, CONSTRUCTOR)
|
||||
#endif
|
||||
LOOP_PASS("loop-reduce", LoopStrengthReducePass, ())
|
||||
#undef LOOP_PASS
|
||||
|
||||
#ifndef MACHINE_MODULE_PASS
|
||||
#define MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)
|
||||
#endif
|
||||
#undef MACHINE_MODULE_PASS
|
||||
|
||||
#ifndef MACHINE_FUNCTION_ANALYSIS
|
||||
#define MACHINE_FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)
|
||||
#endif
|
||||
MACHINE_FUNCTION_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis, (PIC))
|
||||
// LiveVariables currently requires pure SSA form.
|
||||
// FIXME: Once TwoAddressInstruction pass no longer uses kill flags,
|
||||
// LiveVariables can be removed completely, and LiveIntervals can be directly
|
||||
// computed. (We still either need to regenerate kill flags after regalloc, or
|
||||
// preferably fix the scavenger to not depend on them).
|
||||
// MACHINE_FUNCTION_ANALYSIS("live-vars", LiveVariablesAnalysis())
|
||||
|
||||
// MACHINE_FUNCTION_ANALYSIS("live-stacks", LiveStacksPass())
|
||||
// MACHINE_FUNCTION_ANALYSIS("slot-indexes", SlotIndexesAnalysis())
|
||||
// MACHINE_FUNCTION_ANALYSIS("edge-bundles", EdgeBundlesAnalysis())
|
||||
// MACHINE_FUNCTION_ANALYSIS("lazy-machine-bfi", LazyMachineBlockFrequencyInfoAnalysis())
|
||||
// MACHINE_FUNCTION_ANALYSIS("machine-bfi", MachineBlockFrequencyInfoAnalysis())
|
||||
// MACHINE_FUNCTION_ANALYSIS("machine-loops", MachineLoopInfoAnalysis())
|
||||
// MACHINE_FUNCTION_ANALYSIS("machine-dom-frontier", MachineDominanceFrontierAnalysis())
|
||||
// MACHINE_FUNCTION_ANALYSIS("machine-dom-tree", MachineDominatorTreeAnalysis())
|
||||
// MACHINE_FUNCTION_ANALYSIS("machine-ore", MachineOptimizationRemarkEmitterPassAnalysis())
|
||||
// MACHINE_FUNCTION_ANALYSIS("machine-post-dom-tree", MachinePostDominatorTreeAnalysis())
|
||||
// MACHINE_FUNCTION_ANALYSIS("machine-region-info", MachineRegionInfoPassAnalysis())
|
||||
// MACHINE_FUNCTION_ANALYSIS("machine-trace-metrics", MachineTraceMetricsAnalysis())
|
||||
// MACHINE_FUNCTION_ANALYSIS("reaching-def", ReachingDefAnalysisAnalysis())
|
||||
// MACHINE_FUNCTION_ANALYSIS("live-reg-matrix", LiveRegMatrixAnalysis())
|
||||
// MACHINE_FUNCTION_ANALYSIS("gc-analysis", GCMachineCodeAnalysisPass())
|
||||
#undef MACHINE_FUNCTION_ANALYSIS
|
||||
|
||||
#ifndef MACHINE_FUNCTION_PASS
|
||||
#define MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)
|
||||
#endif
|
||||
// MACHINE_FUNCTION_PASS("mir-printer", PrintMIRPass, ())
|
||||
// MACHINE_FUNCTION_PASS("free-machine-function", FreeMachineFunctionPass, ())
|
||||
#undef MACHINE_FUNCTION_PASS
|
||||
|
||||
// After a pass is converted to new pass manager, its entry should be moved from
|
||||
// dummy table to the normal one. For example, for a machine function pass,
|
||||
// DUMMY_MACHINE_FUNCTION_PASS to MACHINE_FUNCTION_PASS.
|
||||
|
||||
#ifndef DUMMY_FUNCTION_PASS
|
||||
#define DUMMY_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)
|
||||
#endif
|
||||
DUMMY_FUNCTION_PASS("expandmemcmp", ExpandMemCmpPass, ())
|
||||
DUMMY_FUNCTION_PASS("gc-lowering", GCLoweringPass, ())
|
||||
DUMMY_FUNCTION_PASS("shadow-stack-gc-lowering", ShadowStackGCLoweringPass, ())
|
||||
DUMMY_FUNCTION_PASS("scalarize-masked-mem-intrin", ScalarizeMaskedMemIntrinPass, ())
|
||||
DUMMY_FUNCTION_PASS("sjljehprepare", SjLjEHPreparePass, ())
|
||||
DUMMY_FUNCTION_PASS("dwarfehprepare", DwarfEHPass, ())
|
||||
DUMMY_FUNCTION_PASS("winehprepare", WinEHPass, ())
|
||||
DUMMY_FUNCTION_PASS("wasmehprepare", WasmEHPass, ())
|
||||
DUMMY_FUNCTION_PASS("codegenprepare", CodeGenPreparePass, ())
|
||||
DUMMY_FUNCTION_PASS("safe-stack", SafeStackPass, ())
|
||||
DUMMY_FUNCTION_PASS("stack-protector", StackProtectorPass, ())
|
||||
DUMMY_FUNCTION_PASS("atomic-expand", AtomicExpandPass, ())
|
||||
DUMMY_FUNCTION_PASS("interleaved-access", InterleavedAccessPass, ())
|
||||
DUMMY_FUNCTION_PASS("indirectbr-expand", IndirectBrExpandPass, ())
|
||||
DUMMY_FUNCTION_PASS("cfguard-dispatch", CFGuardDispatchPass, ())
|
||||
DUMMY_FUNCTION_PASS("cfguard-check", CFGuardCheckPass, ())
|
||||
DUMMY_FUNCTION_PASS("gc-info-printer", GCInfoPrinterPass, ())
|
||||
#undef DUMMY_FUNCTION_PASS
|
||||
|
||||
#ifndef DUMMY_MODULE_PASS
|
||||
#define DUMMY_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)
|
||||
#endif
|
||||
DUMMY_MODULE_PASS("lower-emutls", LowerEmuTLSPass, ())
|
||||
#undef DUMMY_MODULE_PASS
|
||||
|
||||
#ifndef DUMMY_MACHINE_MODULE_PASS
|
||||
#define DUMMY_MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)
|
||||
#endif
|
||||
DUMMY_MACHINE_MODULE_PASS("machine-outliner", MachineOutlinerPass, ())
|
||||
#undef DUMMY_MACHINE_MODULE_PASS
|
||||
|
||||
#ifndef DUMMY_MACHINE_FUNCTION_PASS
|
||||
#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)
|
||||
#endif
|
||||
DUMMY_MACHINE_FUNCTION_PASS("mir-printer", PrintMIRPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("free-machine-function", FreeMachineFunctionPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("finalize-isel", FinalizeISelPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("localstackalloc", LocalStackSlotPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("shrink-wrap", ShrinkWrapPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("prologepilog", PrologEpilogInserterPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("postrapseudos", ExpandPostRAPseudosPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("implicit-null-checks", ImplicitNullChecksPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("postmisched", PostMachineSchedulerPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("machine-scheduler", MachineSchedulerPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("machine-cp", MachineCopyPropagationPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("post-RA-sched", PostRASchedulerPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("fentry-insert", FEntryInserterPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("xray-instrumentation", XRayInstrumentationPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("patchable-function", PatchableFunctionPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("reg-usage-propagation", RegUsageInfoPropagationPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("reg-usage-collector", RegUsageInfoCollectorPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("funclet-layout", FuncletLayoutPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("stackmap-liveness", StackMapLivenessPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("livedebugvalues", LiveDebugValuesPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("early-tailduplication", EarlyTailDuplicatePass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("opt-phis", OptimizePHIsPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("stack-coloring", StackColoringPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("dead-mi-elimination", DeadMachineInstructionElimPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("early-machinelicm", EarlyMachineLICMPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("machinelicm", MachineLICMPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("machine-cse", MachineCSEPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("machine-sink", MachineSinkingPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("postra-machine-sink", PostRAMachineSinkingPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("peephole-opt", PeepholeOptimizerPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("regalloc", RegAllocPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("virtregrewriter", VirtRegRewriterPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("stack-slot-coloring", StackSlotColoringPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("phi-node-elimination", PHIEliminationPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("twoaddressinstruction", TwoAddressInstructionPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("detect-dead-lanes", DetectDeadLanesPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("processimpdefs", ProcessImplicitDefsPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("liveintervals", LiveIntervalsPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("simple-register-coalescing", RegisterCoalescerPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("rename-independent-subregs", RenameIndependentSubregsPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("branch-folder", BranchFolderPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("tailduplication", TailDuplicatePass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("block-placement", MachineBlockPlacementPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("block-placement-stats", MachineBlockPlacementStatsPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("early-ifcvt", EarlyIfConverterPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("machine-combiner", MachineCombinerPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("lrshrink", LiveRangeShrinkPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("break-false-deps", BreakFalseDepsPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("cfi-instr-inserter", CFIInstrInserterPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("cfguard-longjmp", CFGuardLongjmpPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("ra-basic", RABasicPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("ra-fast", RAFastPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("ra-greedy", RAGreedyPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("ra-pbqp", RAPBQPPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("legalizer", LegalizerPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("irtranslator", IRTranslatorPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("regbankselect", RegBankSelectPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("instruction-select", InstructionSelectPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("reset-machine-function", ResetMachineFunctionPass, ())
|
||||
DUMMY_MACHINE_FUNCTION_PASS("machineverifier", MachineVerifierPass, ())
|
||||
#undef DUMMY_MACHINE_FUNCTION_PASS
|
|
@ -25,6 +25,7 @@ struct MachineSchedContext;
|
|||
class PassConfigImpl;
|
||||
class ScheduleDAGInstrs;
|
||||
class CSEConfigBase;
|
||||
class PassInstrumentationCallbacks;
|
||||
|
||||
// The old pass manager infrastructure is hidden in a legacy namespace now.
|
||||
namespace legacy {
|
||||
|
@ -465,6 +466,9 @@ protected:
|
|||
virtual bool addRegAssignmentOptimized();
|
||||
};
|
||||
|
||||
void registerCodeGenCallback(PassInstrumentationCallbacks &PIC,
|
||||
LLVMTargetMachine &);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_CODEGEN_TARGETPASSCONFIG_H
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
//===- CGPassBuilderOption.h - Options for pass builder ---------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the CCState and CCValAssign classes, used for lowering
|
||||
// and implementing calling conventions.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CODEGEN_PASSBUILDER_OPTION_H
|
||||
#define LLVM_CODEGEN_PASSBUILDER_OPTION_H
|
||||
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
class TargetMachine;
|
||||
|
||||
enum class RunOutliner { TargetDefault, AlwaysOutline, NeverOutline };
|
||||
enum class RegAllocType { Default, Basic, Fast, Greedy, PBQP };
|
||||
enum class CFLAAType { None, Steensgaard, Andersen, Both };
|
||||
|
||||
// Not one-on-one but mostly corresponding to commandline options in
|
||||
// TargetPassConfig.cpp.
|
||||
struct CGPassBuilderOption {
|
||||
Optional<bool> OptimizeRegAlloc;
|
||||
Optional<bool> EnableIPRA;
|
||||
bool DebugPM = false;
|
||||
bool DisableVerify = false;
|
||||
bool EnableImplicitNullChecks = false;
|
||||
bool EnableBlockPlacementStats = false;
|
||||
bool MISchedPostRA = false;
|
||||
bool EarlyLiveIntervals = false;
|
||||
|
||||
bool DisableLSR = false;
|
||||
bool DisableCGP = false;
|
||||
bool PrintLSR = false;
|
||||
bool DisableMergeICmps = false;
|
||||
bool DisablePartialLibcallInlining = false;
|
||||
bool DisableConstantHoisting = false;
|
||||
bool PrintISelInput = false;
|
||||
bool PrintGCInfo = false;
|
||||
bool RequiresCodeGenSCCOrder = false;
|
||||
|
||||
RunOutliner EnableMachineOutliner = RunOutliner::TargetDefault;
|
||||
RegAllocType RegAlloc = RegAllocType::Default;
|
||||
CFLAAType UseCFLAA = CFLAAType::None;
|
||||
Optional<GlobalISelAbortMode> EnableGlobalISelAbort;
|
||||
|
||||
Optional<bool> VerifyMachineCode;
|
||||
Optional<bool> EnableFastISelOption;
|
||||
Optional<bool> EnableGlobalISelOption;
|
||||
};
|
||||
|
||||
CGPassBuilderOption getCGPassBuilderOption();
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_CODEGEN_PASSBUILDER_OPTION_H
|
|
@ -16,22 +16,32 @@
|
|||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/CodeGen.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Target/CGPassBuilderOption.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class AAManager;
|
||||
template <typename IRUnitT, typename AnalysisManagerT, typename... ExtraArgTs>
|
||||
class PassManager;
|
||||
using ModulePassManager = PassManager<Module>;
|
||||
|
||||
class Function;
|
||||
class GlobalValue;
|
||||
class MachineFunctionPassManager;
|
||||
class MachineFunctionAnalysisManager;
|
||||
class MachineModuleInfoWrapperPass;
|
||||
class Mangler;
|
||||
class MCAsmInfo;
|
||||
class MCContext;
|
||||
class MCInstrInfo;
|
||||
class MCRegisterInfo;
|
||||
class MCStreamer;
|
||||
class MCSubtargetInfo;
|
||||
class MCSymbol;
|
||||
class raw_pwrite_stream;
|
||||
|
@ -401,6 +411,21 @@ public:
|
|||
bool DisableVerify = true,
|
||||
MachineModuleInfoWrapperPass *MMIWP = nullptr) override;
|
||||
|
||||
virtual Error buildCodeGenPipeline(ModulePassManager &,
|
||||
MachineFunctionPassManager &,
|
||||
MachineFunctionAnalysisManager &,
|
||||
raw_pwrite_stream &, raw_pwrite_stream *,
|
||||
CodeGenFileType, CGPassBuilderOption,
|
||||
PassInstrumentationCallbacks *) {
|
||||
return make_error<StringError>("buildCodeGenPipeline is not overriden",
|
||||
inconvertibleErrorCode());
|
||||
}
|
||||
|
||||
virtual std::pair<StringRef, bool> getPassNameFromLegacyName(StringRef) {
|
||||
llvm_unreachable(
|
||||
"getPassNameFromLegacyName parseMIRPipeline is not overriden");
|
||||
}
|
||||
|
||||
/// 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
|
||||
/// fills the MCContext Ctx pointer which can be used to build custom
|
||||
|
@ -421,6 +446,10 @@ public:
|
|||
raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
|
||||
MCContext &Context);
|
||||
|
||||
Expected<std::unique_ptr<MCStreamer>>
|
||||
createMCStreamer(raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
|
||||
CodeGenFileType FileType, MCContext &Ctx);
|
||||
|
||||
/// True if the target uses physical regs (as nearly all targets do). False
|
||||
/// for stack machines such as WebAssembly and other virtual-register
|
||||
/// machines. If true, all vregs must be allocated before PEI. If false, then
|
||||
|
|
|
@ -14,6 +14,7 @@ add_llvm_component_library(LLVMCodeGen
|
|||
CFGuardLongjmp.cpp
|
||||
CFIInstrInserter.cpp
|
||||
CodeGen.cpp
|
||||
CodeGenPassBuilder.cpp
|
||||
CodeGenPrepare.cpp
|
||||
CommandFlags.cpp
|
||||
CriticalAntiDepBreaker.cpp
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
//===--- CodeGenPassBuilder.cpp --------------------------------------- ---===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines interfaces to access the target independent code
|
||||
// generation passes provided by the LLVM backend.
|
||||
//
|
||||
//===---------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/CodeGen/CodeGenPassBuilder.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace llvm {
|
||||
#define DUMMY_MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
|
||||
AnalysisKey PASS_NAME::Key;
|
||||
#include "llvm/CodeGen/MachinePassRegistry.def"
|
||||
#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
|
||||
AnalysisKey PASS_NAME::Key;
|
||||
#include "llvm/CodeGen/MachinePassRegistry.def"
|
||||
} // namespace llvm
|
|
@ -121,6 +121,24 @@ bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM,
|
|||
raw_pwrite_stream *DwoOut,
|
||||
CodeGenFileType FileType,
|
||||
MCContext &Context) {
|
||||
Expected<std::unique_ptr<MCStreamer>> MCStreamerOrErr =
|
||||
createMCStreamer(Out, DwoOut, FileType, Context);
|
||||
if (auto Err = MCStreamerOrErr.takeError())
|
||||
return true;
|
||||
|
||||
// Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
|
||||
FunctionPass *Printer =
|
||||
getTarget().createAsmPrinter(*this, std::move(*MCStreamerOrErr));
|
||||
if (!Printer)
|
||||
return true;
|
||||
|
||||
PM.add(Printer);
|
||||
return false;
|
||||
}
|
||||
|
||||
Expected<std::unique_ptr<MCStreamer>> LLVMTargetMachine::createMCStreamer(
|
||||
raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
|
||||
MCContext &Context) {
|
||||
if (Options.MCOptions.MCSaveTempLabels)
|
||||
Context.setAllowTemporaryLabels(false);
|
||||
|
||||
|
@ -155,10 +173,14 @@ bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM,
|
|||
// Create the code emitter for the target if it exists. If not, .o file
|
||||
// emission fails.
|
||||
MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, MRI, Context);
|
||||
if (!MCE)
|
||||
return make_error<StringError>("createMCCodeEmitter failed",
|
||||
inconvertibleErrorCode());
|
||||
MCAsmBackend *MAB =
|
||||
getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions);
|
||||
if (!MCE || !MAB)
|
||||
return true;
|
||||
if (!MAB)
|
||||
return make_error<StringError>("createMCAsmBackend failed",
|
||||
inconvertibleErrorCode());
|
||||
|
||||
Triple T(getTargetTriple().str());
|
||||
AsmStreamer.reset(getTarget().createMCObjectStreamer(
|
||||
|
@ -177,14 +199,7 @@ bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM,
|
|||
break;
|
||||
}
|
||||
|
||||
// Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
|
||||
FunctionPass *Printer =
|
||||
getTarget().createAsmPrinter(*this, std::move(AsmStreamer));
|
||||
if (!Printer)
|
||||
return true;
|
||||
|
||||
PM.add(Printer);
|
||||
return false;
|
||||
return AsmStreamer;
|
||||
}
|
||||
|
||||
bool LLVMTargetMachine::addPassesToEmitFile(
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "llvm/CodeGen/RegAllocRegistry.h"
|
||||
#include "llvm/IR/IRPrintingPasses.h"
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/IR/PassInstrumentation.h"
|
||||
#include "llvm/IR/Verifier.h"
|
||||
#include "llvm/InitializePasses.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
|
@ -41,6 +42,7 @@
|
|||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/SaveAndRestore.h"
|
||||
#include "llvm/Support/Threading.h"
|
||||
#include "llvm/Target/CGPassBuilderOption.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
#include "llvm/Transforms/Utils.h"
|
||||
|
@ -126,16 +128,16 @@ static cl::opt<cl::boolOrDefault> DebugifyCheckAndStripAll(
|
|||
"Debugify MIR before, by checking and stripping the debug info after, "
|
||||
"each pass except those known to be unsafe when debug info is present"),
|
||||
cl::ZeroOrMore);
|
||||
enum RunOutliner { AlwaysOutline, NeverOutline, TargetDefault };
|
||||
// Enable or disable the MachineOutliner.
|
||||
static cl::opt<RunOutliner> EnableMachineOutliner(
|
||||
"enable-machine-outliner", cl::desc("Enable the machine outliner"),
|
||||
cl::Hidden, cl::ValueOptional, cl::init(TargetDefault),
|
||||
cl::values(clEnumValN(AlwaysOutline, "always",
|
||||
cl::Hidden, cl::ValueOptional, cl::init(RunOutliner::TargetDefault),
|
||||
cl::values(clEnumValN(RunOutliner::AlwaysOutline, "always",
|
||||
"Run on all functions guaranteed to be beneficial"),
|
||||
clEnumValN(NeverOutline, "never", "Disable all outlining"),
|
||||
clEnumValN(RunOutliner::NeverOutline, "never",
|
||||
"Disable all outlining"),
|
||||
// Sentinel value for unspecified option.
|
||||
clEnumValN(AlwaysOutline, "", "")));
|
||||
clEnumValN(RunOutliner::AlwaysOutline, "", "")));
|
||||
// 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.
|
||||
|
@ -178,7 +180,6 @@ static cl::opt<bool> EarlyLiveIntervals("early-live-intervals", cl::Hidden,
|
|||
cl::desc("Run live interval analysis earlier in the pipeline"));
|
||||
|
||||
// Experimental option to use CFL-AA in codegen
|
||||
enum class CFLAAType { None, Steensgaard, Andersen, Both };
|
||||
static cl::opt<CFLAAType> UseCFLAA(
|
||||
"use-cfl-aa-in-codegen", cl::init(CFLAAType::None), cl::Hidden,
|
||||
cl::desc("Enable the new, experimental CFL alias analysis in CodeGen"),
|
||||
|
@ -415,6 +416,145 @@ void TargetPassConfig::setStartStopPasses() {
|
|||
Started = (StartAfter == nullptr) && (StartBefore == nullptr);
|
||||
}
|
||||
|
||||
CGPassBuilderOption llvm::getCGPassBuilderOption() {
|
||||
CGPassBuilderOption Opt;
|
||||
|
||||
#define SET_OPTION(Option) \
|
||||
if (Option.getNumOccurrences()) \
|
||||
Opt.Option = Option;
|
||||
|
||||
SET_OPTION(EnableFastISelOption)
|
||||
SET_OPTION(EnableGlobalISelAbort)
|
||||
SET_OPTION(EnableGlobalISelOption)
|
||||
SET_OPTION(EnableIPRA)
|
||||
SET_OPTION(OptimizeRegAlloc)
|
||||
SET_OPTION(VerifyMachineCode)
|
||||
|
||||
#define SET_BOOLEAN_OPTION(Option) Opt.Option = Option;
|
||||
|
||||
SET_BOOLEAN_OPTION(EarlyLiveIntervals)
|
||||
SET_BOOLEAN_OPTION(EnableBlockPlacementStats)
|
||||
SET_BOOLEAN_OPTION(EnableImplicitNullChecks)
|
||||
SET_BOOLEAN_OPTION(EnableMachineOutliner)
|
||||
SET_BOOLEAN_OPTION(MISchedPostRA)
|
||||
SET_BOOLEAN_OPTION(UseCFLAA)
|
||||
SET_BOOLEAN_OPTION(DisableMergeICmps)
|
||||
SET_BOOLEAN_OPTION(DisableLSR)
|
||||
SET_BOOLEAN_OPTION(DisableConstantHoisting)
|
||||
SET_BOOLEAN_OPTION(DisableCGP)
|
||||
SET_BOOLEAN_OPTION(DisablePartialLibcallInlining)
|
||||
SET_BOOLEAN_OPTION(PrintLSR)
|
||||
SET_BOOLEAN_OPTION(PrintISelInput)
|
||||
SET_BOOLEAN_OPTION(PrintGCInfo)
|
||||
|
||||
return Opt;
|
||||
}
|
||||
|
||||
static void registerPartialPipelineCallback(PassInstrumentationCallbacks &PIC,
|
||||
LLVMTargetMachine &LLVMTM) {
|
||||
StringRef StartBefore;
|
||||
StringRef StartAfter;
|
||||
StringRef StopBefore;
|
||||
StringRef StopAfter;
|
||||
|
||||
unsigned StartBeforeInstanceNum = 0;
|
||||
unsigned StartAfterInstanceNum = 0;
|
||||
unsigned StopBeforeInstanceNum = 0;
|
||||
unsigned StopAfterInstanceNum = 0;
|
||||
|
||||
std::tie(StartBefore, StartBeforeInstanceNum) =
|
||||
getPassNameAndInstanceNum(StartBeforeOpt);
|
||||
std::tie(StartAfter, StartAfterInstanceNum) =
|
||||
getPassNameAndInstanceNum(StartAfterOpt);
|
||||
std::tie(StopBefore, StopBeforeInstanceNum) =
|
||||
getPassNameAndInstanceNum(StopBeforeOpt);
|
||||
std::tie(StopAfter, StopAfterInstanceNum) =
|
||||
getPassNameAndInstanceNum(StopAfterOpt);
|
||||
|
||||
if (StartBefore.empty() && StartAfter.empty() && StopBefore.empty() &&
|
||||
StopAfter.empty())
|
||||
return;
|
||||
|
||||
std::tie(StartBefore, std::ignore) =
|
||||
LLVMTM.getPassNameFromLegacyName(StartBefore);
|
||||
std::tie(StartAfter, std::ignore) =
|
||||
LLVMTM.getPassNameFromLegacyName(StartAfter);
|
||||
std::tie(StopBefore, std::ignore) =
|
||||
LLVMTM.getPassNameFromLegacyName(StopBefore);
|
||||
std::tie(StopAfter, std::ignore) =
|
||||
LLVMTM.getPassNameFromLegacyName(StopAfter);
|
||||
if (!StartBefore.empty() && !StartAfter.empty())
|
||||
report_fatal_error(Twine(StartBeforeOptName) + Twine(" and ") +
|
||||
Twine(StartAfterOptName) + Twine(" specified!"));
|
||||
if (!StopBefore.empty() && !StopAfter.empty())
|
||||
report_fatal_error(Twine(StopBeforeOptName) + Twine(" and ") +
|
||||
Twine(StopAfterOptName) + Twine(" specified!"));
|
||||
|
||||
PIC.registerShouldRunOptionalPassCallback(
|
||||
[=, EnableCurrent = StartBefore.empty() && StartAfter.empty(),
|
||||
EnableNext = Optional<bool>(), StartBeforeCount = 0u,
|
||||
StartAfterCount = 0u, StopBeforeCount = 0u,
|
||||
StopAfterCount = 0u](StringRef P, Any) mutable {
|
||||
bool StartBeforePass = !StartBefore.empty() && P.contains(StartBefore);
|
||||
bool StartAfterPass = !StartAfter.empty() && P.contains(StartAfter);
|
||||
bool StopBeforePass = !StopBefore.empty() && P.contains(StopBefore);
|
||||
bool StopAfterPass = !StopAfter.empty() && P.contains(StopAfter);
|
||||
|
||||
// Implement -start-after/-stop-after
|
||||
if (EnableNext) {
|
||||
EnableCurrent = *EnableNext;
|
||||
EnableNext.reset();
|
||||
}
|
||||
|
||||
// Using PIC.registerAfterPassCallback won't work because if this
|
||||
// callback returns false, AfterPassCallback is also skipped.
|
||||
if (StartAfterPass && StartAfterCount++ == StartAfterInstanceNum) {
|
||||
assert(!EnableNext && "Error: assign to EnableNext more than once");
|
||||
EnableNext = true;
|
||||
}
|
||||
if (StopAfterPass && StopAfterCount++ == StopAfterInstanceNum) {
|
||||
assert(!EnableNext && "Error: assign to EnableNext more than once");
|
||||
EnableNext = false;
|
||||
}
|
||||
|
||||
if (StartBeforePass && StartBeforeCount++ == StartBeforeInstanceNum)
|
||||
EnableCurrent = true;
|
||||
if (StopBeforePass && StopBeforeCount++ == StopBeforeInstanceNum)
|
||||
EnableCurrent = false;
|
||||
return EnableCurrent;
|
||||
});
|
||||
}
|
||||
|
||||
void llvm::registerCodeGenCallback(PassInstrumentationCallbacks &PIC,
|
||||
LLVMTargetMachine &LLVMTM) {
|
||||
|
||||
// Register a callback for disabling passes.
|
||||
PIC.registerShouldRunOptionalPassCallback([](StringRef P, Any) {
|
||||
|
||||
#define DISABLE_PASS(Option, Name) \
|
||||
if (Option && P.contains(#Name)) \
|
||||
return false;
|
||||
DISABLE_PASS(DisableBlockPlacement, MachineBlockPlacementPass)
|
||||
DISABLE_PASS(DisableBranchFold, BranchFolderPass)
|
||||
DISABLE_PASS(DisableCopyProp, MachineCopyPropagationPass)
|
||||
DISABLE_PASS(DisableEarlyIfConversion, EarlyIfConverterPass)
|
||||
DISABLE_PASS(DisableEarlyTailDup, EarlyTailDuplicatePass)
|
||||
DISABLE_PASS(DisableMachineCSE, MachineCSEPass)
|
||||
DISABLE_PASS(DisableMachineDCE, DeadMachineInstructionElimPass)
|
||||
DISABLE_PASS(DisableMachineLICM, EarlyMachineLICMPass)
|
||||
DISABLE_PASS(DisableMachineSink, MachineSinkingPass)
|
||||
DISABLE_PASS(DisablePostRAMachineLICM, MachineLICMPass)
|
||||
DISABLE_PASS(DisablePostRAMachineSink, PostRAMachineSinkingPass)
|
||||
DISABLE_PASS(DisablePostRASched, PostRASchedulerPass)
|
||||
DISABLE_PASS(DisableSSC, StackSlotColoringPass)
|
||||
DISABLE_PASS(DisableTailDuplicate, TailDuplicatePass)
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
registerPartialPipelineCallback(PIC, LLVMTM);
|
||||
}
|
||||
|
||||
// Out of line constructor provides default values for pass options and
|
||||
// registers all common codegen passes.
|
||||
TargetPassConfig::TargetPassConfig(LLVMTargetMachine &TM, PassManagerBase &pm)
|
||||
|
@ -1037,10 +1177,11 @@ void TargetPassConfig::addMachinePasses() {
|
|||
addPass(&LiveDebugValuesID, false);
|
||||
|
||||
if (TM->Options.EnableMachineOutliner && getOptLevel() != CodeGenOpt::None &&
|
||||
EnableMachineOutliner != NeverOutline) {
|
||||
bool RunOnAllFunctions = (EnableMachineOutliner == AlwaysOutline);
|
||||
bool AddOutliner = RunOnAllFunctions ||
|
||||
TM->Options.SupportsDefaultOutlining;
|
||||
EnableMachineOutliner != RunOutliner::NeverOutline) {
|
||||
bool RunOnAllFunctions =
|
||||
(EnableMachineOutliner == RunOutliner::AlwaysOutline);
|
||||
bool AddOutliner =
|
||||
RunOnAllFunctions || TM->Options.SupportsDefaultOutlining;
|
||||
if (AddOutliner)
|
||||
addPass(createMachineOutlinerPass(RunOnAllFunctions));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue