llvm.org GIT mirror llvm / 95d08bc
Add a GCStrategy for CoreCLR This change adds a new GC strategy for supporting the CoreCLR runtime. This strategy is currently identical to Statepoint-example GC, but is necessary for several upcoming changes specific to CoreCLR, such as: 1. Base-pointers not explicitly reported for interior pointers 2. Different format for stack-map encoding 3. Location of Safe-point polls: polls are only needed before loop-back edges and before tail-calls (not needed at function-entry) 4. Runtime specific handshake between calls to managed/unmanaged functions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237753 91177308-0d34-0410-b5e6-96231b3b80d8 Swaroop Sridhar 5 years ago
7 changed file(s) with 105 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
2020 /// FIXME: Collector instances are not useful on their own. These no longer
2121 /// serve any purpose except to link in the plugins.
2222
23 /// Creates a CoreCLR-compatible garbage collector.
24 void linkCoreCLRGC();
25
2326 /// Creates an ocaml-compatible garbage collector.
2427 void linkOcamlGC();
2528
3535 (void) llvm::createGreedyRegisterAllocator();
3636 (void) llvm::createDefaultPBQPRegisterAllocator();
3737
38 llvm::linkCoreCLRGC();
3839 llvm::linkOcamlGC();
3940 llvm::linkErlangGC();
4041 llvm::linkShadowStackGC();
88 CallingConvLower.cpp
99 CodeGen.cpp
1010 CodeGenPrepare.cpp
11 CoreCLRGC.cpp
1112 CriticalAntiDepBreaker.cpp
1213 DFAPacketizer.cpp
1314 DeadMachineInstructionElim.cpp
0 //===-- CoreCLRGC.cpp - CoreCLR Runtime GC Strategy -----------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains a GCStrategy for the CoreCLR Runtime.
10 // The strategy is similar to Statepoint-example GC, but differs from it in
11 // certain aspects, such as:
12 // 1) Base-pointers need not be explicitly tracked and reported for
13 // interior pointers
14 // 2) Uses a different format for encoding stack-maps
15 // 3) Location of Safe-point polls: polls are only needed before loop-back edges
16 // and before tail-calls (not needed at function-entry)
17 //
18 // The above differences in behavior are to be implemented in upcoming checkins.
19 //
20 //===----------------------------------------------------------------------===//
21
22 #include "llvm/CodeGen/GCStrategy.h"
23 #include "llvm/IR/DerivedTypes.h"
24 #include "llvm/IR/Value.h"
25
26 using namespace llvm;
27
28 namespace {
29 class CoreCLRGC : public GCStrategy {
30 public:
31 CoreCLRGC() {
32 UseStatepoints = true;
33 // These options are all gc.root specific, we specify them so that the
34 // gc.root lowering code doesn't run.
35 InitRoots = false;
36 NeededSafePoints = 0;
37 UsesMetadata = false;
38 CustomRoots = false;
39 }
40 Optional isGCManagedPointer(const Value *V) const override {
41 // Method is only valid on pointer typed values.
42 PointerType *PT = cast(V->getType());
43 // We pick addrspace(1) as our GC managed heap.
44 return (1 == PT->getAddressSpace());
45 }
46 };
47 }
48
49 static GCRegistry::Add X("coreclr",
50 "CoreCLR-compatible GC");
51
52 namespace llvm {
53 void linkCoreCLRGC() {}
54 }
5252 #include "llvm/ADT/SetOperations.h"
5353 #include "llvm/ADT/SetVector.h"
5454 #include "llvm/ADT/Statistic.h"
55 #include "llvm/ADT/StringRef.h"
5556 #include "llvm/Analysis/LoopPass.h"
5657 #include "llvm/Analysis/LoopInfo.h"
5758 #include "llvm/Analysis/ScalarEvolution.h"
522523 static bool shouldRewriteFunction(Function &F) {
523524 // TODO: This should check the GCStrategy
524525 if (F.hasGC()) {
525 const std::string StatepointExampleName("statepoint-example");
526 return StatepointExampleName == F.getGC();
526 const char *FunctionGCName = F.getGC();
527 const StringRef StatepointExampleName("statepoint-example");
528 const StringRef CoreCLRName("coreclr");
529 return (StatepointExampleName == FunctionGCName) ||
530 (CoreCLRName == FunctionGCName);
527531 } else
528532 return false;
529533 }
1818 #include "llvm/ADT/Statistic.h"
1919 #include "llvm/ADT/DenseSet.h"
2020 #include "llvm/ADT/SetVector.h"
21 #include "llvm/ADT/StringRef.h"
2122 #include "llvm/IR/BasicBlock.h"
2223 #include "llvm/IR/CallSite.h"
2324 #include "llvm/IR/Dominators.h"
22002201 static bool shouldRewriteStatepointsIn(Function &F) {
22012202 // TODO: This should check the GCStrategy
22022203 if (F.hasGC()) {
2203 const std::string StatepointExampleName("statepoint-example");
2204 return StatepointExampleName == F.getGC();
2205 } else
2204 const char *FunctionGCName = F.getGC();
2205 const StringRef StatepointExampleName("statepoint-example");
2206 const StringRef CoreCLRName("coreclr");
2207 return (StatepointExampleName == FunctionGCName) ||
2208 (CoreCLRName == FunctionGCName);
2209 }
2210 else
22062211 return false;
22072212 }
22082213
0 ; RUN: opt %s -S -place-safepoints | FileCheck %s
1
2 ; Basic test to make sure that safepoints are placed
3 ; for CoreCLR GC
4
5 declare void @foo()
6
7 define void @test_simple_call() gc "coreclr" {
8 ; CHECK-LABEL: test_simple_call
9 entry:
10 br label %other
11 other:
12 ; CHECK-LABEL: other
13 ; CHECK: statepoint
14 ; CHECK-NOT: gc.result
15 call void @foo()
16 ret void
17 }
18
19 ; This function is inlined when inserting a poll. To avoid recursive
20 ; issues, make sure we don't place safepoints in it.
21 declare void @do_safepoint()
22 define void @gc.safepoint_poll() {
23 ; CHECK-LABEL: gc.safepoint_poll
24 ; CHECK-LABEL: entry
25 ; CHECK-NEXT: do_safepoint
26 ; CHECK-NEXT: ret void
27 entry:
28 call void @do_safepoint()
29 ret void
30 }