GCStrategy.h revision 296417
1193323Sed//===-- llvm/CodeGen/GCStrategy.h - Garbage collection ----------*- C++ -*-===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// GCStrategy coordinates code generation algorithms and implements some itself
11193323Sed// in order to generate code compatible with a target code generator as
12193323Sed// specified in a function's 'gc' attribute. Algorithms are enabled by setting
13193323Sed// flags in a subclass's constructor, and some virtual methods can be
14193323Sed// overridden.
15280031Sdim//
16280031Sdim// GCStrategy is relevant for implementations using either gc.root or
17280031Sdim// gc.statepoint based lowering strategies, but is currently focused mostly on
18280031Sdim// options for gc.root.  This will change over time.
19288943Sdim//
20280031Sdim// When requested by a subclass of GCStrategy, the gc.root implementation will
21280031Sdim// populate GCModuleInfo and GCFunctionInfo with that about each Function in
22280031Sdim// the Module that opts in to garbage collection.  Specifically:
23288943Sdim//
24193323Sed// - Safe points
25193323Sed//   Garbage collection is generally only possible at certain points in code.
26193323Sed//   GCStrategy can request that the collector insert such points:
27193323Sed//
28193323Sed//     - At and after any call to a subroutine
29193323Sed//     - Before returning from the current function
30193323Sed//     - Before backwards branches (loops)
31288943Sdim//
32193323Sed// - Roots
33193323Sed//   When a reference to a GC-allocated object exists on the stack, it must be
34193323Sed//   stored in an alloca registered with llvm.gcoot.
35193323Sed//
36193323Sed// This information can used to emit the metadata tables which are required by
37193323Sed// the target garbage collector runtime.
38193323Sed//
39280031Sdim// When used with gc.statepoint, information about safepoint and roots can be
40280031Sdim// found in the binary StackMap section after code generation.  Safepoint
41280031Sdim// placement is currently the responsibility of the frontend, though late
42280031Sdim// insertion support is planned.  gc.statepoint does not currently support
43280031Sdim// custom stack map formats; such can be generated by parsing the standard
44280031Sdim// stack map section if desired.
45288943Sdim//
46280031Sdim// The read and write barrier support can be used with either implementation.
47280031Sdim//
48193323Sed//===----------------------------------------------------------------------===//
49193323Sed
50288943Sdim#ifndef LLVM_IR_GCSTRATEGY_H
51288943Sdim#define LLVM_IR_GCSTRATEGY_H
52193323Sed
53280031Sdim#include "llvm/ADT/Optional.h"
54288943Sdim#include "llvm/IR/Function.h"
55288943Sdim#include "llvm/IR/Module.h"
56288943Sdim#include "llvm/IR/Value.h"
57288943Sdim#include "llvm/Support/ErrorHandling.h"
58193323Sed#include "llvm/Support/Registry.h"
59193323Sed#include <string>
60193323Sed
61193323Sednamespace llvm {
62288943Sdimnamespace GC {
63288943Sdim/// PointKind - Used to indicate whether the address of the call instruction
64288943Sdim/// or the address after the call instruction is listed in the stackmap.  For
65288943Sdim/// most runtimes, PostCall safepoints are appropriate.
66288943Sdim///
67288943Sdimenum PointKind {
68288943Sdim  PreCall, ///< Instr is a call instruction.
69288943Sdim  PostCall ///< Instr is the return address of a call.
70288943Sdim};
71288943Sdim}
72280031Sdim
73288943Sdim/// GCStrategy describes a garbage collector algorithm's code generation
74288943Sdim/// requirements, and provides overridable hooks for those needs which cannot
75288943Sdim/// be abstractly described.  GCStrategy objects must be looked up through
76288943Sdim/// the Function.  The objects themselves are owned by the Context and must
77288943Sdim/// be immutable.
78288943Sdimclass GCStrategy {
79288943Sdimprivate:
80288943Sdim  std::string Name;
81288943Sdim  friend class GCModuleInfo;
82193323Sed
83288943Sdimprotected:
84288943Sdim  bool UseStatepoints; /// Uses gc.statepoints as opposed to gc.roots,
85288943Sdim                       /// if set, none of the other options can be
86288943Sdim                       /// anything but their default values.
87193323Sed
88288943Sdim  unsigned NeededSafePoints; ///< Bitmask of required safe points.
89288943Sdim  bool CustomReadBarriers;   ///< Default is to insert loads.
90288943Sdim  bool CustomWriteBarriers;  ///< Default is to insert stores.
91288943Sdim  bool CustomRoots;          ///< Default is to pass through to backend.
92288943Sdim  bool InitRoots;            ///< If set, roots are nulled during lowering.
93288943Sdim  bool UsesMetadata;         ///< If set, backend must emit metadata tables.
94280031Sdim
95288943Sdimpublic:
96288943Sdim  GCStrategy();
97288943Sdim  virtual ~GCStrategy() {}
98280031Sdim
99288943Sdim  /// Return the name of the GC strategy.  This is the value of the collector
100288943Sdim  /// name string specified on functions which use this strategy.
101288943Sdim  const std::string &getName() const { return Name; }
102280031Sdim
103288943Sdim  /// By default, write barriers are replaced with simple store
104288943Sdim  /// instructions. If true, you must provide a custom pass to lower
105288943Sdim  /// calls to @llvm.gcwrite.
106288943Sdim  bool customWriteBarrier() const { return CustomWriteBarriers; }
107280031Sdim
108288943Sdim  /// By default, read barriers are replaced with simple load
109288943Sdim  /// instructions. If true, you must provide a custom pass to lower
110288943Sdim  /// calls to @llvm.gcread.
111288943Sdim  bool customReadBarrier() const { return CustomReadBarriers; }
112234353Sdim
113288943Sdim  /// Returns true if this strategy is expecting the use of gc.statepoints,
114288943Sdim  /// and false otherwise.
115288943Sdim  bool useStatepoints() const { return UseStatepoints; }
116280031Sdim
117288943Sdim  /** @name Statepoint Specific Properties */
118288943Sdim  ///@{
119280031Sdim
120296417Sdim  /// If the type specified can be reliably distinguished, returns true for
121288943Sdim  /// pointers to GC managed locations and false for pointers to non-GC
122288943Sdim  /// managed locations.  Note a GCStrategy can always return 'None' (i.e. an
123288943Sdim  /// empty optional indicating it can't reliably distinguish.
124296417Sdim  virtual Optional<bool> isGCManagedPointer(const Type *Ty) const {
125288943Sdim    return None;
126288943Sdim  }
127288943Sdim  ///@}
128288943Sdim
129288943Sdim  /** @name GCRoot Specific Properties
130288943Sdim   * These properties and overrides only apply to collector strategies using
131288943Sdim   * GCRoot.
132288943Sdim   */
133288943Sdim  ///@{
134288943Sdim
135288943Sdim  /// True if safe points of any kind are required. By default, none are
136288943Sdim  /// recorded.
137288943Sdim  bool needsSafePoints() const { return NeededSafePoints != 0; }
138288943Sdim
139288943Sdim  /// True if the given kind of safe point is required. By default, none are
140288943Sdim  /// recorded.
141288943Sdim  bool needsSafePoint(GC::PointKind Kind) const {
142288943Sdim    return (NeededSafePoints & 1 << Kind) != 0;
143288943Sdim  }
144288943Sdim
145288943Sdim  /// By default, roots are left for the code generator so it can generate a
146288943Sdim  /// stack map. If true, you must provide a custom pass to lower
147288943Sdim  /// calls to @llvm.gcroot.
148288943Sdim  bool customRoots() const { return CustomRoots; }
149288943Sdim
150288943Sdim  /// If set, gcroot intrinsics should initialize their allocas to null
151288943Sdim  /// before the first use. This is necessary for most GCs and is enabled by
152288943Sdim  /// default.
153288943Sdim  bool initializeRoots() const { return InitRoots; }
154288943Sdim
155288943Sdim  /// If set, appropriate metadata tables must be emitted by the back-end
156288943Sdim  /// (assembler, JIT, or otherwise). For statepoint, this method is
157288943Sdim  /// currently unsupported.  The stackmap information can be found in the
158288943Sdim  /// StackMap section as described in the documentation.
159288943Sdim  bool usesMetadata() const { return UsesMetadata; }
160288943Sdim
161288943Sdim  ///@}
162288943Sdim};
163288943Sdim
164288943Sdim/// Subclasses of GCStrategy are made available for use during compilation by
165288943Sdim/// adding them to the global GCRegistry.  This can done either within the
166288943Sdim/// LLVM source tree or via a loadable plugin.  An example registeration
167288943Sdim/// would be:
168288943Sdim/// static GCRegistry::Add<CustomGC> X("custom-name",
169288943Sdim///        "my custom supper fancy gc strategy");
170288943Sdim///
171288943Sdim/// Note that to use a custom GCMetadataPrinter w/gc.roots, you must also
172288943Sdim/// register your GCMetadataPrinter subclass with the
173288943Sdim/// GCMetadataPrinterRegistery as well.
174288943Sdimtypedef Registry<GCStrategy> GCRegistry;
175193323Sed}
176193323Sed
177193323Sed#endif
178