Skip to content

[NewPM][CodeGen] Add NPM support to llc #69879

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
359 changes: 282 additions & 77 deletions llvm/include/llvm/CodeGen/CodeGenPassBuilder.h

Large diffs are not rendered by default.

11 changes: 3 additions & 8 deletions llvm/include/llvm/CodeGen/MachinePassManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Support/Error.h"
#include "llvm/Target/CGPassBuilderOption.h"

#include <map>

Expand Down Expand Up @@ -150,10 +151,7 @@ class MachineFunctionPassManager
using Base = PassManager<MachineFunction, MachineFunctionAnalysisManager>;

public:
MachineFunctionPassManager(bool RequireCodeGenSCCOrder = false,
bool VerifyMachineFunction = false)
: RequireCodeGenSCCOrder(RequireCodeGenSCCOrder),
VerifyMachineFunction(VerifyMachineFunction) {}
MachineFunctionPassManager() : Opt(getCGPassBuilderOption()) {}
MachineFunctionPassManager(MachineFunctionPassManager &&) = default;
MachineFunctionPassManager &
operator=(MachineFunctionPassManager &&) = default;
Expand Down Expand Up @@ -261,10 +259,7 @@ class MachineFunctionPassManager
using PassIndex = decltype(Passes)::size_type;
std::map<PassIndex, llvm::unique_function<FuncTy>> MachineModulePasses;

// Run codegen in the SCC order.
bool RequireCodeGenSCCOrder;

