GCStrategy.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. //===-- llvm/CodeGen/GCStrategy.h - Garbage collection ----------*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // GCStrategy coordinates code generation algorithms and implements some itself
  11. // in order to generate code compatible with a target code generator as
  12. // specified in a function's 'gc' attribute. Algorithms are enabled by setting
  13. // flags in a subclass's constructor, and some virtual methods can be
  14. // overridden.
  15. //
  16. // GCStrategy is relevant for implementations using either gc.root or
  17. // gc.statepoint based lowering strategies, but is currently focused mostly on
  18. // options for gc.root. This will change over time.
  19. //
  20. // When requested by a subclass of GCStrategy, the gc.root implementation will
  21. // populate GCModuleInfo and GCFunctionInfo with that about each Function in
  22. // the Module that opts in to garbage collection. Specifically:
  23. //
  24. // - Safe points
  25. // Garbage collection is generally only possible at certain points in code.
  26. // GCStrategy can request that the collector insert such points:
  27. //
  28. // - At and after any call to a subroutine
  29. // - Before returning from the current function
  30. // - Before backwards branches (loops)
  31. //
  32. // - Roots
  33. // When a reference to a GC-allocated object exists on the stack, it must be
  34. // stored in an alloca registered with llvm.gcoot.
  35. //
  36. // This information can used to emit the metadata tables which are required by
  37. // the target garbage collector runtime.
  38. //
  39. // When used with gc.statepoint, information about safepoint and roots can be
  40. // found in the binary StackMap section after code generation. Safepoint
  41. // placement is currently the responsibility of the frontend, though late
  42. // insertion support is planned. gc.statepoint does not currently support
  43. // custom stack map formats; such can be generated by parsing the standard
  44. // stack map section if desired.
  45. //
  46. // The read and write barrier support can be used with either implementation.
  47. //
  48. //===----------------------------------------------------------------------===//
  49. #ifndef LLVM_IR_GCSTRATEGY_H
  50. #define LLVM_IR_GCSTRATEGY_H
  51. #include "llvm/ADT/Optional.h"
  52. #include "llvm/IR/Function.h"
  53. #include "llvm/IR/Module.h"
  54. #include "llvm/IR/Value.h"
  55. #include "llvm/Support/ErrorHandling.h"
  56. #include "llvm/Support/Registry.h"
  57. #include <string>
  58. namespace llvm {
  59. namespace GC {
  60. /// PointKind - Used to indicate whether the address of the call instruction
  61. /// or the address after the call instruction is listed in the stackmap. For
  62. /// most runtimes, PostCall safepoints are appropriate.
  63. ///
  64. enum PointKind {
  65. PreCall, ///< Instr is a call instruction.
  66. PostCall ///< Instr is the return address of a call.
  67. };
  68. }
  69. /// GCStrategy describes a garbage collector algorithm's code generation
  70. /// requirements, and provides overridable hooks for those needs which cannot
  71. /// be abstractly described. GCStrategy objects must be looked up through
  72. /// the Function. The objects themselves are owned by the Context and must
  73. /// be immutable.
  74. class GCStrategy {
  75. private:
  76. std::string Name;
  77. friend class GCModuleInfo;
  78. protected:
  79. bool UseStatepoints; /// Uses gc.statepoints as opposed to gc.roots,
  80. /// if set, none of the other options can be
  81. /// anything but their default values.
  82. unsigned NeededSafePoints; ///< Bitmask of required safe points.
  83. bool CustomReadBarriers; ///< Default is to insert loads.
  84. bool CustomWriteBarriers; ///< Default is to insert stores.
  85. bool CustomRoots; ///< Default is to pass through to backend.
  86. bool InitRoots; ///< If set, roots are nulled during lowering.
  87. bool UsesMetadata; ///< If set, backend must emit metadata tables.
  88. public:
  89. GCStrategy();
  90. virtual ~GCStrategy() {}
  91. /// Return the name of the GC strategy. This is the value of the collector
  92. /// name string specified on functions which use this strategy.
  93. const std::string &getName() const { return Name; }
  94. /// By default, write barriers are replaced with simple store
  95. /// instructions. If true, you must provide a custom pass to lower
  96. /// calls to @llvm.gcwrite.
  97. bool customWriteBarrier() const { return CustomWriteBarriers; }
  98. /// By default, read barriers are replaced with simple load
  99. /// instructions. If true, you must provide a custom pass to lower
  100. /// calls to @llvm.gcread.
  101. bool customReadBarrier() const { return CustomReadBarriers; }
  102. /// Returns true if this strategy is expecting the use of gc.statepoints,
  103. /// and false otherwise.
  104. bool useStatepoints() const { return UseStatepoints; }
  105. /** @name Statepoint Specific Properties */
  106. ///@{
  107. /// If the value specified can be reliably distinguished, returns true for
  108. /// pointers to GC managed locations and false for pointers to non-GC
  109. /// managed locations. Note a GCStrategy can always return 'None' (i.e. an
  110. /// empty optional indicating it can't reliably distinguish.
  111. virtual Optional<bool> isGCManagedPointer(const Value *V) const {
  112. return None;
  113. }
  114. ///@}
  115. /** @name GCRoot Specific Properties
  116. * These properties and overrides only apply to collector strategies using
  117. * GCRoot.
  118. */
  119. ///@{
  120. /// True if safe points of any kind are required. By default, none are
  121. /// recorded.
  122. bool needsSafePoints() const { return NeededSafePoints != 0; }
  123. /// True if the given kind of safe point is required. By default, none are
  124. /// recorded.
  125. bool needsSafePoint(GC::PointKind Kind) const {
  126. return (NeededSafePoints & 1 << Kind) != 0;
  127. }
  128. /// By default, roots are left for the code generator so it can generate a
  129. /// stack map. If true, you must provide a custom pass to lower
  130. /// calls to @llvm.gcroot.
  131. bool customRoots() const { return CustomRoots; }
  132. /// If set, gcroot intrinsics should initialize their allocas to null
  133. /// before the first use. This is necessary for most GCs and is enabled by
  134. /// default.
  135. bool initializeRoots() const { return InitRoots; }
  136. /// If set, appropriate metadata tables must be emitted by the back-end
  137. /// (assembler, JIT, or otherwise). For statepoint, this method is
  138. /// currently unsupported. The stackmap information can be found in the
  139. /// StackMap section as described in the documentation.
  140. bool usesMetadata() const { return UsesMetadata; }
  141. ///@}
  142. };
  143. /// Subclasses of GCStrategy are made available for use during compilation by
  144. /// adding them to the global GCRegistry. This can done either within the
  145. /// LLVM source tree or via a loadable plugin. An example registeration
  146. /// would be:
  147. /// static GCRegistry::Add<CustomGC> X("custom-name",
  148. /// "my custom supper fancy gc strategy");
  149. ///
  150. /// Note that to use a custom GCMetadataPrinter w/gc.roots, you must also
  151. /// register your GCMetadataPrinter subclass with the
  152. /// GCMetadataPrinterRegistery as well.
  153. typedef Registry<GCStrategy> GCRegistry;
  154. }
  155. #endif