15eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen//===-- llvm/CodeGen/GCStrategy.h - Garbage collection ----------*- C++ -*-===//
2364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen//
3364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen//                     The LLVM Compiler Infrastructure
4364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen//
57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// This file is distributed under the University of Illinois Open Source
67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// License. See LICENSE.TXT for details.
7364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen//
8364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen//===----------------------------------------------------------------------===//
9364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen//
105eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen// GCStrategy coordinates code generation algorithms and implements some itself
115eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen// in order to generate code compatible with a target code generator as
125eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen// specified in a function's 'gc' attribute. Algorithms are enabled by setting
135eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen// flags in a subclass's constructor, and some virtual methods can be
145eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen// overridden.
155eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen//
165eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen// When requested, the GCStrategy will be populated with data about each
175eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen// function which uses it. Specifically:
18364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen//
19364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen// - Safe points
205eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen//   Garbage collection is generally only possible at certain points in code.
215eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen//   GCStrategy can request that the collector insert such points:
22364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen//
23364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen//     - At and after any call to a subroutine
24364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen//     - Before returning from the current function
25364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen//     - Before backwards branches (loops)
26364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen//
27364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen// - Roots
28364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen//   When a reference to a GC-allocated object exists on the stack, it must be
29364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen//   stored in an alloca registered with llvm.gcoot.
30364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen//
315eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen// This information can used to emit the metadata tables which are required by
325eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen// the target garbage collector runtime.
33364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen//
34364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen//===----------------------------------------------------------------------===//
35364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen
365eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen#ifndef LLVM_CODEGEN_GCSTRATEGY_H
375eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen#define LLVM_CODEGEN_GCSTRATEGY_H
38364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen
395a29c9eed157af51a8d338b5a225b146881819e8Gordon Henriksen#include "llvm/CodeGen/GCMetadata.h"
407b8c2f8587763e0a8ce48f9b7b67287930129c8dNicolas Geoffray#include "llvm/CodeGen/MachineFunction.h"
415eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen#include "llvm/Support/Registry.h"
42ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen#include <string>
43364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen
44364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksennamespace llvm {
45364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen
465eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen  class GCStrategy;
475eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen
485eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen  /// The GC strategy registry uses all the defaults from Registry.
495eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen  ///
505eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen  typedef Registry<GCStrategy> GCRegistry;
515eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen
525eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen  /// GCStrategy describes a garbage collector algorithm's code generation
535eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen  /// requirements, and provides overridable hooks for those needs which cannot
545eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen  /// be abstractly described.
555eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen  class GCStrategy {
56ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen  public:
575eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    typedef std::vector<GCFunctionInfo*> list_type;
58ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen    typedef list_type::iterator iterator;
59ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen
60ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen  private:
615eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    friend class GCModuleInfo;
62ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen    const Module *M;
63ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen    std::string Name;
64ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen
65ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen    list_type Functions;
66ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen
67364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen  protected:
6877592fe39c404f3c48b06fae48b965058b3a5ee8Dmitri Gribenko    unsigned NeededSafePoints; ///< Bitmask of required safe points.
6977592fe39c404f3c48b06fae48b965058b3a5ee8Dmitri Gribenko    bool CustomReadBarriers;   ///< Default is to insert loads.
7077592fe39c404f3c48b06fae48b965058b3a5ee8Dmitri Gribenko    bool CustomWriteBarriers;  ///< Default is to insert stores.
7177592fe39c404f3c48b06fae48b965058b3a5ee8Dmitri Gribenko    bool CustomRoots;          ///< Default is to pass through to backend.
7277592fe39c404f3c48b06fae48b965058b3a5ee8Dmitri Gribenko    bool CustomSafePoints;     ///< Default is to use NeededSafePoints
7377592fe39c404f3c48b06fae48b965058b3a5ee8Dmitri Gribenko                               ///< to find safe points.
7477592fe39c404f3c48b06fae48b965058b3a5ee8Dmitri Gribenko    bool InitRoots;            ///< If set, roots are nulled during lowering.
7577592fe39c404f3c48b06fae48b965058b3a5ee8Dmitri Gribenko    bool UsesMetadata;         ///< If set, backend must emit metadata tables.
76364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen
77364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen  public:
785eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    GCStrategy();
79364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen
805eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    virtual ~GCStrategy();
81364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen
82364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen
835eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    /// getName - The name of the GC strategy, for debugging.
84ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen    ///
85ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen    const std::string &getName() const { return Name; }
86ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen
875eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    /// getModule - The module within which the GC strategy is operating.
88ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen    ///
89ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen    const Module &getModule() const { return *M; }
90ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen
915eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    /// needsSafePoitns - True if safe points of any kind are required. By
925eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    //                    default, none are recorded.
937b8c2f8587763e0a8ce48f9b7b67287930129c8dNicolas Geoffray    bool needsSafePoints() const {
947b8c2f8587763e0a8ce48f9b7b67287930129c8dNicolas Geoffray      return CustomSafePoints || NeededSafePoints != 0;
957b8c2f8587763e0a8ce48f9b7b67287930129c8dNicolas Geoffray    }
96364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen
975eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    /// needsSafePoint(Kind) - True if the given kind of safe point is
985eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    //                          required. By default, none are recorded.
99364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen    bool needsSafePoint(GC::PointKind Kind) const {
100364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen      return (NeededSafePoints & 1 << Kind) != 0;
101364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen    }
102364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen
1035eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    /// customWriteBarrier - By default, write barriers are replaced with simple
1045eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    ///                      store instructions. If true, then
1055eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    ///                      performCustomLowering must instead lower them.
106364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen    bool customWriteBarrier() const { return CustomWriteBarriers; }
107364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen
1085eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    /// customReadBarrier - By default, read barriers are replaced with simple
1095eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    ///                     load instructions. If true, then
1105eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    ///                     performCustomLowering must instead lower them.
111364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen    bool customReadBarrier() const { return CustomReadBarriers; }
112364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen
1135eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    /// customRoots - By default, roots are left for the code generator so it
1145eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    ///               can generate a stack map. If true, then
1155eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    //                performCustomLowering must delete them.
116364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen    bool customRoots() const { return CustomRoots; }
1177b8c2f8587763e0a8ce48f9b7b67287930129c8dNicolas Geoffray
1187b8c2f8587763e0a8ce48f9b7b67287930129c8dNicolas Geoffray    /// customSafePoints - By default, the GC analysis will find safe
1197b8c2f8587763e0a8ce48f9b7b67287930129c8dNicolas Geoffray    ///                    points according to NeededSafePoints. If true,
1207b8c2f8587763e0a8ce48f9b7b67287930129c8dNicolas Geoffray    ///                    then findCustomSafePoints must create them.
1217b8c2f8587763e0a8ce48f9b7b67287930129c8dNicolas Geoffray    bool customSafePoints() const { return CustomSafePoints; }
122364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen
1235eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    /// initializeRoots - If set, gcroot intrinsics should initialize their
1245eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    //                    allocas to null before the first use. This is
1255eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    //                    necessary for most GCs and is enabled by default.
126364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen    bool initializeRoots() const { return InitRoots; }
127364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen
1285eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    /// usesMetadata - If set, appropriate metadata tables must be emitted by
1295eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    ///                the back-end (assembler, JIT, or otherwise).
130c317a60c2714a5b90700a11ba646285cb754a5d3Gordon Henriksen    bool usesMetadata() const { return UsesMetadata; }
131ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen
132ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen    /// begin/end - Iterators for function metadata.
133ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen    ///
134ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen    iterator begin() { return Functions.begin(); }
135ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen    iterator end()   { return Functions.end();   }
136ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen
137ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen    /// insertFunctionMetadata - Creates metadata for a function.
138ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen    ///
1395eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    GCFunctionInfo *insertFunctionInfo(const Function &F);
140ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen
141ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen    /// initializeCustomLowering/performCustomLowering - If any of the actions
1425eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    /// are set to custom, performCustomLowering must be overriden to transform
1435eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    /// the corresponding actions to LLVM IR. initializeCustomLowering is
1445eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    /// optional to override. These are the only GCStrategy methods through
145ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen    /// which the LLVM IR can be modified.
146ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen    virtual bool initializeCustomLowering(Module &F);
147ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen    virtual bool performCustomLowering(Function &F);
1487b8c2f8587763e0a8ce48f9b7b67287930129c8dNicolas Geoffray    virtual bool findCustomSafePoints(GCFunctionInfo& FI, MachineFunction& MF);
149364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen  };
150364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen
151364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen}
152364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen
153364caf0e19e570d00cfd03d9dd3fcda21fb2e459Gordon Henriksen#endif
154