17a7e6055SDimitry Andric //===- BuiltinGCs.cpp - Boilerplate for our built in GC types -------------===//
23ca95b02SDimitry Andric //
33ca95b02SDimitry Andric //                     The LLVM Compiler Infrastructure
43ca95b02SDimitry Andric //
53ca95b02SDimitry Andric // This file is distributed under the University of Illinois Open Source
63ca95b02SDimitry Andric // License. See LICENSE.TXT for details.
73ca95b02SDimitry Andric //
83ca95b02SDimitry Andric //===----------------------------------------------------------------------===//
93ca95b02SDimitry Andric //
103ca95b02SDimitry Andric // This file contains the boilerplate required to define our various built in
113ca95b02SDimitry Andric // gc lowering strategies.
123ca95b02SDimitry Andric //
133ca95b02SDimitry Andric //===----------------------------------------------------------------------===//
143ca95b02SDimitry Andric 
15*b5893f02SDimitry Andric #include "llvm/CodeGen/BuiltinGCs.h"
163ca95b02SDimitry Andric #include "llvm/CodeGen/GCStrategy.h"
177a7e6055SDimitry Andric #include "llvm/IR/DerivedTypes.h"
187a7e6055SDimitry Andric #include "llvm/Support/Casting.h"
193ca95b02SDimitry Andric 
203ca95b02SDimitry Andric using namespace llvm;
213ca95b02SDimitry Andric 
223ca95b02SDimitry Andric namespace {
233ca95b02SDimitry Andric 
243ca95b02SDimitry Andric /// An example GC which attempts to be compatibile with Erlang/OTP garbage
253ca95b02SDimitry Andric /// collector.
263ca95b02SDimitry Andric ///
273ca95b02SDimitry Andric /// The frametable emitter is in ErlangGCPrinter.cpp.
283ca95b02SDimitry Andric class ErlangGC : public GCStrategy {
293ca95b02SDimitry Andric public:
ErlangGC()303ca95b02SDimitry Andric   ErlangGC() {
31*b5893f02SDimitry Andric     NeededSafePoints = true;
323ca95b02SDimitry Andric     UsesMetadata = true;
333ca95b02SDimitry Andric   }
343ca95b02SDimitry Andric };
353ca95b02SDimitry Andric 
363ca95b02SDimitry Andric /// An example GC which attempts to be compatible with Objective Caml 3.10.0
373ca95b02SDimitry Andric ///
383ca95b02SDimitry Andric /// The frametable emitter is in OcamlGCPrinter.cpp.
393ca95b02SDimitry Andric class OcamlGC : public GCStrategy {
403ca95b02SDimitry Andric public:
OcamlGC()413ca95b02SDimitry Andric   OcamlGC() {
42*b5893f02SDimitry Andric     NeededSafePoints = true;
433ca95b02SDimitry Andric     UsesMetadata = true;
443ca95b02SDimitry Andric   }
453ca95b02SDimitry Andric };
463ca95b02SDimitry Andric 
473ca95b02SDimitry Andric /// A GC strategy for uncooperative targets.  This implements lowering for the
483ca95b02SDimitry Andric /// llvm.gc* intrinsics for targets that do not natively support them (which
493ca95b02SDimitry Andric /// includes the C backend). Note that the code generated is not quite as
503ca95b02SDimitry Andric /// efficient as algorithms which generate stack maps to identify roots.
513ca95b02SDimitry Andric ///
523ca95b02SDimitry Andric /// In order to support this particular transformation, all stack roots are
533ca95b02SDimitry Andric /// coallocated in the stack. This allows a fully target-independent stack map
543ca95b02SDimitry Andric /// while introducing only minor runtime overhead.
553ca95b02SDimitry Andric class ShadowStackGC : public GCStrategy {
563ca95b02SDimitry Andric public:
ShadowStackGC()57*b5893f02SDimitry Andric   ShadowStackGC() {}
583ca95b02SDimitry Andric };
593ca95b02SDimitry Andric 
603ca95b02SDimitry Andric /// A GCStrategy which serves as an example for the usage of a statepoint based
613ca95b02SDimitry Andric /// lowering strategy.  This GCStrategy is intended to suitable as a default
623ca95b02SDimitry Andric /// implementation usable with any collector which can consume the standard
633ca95b02SDimitry Andric /// stackmap format generated by statepoints, uses the default addrespace to
643ca95b02SDimitry Andric /// distinguish between gc managed and non-gc managed pointers, and has
653ca95b02SDimitry Andric /// reasonable relocation semantics.
663ca95b02SDimitry Andric class StatepointGC : public GCStrategy {
673ca95b02SDimitry Andric public:
StatepointGC()683ca95b02SDimitry Andric   StatepointGC() {
693ca95b02SDimitry Andric     UseStatepoints = true;
703ca95b02SDimitry Andric     // These options are all gc.root specific, we specify them so that the
713ca95b02SDimitry Andric     // gc.root lowering code doesn't run.
72*b5893f02SDimitry Andric     NeededSafePoints = false;
733ca95b02SDimitry Andric     UsesMetadata = false;
743ca95b02SDimitry Andric   }
757a7e6055SDimitry Andric 
isGCManagedPointer(const Type * Ty) const763ca95b02SDimitry Andric   Optional<bool> isGCManagedPointer(const Type *Ty) const override {
773ca95b02SDimitry Andric     // Method is only valid on pointer typed values.
783ca95b02SDimitry Andric     const PointerType *PT = cast<PointerType>(Ty);
793ca95b02SDimitry Andric     // For the sake of this example GC, we arbitrarily pick addrspace(1) as our
803ca95b02SDimitry Andric     // GC managed heap.  We know that a pointer into this heap needs to be
813ca95b02SDimitry Andric     // updated and that no other pointer does.  Note that addrspace(1) is used
823ca95b02SDimitry Andric     // only as an example, it has no special meaning, and is not reserved for
833ca95b02SDimitry Andric     // GC usage.
843ca95b02SDimitry Andric     return (1 == PT->getAddressSpace());
853ca95b02SDimitry Andric   }
863ca95b02SDimitry Andric };
873ca95b02SDimitry Andric 
883ca95b02SDimitry Andric /// A GCStrategy for the CoreCLR Runtime. The strategy is similar to
893ca95b02SDimitry Andric /// Statepoint-example GC, but differs from it in certain aspects, such as:
903ca95b02SDimitry Andric /// 1) Base-pointers need not be explicitly tracked and reported for
913ca95b02SDimitry Andric ///    interior pointers
923ca95b02SDimitry Andric /// 2) Uses a different format for encoding stack-maps
933ca95b02SDimitry Andric /// 3) Location of Safe-point polls: polls are only needed before loop-back
943ca95b02SDimitry Andric ///    edges and before tail-calls (not needed at function-entry)
953ca95b02SDimitry Andric ///
963ca95b02SDimitry Andric /// The above differences in behavior are to be implemented in upcoming
973ca95b02SDimitry Andric /// checkins.
983ca95b02SDimitry Andric class CoreCLRGC : public GCStrategy {
993ca95b02SDimitry Andric public:
CoreCLRGC()1003ca95b02SDimitry Andric   CoreCLRGC() {
1013ca95b02SDimitry Andric     UseStatepoints = true;
1023ca95b02SDimitry Andric     // These options are all gc.root specific, we specify them so that the
1033ca95b02SDimitry Andric     // gc.root lowering code doesn't run.
104*b5893f02SDimitry Andric     NeededSafePoints = false;
1053ca95b02SDimitry Andric     UsesMetadata = false;
1063ca95b02SDimitry Andric   }
1077a7e6055SDimitry Andric 
isGCManagedPointer(const Type * Ty) const1083ca95b02SDimitry Andric   Optional<bool> isGCManagedPointer(const Type *Ty) const override {
1093ca95b02SDimitry Andric     // Method is only valid on pointer typed values.
1103ca95b02SDimitry Andric     const PointerType *PT = cast<PointerType>(Ty);
1113ca95b02SDimitry Andric     // We pick addrspace(1) as our GC managed heap.
1123ca95b02SDimitry Andric     return (1 == PT->getAddressSpace());
1133ca95b02SDimitry Andric   }
1143ca95b02SDimitry Andric };
1157a7e6055SDimitry Andric 
1167a7e6055SDimitry Andric } // end anonymous namespace
1173ca95b02SDimitry Andric 
1183ca95b02SDimitry Andric // Register all the above so that they can be found at runtime.  Note that
1193ca95b02SDimitry Andric // these static initializers are important since the registration list is
1203ca95b02SDimitry Andric // constructed from their storage.
1213ca95b02SDimitry Andric static GCRegistry::Add<ErlangGC> A("erlang",
1223ca95b02SDimitry Andric                                    "erlang-compatible garbage collector");
1233ca95b02SDimitry Andric static GCRegistry::Add<OcamlGC> B("ocaml", "ocaml 3.10-compatible GC");
1243ca95b02SDimitry Andric static GCRegistry::Add<ShadowStackGC>
1253ca95b02SDimitry Andric     C("shadow-stack", "Very portable GC for uncooperative code generators");
1263ca95b02SDimitry Andric static GCRegistry::Add<StatepointGC> D("statepoint-example",
1273ca95b02SDimitry Andric                                        "an example strategy for statepoint");
1283ca95b02SDimitry Andric static GCRegistry::Add<CoreCLRGC> E("coreclr", "CoreCLR-compatible GC");
1293ca95b02SDimitry Andric 
130*b5893f02SDimitry Andric // Provide hook to ensure the containing library is fully loaded.
linkAllBuiltinGCs()131*b5893f02SDimitry Andric void llvm::linkAllBuiltinGCs() {}
132