-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[CodeGen][NewPM] Port AsmPrinter
to new pass manager
#99320
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
base: main
Are you sure you want to change the base?
Conversation
9f0778a
to
9ef2bbe
Compare
@llvm/pr-subscribers-backend-powerpc @llvm/pr-subscribers-backend-x86 Author: None (paperchalice) ChangesJust simply wrap it in a pass.
Patch is 53.75 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/99320.diff 29 Files Affected:
diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index dc00bd57d655d..48f96ebff37cb 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -21,6 +21,7 @@
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/DwarfStringPoolEntry.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachinePassManager.h"
#include "llvm/CodeGen/StackMaps.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/IR/InlineAsm.h"
@@ -83,7 +84,7 @@ class RemarkStreamer;
}
/// This class is intended to be used as a driving class for all asm writers.
-class AsmPrinter : public MachineFunctionPass {
+class AsmPrinter {
public:
/// Target machine description.
TargetMachine &TM;
@@ -179,8 +180,6 @@ class AsmPrinter : public MachineFunctionPass {
/// List of symbols to be inserted into PC sections.
DenseMap<const MDNode *, SmallVector<const MCSymbol *>> PCSectionsSymbols;
- static char ID;
-
protected:
MCSymbol *CurrentFnBegin = nullptr;
@@ -198,6 +197,10 @@ class AsmPrinter : public MachineFunctionPass {
StackMaps SM;
+ MachineFunctionPass *P = nullptr;
+ ModuleAnalysisManager *MAM = nullptr;
+ MachineFunctionAnalysisManager *MFAM = nullptr;
+
private:
/// If generated on the fly this own the instance.
std::unique_ptr<MachineDominatorTree> OwnedMDT;
@@ -229,7 +232,7 @@ class AsmPrinter : public MachineFunctionPass {
explicit AsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer);
public:
- ~AsmPrinter() override;
+ virtual ~AsmPrinter();
DwarfDebug *getDwarfDebug() { return DD; }
DwarfDebug *getDwarfDebug() const { return DD; }
@@ -369,24 +372,36 @@ class AsmPrinter : public MachineFunctionPass {
// MachineFunctionPass Implementation.
//===------------------------------------------------------------------===//
+ virtual StringRef getPassName() const;
+
/// Record analysis usage.
- void getAnalysisUsage(AnalysisUsage &AU) const override;
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
/// Set up the AsmPrinter when we are working on a new module. If your pass
/// overrides this, it must make sure to explicitly call this implementation.
- bool doInitialization(Module &M) override;
+ virtual bool doInitialization(Module &M);
/// Shut down the asmprinter. If you override this in your pass, you must make
/// sure to call it explicitly.
- bool doFinalization(Module &M) override;
+ virtual bool doFinalization(Module &M);
/// Emit the specified function out to the OutStreamer.
- bool runOnMachineFunction(MachineFunction &MF) override {
+ virtual bool runOnMachineFunction(MachineFunction &MF) {
SetupMachineFunction(MF);
emitFunctionBody();
return false;
}
+ void setPass(MachineFunctionPass *Pass) { P = Pass; }
+ void setMAM(ModuleAnalysisManager &AM) { MAM = &AM; }
+ void setMFAM(MachineFunctionAnalysisManager &AM) { MFAM = &AM; }
+
+ //===------------------------------------------------------------------===//
+ // New Pass Manager Implementation.
+ //===------------------------------------------------------------------===//
+
+ virtual void getPreservedAnalyses(PreservedAnalyses &PA) const {}
+
//===------------------------------------------------------------------===//
// Coarse grained IR lowering routines.
//===------------------------------------------------------------------===//
@@ -514,6 +529,7 @@ class AsmPrinter : public MachineFunctionPass {
/// Emit the stack maps.
void emitStackMaps();
+ void emitStackMaps(Module &M); // For new pass manager version.
//===------------------------------------------------------------------===//
// Overridable Hooks
@@ -905,6 +921,78 @@ class AsmPrinter : public MachineFunctionPass {
}
};
+class AsmPrinterInitializePass
+ : public PassInfoMixin<AsmPrinterInitializePass> {
+ std::shared_ptr<AsmPrinter> Printer;
+
+public:
+ explicit AsmPrinterInitializePass(std::shared_ptr<AsmPrinter> AP)
+ : Printer(AP) {}
+
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
+};
+
+class AsmPrinterPass : public PassInfoMixin<AsmPrinterPass> {
+ std::shared_ptr<AsmPrinter> Printer;
+
+public:
+ explicit AsmPrinterPass(std::shared_ptr<AsmPrinter> AP)
+ : Printer(std::move(AP)) {}
+
+ PreservedAnalyses run(MachineFunction &MF,
+ MachineFunctionAnalysisManager &MFAM);
+};
+
+class AsmPrinterFinalizePass : public PassInfoMixin<AsmPrinterFinalizePass> {
+ std::shared_ptr<AsmPrinter> Printer;
+
+public:
+ explicit AsmPrinterFinalizePass(std::shared_ptr<AsmPrinter> AP)
+ : Printer(AP) {}
+
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
+};
+
+class AsmPrinterLegacy : public MachineFunctionPass {
+ std::unique_ptr<AsmPrinter> Printer;
+
+public:
+ static char ID;
+
+ explicit AsmPrinterLegacy(std::unique_ptr<AsmPrinter> AP);
+
+ AsmPrinter &getPrinter() { return *Printer; }
+
+ //===------------------------------------------------------------------===//
+ // MachineFunctionPass Implementation.
+ //===------------------------------------------------------------------===//
+
+ /// Record analysis usage.
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ MachineFunctionPass::getAnalysisUsage(AU);
+ Printer->getAnalysisUsage(AU);
+ }
+
+ /// Set up the AsmPrinter when we are working on a new module. If your pass
+ /// overrides this, it must make sure to explicitly call this implementation.
+ bool doInitialization(Module &M) override {
+ return Printer->doInitialization(M);
+ }
+
+ /// Shut down the asmprinter. If you override this in your pass, you must make
+ /// sure to call it explicitly.
+ bool doFinalization(Module &M) override { return Printer->doFinalization(M); }
+
+ /// Emit the specified function out to the OutStreamer.
+ bool runOnMachineFunction(MachineFunction &MF) override {
+ return Printer->runOnMachineFunction(MF);
+ }
+
+ StringRef getPassName() const override { return Printer->getPassName(); }
+};
+
+AsmPrinterLegacy *createAsmPrinterLegacy(std::unique_ptr<AsmPrinter> AP);
+
} // end namespace llvm
#endif // LLVM_CODEGEN_ASMPRINTER_H
diff --git a/llvm/include/llvm/CodeGen/GCMetadata.h b/llvm/include/llvm/CodeGen/GCMetadata.h
index ca6a511185c7c..f22aa2c54f401 100644
--- a/llvm/include/llvm/CodeGen/GCMetadata.h
+++ b/llvm/include/llvm/CodeGen/GCMetadata.h
@@ -151,15 +151,46 @@ class GCFunctionInfo {
size_t live_size(const iterator &p) const { return roots_size(); }
};
-struct GCStrategyMap {
+class GCStrategyMap {
StringMap<std::unique_ptr<GCStrategy>> StrategyMap;
+ SmallVector<GCStrategy *, 1> StrategyList; // For bidirectional iterator.
+ using StrategyListT = SmallVector<GCStrategy *, 1>;
+ FunctionAnalysisManager *FAM = nullptr;
+
+public:
GCStrategyMap() = default;
GCStrategyMap(GCStrategyMap &&) = default;
+ GCStrategyMap(FunctionAnalysisManager &FAM) : FAM(&FAM) {}
/// Handle invalidation explicitly.
bool invalidate(Module &M, const PreservedAnalyses &PA,
ModuleAnalysisManager::Invalidator &Inv);
+
+ GCFunctionInfo &getFunctionInfo(Function &F);
+
+ bool empty() const { return StrategyMap.empty(); }
+
+ bool contains(StringRef Name) const { return StrategyMap.contains(Name); }
+
+ /// Insert a new strategy if it is not existed, otherwise do nothing.
+ void insert(StringRef Name, std::unique_ptr<GCStrategy> Strategy) {
+ auto &S = StrategyMap[Name];
+ if (!S) {
+ S = std::move(Strategy);
+ StrategyList.push_back(S.get());
+ }
+ }
+
+ GCStrategy &at(StringRef Name) { return *StrategyMap.at(Name); }
+
+ // This class must support bidirectional iterator which is used by AsmPrinter.
+ using iterator = StrategyListT::iterator;
+ iterator begin() { return StrategyList.begin(); }
+ iterator end() { return StrategyList.end(); }
+ using reverse_iterator = StrategyListT::reverse_iterator;
+ reverse_iterator rbegin() { return StrategyList.rbegin(); }
+ reverse_iterator rend() { return StrategyList.rend(); }
};
/// An analysis pass which caches information about the entire Module.
diff --git a/llvm/include/llvm/CodeGen/GCMetadataPrinter.h b/llvm/include/llvm/CodeGen/GCMetadataPrinter.h
index f9527c9f8752e..a7cf6ec914b9c 100644
--- a/llvm/include/llvm/CodeGen/GCMetadataPrinter.h
+++ b/llvm/include/llvm/CodeGen/GCMetadataPrinter.h
@@ -27,8 +27,11 @@ class AsmPrinter;
class GCMetadataPrinter;
class GCModuleInfo;
class GCStrategy;
+class GCStrategyMap;
class Module;
class StackMaps;
+template <typename IRUnitT, typename... ExtraArgTs> class AnalysisManager;
+using ModuleAnalysisManager = AnalysisManager<Module>;
/// GCMetadataPrinterRegistry - The GC assembly printer registry uses all the
/// defaults from Registry.
@@ -56,10 +59,12 @@ class GCMetadataPrinter {
/// Called before the assembly for the module is generated by
/// the AsmPrinter (but after target specific hooks.)
virtual void beginAssembly(Module &M, GCModuleInfo &Info, AsmPrinter &AP) {}
+ virtual void beginAssembly(Module &M, GCStrategyMap &Map, AsmPrinter &AP) {}
/// Called after the assembly for the module is generated by
/// the AsmPrinter (but before target specific hooks)
virtual void finishAssembly(Module &M, GCModuleInfo &Info, AsmPrinter &AP) {}
+ virtual void finishAssembly(Module &M, GCStrategyMap &Map, AsmPrinter &AP) {}
/// Called when the stack maps are generated. Return true if
/// stack maps with a custom format are generated. Otherwise
diff --git a/llvm/include/llvm/MC/TargetRegistry.h b/llvm/include/llvm/MC/TargetRegistry.h
index 5038b87cd1dc9..1c48dfe2f3fa9 100644
--- a/llvm/include/llvm/MC/TargetRegistry.h
+++ b/llvm/include/llvm/MC/TargetRegistry.h
@@ -36,6 +36,7 @@
namespace llvm {
class AsmPrinter;
+class AsmPrinterLegacy;
class MCAsmBackend;
class MCAsmInfo;
class MCAsmParser;
@@ -57,6 +58,8 @@ class MCTargetStreamer;
class raw_ostream;
class TargetMachine;
class TargetOptions;
+
+AsmPrinterLegacy *createAsmPrinterLegacy(std::unique_ptr<AsmPrinter> AP);
namespace mca {
class CustomBehaviour;
class InstrPostProcess;
@@ -170,8 +173,12 @@ class Target {
// If it weren't for layering issues (this header is in llvm/Support, but
// depends on MC?) this should take the Streamer by value rather than rvalue
// reference.
- using AsmPrinterCtorTy = AsmPrinter *(*)(
- TargetMachine &TM, std::unique_ptr<MCStreamer> &&Streamer);
+ using AsmPrinterLegacyCtorTy =
+ AsmPrinterLegacy *(*)(TargetMachine &TM,
+ std::unique_ptr<MCStreamer> &&Streamer);
+ using AsmPrinterCtorTy =
+ AsmPrinter *(*)(TargetMachine &TM,
+ std::unique_ptr<MCStreamer> &&Streamer);
using MCAsmBackendCtorTy = MCAsmBackend *(*)(const Target &T,
const MCSubtargetInfo &STI,
const MCRegisterInfo &MRI,
@@ -314,6 +321,7 @@ class Target {
/// AsmPrinterCtorFn - Construction function for this target's AsmPrinter,
/// if registered.
+ AsmPrinterLegacyCtorTy AsmPrinterLegacyCtorFn;
AsmPrinterCtorTy AsmPrinterCtorFn;
/// MCDisassemblerCtorFn - Construction function for this target's
@@ -517,6 +525,16 @@ class Target {
/// createAsmPrinter - Create a target specific assembly printer pass. This
/// takes ownership of the MCStreamer object.
+ AsmPrinterLegacy *
+ createAsmPrinterLegacy(TargetMachine &TM,
+ std::unique_ptr<MCStreamer> &&Streamer) const {
+ if (!AsmPrinterLegacyCtorFn)
+ return nullptr;
+ return AsmPrinterLegacyCtorFn(TM, std::move(Streamer));
+ }
+
+ /// Same as `createAsmPrinter`, but only create AsmPrinter, for new pass
+ /// manager.
AsmPrinter *createAsmPrinter(TargetMachine &TM,
std::unique_ptr<MCStreamer> &&Streamer) const {
if (!AsmPrinterCtorFn)
@@ -963,6 +981,9 @@ struct TargetRegistry {
///
/// @param T - The target being registered.
/// @param Fn - A function to construct an AsmPrinter for the target.
+ static void RegisterAsmPrinter(Target &T, Target::AsmPrinterLegacyCtorTy Fn) {
+ T.AsmPrinterLegacyCtorFn = Fn;
+ }
static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
T.AsmPrinterCtorFn = Fn;
}
@@ -1428,9 +1449,16 @@ template <class MCAsmParserImpl> struct RegisterMCAsmParser {
template <class AsmPrinterImpl> struct RegisterAsmPrinter {
RegisterAsmPrinter(Target &T) {
TargetRegistry::RegisterAsmPrinter(T, &Allocator);
+ TargetRegistry::RegisterAsmPrinter(T, &AllocatorLegacy);
}
private:
+ static AsmPrinterLegacy *
+ AllocatorLegacy(TargetMachine &TM, std::unique_ptr<MCStreamer> &&Streamer) {
+ auto *P = new AsmPrinterImpl(TM, std::move(Streamer));
+ return createAsmPrinterLegacy(std::unique_ptr<AsmPrinter>(P));
+ }
+
static AsmPrinter *Allocator(TargetMachine &TM,
std::unique_ptr<MCStreamer> &&Streamer) {
return new AsmPrinterImpl(TM, std::move(Streamer));
diff --git a/llvm/include/llvm/Passes/CodeGenPassBuilder.h b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
index fb7a3c107d88a..f73e1a12e70ac 100644
--- a/llvm/include/llvm/Passes/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
@@ -22,6 +22,7 @@
#include "llvm/Analysis/ScopedNoAliasAA.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/TypeBasedAliasAnalysis.h"
+#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/AssignmentTrackingAnalysis.h"
#include "llvm/CodeGen/CallBrPrepare.h"
#include "llvm/CodeGen/CodeGenPrepare.h"
@@ -62,6 +63,7 @@
#include "llvm/IRPrinter/IRPrintingPasses.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCTargetOptions.h"
+#include "llvm/Passes/PassBuilder.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Error.h"
@@ -119,9 +121,8 @@ namespace llvm {
template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
public:
explicit CodeGenPassBuilder(TargetMachineT &TM,
- const CGPassBuilderOption &Opts,
- PassInstrumentationCallbacks *PIC)
- : TM(TM), Opt(Opts), PIC(PIC) {
+ const CGPassBuilderOption &Opts, PassBuilder &PB)
+ : TM(TM), Opt(Opts), PB(PB), PIC(PB.getPassInstrumentationCallbacks()) {
// Target could set CGPassBuilderOption::MISchedPostRA to true to achieve
// substitutePass(&PostRASchedulerID, &PostMachineSchedulerID)
@@ -138,8 +139,8 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
}
Error buildPipeline(ModulePassManager &MPM, raw_pwrite_stream &Out,
- raw_pwrite_stream *DwoOut,
- CodeGenFileType FileType) const;
+ raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
+ MCContext &Ctx) const;
PassInstrumentationCallbacks *getPassInstrumentationCallbacks() const {
return PIC;
@@ -256,7 +257,9 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
TargetMachineT &TM;
CGPassBuilderOption Opt;
+ PassBuilder &PB;
PassInstrumentationCallbacks *PIC;
+ mutable std::shared_ptr<AsmPrinter> PrinterImpl;
template <typename TMC> TMC &getTM() const { return static_cast<TMC &>(TM); }
CodeGenOptLevel getOptLevel() const { return TM.getOptLevel(); }
@@ -518,7 +521,7 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
template <typename Derived, typename TargetMachineT>
Error CodeGenPassBuilder<Derived, TargetMachineT>::buildPipeline(
ModulePassManager &MPM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
- CodeGenFileType FileType) const {
+ CodeGenFileType FileType, MCContext &Ctx) const {
auto StartStopInfo = TargetPassConfig::getStartStopInfo(*PIC);
if (!StartStopInfo)
return StartStopInfo.takeError();
@@ -527,6 +530,14 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::buildPipeline(
bool PrintAsm = TargetPassConfig::willCompleteCodeGenPipeline();
bool PrintMIR = !PrintAsm && FileType != CodeGenFileType::Null;
+ if (PrintAsm) {
+ Expected<std::unique_ptr<MCStreamer>> MCStreamerOrErr =
+ TM.createMCStreamer(Out, DwoOut, FileType, Ctx);
+ if (auto Err = MCStreamerOrErr.takeError())
+ return Err;
+ PrinterImpl = PB.getAsmPrinter(std::move(*MCStreamerOrErr));
+ }
+
{
AddIRPass addIRPass(MPM, derived());
addIRPass(RequireAnalysisPass<MachineModuleAnalysis, Module>());
@@ -535,26 +546,30 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::buildPipeline(
addISelPasses(addIRPass);
}
- AddMachinePass addPass(MPM, derived());
+ // Ensure we destruct `addPass`.
+ {
+ AddMachinePass addPass(MPM, derived());
- if (PrintMIR)
- addPass(PrintMIRPreparePass(Out), /*Force=*/true);
+ if (PrintMIR)
+ addPass(PrintMIRPreparePass(Out), /*Force=*/true);
- if (auto Err = addCoreISelPasses(addPass))
- return std::move(Err);
+ if (auto Err = addCoreISelPasses(addPass))
+ return std::move(Err);
- if (auto Err = derived().addMachinePasses(addPass))
- return std::move(Err);
+ if (auto Err = derived().addMachinePasses(addPass))
+ return std::move(Err);
- if (PrintAsm) {
- derived().addAsmPrinter(
- addPass, [this, &Out, DwoOut, FileType](MCContext &Ctx) {
- return this->TM.createMCStreamer(Out, DwoOut, FileType, Ctx);
- });
+ if (PrintAsm)
+ addPass(AsmPrinterPass(PrinterImpl));
+
+ if (PrintMIR)
+ addPass(PrintMIRPass(Out), /*Force=*/true);
}
- if (PrintMIR)
- addPass(PrintMIRPass(Out), /*Force=*/true);
+ {
+ AddIRPass addIRPass(MPM, derived());
+ addIRPass(AsmPrinterFinalizePass(PrinterImpl));
+ }
return verifyStartStop(*StartStopInfo);
}
@@ -665,6 +680,10 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addIRPasses(
addPass(ExpandMemCmpPass(&TM));
}
+ // This should be the last IR module pass.
+ if (TargetPassConfig::willCompleteCodeGenPipeline())
+ addPass(AsmPrinterInitializePass(PrinterImpl));
+
// Run GC lowering passes for builtin collectors
// TODO: add a pass insertion point here
addPass(GCLoweringPass());
diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h
index 551d297e0c089..46759eabd58af 100644
--- a/llvm/include/llvm/Passes/PassBuilder.h
+++ b/llvm/include/llvm/Passes/PassBuilder.h
@@ -32,6 +32,7 @@
namespace llvm {
class StringRef;
+class AsmPrinter;
class AAManager;
class TargetMachine;
class ModuleSummaryIndex;
@@ -590,6 +591,12 @@ class PassBuilder {
RegClassFilterParsingCallbacks.push_back(C);
}
+ void registerAsmPrinterCreationCallback(
+ const std::function<
+ std::shared_ptr<AsmPrinter>(std::unique_ptr<MCStreamer>)> &C) {
+ AsmPrinterCreationCallback = C;
+ }
+
/// Register a callback for a top-level pipeline entry.
///
/// If the PassManager type is not given at the top level of the pipeline
@@ -693,6 +700,11 @@ class PassBuilder {
StringRef OptionName,
StringRef PassName);
+ // Create target asm printer directly, this can bypass
+ // LLVMInitializeXXXAsmPrinter.
+ std::shared_ptr<AsmPrinter>
+ getAsmPrinter(std::unique_ptr<MCStreamer> Streamer);
+
private:
// O1 pass pipeline
FunctionPassManager
@@ -809,6 +821,9 @@ class PassBuilder {
// Callbacks to parse `filter` parameter in register allocation passes
SmallVector<std::function<RegClassFilterFunc(StringRef)>, 2>
RegClassFilterParsingCallbacks;
+ // Callback to create `AsmPrinterPass`.
+ std::function<std::shared_ptr<AsmPrinter>(std::unique_ptr<MCStreamer>)>
+ AsmPrinterCreationCallback;
};
/// This utility template takes care of adding require<> and invalidate<>
diff --git a/llvm/include/llvm/Target/TargetMachine.h b/llvm/include/llvm/Target/TargetMachine.h
index b8e56c755fbda..043d88fa47acd 100644
--- a/llvm/include/llvm/Target/TargetMachine.h
+++ b/llvm/include/llvm/Target/TargetMachine.h
@@ -471,8 +471,8 @@ class LLVMTargetMachine : public TargetMachine {
virtual Error b...
[truncated]
|
@llvm/pr-subscribers-backend-amdgpu Author: None (paperchalice) ChangesJust simply wrap it in a pass.
Patch is 53.75 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/99320.diff 29 Files Affected:
diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index dc00bd57d655d..48f96ebff37cb 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -21,6 +21,7 @@
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/DwarfStringPoolEntry.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachinePassManager.h"
#include "llvm/CodeGen/StackMaps.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/IR/InlineAsm.h"
@@ -83,7 +84,7 @@ class RemarkStreamer;
}
/// This class is intended to be used as a driving class for all asm writers.
-class AsmPrinter : public MachineFunctionPass {
+class AsmPrinter {
public:
/// Target machine description.
TargetMachine &TM;
@@ -179,8 +180,6 @@ class AsmPrinter : public MachineFunctionPass {
/// List of symbols to be inserted into PC sections.
DenseMap<const MDNode *, SmallVector<const MCSymbol *>> PCSectionsSymbols;
- static char ID;
-
protected:
MCSymbol *CurrentFnBegin = nullptr;
@@ -198,6 +197,10 @@ class AsmPrinter : public MachineFunctionPass {
StackMaps SM;
+ MachineFunctionPass *P = nullptr;
+ ModuleAnalysisManager *MAM = nullptr;
+ MachineFunctionAnalysisManager *MFAM = nullptr;
+
private:
/// If generated on the fly this own the instance.
std::unique_ptr<MachineDominatorTree> OwnedMDT;
@@ -229,7 +232,7 @@ class AsmPrinter : public MachineFunctionPass {
explicit AsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer);
public:
- ~AsmPrinter() override;
+ virtual ~AsmPrinter();
DwarfDebug *getDwarfDebug() { return DD; }
DwarfDebug *getDwarfDebug() const { return DD; }
@@ -369,24 +372,36 @@ class AsmPrinter : public MachineFunctionPass {
// MachineFunctionPass Implementation.
//===------------------------------------------------------------------===//
+ virtual StringRef getPassName() const;
+
/// Record analysis usage.
- void getAnalysisUsage(AnalysisUsage &AU) const override;
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
/// Set up the AsmPrinter when we are working on a new module. If your pass
/// overrides this, it must make sure to explicitly call this implementation.
- bool doInitialization(Module &M) override;
+ virtual bool doInitialization(Module &M);
/// Shut down the asmprinter. If you override this in your pass, you must make
/// sure to call it explicitly.
- bool doFinalization(Module &M) override;
+ virtual bool doFinalization(Module &M);
/// Emit the specified function out to the OutStreamer.
- bool runOnMachineFunction(MachineFunction &MF) override {
+ virtual bool runOnMachineFunction(MachineFunction &MF) {
SetupMachineFunction(MF);
emitFunctionBody();
return false;
}
+ void setPass(MachineFunctionPass *Pass) { P = Pass; }
+ void setMAM(ModuleAnalysisManager &AM) { MAM = &AM; }
+ void setMFAM(MachineFunctionAnalysisManager &AM) { MFAM = &AM; }
+
+ //===------------------------------------------------------------------===//
+ // New Pass Manager Implementation.
+ //===------------------------------------------------------------------===//
+
+ virtual void getPreservedAnalyses(PreservedAnalyses &PA) const {}
+
//===------------------------------------------------------------------===//
// Coarse grained IR lowering routines.
//===------------------------------------------------------------------===//
@@ -514,6 +529,7 @@ class AsmPrinter : public MachineFunctionPass {
/// Emit the stack maps.
void emitStackMaps();
+ void emitStackMaps(Module &M); // For new pass manager version.
//===------------------------------------------------------------------===//
// Overridable Hooks
@@ -905,6 +921,78 @@ class AsmPrinter : public MachineFunctionPass {
}
};
+class AsmPrinterInitializePass
+ : public PassInfoMixin<AsmPrinterInitializePass> {
+ std::shared_ptr<AsmPrinter> Printer;
+
+public:
+ explicit AsmPrinterInitializePass(std::shared_ptr<AsmPrinter> AP)
+ : Printer(AP) {}
+
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
+};
+
+class AsmPrinterPass : public PassInfoMixin<AsmPrinterPass> {
+ std::shared_ptr<AsmPrinter> Printer;
+
+public:
+ explicit AsmPrinterPass(std::shared_ptr<AsmPrinter> AP)
+ : Printer(std::move(AP)) {}
+
+ PreservedAnalyses run(MachineFunction &MF,
+ MachineFunctionAnalysisManager &MFAM);
+};
+
+class AsmPrinterFinalizePass : public PassInfoMixin<AsmPrinterFinalizePass> {
+ std::shared_ptr<AsmPrinter> Printer;
+
+public:
+ explicit AsmPrinterFinalizePass(std::shared_ptr<AsmPrinter> AP)
+ : Printer(AP) {}
+
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
+};
+
+class AsmPrinterLegacy : public MachineFunctionPass {
+ std::unique_ptr<AsmPrinter> Printer;
+
+public:
+ static char ID;
+
+ explicit AsmPrinterLegacy(std::unique_ptr<AsmPrinter> AP);
+
+ AsmPrinter &getPrinter() { return *Printer; }
+
+ //===------------------------------------------------------------------===//
+ // MachineFunctionPass Implementation.
+ //===------------------------------------------------------------------===//
+
+ /// Record analysis usage.
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ MachineFunctionPass::getAnalysisUsage(AU);
+ Printer->getAnalysisUsage(AU);
+ }
+
+ /// Set up the AsmPrinter when we are working on a new module. If your pass
+ /// overrides this, it must make sure to explicitly call this implementation.
+ bool doInitialization(Module &M) override {
+ return Printer->doInitialization(M);
+ }
+
+ /// Shut down the asmprinter. If you override this in your pass, you must make
+ /// sure to call it explicitly.
+ bool doFinalization(Module &M) override { return Printer->doFinalization(M); }
+
+ /// Emit the specified function out to the OutStreamer.
+ bool runOnMachineFunction(MachineFunction &MF) override {
+ return Printer->runOnMachineFunction(MF);
+ }
+
+ StringRef getPassName() const override { return Printer->getPassName(); }
+};
+
+AsmPrinterLegacy *createAsmPrinterLegacy(std::unique_ptr<AsmPrinter> AP);
+
} // end namespace llvm
#endif // LLVM_CODEGEN_ASMPRINTER_H
diff --git a/llvm/include/llvm/CodeGen/GCMetadata.h b/llvm/include/llvm/CodeGen/GCMetadata.h
index ca6a511185c7c..f22aa2c54f401 100644
--- a/llvm/include/llvm/CodeGen/GCMetadata.h
+++ b/llvm/include/llvm/CodeGen/GCMetadata.h
@@ -151,15 +151,46 @@ class GCFunctionInfo {
size_t live_size(const iterator &p) const { return roots_size(); }
};
-struct GCStrategyMap {
+class GCStrategyMap {
StringMap<std::unique_ptr<GCStrategy>> StrategyMap;
+ SmallVector<GCStrategy *, 1> StrategyList; // For bidirectional iterator.
+ using StrategyListT = SmallVector<GCStrategy *, 1>;
+ FunctionAnalysisManager *FAM = nullptr;
+
+public:
GCStrategyMap() = default;
GCStrategyMap(GCStrategyMap &&) = default;
+ GCStrategyMap(FunctionAnalysisManager &FAM) : FAM(&FAM) {}
/// Handle invalidation explicitly.
bool invalidate(Module &M, const PreservedAnalyses &PA,
ModuleAnalysisManager::Invalidator &Inv);
+
+ GCFunctionInfo &getFunctionInfo(Function &F);
+
+ bool empty() const { return StrategyMap.empty(); }
+
+ bool contains(StringRef Name) const { return StrategyMap.contains(Name); }
+
+ /// Insert a new strategy if it is not existed, otherwise do nothing.
+ void insert(StringRef Name, std::unique_ptr<GCStrategy> Strategy) {
+ auto &S = StrategyMap[Name];
+ if (!S) {
+ S = std::move(Strategy);
+ StrategyList.push_back(S.get());
+ }
+ }
+
+ GCStrategy &at(StringRef Name) { return *StrategyMap.at(Name); }
+
+ // This class must support bidirectional iterator which is used by AsmPrinter.
+ using iterator = StrategyListT::iterator;
+ iterator begin() { return StrategyList.begin(); }
+ iterator end() { return StrategyList.end(); }
+ using reverse_iterator = StrategyListT::reverse_iterator;
+ reverse_iterator rbegin() { return StrategyList.rbegin(); }
+ reverse_iterator rend() { return StrategyList.rend(); }
};
/// An analysis pass which caches information about the entire Module.
diff --git a/llvm/include/llvm/CodeGen/GCMetadataPrinter.h b/llvm/include/llvm/CodeGen/GCMetadataPrinter.h
index f9527c9f8752e..a7cf6ec914b9c 100644
--- a/llvm/include/llvm/CodeGen/GCMetadataPrinter.h
+++ b/llvm/include/llvm/CodeGen/GCMetadataPrinter.h
@@ -27,8 +27,11 @@ class AsmPrinter;
class GCMetadataPrinter;
class GCModuleInfo;
class GCStrategy;
+class GCStrategyMap;
class Module;
class StackMaps;
+template <typename IRUnitT, typename... ExtraArgTs> class AnalysisManager;
+using ModuleAnalysisManager = AnalysisManager<Module>;
/// GCMetadataPrinterRegistry - The GC assembly printer registry uses all the
/// defaults from Registry.
@@ -56,10 +59,12 @@ class GCMetadataPrinter {
/// Called before the assembly for the module is generated by
/// the AsmPrinter (but after target specific hooks.)
virtual void beginAssembly(Module &M, GCModuleInfo &Info, AsmPrinter &AP) {}
+ virtual void beginAssembly(Module &M, GCStrategyMap &Map, AsmPrinter &AP) {}
/// Called after the assembly for the module is generated by
/// the AsmPrinter (but before target specific hooks)
virtual void finishAssembly(Module &M, GCModuleInfo &Info, AsmPrinter &AP) {}
+ virtual void finishAssembly(Module &M, GCStrategyMap &Map, AsmPrinter &AP) {}
/// Called when the stack maps are generated. Return true if
/// stack maps with a custom format are generated. Otherwise
diff --git a/llvm/include/llvm/MC/TargetRegistry.h b/llvm/include/llvm/MC/TargetRegistry.h
index 5038b87cd1dc9..1c48dfe2f3fa9 100644
--- a/llvm/include/llvm/MC/TargetRegistry.h
+++ b/llvm/include/llvm/MC/TargetRegistry.h
@@ -36,6 +36,7 @@
namespace llvm {
class AsmPrinter;
+class AsmPrinterLegacy;
class MCAsmBackend;
class MCAsmInfo;
class MCAsmParser;
@@ -57,6 +58,8 @@ class MCTargetStreamer;
class raw_ostream;
class TargetMachine;
class TargetOptions;
+
+AsmPrinterLegacy *createAsmPrinterLegacy(std::unique_ptr<AsmPrinter> AP);
namespace mca {
class CustomBehaviour;
class InstrPostProcess;
@@ -170,8 +173,12 @@ class Target {
// If it weren't for layering issues (this header is in llvm/Support, but
// depends on MC?) this should take the Streamer by value rather than rvalue
// reference.
- using AsmPrinterCtorTy = AsmPrinter *(*)(
- TargetMachine &TM, std::unique_ptr<MCStreamer> &&Streamer);
+ using AsmPrinterLegacyCtorTy =
+ AsmPrinterLegacy *(*)(TargetMachine &TM,
+ std::unique_ptr<MCStreamer> &&Streamer);
+ using AsmPrinterCtorTy =
+ AsmPrinter *(*)(TargetMachine &TM,
+ std::unique_ptr<MCStreamer> &&Streamer);
using MCAsmBackendCtorTy = MCAsmBackend *(*)(const Target &T,
const MCSubtargetInfo &STI,
const MCRegisterInfo &MRI,
@@ -314,6 +321,7 @@ class Target {
/// AsmPrinterCtorFn - Construction function for this target's AsmPrinter,
/// if registered.
+ AsmPrinterLegacyCtorTy AsmPrinterLegacyCtorFn;
AsmPrinterCtorTy AsmPrinterCtorFn;
/// MCDisassemblerCtorFn - Construction function for this target's
@@ -517,6 +525,16 @@ class Target {
/// createAsmPrinter - Create a target specific assembly printer pass. This
/// takes ownership of the MCStreamer object.
+ AsmPrinterLegacy *
+ createAsmPrinterLegacy(TargetMachine &TM,
+ std::unique_ptr<MCStreamer> &&Streamer) const {
+ if (!AsmPrinterLegacyCtorFn)
+ return nullptr;
+ return AsmPrinterLegacyCtorFn(TM, std::move(Streamer));
+ }
+
+ /// Same as `createAsmPrinter`, but only create AsmPrinter, for new pass
+ /// manager.
AsmPrinter *createAsmPrinter(TargetMachine &TM,
std::unique_ptr<MCStreamer> &&Streamer) const {
if (!AsmPrinterCtorFn)
@@ -963,6 +981,9 @@ struct TargetRegistry {
///
/// @param T - The target being registered.
/// @param Fn - A function to construct an AsmPrinter for the target.
+ static void RegisterAsmPrinter(Target &T, Target::AsmPrinterLegacyCtorTy Fn) {
+ T.AsmPrinterLegacyCtorFn = Fn;
+ }
static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
T.AsmPrinterCtorFn = Fn;
}
@@ -1428,9 +1449,16 @@ template <class MCAsmParserImpl> struct RegisterMCAsmParser {
template <class AsmPrinterImpl> struct RegisterAsmPrinter {
RegisterAsmPrinter(Target &T) {
TargetRegistry::RegisterAsmPrinter(T, &Allocator);
+ TargetRegistry::RegisterAsmPrinter(T, &AllocatorLegacy);
}
private:
+ static AsmPrinterLegacy *
+ AllocatorLegacy(TargetMachine &TM, std::unique_ptr<MCStreamer> &&Streamer) {
+ auto *P = new AsmPrinterImpl(TM, std::move(Streamer));
+ return createAsmPrinterLegacy(std::unique_ptr<AsmPrinter>(P));
+ }
+
static AsmPrinter *Allocator(TargetMachine &TM,
std::unique_ptr<MCStreamer> &&Streamer) {
return new AsmPrinterImpl(TM, std::move(Streamer));
diff --git a/llvm/include/llvm/Passes/CodeGenPassBuilder.h b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
index fb7a3c107d88a..f73e1a12e70ac 100644
--- a/llvm/include/llvm/Passes/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
@@ -22,6 +22,7 @@
#include "llvm/Analysis/ScopedNoAliasAA.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/TypeBasedAliasAnalysis.h"
+#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/AssignmentTrackingAnalysis.h"
#include "llvm/CodeGen/CallBrPrepare.h"
#include "llvm/CodeGen/CodeGenPrepare.h"
@@ -62,6 +63,7 @@
#include "llvm/IRPrinter/IRPrintingPasses.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCTargetOptions.h"
+#include "llvm/Passes/PassBuilder.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Error.h"
@@ -119,9 +121,8 @@ namespace llvm {
template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
public:
explicit CodeGenPassBuilder(TargetMachineT &TM,
- const CGPassBuilderOption &Opts,
- PassInstrumentationCallbacks *PIC)
- : TM(TM), Opt(Opts), PIC(PIC) {
+ const CGPassBuilderOption &Opts, PassBuilder &PB)
+ : TM(TM), Opt(Opts), PB(PB), PIC(PB.getPassInstrumentationCallbacks()) {
// Target could set CGPassBuilderOption::MISchedPostRA to true to achieve
// substitutePass(&PostRASchedulerID, &PostMachineSchedulerID)
@@ -138,8 +139,8 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
}
Error buildPipeline(ModulePassManager &MPM, raw_pwrite_stream &Out,
- raw_pwrite_stream *DwoOut,
- CodeGenFileType FileType) const;
+ raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
+ MCContext &Ctx) const;
PassInstrumentationCallbacks *getPassInstrumentationCallbacks() const {
return PIC;
@@ -256,7 +257,9 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
TargetMachineT &TM;
CGPassBuilderOption Opt;
+ PassBuilder &PB;
PassInstrumentationCallbacks *PIC;
+ mutable std::shared_ptr<AsmPrinter> PrinterImpl;
template <typename TMC> TMC &getTM() const { return static_cast<TMC &>(TM); }
CodeGenOptLevel getOptLevel() const { return TM.getOptLevel(); }
@@ -518,7 +521,7 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
template <typename Derived, typename TargetMachineT>
Error CodeGenPassBuilder<Derived, TargetMachineT>::buildPipeline(
ModulePassManager &MPM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
- CodeGenFileType FileType) const {
+ CodeGenFileType FileType, MCContext &Ctx) const {
auto StartStopInfo = TargetPassConfig::getStartStopInfo(*PIC);
if (!StartStopInfo)
return StartStopInfo.takeError();
@@ -527,6 +530,14 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::buildPipeline(
bool PrintAsm = TargetPassConfig::willCompleteCodeGenPipeline();
bool PrintMIR = !PrintAsm && FileType != CodeGenFileType::Null;
+ if (PrintAsm) {
+ Expected<std::unique_ptr<MCStreamer>> MCStreamerOrErr =
+ TM.createMCStreamer(Out, DwoOut, FileType, Ctx);
+ if (auto Err = MCStreamerOrErr.takeError())
+ return Err;
+ PrinterImpl = PB.getAsmPrinter(std::move(*MCStreamerOrErr));
+ }
+
{
AddIRPass addIRPass(MPM, derived());
addIRPass(RequireAnalysisPass<MachineModuleAnalysis, Module>());
@@ -535,26 +546,30 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::buildPipeline(
addISelPasses(addIRPass);
}
- AddMachinePass addPass(MPM, derived());
+ // Ensure we destruct `addPass`.
+ {
+ AddMachinePass addPass(MPM, derived());
- if (PrintMIR)
- addPass(PrintMIRPreparePass(Out), /*Force=*/true);
+ if (PrintMIR)
+ addPass(PrintMIRPreparePass(Out), /*Force=*/true);
- if (auto Err = addCoreISelPasses(addPass))
- return std::move(Err);
+ if (auto Err = addCoreISelPasses(addPass))
+ return std::move(Err);
- if (auto Err = derived().addMachinePasses(addPass))
- return std::move(Err);
+ if (auto Err = derived().addMachinePasses(addPass))
+ return std::move(Err);
- if (PrintAsm) {
- derived().addAsmPrinter(
- addPass, [this, &Out, DwoOut, FileType](MCContext &Ctx) {
- return this->TM.createMCStreamer(Out, DwoOut, FileType, Ctx);
- });
+ if (PrintAsm)
+ addPass(AsmPrinterPass(PrinterImpl));
+
+ if (PrintMIR)
+ addPass(PrintMIRPass(Out), /*Force=*/true);
}
- if (PrintMIR)
- addPass(PrintMIRPass(Out), /*Force=*/true);
+ {
+ AddIRPass addIRPass(MPM, derived());
+ addIRPass(AsmPrinterFinalizePass(PrinterImpl));
+ }
return verifyStartStop(*StartStopInfo);
}
@@ -665,6 +680,10 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addIRPasses(
addPass(ExpandMemCmpPass(&TM));
}
+ // This should be the last IR module pass.
+ if (TargetPassConfig::willCompleteCodeGenPipeline())
+ addPass(AsmPrinterInitializePass(PrinterImpl));
+
// Run GC lowering passes for builtin collectors
// TODO: add a pass insertion point here
addPass(GCLoweringPass());
diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h
index 551d297e0c089..46759eabd58af 100644
--- a/llvm/include/llvm/Passes/PassBuilder.h
+++ b/llvm/include/llvm/Passes/PassBuilder.h
@@ -32,6 +32,7 @@
namespace llvm {
class StringRef;
+class AsmPrinter;
class AAManager;
class TargetMachine;
class ModuleSummaryIndex;
@@ -590,6 +591,12 @@ class PassBuilder {
RegClassFilterParsingCallbacks.push_back(C);
}
+ void registerAsmPrinterCreationCallback(
+ const std::function<
+ std::shared_ptr<AsmPrinter>(std::unique_ptr<MCStreamer>)> &C) {
+ AsmPrinterCreationCallback = C;
+ }
+
/// Register a callback for a top-level pipeline entry.
///
/// If the PassManager type is not given at the top level of the pipeline
@@ -693,6 +700,11 @@ class PassBuilder {
StringRef OptionName,
StringRef PassName);
+ // Create target asm printer directly, this can bypass
+ // LLVMInitializeXXXAsmPrinter.
+ std::shared_ptr<AsmPrinter>
+ getAsmPrinter(std::unique_ptr<MCStreamer> Streamer);
+
private:
// O1 pass pipeline
FunctionPassManager
@@ -809,6 +821,9 @@ class PassBuilder {
// Callbacks to parse `filter` parameter in register allocation passes
SmallVector<std::function<RegClassFilterFunc(StringRef)>, 2>
RegClassFilterParsingCallbacks;
+ // Callback to create `AsmPrinterPass`.
+ std::function<std::shared_ptr<AsmPrinter>(std::unique_ptr<MCStreamer>)>
+ AsmPrinterCreationCallback;
};
/// This utility template takes care of adding require<> and invalidate<>
diff --git a/llvm/include/llvm/Target/TargetMachine.h b/llvm/include/llvm/Target/TargetMachine.h
index b8e56c755fbda..043d88fa47acd 100644
--- a/llvm/include/llvm/Target/TargetMachine.h
+++ b/llvm/include/llvm/Target/TargetMachine.h
@@ -471,8 +471,8 @@ class LLVMTargetMachine : public TargetMachine {
virtual Error b...
[truncated]
|
@@ -905,6 +921,78 @@ class AsmPrinter : public MachineFunctionPass { | |||
} | |||
}; | |||
|
|||
class AsmPrinterInitializePass | |||
: public PassInfoMixin<AsmPrinterInitializePass> { | |||
std::shared_ptr<AsmPrinter> Printer; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be no reason to use shared_ptr instead of unique_ptr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently these three passes are tightly coupled, AsmPrinterInitializePass
may modify some states in AsmPrinter
. Also, they must share the same streamer, which is used by all three passes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would expect the state to move from one pass to the next. It does not need atomic reference counting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another problem is the ownership of std::unique_ptr<MCStreamer> OutStreamer;
, it looks like they must share the same streamer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if the first pass owned the pointer, the next 2 depend on it, and the second 2 only use a non-smart reference?
}; | ||
|
||
class AsmPrinterPass : public PassInfoMixin<AsmPrinterPass> { | ||
std::shared_ptr<AsmPrinter> Printer; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto
@@ -693,6 +700,11 @@ class PassBuilder { | |||
StringRef OptionName, | |||
StringRef PassName); | |||
|
|||
// Create target asm printer directly, this can bypass | |||
// LLVMInitializeXXXAsmPrinter. | |||
std::shared_ptr<AsmPrinter> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No shared_ptrs
@@ -517,6 +525,16 @@ class Target { | |||
|
|||
/// createAsmPrinter - Create a target specific assembly printer pass. This | |||
/// takes ownership of the MCStreamer object. | |||
AsmPrinterLegacy * | |||
createAsmPrinterLegacy(TargetMachine &TM, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the point of having the legacy pass overridable by targets? This doesn't seem to be useful (or used), because the legacy pass just wraps the AsmPrinter, which provides virtual functions for everything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a compromise to ensure there is no circular dependency between CodeGen
, MC
, Target
, etc...
// Create the AsmPrinter, which takes ownership of AsmStreamer if successful. | ||
FunctionPass *Printer = | ||
getTarget().createAsmPrinter(*this, std::move(*MCStreamerOrErr)); | ||
AsmPrinterLegacy *Printer = | ||
getTarget().createAsmPrinterLegacy(*this, std::move(*MCStreamerOrErr)); | ||
if (!Printer) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is createAsmPrinterLegacy(getTarget().createAsmPrinter(...))
possible here? (and then remove the AsmPrinterLegacyCtorFn)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some DWARF classes still use it, so it is possible when we can use callback style pass builder and decouple DWARF classes with AsmPrinter.
PreservedAnalyses AsmPrinterPass::run(MachineFunction &MF, | ||
MachineFunctionAnalysisManager &MFAM) { | ||
auto PA = getMachineFunctionPassPreservedAnalyses(); | ||
PA.preserve<MachineOptimizationRemarkEmitterAnalysis>(); | ||
PA.preserve<CollectorMetadataAnalysis>(); | ||
PA.preserve<MachineBlockFrequencyAnalysis>(); | ||
PA.preserve<MachineBranchProbabilityAnalysis>(); | ||
Printer->getPreservedAnalyses(PA); | ||
return PA; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should have Printer->runOnMachineFunction(MF)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I missed it...
Expected<std::unique_ptr<MCStreamer>> MCStreamerOrErr = | ||
TM.createMCStreamer(Out, DwoOut, FileType, Ctx); | ||
if (auto Err = MCStreamerOrErr.takeError()) | ||
return Err; | ||
PrinterImpl = PB.getAsmPrinter(std::move(*MCStreamerOrErr)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We construct MCStreamer
directly from TM here; is there a reason why TM.createAsmPrinter()
is not used directly as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently I plan to decoupling pipeline building from TargetMachine
, let pass builder handles MCStreamer
creation etc. So we can get rid of LLVMTargetMachine
finally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, so I gather that TM would only be used through PB.registerPassBuilderCallbacks()
.
9ef2bbe
to
a5a26ec
Compare
Use thread unsafe version |
9680421
to
64248f8
Compare
void AsmPrinter::emitStackMaps(Module &M) { | ||
auto &Map = MAM->getResult<CollectorMetadataAnalysis>(M); | ||
bool NeedsDefault = false; | ||
if (Map.empty()) | ||
// No GC strategy, use the default format. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of duplicating multiple things can this class just take the analysis results directly (and not use pass managers)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This result is used in some gc lowering passes, and these passes will fill the analysis result.
@@ -151,15 +151,46 @@ class GCFunctionInfo { | |||
size_t live_size(const iterator &p) const { return roots_size(); } | |||
}; | |||
|
|||
struct GCStrategyMap { | |||
class GCStrategyMap { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
spilled-over patch?
ping? |
Personally I want to revisit it after #137290, because it can handle 3 asm printer passes better. |
Rebased. Convert to pimpl style implementation and currently |
"asm-printer-initialize"); | ||
PIC->addClassToPassName(AsmPrinterPass::name(), "asm-printer"); | ||
PIC->addClassToPassName(AsmPrinterFinalizePass::name(), | ||
"asm-printer-finalize"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we provide a unified wrapper, then the name <target>-asm-printer
is no longer available.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could let targets add their pass name in the PB callback also?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found pass builder can construct pass name by getTargetTriple().getArchName()+"-asm-printer"
fix typo Co-authored-by: Akshat Oke <Akshat.Oke@amd.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems good to me, I can get it working for AMDGPU.
Can wait if other people have anything.
Just simply wrap it in a pass.
AsmPrinterLegacy
doInitialization/doFinalization
in new pass concept, it is divided into 3 parts in new pass manager version, but we can handle the order ofGlobalMerge
andAsmPrinter
correctly.AsmPrinter
implementation and legacy pass in target registry.CodeGenPassBuilder
so it can createAsmPrinter
.PassBuilder
without circular dependencies.