llvm.org GIT mirror llvm / 44d65ea
[Statepoints] Let patchable statepoints have a symbolic call target. Summary: As added initially, statepoints required their call targets to be a constant pointer null if ``numPatchBytes`` was non-zero. This turns out to be a problem ergonomically, since there is no way to mark patchable statepoints as calling a (readable) symbolic value. This change remove the restriction of requiring ``null`` call targets for patchable statepoints, and changes PlaceSafepoints to maintain the symbolic call target through its transformation. Reviewers: reames, swaroop.sridhar Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D11550 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243502 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjoy Das 4 years ago
6 changed file(s) with 25 addition(s) and 32 deletion(s). Raw diff Collapse all Expand all
330330 calling sequence specific to their runtime before executing the
331331 generated machine code. There are no guarantees with respect to the
332332 alignment of the nop sequence. Unlike :doc:`StackMaps` statepoints do
333 not have a concept of shadow bytes.
333 not have a concept of shadow bytes. Note that semantically the
334 statepoint still represents a call or invoke to 'target', and the nop
335 sequence after patching is expected to represent an operation
336 equivalent to a call or invoke to 'target'.
334337
335338 The 'target' operand is the function actually being called. The
336339 target can be specified as either a symbolic LLVM function, or as an
337340 arbitrary Value of appropriate function type. Note that the function
338341 type must match the signature of the callee and the types of the 'call
339 parameters' arguments. If 'num patch bytes' is non-zero then 'target'
340 has to be the constant pointer null of the appropriate function type.
342 parameters' arguments.
341343
342344 The '#call args' operand is the number of arguments to the actual
343345 call. It must exactly match the number of arguments passed in the
288288
289289 ImmutableCallSite CS(ISP.getCallSite());
290290
291 SDValue ActualCallee = Builder.getValue(ISP.getCalledValue());
291 SDValue ActualCallee;
292
293 if (ISP.getNumPatchBytes() > 0) {
294 // If we've been asked to emit a nop sequence instead of a call instruction
295 // for this statepoint then don't lower the call target, but use a constant
296 // `null` instead. Not lowering the call target lets statepoint clients get
297 // away without providing a physical address for the symbolic call target at
298 // link time.
299
300 const auto &TLI = Builder.DAG.getTargetLoweringInfo();
301 const auto &DL = Builder.DAG.getDataLayout();
302
303 unsigned AS = ISP.getCalledValue()->getType()->getPointerAddressSpace();
304 ActualCallee = Builder.DAG.getConstant(0, Builder.getCurSDLoc(),
305 TLI.getPointerTy(DL, AS));
306 } else
307 ActualCallee = Builder.getValue(ISP.getCalledValue());
292308
293309 assert(CS.getCallingConv() != CallingConv::AnyReg &&
294310 "anyregcc is not supported on statepoints!");
15421542 Assert(PT && PT->getElementType()->isFunctionTy(),
15431543 "gc.statepoint callee must be of function pointer type", &CI, Target);
15441544 FunctionType *TargetFuncType = cast(PT->getElementType());
1545
1546 if (NumPatchBytes)
1547 Assert(isa(Target->stripPointerCasts()),
1548 "gc.statepoint must have null as call target if number of patchable "
1549 "bytes is non zero",
1550 &CI);
15511545
15521546 const Value *NumCallArgsV = CS.getArgument(3);
15531547 Assert(isa(NumCallArgsV),
916916 CS.getInstruction()->getContext(), AttributeSet::FunctionIndex,
917917 AttrsToRemove);
918918
919 Value *StatepointTarget = NumPatchBytes == 0
920 ? CS.getCalledValue()
921 : ConstantPointerNull::get(cast(
922 CS.getCalledValue()->getType()));
923
924919 if (CS.isCall()) {
925920 CallInst *ToReplace = cast(CS.getInstruction());
926921 CallInst *Call = Builder.CreateGCStatepointCall(
927 ID, NumPatchBytes, StatepointTarget,
922 ID, NumPatchBytes, CS.getCalledValue(),
928923 makeArrayRef(CS.arg_begin(), CS.arg_end()), None, None,
929924 "safepoint_token");
930925 Call->setTailCall(ToReplace->isTailCall());
950945 // original block.
951946 Builder.SetInsertPoint(ToReplace->getParent());
952947 InvokeInst *Invoke = Builder.CreateGCStatepointInvoke(
953 ID, NumPatchBytes, StatepointTarget, ToReplace->getNormalDest(),
948 ID, NumPatchBytes, CS.getCalledValue(), ToReplace->getNormalDest(),
954949 ToReplace->getUnwindDest(), makeArrayRef(CS.arg_begin(), CS.arg_end()),
955950 None, None, "safepoint_token");
956951
2121 ; CHECK-LABEL: @test_num_patch_bytes(
2222 entry:
2323 ; CHECK-LABEL: entry:
24 ; CHECK: invoke i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 99, void ()* null,
24 ; CHECK: invoke i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 99, void ()* @f,
2525 invoke void @f() "statepoint-num-patch-bytes"="99" to label %normal_return unwind label %exceptional_return
2626
2727 normal_return:
+0
-14
test/Verifier/invalid-patchable-statepoint.ll less more
None ; RUN: not opt -verify 2>&1 < %s | FileCheck %s
1
2 ; CHECK: gc.statepoint must have null as call target if number of patchable bytes is non zero
3
4 define i1 @invalid_patchable_statepoint() gc "statepoint-example" {
5 entry:
6 %safepoint_token = tail call i32 (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 3, i1 ()* @func, i32 0, i32 0, i32 0, i32 0)
7 %call1 = call i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
8 ret i1 %call1
9 }
10
11 declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
12 declare i1 @llvm.experimental.gc.result.i1(i32)
13 declare i1 @func()