bool VerifyMachineFunction;
CGPassBuilderOption Opt;
};

} // end namespace llvm
Expand Down
33 changes: 33 additions & 0 deletions llvm/include/llvm/IR/PassInstrumentation.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,23 @@ class PassInstrumentationCallbacks {
using AfterAnalysisFunc = void(StringRef, Any);
using AnalysisInvalidatedFunc = void(StringRef, Any);
using AnalysesClearedFunc = void(StringRef);
using StartStopFunc = bool(StringRef, Any);

struct CodeGenStartStopInfo {
StringRef Start;
StringRef Stop;

bool IsStopMachinePass = false;

llvm::unique_function<StartStopFunc> StartStopCallback;

bool operator()(StringRef PassID, Any IR) {
return StartStopCallback(PassID, IR);
}
bool isStopMachineFunctionPass() const { return IsStopMachinePass; }
bool willCompleteCodeGenPipeline() const { return Stop.empty(); }
StringRef getStop() const { return Stop; }
};

public:
PassInstrumentationCallbacks() = default;
Expand Down Expand Up @@ -148,6 +165,17 @@ class PassInstrumentationCallbacks {
AnalysesClearedCallbacks.emplace_back(std::move(C));
}

void registerStartStopInfo(CodeGenStartStopInfo &&C) {
StartStopInfo = std::move(C);
}

bool isStartStopInfoRegistered() const { return StartStopInfo.has_value(); }

CodeGenStartStopInfo &getStartStopInfo() {
assert(StartStopInfo.has_value() && "StartStopInfo is unregistered!");
return *StartStopInfo;
}

/// Add a class name to pass name mapping for use by pass instrumentation.
void addClassToPassName(StringRef ClassName, StringRef PassName);
/// Get the pass name for a given pass class name.
Expand Down Expand Up @@ -183,6 +211,8 @@ class PassInstrumentationCallbacks {
/// These are run on analyses that have been cleared.
SmallVector<llvm::unique_function<AnalysesClearedFunc>, 4>
AnalysesClearedCallbacks;
/// For `llc` -start-* -stop-* options.
std::optional<CodeGenStartStopInfo> StartStopInfo;

StringMap<std::string> ClassToPassName;
};
Expand Down Expand Up @@ -236,6 +266,9 @@ class PassInstrumentation {
ShouldRun &= C(Pass.name(), llvm::Any(&IR));
}

if (Callbacks->StartStopInfo)
ShouldRun &= (*Callbacks->StartStopInfo)(Pass.name(), llvm::Any(&IR));

if (ShouldRun) {
for (auto &C : Callbacks->BeforeNonSkippedPassCallbacks)
C(Pass.name(), llvm::Any(&IR));
Expand Down
11 changes: 9 additions & 2 deletions llvm/include/llvm/Target/TargetMachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -461,8 +461,15 @@ class LLVMTargetMachine : public TargetMachine {
}

virtual std::pair<StringRef, bool> getPassNameFromLegacyName(StringRef) {
llvm_unreachable(
"getPassNameFromLegacyName parseMIRPipeline is not overridden");
llvm_unreachable("getPassNameFromLegacyName is not overridden");
}

virtual Error parseMIRPipeline(MachineFunctionPassManager &MFPM,
StringRef PipelineText,
CGPassBuilderOption Opts,
MachineFunctionAnalysisManager &MFAM,
PassInstrumentationCallbacks *PIC) {
llvm_unreachable("parseMIRPipeline is not overridden");
}

/// Add passes to the specified pass manager to get machine code emitted with
Expand Down
18 changes: 2 additions & 16 deletions llvm/lib/CodeGen/MachinePassManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ template class AllAnalysesOn<MachineFunction>;
template class AnalysisManager<MachineFunction>;
template class PassManager<MachineFunction>;

// TODO: Add a way to run verifier and debugify passes.
Error MachineFunctionPassManager::run(Module &M,
MachineFunctionAnalysisManager &MFAM) {
// MachineModuleAnalysis is a module analysis pass that is never invalidated
Expand All @@ -30,26 +31,11 @@ Error MachineFunctionPassManager::run(Module &M,
// result of MachineModuleAnalysis. MMI should not be recomputed.
auto &MMI = MFAM.getResult<MachineModuleAnalysis>(M);

(void)RequireCodeGenSCCOrder;
assert(!RequireCodeGenSCCOrder && "not implemented");
assert(!Opt.RequiresCodeGenSCCOrder && "not implemented");

// M is unused here
PassInstrumentation PI = MFAM.getResult<PassInstrumentationAnalysis>(M);

// Add a PIC to verify machine functions.
if (VerifyMachineFunction) {
// No need to pop this callback later since MIR pipeline is flat which means
// current pipeline is the top-level pipeline. Callbacks are not used after
// current pipeline.
PI.pushBeforeNonSkippedPassCallback([&MFAM](StringRef PassID, Any IR) {
assert(llvm::any_cast<const MachineFunction *>(&IR));
const MachineFunction *MF = llvm::any_cast<const MachineFunction *>(IR);
assert(MF && "Machine function should be valid for printing");
std::string Banner = std::string("After ") + std::string(PassID);
verifyMachineFunction(&MFAM, Banner, *MF);
});
}

for (auto &F : InitializationFuncs) {
if (auto Err = F(M, MFAM))
return Err;
Expand Down
19 changes: 16 additions & 3 deletions llvm/lib/CodeGen/TargetPassConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,9 @@ static void registerPartialPipelineCallback(PassInstrumentationCallbacks &PIC,
unsigned StopBeforeInstanceNum = 0;
unsigned StopAfterInstanceNum = 0;

bool IsStopBeforeMachinePass = false;
bool IsStopAfterMachinePass = false;

std::tie(StartBefore, StartBeforeInstanceNum) =
getPassNameAndInstanceNum(StartBeforeOpt);
std::tie(StartAfter, StartAfterInstanceNum) =
Expand Down Expand Up @@ -544,7 +547,15 @@ static void registerPartialPipelineCallback(PassInstrumentationCallbacks &PIC,
report_fatal_error(Twine(StopBeforeOptName) + Twine(" and ") +
Twine(StopAfterOptName) + Twine(" specified!"));

PIC.registerShouldRunOptionalPassCallback(
std::vector<StringRef> SpecialPasses = {"PassManager", "PassAdaptor",
"PrintMIRPass", "PrintModulePass"};

PassInstrumentationCallbacks::CodeGenStartStopInfo Info;
Info.Start = StartBefore.empty() ? StartAfter : StartBefore;
Info.Stop = StopBefore.empty() ? StopAfter : StopBefore;

Info.IsStopMachinePass = IsStopBeforeMachinePass || IsStopAfterMachinePass;
Info.StartStopCallback =
[=, EnableCurrent = StartBefore.empty() && StartAfter.empty(),
EnableNext = std::optional<bool>(), StartBeforeCount = 0u,
StartAfterCount = 0u, StopBeforeCount = 0u,
Expand Down Expand Up @@ -575,8 +586,10 @@ static void registerPartialPipelineCallback(PassInstrumentationCallbacks &PIC,
EnableCurrent = true;
if (StopBeforePass && StopBeforeCount++ == StopBeforeInstanceNum)
EnableCurrent = false;
return EnableCurrent;
});
return EnableCurrent || isSpecialPass(P, SpecialPasses);
};

PIC.registerStartStopInfo(std::move(Info));
}

void llvm::registerCodeGenCallback(PassInstrumentationCallbacks &PIC,
Expand Down
7 changes: 4 additions & 3 deletions llvm/lib/Passes/StandardInstrumentations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1039,9 +1039,10 @@ void PrintPassInstrumentation::registerCallbacks(
SpecialPasses.emplace_back("PassAdaptor");
}

PIC.registerBeforeSkippedPassCallback([this, SpecialPasses](StringRef PassID,
Any IR) {
assert(!isSpecialPass(PassID, SpecialPasses) &&
PIC.registerBeforeSkippedPassCallback([this, SpecialPasses,
&PIC](StringRef PassID, Any IR) {
assert((!isSpecialPass(PassID, SpecialPasses) ||
PIC.isStartStopInfoRegistered()) &&
"Unexpectedly skipping special pass");

print() << "Skipping pass: " << PassID << " on " << getIRName(IR) << "\n";
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/X86/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,10 @@ add_llvm_target(X86CodeGen ${sources}
Core
GlobalISel
Instrumentation
IRPrinter
MC
ProfileData
ScalarOpts
SelectionDAG
Support
Target
Expand Down
76 changes: 76 additions & 0 deletions llvm/lib/Target/X86/X86PassRegistry.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
//===- X86PassRegistry.def - Registry of passes for X86 ---------*- 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
//
//===----------------------------------------------------------------------===//
//
// X86 pass registry
//
//===----------------------------------------------------------------------===//

// NOTE: NO INCLUDE GUARD DESIRED!

#ifndef FUNCTION_PASS
#define FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)
#endif

#undef FUNCTION_PASS

#ifndef DUMMY_FUNCTION_PASS
#define DUMMY_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)
#endif
DUMMY_FUNCTION_PASS("x86-win-eh-state", X86WinEHStatePass, ())
#undef DUMMY_FUNCTION_PASS

#ifndef MACHINE_FUNCTION_PASS
#define MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)
#endif

#undef MACHINE_FUNCTION_PASS

// PASS_NAME is for mocking machine passes, remove it after all machine passes
// are added new pass manager interface.
#ifndef DUMMY_MACHINE_FUNCTION_PASS
#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)
#endif
DUMMY_MACHINE_FUNCTION_PASS("x86-isel-dag", X86ISelDagPass, (getTM<X86TargetMachine>(), getOptLevel()))
DUMMY_MACHINE_FUNCTION_PASS("x86-global-basereg", X86GlobalBaseRegPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-cmov-converter", X86CmovConverterDummyPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-fixup-setcc", X86FixupSetCCPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-opt-leas", X86OptimizeLEAsPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-callframe-opt", X86CallFrameOptimizationPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-avoid-store-foword-block", X86AvoidStoreForwardingBlocksPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-speculative-load-hardening", X86SpeculativeLoadHardeningPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-flags-copy-lowering", X86FlagsCopyLoweringDummyPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-domain-reassign", X86DomainReassignmentPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-fp-stackifier", X86FloatingPointStackifierPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-expand-pseudo", X86ExpandPseudoPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-exec-domain-fix", X86ExecutionDomainFixPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-indirectbr-tracking", X86IndirectBranchTrackingPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-issue-vzero-upper", X86IssueVZeroUpperPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-fixup-bwinsts", X86FixupBWInstsPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-pad-short-funcs", X86PadShortFunctionsPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-fixup-leas", X86FixupLEAsPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-evex-to-vex-insts", X86EvexToVexInstsPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-discriminate-memops", X86DiscriminateMemOpsPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-insert-prefetch", X86InsertPrefetchPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-insert-x87-wait", X86InsertX87waitPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-avoid-trailing-call", X86AvoidTrailingCallPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-asm-printer", X86AsmPrinterPass, ())
DUMMY_MACHINE_FUNCTION_PASS("cleanup-local-dyn-tls", CleanupLocalDynamicTLSPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-fixup-inst-tuning", X86FixupInstTuningPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-fixup-vector-constants", X86FixupVectorConstantsPass, ())
DUMMY_MACHINE_FUNCTION_PASS("ehcontguard-catchret", EHContGuardCatchretPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-lvi-ret", X86LoadValueInjectionRetHardeningPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-lower-tile-copy", X86LowerTileCopyPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-seses", X86SpeculativeExecutionSideEffectSuppressionPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-retpoline-thunks", X86IndirectThunksPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-return-thunks", X86ReturnThunksPass, ())
DUMMY_MACHINE_FUNCTION_PASS("tileconfig", X86TileConfigPass, ())
DUMMY_MACHINE_FUNCTION_PASS("tile-pre-config", X86PreTileConfigPass, ())
DUMMY_MACHINE_FUNCTION_PASS("fastpretileconfig", X86FastPreTileConfigPass, ())
DUMMY_MACHINE_FUNCTION_PASS("fasttileconfig", X86FastTileConfigPass, ())
DUMMY_MACHINE_FUNCTION_PASS("x86-dyn-alloca-expander", X86DynAllocaExpanderPass, ())
#undef DUMMY_MACHINE_FUNCTION_PASS
Loading