diff options
author | Sanjoy Das <sanjoy@playingwithpointers.com> | 2015-05-06 23:53:09 +0000 |
---|---|---|
committer | Sanjoy Das <sanjoy@playingwithpointers.com> | 2015-05-06 23:53:09 +0000 |
commit | 8a86e2564d5e6225f4dc5d1c4be96937022fdd7a (patch) | |
tree | c1306c5845386c39b7dbaae704a0f5beac047a68 /lib/IR/IRBuilder.cpp | |
parent | 4f28a76c2564066e23a7925738b11c3e933c5902 (diff) |
[IRBuilder] Add a CreateGCStatepointInvoke.
Renames the original CreateGCStatepoint to CreateGCStatepointCall, and
moves invoke creating functionality from PlaceSafepoints.cpp to
IRBuilder.cpp.
This changes the labels generated for PlaceSafepoints/invokes.ll so use
a regex there to make the basic block labels more resilient.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@236672 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/IR/IRBuilder.cpp')
-rw-r--r-- | lib/IR/IRBuilder.cpp | 97 |
1 files changed, 76 insertions, 21 deletions
diff --git a/lib/IR/IRBuilder.cpp b/lib/IR/IRBuilder.cpp index 001d10fd69e..c526c862bdc 100644 --- a/lib/IR/IRBuilder.cpp +++ b/lib/IR/IRBuilder.cpp @@ -62,6 +62,19 @@ static CallInst *createCallHelper(Value *Callee, ArrayRef<Value *> Ops, return CI; } +static InvokeInst *createInvokeHelper(Value *Invokee, BasicBlock *NormalDest, + BasicBlock *UnwindDest, + ArrayRef<Value *> Ops, + IRBuilderBase *Builder, + const Twine &Name = "") { + InvokeInst *II = + InvokeInst::Create(Invokee, NormalDest, UnwindDest, Ops, Name); + Builder->GetInsertBlock()->getInstList().insert(Builder->GetInsertPoint(), + II); + Builder->SetInstDebugLocation(II); + return II; +} + CallInst *IRBuilderBase:: CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align, bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag, @@ -231,11 +244,28 @@ CallInst *IRBuilderBase::CreateMaskedIntrinsic(unsigned Id, return createCallHelper(TheFn, Ops, this, Name); } -CallInst *IRBuilderBase::CreateGCStatepoint(Value *ActualCallee, - ArrayRef<Value *> CallArgs, - ArrayRef<Value *> DeoptArgs, - ArrayRef<Value *> GCArgs, - const Twine &Name) { +static std::vector<Value *> getStatepointArgs(IRBuilderBase &B, + Value *ActualCallee, + ArrayRef<Value *> CallArgs, + ArrayRef<Value *> DeoptArgs, + ArrayRef<Value *> GCArgs) { + std::vector<Value *> Args; + Args.push_back(ActualCallee); + Args.push_back(B.getInt32(CallArgs.size())); + Args.push_back(B.getInt32(0)); // unused + Args.insert(Args.end(), CallArgs.begin(), CallArgs.end()); + Args.push_back(B.getInt32(DeoptArgs.size())); + Args.insert(Args.end(), DeoptArgs.begin(), DeoptArgs.end()); + Args.insert(Args.end(), GCArgs.begin(), GCArgs.end()); + + return Args; +} + +CallInst *IRBuilderBase::CreateGCStatepointCall(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()) && @@ -248,27 +278,52 @@ CallInst *IRBuilderBase::CreateGCStatepoint(Value *ActualCallee, 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); + std::vector<llvm::Value *> Args = + getStatepointArgs(*this, ActualCallee, CallArgs, DeoptArgs, GCArgs); + return createCallHelper(FnStatepoint, Args, this, Name); } -CallInst *IRBuilderBase::CreateGCStatepoint(Value *ActualCallee, - ArrayRef<Use> CallArgs, - ArrayRef<Value *> DeoptArgs, - ArrayRef<Value *> GCArgs, - const Twine &Name) { +CallInst *IRBuilderBase::CreateGCStatepointCall(Value *ActualCallee, + ArrayRef<Use> CallArgs, + ArrayRef<Value *> DeoptArgs, + ArrayRef<Value *> GCArgs, + const Twine &Name) { std::vector<Value *> VCallArgs; for (auto &U : CallArgs) VCallArgs.push_back(U.get()); - return CreateGCStatepoint(ActualCallee, VCallArgs, DeoptArgs, GCArgs, Name); + return CreateGCStatepointCall(ActualCallee, VCallArgs, DeoptArgs, GCArgs, + Name); +} + +InvokeInst *IRBuilderBase::CreateGCStatepointInvoke( + Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest, + ArrayRef<Value *> InvokeArgs, ArrayRef<Value *> DeoptArgs, + ArrayRef<Value *> GCArgs, const Twine &Name) { + // Extract out the type of the callee. + PointerType *FuncPtrType = cast<PointerType>(ActualInvokee->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) + Function *FnStatepoint = Intrinsic::getDeclaration( + M, Intrinsic::experimental_gc_statepoint, {FuncPtrType}); + + std::vector<llvm::Value *> Args = + getStatepointArgs(*this, ActualInvokee, InvokeArgs, DeoptArgs, GCArgs); + return createInvokeHelper(FnStatepoint, NormalDest, UnwindDest, Args, this, + Name); +} + +InvokeInst *IRBuilderBase::CreateGCStatepointInvoke( + Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest, + ArrayRef<Use> InvokeArgs, ArrayRef<Value *> DeoptArgs, + ArrayRef<Value *> GCArgs, const Twine &Name) { + std::vector<Value *> VCallArgs; + for (auto &U : InvokeArgs) + VCallArgs.push_back(U.get()); + return CreateGCStatepointInvoke(ActualInvokee, NormalDest, UnwindDest, + VCallArgs, DeoptArgs, GCArgs, Name); } CallInst *IRBuilderBase::CreateGCResult(Instruction *Statepoint, |