mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-24 09:29:42 +00: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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237753 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a6f501cb97
commit
95d08bce87
@ -21,6 +21,9 @@ class GCMetadataPrinter;
|
|||||||
/// FIXME: Collector instances are not useful on their own. These no longer
|
/// FIXME: Collector instances are not useful on their own. These no longer
|
||||||
/// serve any purpose except to link in the plugins.
|
/// serve any purpose except to link in the plugins.
|
||||||
|
|
||||||
|
/// Creates a CoreCLR-compatible garbage collector.
|
||||||
|
void linkCoreCLRGC();
|
||||||
|
|
||||||
/// Creates an ocaml-compatible garbage collector.
|
/// Creates an ocaml-compatible garbage collector.
|
||||||
void linkOcamlGC();
|
void linkOcamlGC();
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ namespace {
|
|||||||
(void) llvm::createGreedyRegisterAllocator();
|
(void) llvm::createGreedyRegisterAllocator();
|
||||||
(void) llvm::createDefaultPBQPRegisterAllocator();
|
(void) llvm::createDefaultPBQPRegisterAllocator();
|
||||||
|
|
||||||
|
llvm::linkCoreCLRGC();
|
||||||
llvm::linkOcamlGC();
|
llvm::linkOcamlGC();
|
||||||
llvm::linkErlangGC();
|
llvm::linkErlangGC();
|
||||||
llvm::linkShadowStackGC();
|
llvm::linkShadowStackGC();
|
||||||
|
@ -9,6 +9,7 @@ add_llvm_library(LLVMCodeGen
|
|||||||
CallingConvLower.cpp
|
CallingConvLower.cpp
|
||||||
CodeGen.cpp
|
CodeGen.cpp
|
||||||
CodeGenPrepare.cpp
|
CodeGenPrepare.cpp
|
||||||
|
CoreCLRGC.cpp
|
||||||
CriticalAntiDepBreaker.cpp
|
CriticalAntiDepBreaker.cpp
|
||||||
DFAPacketizer.cpp
|
DFAPacketizer.cpp
|
||||||
DeadMachineInstructionElim.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/SetOperations.h"
|
||||||
#include "llvm/ADT/SetVector.h"
|
#include "llvm/ADT/SetVector.h"
|
||||||
#include "llvm/ADT/Statistic.h"
|
#include "llvm/ADT/Statistic.h"
|
||||||
|
#include "llvm/ADT/StringRef.h"
|
||||||
#include "llvm/Analysis/LoopPass.h"
|
#include "llvm/Analysis/LoopPass.h"
|
||||||
#include "llvm/Analysis/LoopInfo.h"
|
#include "llvm/Analysis/LoopInfo.h"
|
||||||
#include "llvm/Analysis/ScalarEvolution.h"
|
#include "llvm/Analysis/ScalarEvolution.h"
|
||||||
@ -523,8 +524,11 @@ static bool isGCSafepointPoll(Function &F) {
|
|||||||
static bool shouldRewriteFunction(Function &F) {
|
static bool shouldRewriteFunction(Function &F) {
|
||||||
// TODO: This should check the GCStrategy
|
// TODO: This should check the GCStrategy
|
||||||
if (F.hasGC()) {
|
if (F.hasGC()) {
|
||||||
const std::string StatepointExampleName("statepoint-example");
|
const char *FunctionGCName = F.getGC();
|
||||||
return StatepointExampleName == F.getGC();
|
const StringRef StatepointExampleName("statepoint-example");
|
||||||
|
const StringRef CoreCLRName("coreclr");
|
||||||
|
return (StatepointExampleName == FunctionGCName) ||
|
||||||
|
(CoreCLRName == FunctionGCName);
|
||||||
} else
|
} else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "llvm/ADT/Statistic.h"
|
#include "llvm/ADT/Statistic.h"
|
||||||
#include "llvm/ADT/DenseSet.h"
|
#include "llvm/ADT/DenseSet.h"
|
||||||
#include "llvm/ADT/SetVector.h"
|
#include "llvm/ADT/SetVector.h"
|
||||||
|
#include "llvm/ADT/StringRef.h"
|
||||||
#include "llvm/IR/BasicBlock.h"
|
#include "llvm/IR/BasicBlock.h"
|
||||||
#include "llvm/IR/CallSite.h"
|
#include "llvm/IR/CallSite.h"
|
||||||
#include "llvm/IR/Dominators.h"
|
#include "llvm/IR/Dominators.h"
|
||||||
@ -2201,9 +2202,13 @@ static bool insertParsePoints(Function &F, DominatorTree &DT, Pass *P,
|
|||||||
static bool shouldRewriteStatepointsIn(Function &F) {
|
static bool shouldRewriteStatepointsIn(Function &F) {
|
||||||
// TODO: This should check the GCStrategy
|
// TODO: This should check the GCStrategy
|
||||||
if (F.hasGC()) {
|
if (F.hasGC()) {
|
||||||
const std::string StatepointExampleName("statepoint-example");
|
const char *FunctionGCName = F.getGC();
|
||||||
return StatepointExampleName == F.getGC();
|
const StringRef StatepointExampleName("statepoint-example");
|
||||||
} else
|
const StringRef CoreCLRName("coreclr");
|
||||||
|
return (StatepointExampleName == FunctionGCName) ||
|
||||||
|
(CoreCLRName == FunctionGCName);
|
||||||
|
}
|
||||||
|
else
|
||||||
return false;
|
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