From e34457738879a6f5059d5b72b30e9bfa001bab59 Mon Sep 17 00:00:00 2001 From: Sanjoy Das Date: Wed, 7 Oct 2015 19:52:12 +0000 Subject: [PATCH] [IRBuilder] Add gc.statepoint related methods to IRBuilder Summary: This adds some more routines to `IRBuilder` around creating calls and invokes to `gc.statepoint`. These will be used later. Reviewers: reames, swaroop.sridhar Subscribers: sanjoy, llvm-commits Differential Revision: http://reviews.llvm.org/D13371 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249596 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/IRBuilder.h | 20 +++++++ lib/IR/IRBuilder.cpp | 106 +++++++++++++++++++++++++----------- 2 files changed, 94 insertions(+), 32 deletions(-) diff --git a/include/llvm/IR/IRBuilder.h b/include/llvm/IR/IRBuilder.h index f02128391ce..f8e280d0043 100644 --- a/include/llvm/IR/IRBuilder.h +++ b/include/llvm/IR/IRBuilder.h @@ -25,6 +25,7 @@ #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" +#include "llvm/IR/Statepoint.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Operator.h" #include "llvm/IR/ValueHandle.h" @@ -445,6 +446,16 @@ public: ArrayRef GCArgs, const Twine &Name = ""); + /// \brief Create a call to the experimental.gc.statepoint intrinsic to + /// start a new statepoint sequence. + CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes, + Value *ActualCallee, StatepointFlags Flags, + ArrayRef CallArgs, + ArrayRef TransitionArgs, + ArrayRef DeoptArgs, + ArrayRef GCArgs, + const Twine &Name = ""); + // \brief Conveninence function for the common case when CallArgs are filled // in using makeArrayRef(CS.arg_begin(), CS.arg_end()); Use needs to be // .get()'ed to get the Value pointer. @@ -463,6 +474,15 @@ public: ArrayRef DeoptArgs, ArrayRef GCArgs, const Twine &Name = ""); + /// brief Create an invoke to the experimental.gc.statepoint intrinsic to + /// start a new statepoint sequence. + InvokeInst *CreateGCStatepointInvoke( + uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee, + BasicBlock *NormalDest, BasicBlock *UnwindDest, StatepointFlags Flags, + ArrayRef InvokeArgs, ArrayRef TransitionArgs, + ArrayRef DeoptArgs, ArrayRef GCArgs, + const Twine &Name = ""); + // Conveninence function for the common case when CallArgs are filled in using // makeArrayRef(CS.arg_begin(), CS.arg_end()); Use needs to be .get()'ed to // get the Value *. diff --git a/lib/IR/IRBuilder.cpp b/lib/IR/IRBuilder.cpp index bddb278dee7..aac1ed376d8 100644 --- a/lib/IR/IRBuilder.cpp +++ b/lib/IR/IRBuilder.cpp @@ -247,18 +247,21 @@ CallInst *IRBuilderBase::CreateMaskedIntrinsic(Intrinsic::ID Id, return createCallHelper(TheFn, Ops, this, Name); } +template static std::vector getStatepointArgs(IRBuilderBase &B, uint64_t ID, uint32_t NumPatchBytes, - Value *ActualCallee, ArrayRef CallArgs, - ArrayRef DeoptArgs, ArrayRef GCArgs) { + Value *ActualCallee, StatepointFlags Flags, + ArrayRef CallArgs, ArrayRef TransitionArgs, + ArrayRef DeoptArgs, ArrayRef GCArgs) { std::vector Args; Args.push_back(B.getInt64(ID)); Args.push_back(B.getInt32(NumPatchBytes)); Args.push_back(ActualCallee); Args.push_back(B.getInt32(CallArgs.size())); - Args.push_back(B.getInt32((unsigned)StatepointFlags::None)); + Args.push_back(B.getInt32((unsigned)Flags)); Args.insert(Args.end(), CallArgs.begin(), CallArgs.end()); - Args.push_back(B.getInt32(0 /* no transition args */)); + Args.push_back(B.getInt32(TransitionArgs.size())); + Args.insert(Args.end(), TransitionArgs.begin(), TransitionArgs.end()); Args.push_back(B.getInt32(DeoptArgs.size())); Args.insert(Args.end(), DeoptArgs.begin(), DeoptArgs.end()); Args.insert(Args.end(), GCArgs.begin(), GCArgs.end()); @@ -266,69 +269,108 @@ getStatepointArgs(IRBuilderBase &B, uint64_t ID, uint32_t NumPatchBytes, return Args; } -CallInst *IRBuilderBase::CreateGCStatepointCall( - uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, - ArrayRef CallArgs, ArrayRef DeoptArgs, - ArrayRef GCArgs, const Twine &Name) { +template +static CallInst *CreateGCStatepointCallCommon( + IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes, + Value *ActualCallee, StatepointFlags Flags, ArrayRef CallArgs, + ArrayRef TransitionArgs, ArrayRef DeoptArgs, ArrayRef GCArgs, + const Twine &Name) { // Extract out the type of the callee. PointerType *FuncPtrType = cast(ActualCallee->getType()); assert(isa(FuncPtrType->getElementType()) && "actual callee must be a callable value"); - Module *M = BB->getParent()->getParent(); + Module *M = Builder->GetInsertBlock()->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 Args = getStatepointArgs( - *this, ID, NumPatchBytes, ActualCallee, CallArgs, DeoptArgs, GCArgs); - return createCallHelper(FnStatepoint, Args, this, Name); + std::vector Args = + getStatepointArgs(*Builder, ID, NumPatchBytes, ActualCallee, Flags, + CallArgs, TransitionArgs, DeoptArgs, GCArgs); + return createCallHelper(FnStatepoint, Args, Builder, Name); } CallInst *IRBuilderBase::CreateGCStatepointCall( uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, - ArrayRef CallArgs, ArrayRef DeoptArgs, + ArrayRef CallArgs, ArrayRef DeoptArgs, ArrayRef GCArgs, const Twine &Name) { - std::vector VCallArgs; - for (auto &U : CallArgs) - VCallArgs.push_back(U.get()); - return CreateGCStatepointCall(ID, NumPatchBytes, ActualCallee, VCallArgs, - DeoptArgs, GCArgs, Name); + return CreateGCStatepointCallCommon( + this, ID, NumPatchBytes, ActualCallee, StatepointFlags::None, CallArgs, + None /* No Transition Args */, DeoptArgs, GCArgs, Name); } -InvokeInst *IRBuilderBase::CreateGCStatepointInvoke( - uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee, - BasicBlock *NormalDest, BasicBlock *UnwindDest, - ArrayRef InvokeArgs, ArrayRef DeoptArgs, +CallInst *IRBuilderBase::CreateGCStatepointCall( + uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, + StatepointFlags Flags, ArrayRef CallArgs, ArrayRef TransitionArgs, + ArrayRef DeoptArgs, ArrayRef GCArgs, const Twine &Name) { + return CreateGCStatepointCallCommon( + this, ID, NumPatchBytes, ActualCallee, Flags, CallArgs, TransitionArgs, + DeoptArgs, GCArgs, Name); +} + +CallInst *IRBuilderBase::CreateGCStatepointCall( + uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, + ArrayRef CallArgs, ArrayRef DeoptArgs, ArrayRef GCArgs, const Twine &Name) { + return CreateGCStatepointCallCommon( + this, ID, NumPatchBytes, ActualCallee, StatepointFlags::None, CallArgs, + None, DeoptArgs, GCArgs, Name); +} + +template +static InvokeInst *CreateGCStatepointInvokeCommon( + IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes, + Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest, + StatepointFlags Flags, ArrayRef InvokeArgs, ArrayRef TransitionArgs, + ArrayRef DeoptArgs, ArrayRef GCArgs, const Twine &Name) { // Extract out the type of the callee. PointerType *FuncPtrType = cast(ActualInvokee->getType()); assert(isa(FuncPtrType->getElementType()) && "actual callee must be a callable value"); - Module *M = BB->getParent()->getParent(); + Module *M = Builder->GetInsertBlock()->getParent()->getParent(); // Fill in the one generic type'd argument (the function is also vararg) Function *FnStatepoint = Intrinsic::getDeclaration( M, Intrinsic::experimental_gc_statepoint, {FuncPtrType}); - std::vector Args = getStatepointArgs( - *this, ID, NumPatchBytes, ActualInvokee, InvokeArgs, DeoptArgs, GCArgs); - return createInvokeHelper(FnStatepoint, NormalDest, UnwindDest, Args, this, + std::vector Args = + getStatepointArgs(*Builder, ID, NumPatchBytes, ActualInvokee, Flags, + InvokeArgs, TransitionArgs, DeoptArgs, GCArgs); + return createInvokeHelper(FnStatepoint, NormalDest, UnwindDest, Args, Builder, Name); } +InvokeInst *IRBuilderBase::CreateGCStatepointInvoke( + uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee, + BasicBlock *NormalDest, BasicBlock *UnwindDest, + ArrayRef InvokeArgs, ArrayRef DeoptArgs, + ArrayRef GCArgs, const Twine &Name) { + return CreateGCStatepointInvokeCommon( + this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest, + StatepointFlags::None, InvokeArgs, None /* No Transition Args*/, + DeoptArgs, GCArgs, Name); +} + +InvokeInst *IRBuilderBase::CreateGCStatepointInvoke( + uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee, + BasicBlock *NormalDest, BasicBlock *UnwindDest, StatepointFlags Flags, + ArrayRef InvokeArgs, ArrayRef TransitionArgs, + ArrayRef DeoptArgs, ArrayRef GCArgs, const Twine &Name) { + return CreateGCStatepointInvokeCommon( + this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest, Flags, + InvokeArgs, TransitionArgs, DeoptArgs, GCArgs, Name); +} + InvokeInst *IRBuilderBase::CreateGCStatepointInvoke( uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef InvokeArgs, ArrayRef DeoptArgs, ArrayRef GCArgs, const Twine &Name) { - std::vector VCallArgs; - for (auto &U : InvokeArgs) - VCallArgs.push_back(U.get()); - return CreateGCStatepointInvoke(ID, NumPatchBytes, ActualInvokee, NormalDest, - UnwindDest, VCallArgs, DeoptArgs, GCArgs, - Name); + return CreateGCStatepointInvokeCommon( + this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest, + StatepointFlags::None, InvokeArgs, None, DeoptArgs, GCArgs, Name); } CallInst *IRBuilderBase::CreateGCResult(Instruction *Statepoint, -- 2.34.1