Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:00

0001 //===- llvm/CodeGen/GCStrategy.h - Garbage collection -----------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // GCStrategy coordinates code generation algorithms and implements some itself
0010 // in order to generate code compatible with a target code generator as
0011 // specified in a function's 'gc' attribute. Algorithms are enabled by setting
0012 // flags in a subclass's constructor, and some virtual methods can be
0013 // overridden.
0014 //
0015 // GCStrategy is relevant for implementations using either gc.root or
0016 // gc.statepoint based lowering strategies, but is currently focused mostly on
0017 // options for gc.root.  This will change over time.
0018 //
0019 // When requested by a subclass of GCStrategy, the gc.root implementation will
0020 // populate GCModuleInfo and GCFunctionInfo with that about each Function in
0021 // the Module that opts in to garbage collection.  Specifically:
0022 //
0023 // - Safe points
0024 //   Garbage collection is generally only possible at certain points in code.
0025 //   GCStrategy can request that the collector insert such points:
0026 //
0027 //     - At and after any call to a subroutine
0028 //     - Before returning from the current function
0029 //     - Before backwards branches (loops)
0030 //
0031 // - Roots
0032 //   When a reference to a GC-allocated object exists on the stack, it must be
0033 //   stored in an alloca registered with llvm.gcoot.
0034 //
0035 // This information can used to emit the metadata tables which are required by
0036 // the target garbage collector runtime.
0037 //
0038 // When used with gc.statepoint, information about safepoint and roots can be
0039 // found in the binary StackMap section after code generation.  Safepoint
0040 // placement is currently the responsibility of the frontend, though late
0041 // insertion support is planned.
0042 //
0043 // The read and write barrier support can be used with either implementation.
0044 //
0045 //===----------------------------------------------------------------------===//
0046 
0047 #ifndef LLVM_IR_GCSTRATEGY_H
0048 #define LLVM_IR_GCSTRATEGY_H
0049 
0050 #include "llvm/Support/Registry.h"
0051 #include <optional>
0052 #include <string>
0053 
0054 namespace llvm {
0055 
0056 class Type;
0057 
0058 /// GCStrategy describes a garbage collector algorithm's code generation
0059 /// requirements, and provides overridable hooks for those needs which cannot
0060 /// be abstractly described.  GCStrategy objects must be looked up through
0061 /// the Function.  The objects themselves are owned by the Context and must
0062 /// be immutable.
0063 class GCStrategy {
0064 private:
0065   friend class GCModuleInfo;
0066 
0067   std::string Name;
0068 
0069 protected:
0070   bool UseStatepoints = false; /// Uses gc.statepoints as opposed to gc.roots,
0071                                /// if set, NeededSafePoints and UsesMetadata
0072                                /// should be left at their default values.
0073 
0074   bool UseRS4GC = false; /// If UseStatepoints is set, this determines whether
0075                          /// the RewriteStatepointsForGC pass should rewrite
0076                          /// this function's calls.
0077                          /// This should only be set if UseStatepoints is set.
0078 
0079   bool NeededSafePoints = false;    ///< if set, calls are inferred to be safepoints
0080   bool UsesMetadata = false;     ///< If set, backend must emit metadata tables.
0081 
0082 public:
0083   GCStrategy();
0084   virtual ~GCStrategy() = default;
0085 
0086   /// Return the name of the GC strategy.  This is the value of the collector
0087   /// name string specified on functions which use this strategy.
0088   const std::string &getName() const { return Name; }
0089 
0090   /// Returns true if this strategy is expecting the use of gc.statepoints,
0091   /// and false otherwise.
0092   bool useStatepoints() const { return UseStatepoints; }
0093 
0094   /** @name Statepoint Specific Properties */
0095   ///@{
0096 
0097   /// If the type specified can be reliably distinguished, returns true for
0098   /// pointers to GC managed locations and false for pointers to non-GC
0099   /// managed locations.  Note a GCStrategy can always return 'std::nullopt'
0100   /// (i.e. an empty optional indicating it can't reliably distinguish.
0101   virtual std::optional<bool> isGCManagedPointer(const Type *Ty) const {
0102     return std::nullopt;
0103   }
0104 
0105   /// Returns true if the RewriteStatepointsForGC pass should run on functions
0106   /// using this GC.
0107   bool useRS4GC() const {
0108     assert((!UseRS4GC || useStatepoints()) &&
0109            "GC strategy has useRS4GC but not useStatepoints set");
0110     return UseRS4GC;
0111   }
0112 
0113   ///@}
0114 
0115   /// If set, appropriate metadata tables must be emitted by the back-end
0116   /// (assembler, JIT, or otherwise). The default stackmap information can be
0117   /// found in the StackMap section as described in the documentation.
0118   bool usesMetadata() const { return UsesMetadata; }
0119 
0120   /** @name GCRoot Specific Properties
0121    * These properties and overrides only apply to collector strategies using
0122    * GCRoot.
0123    */
0124   ///@{
0125 
0126   /// True if safe points need to be inferred on call sites
0127   bool needsSafePoints() const { return NeededSafePoints; }
0128 
0129   ///@}
0130 };
0131 
0132 /// Subclasses of GCStrategy are made available for use during compilation by
0133 /// adding them to the global GCRegistry.  This can done either within the
0134 /// LLVM source tree or via a loadable plugin.  An example registeration
0135 /// would be:
0136 /// static GCRegistry::Add<CustomGC> X("custom-name",
0137 ///        "my custom supper fancy gc strategy");
0138 ///
0139 /// Note that to use a custom GCMetadataPrinter, you must also
0140 /// register your GCMetadataPrinter subclass with the
0141 /// GCMetadataPrinterRegistery as well.
0142 using GCRegistry = Registry<GCStrategy>;
0143 
0144 extern template class LLVM_TEMPLATE_ABI Registry<GCStrategy>;
0145 
0146 /// Lookup the GCStrategy object associated with the given gc name.
0147 std::unique_ptr<GCStrategy> getGCStrategy(const StringRef Name);
0148 
0149 } // end namespace llvm
0150 
0151 #endif // LLVM_IR_GCSTRATEGY_H