mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
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. llvm-svn: 237753
This commit is contained in:
parent
d67e7dd667
commit
8765ceb638
@ -21,6 +21,9 @@ class GCMetadataPrinter;
|
||||
/// FIXME: Collector instances are not useful on their own. These no longer
|
||||
/// serve any purpose except to link in the plugins.
|
||||
|
||||
/// Creates a CoreCLR-compatible garbage collector.
|
||||
void linkCoreCLRGC();
|
||||
|
||||
/// Creates an ocaml-compatible garbage collector.
|
||||
void linkOcamlGC();
|
||||
|
||||
|
@ -36,6 +36,7 @@ namespace {
|
||||
(void) llvm::createGreedyRegisterAllocator();
|
||||
(void) llvm::createDefaultPBQPRegisterAllocator();
|
||||
|
||||
llvm::linkCoreCLRGC();
|
||||
llvm::linkOcamlGC();
|
||||
llvm::linkErlangGC();
|
||||
llvm::linkShadowStackGC();
|
||||
|
@ -9,6 +9,7 @@ add_llvm_library(LLVMCodeGen
|
||||
CallingConvLower.cpp
|
||||
CodeGen.cpp
|
||||
CodeGenPrepare.cpp
|
||||
CoreCLRGC.cpp
|
||||
CriticalAntiDepBreaker.cpp
|
||||
DFAPacketizer.cpp
|
||||
DeadMachineInstructionElim.cpp
|
||||
|
55
lib/CodeGen/CoreCLRGC.cpp
Normal file
55
lib/CodeGen/CoreCLRGC.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
//===-- CoreCLRGC.cpp - CoreCLR Runtime GC Strategy -----------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains a GCStrategy for the CoreCLR Runtime.
|
||||
// The strategy is similar to Statepoint-example GC, but differs from it in
|
||||
// certain aspects, such as:
|
||||
// 1) Base-pointers need not be explicitly tracked and reported for
|
||||
// interior pointers
|
||||
// 2) Uses a different format for encoding stack-maps
|
||||
// 3) Location of Safe-point polls: polls are only needed before loop-back edges
|
||||
// and before tail-calls (not needed at function-entry)
|
||||
//
|
||||
// The above differences in behavior are to be implemented in upcoming checkins.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/CodeGen/GCStrategy.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#include "llvm/IR/Value.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
class CoreCLRGC : public GCStrategy {
|
||||
public:
|
||||
CoreCLRGC() {
|
||||
UseStatepoints = true;
|
||||
// These options are all gc.root specific, we specify them so that the
|
||||
// gc.root lowering code doesn't run.
|
||||
InitRoots = false;
|
||||
NeededSafePoints = 0;
|
||||
UsesMetadata = false;
|
||||
CustomRoots = false;
|
||||
}
|
||||
Optional<bool> isGCManagedPointer(const Value *V) const override {
|
||||
// Method is only valid on pointer typed values.
|
||||
PointerType *PT = cast<PointerType>(V->getType());
|
||||
// We pick addrspace(1) as our GC managed heap.
|
||||
return (1 == PT->getAddressSpace());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static GCRegistry::Add<CoreCLRGC> X("coreclr",
|
||||
"CoreCLR-compatible GC");
|
||||
|
||||
namespace llvm {
|
||||
void linkCoreCLRGC() {}
|
||||
}
|
@ -53,6 +53,7 @@
|
||||
#include "llvm/ADT/SetOperations.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Analysis/LoopPass.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/ScalarEvolution.h"
|
||||
@ -523,8 +524,11 @@ static bool isGCSafepointPoll(Function &F) {
|
||||
static bool shouldRewriteFunction(Function &F) {
|
||||
// TODO: This should check the GCStrategy
|
||||
if (F.hasGC()) {
|
||||
const std::string StatepointExampleName("statepoint-example");
|
||||
return StatepointExampleName == F.getGC();
|
||||
const char *FunctionGCName = F.getGC();
|
||||
const StringRef StatepointExampleName("statepoint-example");
|
||||
const StringRef CoreCLRName("coreclr");
|
||||
return (StatepointExampleName == FunctionGCName) ||
|
||||
(CoreCLRName == FunctionGCName);
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/CallSite.h"
|
||||
#include "llvm/IR/Dominators.h"
|
||||
@ -2201,9 +2202,13 @@ static bool insertParsePoints(Function &F, DominatorTree &DT, Pass *P,
|
||||
static bool shouldRewriteStatepointsIn(Function &F) {
|
||||
// TODO: This should check the GCStrategy
|
||||
if (F.hasGC()) {
|
||||
const std::string StatepointExampleName("statepoint-example");
|
||||
return StatepointExampleName == F.getGC();
|
||||
} else
|
||||
const char *FunctionGCName = F.getGC();
|
||||
const StringRef StatepointExampleName("statepoint-example");
|
||||
const StringRef CoreCLRName("coreclr");
|
||||
return (StatepointExampleName == FunctionGCName) ||
|
||||
(CoreCLRName == FunctionGCName);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
31
test/Transforms/PlaceSafepoints/statepoint-coreclr.ll
Normal file
31
test/Transforms/PlaceSafepoints/statepoint-coreclr.ll
Normal file
@ -0,0 +1,31 @@
|
||||
; RUN: opt %s -S -place-safepoints | FileCheck %s
|
||||
|
||||
; Basic test to make sure that safepoints are placed
|
||||
; for CoreCLR GC
|
||||
|
||||
declare void @foo()
|
||||
|
||||
define void @test_simple_call() gc "coreclr" {
|
||||
; CHECK-LABEL: test_simple_call
|
||||
entry:
|
||||
br label %other
|
||||
other:
|
||||
; CHECK-LABEL: other
|
||||
; CHECK: statepoint
|
||||
; CHECK-NOT: gc.result
|
||||
call void @foo()
|
||||
ret void
|
||||
}
|
||||
|
||||
; This function is inlined when inserting a poll. To avoid recursive
|
||||
; issues, make sure we don't place safepoints in it.
|
||||
declare void @do_safepoint()
|
||||
define void @gc.safepoint_poll() {
|
||||
; CHECK-LABEL: gc.safepoint_poll
|
||||
; CHECK-LABEL: entry
|
||||
; CHECK-NEXT: do_safepoint
|
||||
; CHECK-NEXT: ret void
|
||||
entry:
|
||||
call void @do_safepoint()
|
||||
ret void
|
||||
}
|
Loading…
Reference in New Issue
Block a user