diff --git a/include/llvm/CodeGen/GCStrategy.h b/include/llvm/CodeGen/GCStrategy.h index 61ed2d2095b..98c25e4a08d 100644 --- a/include/llvm/CodeGen/GCStrategy.h +++ b/include/llvm/CodeGen/GCStrategy.h @@ -12,9 +12,14 @@ // specified in a function's 'gc' attribute. Algorithms are enabled by setting // flags in a subclass's constructor, and some virtual methods can be // overridden. +// +// GCStrategy is relevant for implementations using either gc.root or +// gc.statepoint based lowering strategies, but is currently focused mostly on +// options for gc.root. This will change over time. // -// When requested, the GCStrategy will be populated with data about each -// function which uses it. Specifically: +// When requested by a subclass of GCStrategy, the gc.root implementation will +// populate GCModuleInfo and GCFunctionInfo with that about each Function in +// the Module that opts in to garbage collection. Specifically: // // - Safe points // Garbage collection is generally only possible at certain points in code. @@ -31,6 +36,15 @@ // This information can used to emit the metadata tables which are required by // the target garbage collector runtime. // +// When used with gc.statepoint, information about safepoint and roots can be +// found in the binary StackMap section after code generation. Safepoint +// placement is currently the responsibility of the frontend, though late +// insertion support is planned. gc.statepoint does not currently support +// custom stack map formats; such can be generated by parsing the standard +// stack map section if desired. +// +// The read and write barrier support can be used with either implementation. +// //===----------------------------------------------------------------------===// #ifndef LLVM_CODEGEN_GCSTRATEGY_H @@ -42,13 +56,6 @@ #include namespace llvm { - - class GCStrategy; - - /// The GC strategy registry uses all the defaults from Registry. - /// - typedef Registry GCRegistry; - /// GCStrategy describes a garbage collector algorithm's code generation /// requirements, and provides overridable hooks for those needs which cannot /// be abstractly described. GCStrategy objects currently must be looked up @@ -56,8 +63,8 @@ namespace llvm { /// pass and recreated every time that pass is invalidated. class GCStrategy { private: - friend class GCModuleInfo; std::string Name; + friend class GCModuleInfo; protected: unsigned NeededSafePoints; ///< Bitmask of required safe points. @@ -71,65 +78,96 @@ namespace llvm { public: GCStrategy(); - virtual ~GCStrategy() {} - - /// getName - The name of the GC strategy, for debugging. - /// + /// Return the name of the GC strategy. This is the value of the collector + /// name string specified on functions which use this strategy. const std::string &getName() const { return Name; } - /// needsSafePoitns - True if safe points of any kind are required. By - // default, none are recorded. + /// By default, write barriers are replaced with simple store + /// instructions. If true, then performCustomLowering must instead lower + /// them. + bool customWriteBarrier() const { return CustomWriteBarriers; } + + /// By default, read barriers are replaced with simple load + /// instructions. If true, then performCustomLowering must instead lower + /// them. + bool customReadBarrier() const { return CustomReadBarriers; } + + /** @name GCRoot Specific Properties + * These properties and overrides only apply to collector strategies using + * GCRoot. + */ + ///@{ + + /// True if safe points of any kind are required. By default, none are + /// recorded. bool needsSafePoints() const { return CustomSafePoints || NeededSafePoints != 0; } - /// needsSafePoint(Kind) - True if the given kind of safe point is - // required. By default, none are recorded. + /// True if the given kind of safe point is required. By default, none are + /// recorded. bool needsSafePoint(GC::PointKind Kind) const { return (NeededSafePoints & 1 << Kind) != 0; } - - /// customWriteBarrier - By default, write barriers are replaced with simple - /// store instructions. If true, then - /// performCustomLowering must instead lower them. - bool customWriteBarrier() const { return CustomWriteBarriers; } - - /// customReadBarrier - By default, read barriers are replaced with simple - /// load instructions. If true, then - /// performCustomLowering must instead lower them. - bool customReadBarrier() const { return CustomReadBarriers; } - - /// customRoots - By default, roots are left for the code generator so it - /// can generate a stack map. If true, then - // performCustomLowering must delete them. + + /// By default, roots are left for the code generator so it can generate a + /// stack map. If true, then performCustomLowering must delete them. bool customRoots() const { return CustomRoots; } - /// customSafePoints - By default, the GC analysis will find safe - /// points according to NeededSafePoints. If true, - /// then findCustomSafePoints must create them. + /// By default, the GC analysis will find safe points according to + /// NeededSafePoints. If true, then findCustomSafePoints must create them. bool customSafePoints() const { return CustomSafePoints; } - /// initializeRoots - If set, gcroot intrinsics should initialize their - // allocas to null before the first use. This is - // necessary for most GCs and is enabled by default. + /// If set, gcroot intrinsics should initialize their allocas to null + /// before the first use. This is necessary for most GCs and is enabled by + /// default. bool initializeRoots() const { return InitRoots; } - /// usesMetadata - If set, appropriate metadata tables must be emitted by - /// the back-end (assembler, JIT, or otherwise). + /// If set, appropriate metadata tables must be emitted by the back-end + /// (assembler, JIT, or otherwise). bool usesMetadata() const { return UsesMetadata; } + + ///@} /// initializeCustomLowering/performCustomLowering - If any of the actions /// are set to custom, performCustomLowering must be overriden to transform /// the corresponding actions to LLVM IR. initializeCustomLowering is /// optional to override. These are the only GCStrategy methods through - /// which the LLVM IR can be modified. - virtual bool initializeCustomLowering(Module &F); - virtual bool performCustomLowering(Function &F); - virtual bool findCustomSafePoints(GCFunctionInfo& FI, MachineFunction& MF); + /// which the LLVM IR can be modified. These methods apply mostly to + /// gc.root based implementations, but can be overriden to provide custom + /// barrier lowerings with gc.statepoint as well. + ///@{ + virtual bool initializeCustomLowering(Module &F) { + // No changes made + return false; + } + virtual bool performCustomLowering(Function &F) { + llvm_unreachable("GCStrategy subclass specified a configuration which" + "requires a custom lowering without providing one"); + } + ///@} + /// Called if customSafepoints returns true, used only by gc.root + /// implementations. + virtual bool findCustomSafePoints(GCFunctionInfo& FI, MachineFunction& MF) { + llvm_unreachable("GCStrategy subclass specified a configuration which" + "requests custom safepoint identification without" + "providing an implementation for such"); + } }; - + + /// Subclasses of GCStrategy are made available for use during compilation by + /// adding them to the global GCRegistry. This can done either within the + /// LLVM source tree or via a loadable plugin. An example registeration + /// would be: + /// static GCRegistry::Add X("custom-name", + /// "my custom supper fancy gc strategy"); + /// + /// Note that to use a custom GCMetadataPrinter w/gc.roots, you must also + /// register your GCMetadataPrinter subclass with the + /// GCMetadataPrinterRegistery as well. + typedef Registry GCRegistry; } #endif diff --git a/lib/CodeGen/GCStrategy.cpp b/lib/CodeGen/GCStrategy.cpp index 044169e04f8..4b03e9e34c6 100644 --- a/lib/CodeGen/GCStrategy.cpp +++ b/lib/CodeGen/GCStrategy.cpp @@ -102,19 +102,6 @@ GCStrategy::GCStrategy() : UsesMetadata(false) {} -bool GCStrategy::initializeCustomLowering(Module &M) { return false; } - -bool GCStrategy::performCustomLowering(Function &F) { - dbgs() << "gc " << getName() << " must override performCustomLowering.\n"; - llvm_unreachable("must override performCustomLowering"); -} - - -bool GCStrategy::findCustomSafePoints(GCFunctionInfo& FI, MachineFunction &F) { - dbgs() << "gc " << getName() << " must override findCustomSafePoints.\n"; - llvm_unreachable(nullptr); -} - // ----------------------------------------------------------------------------- INITIALIZE_PASS_BEGIN(LowerIntrinsics, "gc-lowering", "GC Lowering",