Home | History | Annotate | Download | only in CodeGen
      1 //===-- BuiltinGCs.cpp - Boilerplate for our built in GC types --*- 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 // This file contains the boilerplate required to define our various built in
     11 // gc lowering strategies.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "llvm/CodeGen/GCs.h"
     16 #include "llvm/CodeGen/GCStrategy.h"
     17 
     18 using namespace llvm;
     19 
     20 namespace {
     21 
     22 /// An example GC which attempts to be compatibile with Erlang/OTP garbage
     23 /// collector.
     24 ///
     25 /// The frametable emitter is in ErlangGCPrinter.cpp.
     26 class ErlangGC : public GCStrategy {
     27 public:
     28   ErlangGC() {
     29     InitRoots = false;
     30     NeededSafePoints = 1 << GC::PostCall;
     31     UsesMetadata = true;
     32     CustomRoots = false;
     33   }
     34 };
     35 
     36 /// An example GC which attempts to be compatible with Objective Caml 3.10.0
     37 ///
     38 /// The frametable emitter is in OcamlGCPrinter.cpp.
     39 class OcamlGC : public GCStrategy {
     40 public:
     41   OcamlGC() {
     42     NeededSafePoints = 1 << GC::PostCall;
     43     UsesMetadata = true;
     44   }
     45 };
     46 
     47 /// A GC strategy for uncooperative targets.  This implements lowering for the
     48 /// llvm.gc* intrinsics for targets that do not natively support them (which
     49 /// includes the C backend). Note that the code generated is not quite as
     50 /// efficient as algorithms which generate stack maps to identify roots.
     51 ///
     52 /// In order to support this particular transformation, all stack roots are
     53 /// coallocated in the stack. This allows a fully target-independent stack map
     54 /// while introducing only minor runtime overhead.
     55 class ShadowStackGC : public GCStrategy {
     56 public:
     57   ShadowStackGC() {
     58     InitRoots = true;
     59     CustomRoots = true;
     60   }
     61 };
     62 
     63 /// A GCStrategy which serves as an example for the usage of a statepoint based
     64 /// lowering strategy.  This GCStrategy is intended to suitable as a default
     65 /// implementation usable with any collector which can consume the standard
     66 /// stackmap format generated by statepoints, uses the default addrespace to
     67 /// distinguish between gc managed and non-gc managed pointers, and has
     68 /// reasonable relocation semantics.
     69 class StatepointGC : public GCStrategy {
     70 public:
     71   StatepointGC() {
     72     UseStatepoints = true;
     73     // These options are all gc.root specific, we specify them so that the
     74     // gc.root lowering code doesn't run.
     75     InitRoots = false;
     76     NeededSafePoints = 0;
     77     UsesMetadata = false;
     78     CustomRoots = false;
     79   }
     80   Optional<bool> isGCManagedPointer(const Type *Ty) const override {
     81     // Method is only valid on pointer typed values.
     82     const PointerType *PT = cast<PointerType>(Ty);
     83     // For the sake of this example GC, we arbitrarily pick addrspace(1) as our
     84     // GC managed heap.  We know that a pointer into this heap needs to be
     85     // updated and that no other pointer does.  Note that addrspace(1) is used
     86     // only as an example, it has no special meaning, and is not reserved for
     87     // GC usage.
     88     return (1 == PT->getAddressSpace());
     89   }
     90 };
     91 
     92 /// A GCStrategy for the CoreCLR Runtime. The strategy is similar to
     93 /// Statepoint-example GC, but differs from it in certain aspects, such as:
     94 /// 1) Base-pointers need not be explicitly tracked and reported for
     95 ///    interior pointers
     96 /// 2) Uses a different format for encoding stack-maps
     97 /// 3) Location of Safe-point polls: polls are only needed before loop-back
     98 ///    edges and before tail-calls (not needed at function-entry)
     99 ///
    100 /// The above differences in behavior are to be implemented in upcoming
    101 /// checkins.
    102 class CoreCLRGC : public GCStrategy {
    103 public:
    104   CoreCLRGC() {
    105     UseStatepoints = true;
    106     // These options are all gc.root specific, we specify them so that the
    107     // gc.root lowering code doesn't run.
    108     InitRoots = false;
    109     NeededSafePoints = 0;
    110     UsesMetadata = false;
    111     CustomRoots = false;
    112   }
    113   Optional<bool> isGCManagedPointer(const Type *Ty) const override {
    114     // Method is only valid on pointer typed values.
    115     const PointerType *PT = cast<PointerType>(Ty);
    116     // We pick addrspace(1) as our GC managed heap.
    117     return (1 == PT->getAddressSpace());
    118   }
    119 };
    120 }
    121 
    122 // Register all the above so that they can be found at runtime.  Note that
    123 // these static initializers are important since the registration list is
    124 // constructed from their storage.
    125 static GCRegistry::Add<ErlangGC> A("erlang",
    126                                    "erlang-compatible garbage collector");
    127 static GCRegistry::Add<OcamlGC> B("ocaml", "ocaml 3.10-compatible GC");
    128 static GCRegistry::Add<ShadowStackGC>
    129     C("shadow-stack", "Very portable GC for uncooperative code generators");
    130 static GCRegistry::Add<StatepointGC> D("statepoint-example",
    131                                        "an example strategy for statepoint");
    132 static GCRegistry::Add<CoreCLRGC> E("coreclr", "CoreCLR-compatible GC");
    133 
    134 // Provide hooks to ensure the containing library is fully loaded.
    135 void llvm::linkErlangGC() {}
    136 void llvm::linkOcamlGC() {}
    137 void llvm::linkShadowStackGC() {}
    138 void llvm::linkStatepointExampleGC() {}
    139 void llvm::linkCoreCLRGC() {}
    140