summaryrefslogtreecommitdiff
path: root/lib/IR/IRBuilder.cpp
diff options
context:
space:
mode:
authorSanjoy Das <sanjoy@playingwithpointers.com>2015-05-06 23:53:09 +0000
committerSanjoy Das <sanjoy@playingwithpointers.com>2015-05-06 23:53:09 +0000
commit8a86e2564d5e6225f4dc5d1c4be96937022fdd7a (patch)
treec1306c5845386c39b7dbaae704a0f5beac047a68 /lib/IR/IRBuilder.cpp
parent4f28a76c2564066e23a7925738b11c3e933c5902 (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.cpp97
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,