llvm.org GIT mirror llvm / 8a86e25
[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 Sanjoy Das 4 years ago
4 changed file(s) with 118 addition(s) and 71 deletion(s). Raw diff Collapse all Expand all
446446
447447 /// \brief Create a call to the experimental.gc.statepoint intrinsic to
448448 /// start a new statepoint sequence.
449 CallInst *CreateGCStatepoint(Value *ActualCallee,
450 ArrayRef CallArgs,
451 ArrayRef DeoptArgs,
452 ArrayRef GCArgs,
453 const Twine &Name = "");
449 CallInst *CreateGCStatepointCall(Value *ActualCallee,
450 ArrayRef CallArgs,
451 ArrayRef DeoptArgs,
452 ArrayRef GCArgs,
453 const Twine &Name = "");
454
455 // \brief Conveninence function for the common case when CallArgs are filled
456 // in using makeArrayRef(CS.arg_begin(), CS.arg_end()); Use needs to be
457 // .get()'ed to get the Value pointer.
458 CallInst *CreateGCStatepointCall(Value *ActualCallee, ArrayRef CallArgs,
459 ArrayRef DeoptArgs,
460 ArrayRef GCArgs,
461 const Twine &Name = "");
462
463 /// brief Create an invoke to the experimental.gc.statepoint intrinsic to
464 /// start a new statepoint sequence.
465 InvokeInst *
466 CreateGCStatepointInvoke(Value *ActualInvokee, BasicBlock *NormalDest,
467 BasicBlock *UnwindDest, ArrayRef InvokeArgs,
468 ArrayRef DeoptArgs,
469 ArrayRef GCArgs, const Twine &Name = "");
454470
455471 // Conveninence function for the common case when CallArgs are filled in using
456 // makeArrayRef(CS.arg_begin(), .arg_end()); Use needs to be .get()'ed to get
457 // the Value *.
458 CallInst *CreateGCStatepoint(Value *ActualCallee, ArrayRef CallArgs,
459 ArrayRef DeoptArgs,
460 ArrayRef GCArgs,
461 const Twine &Name = "");
472 // makeArrayRef(CS.arg_begin(), CS.arg_end()); Use needs to be .get()'ed to
473 // get the Value *.
474 InvokeInst *
475 CreateGCStatepointInvoke(Value *ActualInvokee, BasicBlock *NormalDest,
476 BasicBlock *UnwindDest, ArrayRef InvokeArgs,
477 ArrayRef DeoptArgs,
478 ArrayRef GCArgs, const Twine &Name = "");
462479
463480 /// \brief Create a call to the experimental.gc.result intrinsic to extract
464481 /// the result from a call wrapped in a statepoint.
5959 Builder->GetInsertBlock()->getInstList().insert(Builder->GetInsertPoint(),CI);
6060 Builder->SetInstDebugLocation(CI);
6161 return CI;
62 }
63
64 static InvokeInst *createInvokeHelper(Value *Invokee, BasicBlock *NormalDest,
65 BasicBlock *UnwindDest,
66 ArrayRef Ops,
67 IRBuilderBase *Builder,
68 const Twine &Name = "") {
69 InvokeInst *II =
70 InvokeInst::Create(Invokee, NormalDest, UnwindDest, Ops, Name);
71 Builder->GetInsertBlock()->getInstList().insert(Builder->GetInsertPoint(),
72 II);
73 Builder->SetInstDebugLocation(II);
74 return II;
6275 }
6376
6477 CallInst *IRBuilderBase::
230243 return createCallHelper(TheFn, Ops, this, Name);
231244 }
232245
233 CallInst *IRBuilderBase::CreateGCStatepoint(Value *ActualCallee,
234 ArrayRef CallArgs,
235 ArrayRef DeoptArgs,
236 ArrayRef GCArgs,
237 const Twine &Name) {
246 static std::vector getStatepointArgs(IRBuilderBase &B,
247 Value *ActualCallee,
248 ArrayRef CallArgs,
249 ArrayRef DeoptArgs,
250 ArrayRef GCArgs) {
251 std::vector Args;
252 Args.push_back(ActualCallee);
253 Args.push_back(B.getInt32(CallArgs.size()));
254 Args.push_back(B.getInt32(0)); // unused
255 Args.insert(Args.end(), CallArgs.begin(), CallArgs.end());
256 Args.push_back(B.getInt32(DeoptArgs.size()));
257 Args.insert(Args.end(), DeoptArgs.begin(), DeoptArgs.end());
258 Args.insert(Args.end(), GCArgs.begin(), GCArgs.end());
259
260 return Args;
261 }
262
263 CallInst *IRBuilderBase::CreateGCStatepointCall(Value *ActualCallee,
264 ArrayRef CallArgs,
265 ArrayRef DeoptArgs,
266 ArrayRef GCArgs,
267 const Twine &Name) {
238268 // Extract out the type of the callee.
239269 PointerType *FuncPtrType = cast(ActualCallee->getType());
240270 assert(isa(FuncPtrType->getElementType()) &&
247277 Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_statepoint,
248278 ArgTypes);
249279
250 std::vector args;
251 args.push_back(ActualCallee);
252 args.push_back(getInt32(CallArgs.size()));
253 args.push_back(getInt32(0 /*unused*/));
254 args.insert(args.end(), CallArgs.begin(), CallArgs.end());
255 args.push_back(getInt32(DeoptArgs.size()));
256 args.insert(args.end(), DeoptArgs.begin(), DeoptArgs.end());
257 args.insert(args.end(), GCArgs.begin(), GCArgs.end());
258
259 return createCallHelper(FnStatepoint, args, this, Name);
260 }
261
262 CallInst *IRBuilderBase::CreateGCStatepoint(Value *ActualCallee,
263 ArrayRef CallArgs,
264 ArrayRef DeoptArgs,
265 ArrayRef GCArgs,
266 const Twine &Name) {
280 std::vector Args =
281 getStatepointArgs(*this, ActualCallee, CallArgs, DeoptArgs, GCArgs);
282 return createCallHelper(FnStatepoint, Args, this, Name);
283 }
284
285 CallInst *IRBuilderBase::CreateGCStatepointCall(Value *ActualCallee,
286 ArrayRef CallArgs,
287 ArrayRef DeoptArgs,
288 ArrayRef GCArgs,
289 const Twine &Name) {
267290 std::vector VCallArgs;
268291 for (auto &U : CallArgs)
269292 VCallArgs.push_back(U.get());
270 return CreateGCStatepoint(ActualCallee, VCallArgs, DeoptArgs, GCArgs, Name);
293 return CreateGCStatepointCall(ActualCallee, VCallArgs, DeoptArgs, GCArgs,
294 Name);
295 }
296
297 InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
298 Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest,
299 ArrayRef InvokeArgs, ArrayRef DeoptArgs,
300 ArrayRef GCArgs, const Twine &Name) {
301 // Extract out the type of the callee.
302 PointerType *FuncPtrType = cast(ActualInvokee->getType());
303 assert(isa(FuncPtrType->getElementType()) &&
304 "actual callee must be a callable value");
305
306 Module *M = BB->getParent()->getParent();
307 // Fill in the one generic type'd argument (the function is also vararg)
308 Function *FnStatepoint = Intrinsic::getDeclaration(
309 M, Intrinsic::experimental_gc_statepoint, {FuncPtrType});
310
311 std::vector Args =
312 getStatepointArgs(*this, ActualInvokee, InvokeArgs, DeoptArgs, GCArgs);
313 return createInvokeHelper(FnStatepoint, NormalDest, UnwindDest, Args, this,
314 Name);
315 }
316
317 InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
318 Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest,
319 ArrayRef InvokeArgs, ArrayRef DeoptArgs,
320 ArrayRef GCArgs, const Twine &Name) {
321 std::vector VCallArgs;
322 for (auto &U : InvokeArgs)
323 VCallArgs.push_back(U.get());
324 return CreateGCStatepointInvoke(ActualInvokee, NormalDest, UnwindDest,
325 VCallArgs, DeoptArgs, GCArgs, Name);
271326 }
272327
273328 CallInst *IRBuilderBase::CreateGCResult(Instruction *Statepoint,
892892 AttributeSet return_attributes;
893893 if (CS.isCall()) {
894894 CallInst *toReplace = cast(CS.getInstruction());
895 CallInst *Call = Builder.CreateGCStatepoint(
895 CallInst *Call = Builder.CreateGCStatepointCall(
896896 CS.getCalledValue(), makeArrayRef(CS.arg_begin(), CS.arg_end()), None,
897897 None, "safepoint_token");
898898 Call->setTailCall(toReplace->isTailCall());
918918 Builder.SetCurrentDebugLocation(IP->getDebugLoc());
919919
920920 } else if (CS.isInvoke()) {
921 // TODO: make CreateGCStatepoint return an Instruction that we can cast to a
922 // Call or Invoke, instead of doing this junk here.
923
924 // Fill in the one generic type'd argument (the function is also
925 // vararg)
926 std::vector argTypes;
927 argTypes.push_back(CS.getCalledValue()->getType());
928
929 Function *gc_statepoint_decl = Intrinsic::getDeclaration(
930 M, Intrinsic::experimental_gc_statepoint, argTypes);
931
932 // First, create the statepoint (with all live ptrs as arguments).
933 std::vector args;
934 // target, #call args, unused, ... call parameters, #deopt args, ... deopt
935 // parameters, ... gc parameters
936 Value *Target = CS.getCalledValue();
937 args.push_back(Target);
938 int callArgSize = CS.arg_size();
939 // #call args
940 args.push_back(Builder.getInt32(callArgSize));
941 // unused
942 args.push_back(Builder.getInt32(0));
943 // call parameters
944 args.insert(args.end(), CS.arg_begin(), CS.arg_end());
945 // #deopt args: 0
946 args.push_back(Builder.getInt32(0));
947
948921 InvokeInst *toReplace = cast(CS.getInstruction());
949922
950923 // Insert the new invoke into the old block. We'll remove the old one in a
951924 // moment at which point this will become the new terminator for the
952925 // original block.
953 InvokeInst *invoke = InvokeInst::Create(
954 gc_statepoint_decl, toReplace->getNormalDest(),
955 toReplace->getUnwindDest(), args, "", toReplace->getParent());
956 invoke->setCallingConv(toReplace->getCallingConv());
926 Builder.SetInsertPoint(toReplace->getParent());
927 InvokeInst *invoke = Builder.CreateGCStatepointInvoke(
928 CS.getCalledValue(), toReplace->getNormalDest(),
929 toReplace->getUnwindDest(), makeArrayRef(CS.arg_begin(), CS.arg_end()),
930 Builder.getInt32(0), None, "safepoint_token");
957931
958932 // Currently we will fail on parameter attributes and on certain
959933 // function attributes.
6161 }
6262
6363 define i64 addrspace(1)* @test_phi_node(i1 %cond, i64 addrspace(1)* %obj) gc "statepoint-example" {
64 ; CHECK-LABEL: @test_phi_node
6465 ; CHECK-LABEL: entry:
6566 entry:
6667 br i1 %cond, label %left, label %right
7374 %ret_val_right = invoke i64 addrspace(1)* @"some_call"(i64 addrspace(1)* %obj)
7475 to label %merge unwind label %exceptional_return
7576
76 ; CHECK-LABEL: merge1:
77 ; CHECK: merge[[A:[0-9]]]:
7778 ; CHECK: gc.result
78 ; CHECK: br label %merge
79 ; CHECK: br label %[[with_phi:merge[0-9]*]]
7980
80 ; CHECK-LABEL: merge3:
81 ; CHECK: merge[[B:[0-9]]]:
8182 ; CHECK: gc.result
82 ; CHECK: br label %merge
83 ; CHECK: br label %[[with_phi]]
8384
84 ; CHECK-LABEL: merge:
85 ; CHECK: [[with_phi]]:
8586 ; CHECK: phi
8687 ; CHECK: ret i64 addrspace(1)* %ret_val
8788 merge: