mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
Add IRBuilder routines for gc.statepoints, gc.results, and gc.relocates
Nothing particularly interesting, just adding infrastructure for use by in tree users and out of tree users. Note: These were extracted out of a working frontend, but they have not been well tested in isolation. Differential Revision: http://reviews.llvm.org/D6807 llvm-svn: 224981
This commit is contained in:
parent
288a7d5deb
commit
fc9bbfb244
@ -439,6 +439,28 @@ public:
|
||||
/// assume that the provided condition will be true.
|
||||
CallInst *CreateAssumption(Value *Cond);
|
||||
|
||||
/// \brief Create a call to the experimental.gc.statepoint intrinsic to
|
||||
/// start a new statepoint sequence.
|
||||
CallInst *CreateGCStatepoint(Value *ActualCallee,
|
||||
ArrayRef<Value*> CallArgs,
|
||||
ArrayRef<Value*> DeoptArgs,
|
||||
ArrayRef<Value*> GCArgs,
|
||||
const Twine &Name = "");
|
||||
|
||||
/// \brief Create a call to the experimental.gc.result intrinsic to extract
|
||||
/// the result from a call wrapped in a statepoint.
|
||||
CallInst *CreateGCResult(Instruction *Statepoint,
|
||||
Type *ResultType,
|
||||
const Twine &Name = "");
|
||||
|
||||
/// \brief Create a call to the experimental.gc.relocate intrinsics to
|
||||
/// project the relocated value of one pointer from the statepoint.
|
||||
CallInst *CreateGCRelocate(Instruction *Statepoint,
|
||||
int BaseOffset,
|
||||
int DerivedOffset,
|
||||
Type *ResultType,
|
||||
const Twine &Name = "");
|
||||
|
||||
private:
|
||||
/// \brief Create a call to a masked intrinsic with given Id.
|
||||
/// Masked intrinsic has only one overloaded type - data type.
|
||||
|
@ -53,8 +53,9 @@ Value *IRBuilderBase::getCastedInt8PtrValue(Value *Ptr) {
|
||||
}
|
||||
|
||||
static CallInst *createCallHelper(Value *Callee, ArrayRef<Value *> Ops,
|
||||
IRBuilderBase *Builder) {
|
||||
CallInst *CI = CallInst::Create(Callee, Ops, "");
|
||||
IRBuilderBase *Builder,
|
||||
const Twine& Name="") {
|
||||
CallInst *CI = CallInst::Create(Callee, Ops, Name);
|
||||
Builder->GetInsertBlock()->getInstList().insert(Builder->GetInsertPoint(),CI);
|
||||
Builder->SetInstDebugLocation(CI);
|
||||
return CI;
|
||||
@ -209,3 +210,70 @@ CallInst *IRBuilderBase::CreateMaskedIntrinsic(unsigned Id,
|
||||
Value *TheFn = Intrinsic::getDeclaration(M, (Intrinsic::ID)Id, OverloadedTypes);
|
||||
return createCallHelper(TheFn, Ops, this);
|
||||
}
|
||||
|
||||
CallInst *IRBuilderBase::CreateGCStatepoint(Value *ActualCallee,
|
||||
ArrayRef<Value*> CallArgs,
|
||||
ArrayRef<Value*> DeoptArgs,
|
||||
ArrayRef<Value*> GCArgs,
|
||||
const Twine& Name) {
|
||||
// Extract out the type of the callee.
|
||||
PointerType *FuncPtrType = cast<PointerType>(ActualCallee->getType());
|
||||
assert(isa<FunctionType>(FuncPtrType->getElementType()) &&
|
||||
"actual callee must be a callable value");
|
||||
|
||||
|
||||
Module *M = BB->getParent()->getParent();
|
||||
// Fill in the one generic type'd argument (the function is also vararg)
|
||||
Type *ArgTypes[] = { FuncPtrType };
|
||||
Function *FnStatepoint =
|
||||
Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_statepoint,
|
||||
ArgTypes);
|
||||
|
||||
std::vector<llvm::Value *> args;
|
||||
args.push_back(ActualCallee);
|
||||
args.push_back(getInt32(CallArgs.size()));
|
||||
args.push_back(getInt32(0 /*unused*/));
|
||||
args.insert(args.end(), CallArgs.begin(), CallArgs.end());
|
||||
args.push_back(getInt32(DeoptArgs.size()));
|
||||
args.insert(args.end(), DeoptArgs.begin(), DeoptArgs.end());
|
||||
args.insert(args.end(), GCArgs.begin(), GCArgs.end());
|
||||
|
||||
return createCallHelper(FnStatepoint, args, this, Name);
|
||||
}
|
||||
|
||||
CallInst *IRBuilderBase::CreateGCResult(Instruction *Statepoint,
|
||||
Type *ResultType,
|
||||
const Twine &Name) {
|
||||
Intrinsic::ID ID;
|
||||
if (ResultType->isIntegerTy()) {
|
||||
ID = Intrinsic::experimental_gc_result_int;
|
||||
} else if (ResultType->isFloatingPointTy()) {
|
||||
ID = Intrinsic::experimental_gc_result_float;
|
||||
} else if (ResultType->isPointerTy()) {
|
||||
ID = Intrinsic::experimental_gc_result_ptr;
|
||||
} else {
|
||||
llvm_unreachable("unimplemented result type for gc.result");
|
||||
}
|
||||
Module *M = BB->getParent()->getParent();
|
||||
Type *Types[] = {ResultType};
|
||||
Value *FnGCResult = Intrinsic::getDeclaration(M, ID, Types);
|
||||
|
||||
Value *Args[] = {Statepoint};
|
||||
return createCallHelper(FnGCResult, Args, this, Name);
|
||||
}
|
||||
|
||||
CallInst *IRBuilderBase::CreateGCRelocate(Instruction *Statepoint,
|
||||
int BaseOffset,
|
||||
int DerivedOffset,
|
||||
Type *ResultType,
|
||||
const Twine &Name) {
|
||||
Module *M = BB->getParent()->getParent();
|
||||
Type *Types[] = {ResultType};
|
||||
Value *FnGCRelocate =
|
||||
Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_relocate, Types);
|
||||
|
||||
Value *Args[] = {Statepoint,
|
||||
getInt32(BaseOffset),
|
||||
getInt32(DerivedOffset)};
|
||||
return createCallHelper(FnGCRelocate, Args, this, Name);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user