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



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@224981 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Philip Reames 2014-12-30 05:55:58 +00:00
parent d5dd993855
commit e46577f2b2
2 changed files with 92 additions and 2 deletions

View File

@ -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.

View File

@ -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);
}