llvm.org GIT mirror llvm / 3f0ca03
[PlaceSafepoints] New attributes for patchable statepoints. Summary: This patch teaches the PlaceSafepoints pass about two `CallSite` function attributes: * "statepoint-id": if the string value of this attribute can be parsed as an integer, then it is propagated to the ID parameter of the statepoint created. * "statepoint-num-patch-bytes": if the string value of this attribute can be parsed as an integer, then it is propagated to the `num patch bytes` parameter of the statepoint created. This change intentionally does not assert on a malformed value for these attributes, given that they're not "official" attributes. Reviewers: reames, pgavlin Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D9735 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237286 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjoy Das 4 years ago
3 changed file(s) with 99 addition(s) and 12 deletion(s). Raw diff Collapse all Expand all
676676 inside this method are transformed to a ``gc.statepoints``, recursive poll
677677 insertion is not performed.
678678
679 By default PlaceSafepoints passes in ``0xABCDEF00`` as the statepoint
680 ID and ``0`` as the number of patchable bytes to the newly constructed
681 ``gc.statepoint``. These values can be configured on a per-callsite
682 basis using the attributes ``"statepoint-id"`` and
683 ``"statepoint-num-patch-bytes"``. If a call site is marked with a
684 ``"statepoint-id"`` function attribute and its value is a positive
685 integer (represented as a string), then that value is used as the ID
686 of the newly constructed ``gc.statepoint``. If a call site is marked
687 with a ``"statepoint-num-patch-bytes"`` function attribute and its
688 value is a positive integer, then that value is used as the 'num patch
689 bytes' parameter of the newly constructed ``gc.statepoint``. The
690 ``"statepoint-id"`` and ``"statepoint-num-patch-bytes"`` attributes
691 are not propagated to the ``gc.statepoint`` call or invoke if they
692 could be successfully parsed.
693
679694 If you are scheduling the RewriteStatepointsForGC pass late in the pass order,
680695 you should probably schedule this pass immediately before it. The exception
681696 would be if you need to preserve abstract frame information (e.g. for
880880
881881 // Create the statepoint given all the arguments
882882 Instruction *Token = nullptr;
883 AttributeSet OriginalAttrs;
883
884 uint64_t ID;
885 uint32_t NumPatchBytes;
886
887 AttributeSet OriginalAttrs = CS.getAttributes();
888 Attribute AttrID =
889 OriginalAttrs.getAttribute(AttributeSet::FunctionIndex, "statepoint-id");
890 Attribute AttrNumPatchBytes = OriginalAttrs.getAttribute(
891 AttributeSet::FunctionIndex, "statepoint-num-patch-bytes");
892
893 AttrBuilder AttrsToRemove;
894 bool HasID = AttrID.isStringAttribute() &&
895 !AttrID.getValueAsString().getAsInteger(10, ID);
896
897 if (HasID)
898 AttrsToRemove.addAttribute("statepoint-id");
899 else
900 ID = 0xABCDEF00;
901
902 bool HasNumPatchBytes =
903 AttrNumPatchBytes.isStringAttribute() &&
904 !AttrNumPatchBytes.getValueAsString().getAsInteger(10, NumPatchBytes);
905
906 if (HasNumPatchBytes)
907 AttrsToRemove.addAttribute("statepoint-num-patch-bytes");
908 else
909 NumPatchBytes = 0;
910
911 OriginalAttrs = OriginalAttrs.removeAttributes(
912 CS.getInstruction()->getContext(), AttributeSet::FunctionIndex,
913 AttrsToRemove);
914
915 Value *StatepointTarget = NumPatchBytes == 0
916 ? CS.getCalledValue()
917 : ConstantPointerNull::get(cast(
918 CS.getCalledValue()->getType()));
884919
885920 if (CS.isCall()) {
886921 CallInst *ToReplace = cast(CS.getInstruction());
887922 CallInst *Call = Builder.CreateGCStatepointCall(
888 0xABCDEF00, 0, CS.getCalledValue(), makeArrayRef(CS.arg_begin(), CS.arg_end()),
889 None, None, "safepoint_token");
923 ID, NumPatchBytes, StatepointTarget,
924 makeArrayRef(CS.arg_begin(), CS.arg_end()), None, None,
925 "safepoint_token");
890926 Call->setTailCall(ToReplace->isTailCall());
891927 Call->setCallingConv(ToReplace->getCallingConv());
892
893 // Before we have to worry about GC semantics, all attributes are legal
894 // TODO: handle param attributes
895 OriginalAttrs = ToReplace->getAttributes();
896928
897929 // In case if we can handle this set of attributes - set up function
898930 // attributes directly on statepoint and return attributes later for
914946 // original block.
915947 Builder.SetInsertPoint(ToReplace->getParent());
916948 InvokeInst *Invoke = Builder.CreateGCStatepointInvoke(
917 0xABCDEF00, 0, CS.getCalledValue(), ToReplace->getNormalDest(),
949 ID, NumPatchBytes, StatepointTarget, ToReplace->getNormalDest(),
918950 ToReplace->getUnwindDest(), makeArrayRef(CS.arg_begin(), CS.arg_end()),
919951 Builder.getInt32(0), None, "safepoint_token");
920
921 // Currently we will fail on parameter attributes and on certain
922 // function attributes.
923 OriginalAttrs = ToReplace->getAttributes();
924952
925953 // In case if we can handle this set of attributes - set up function
926954 // attributes directly on statepoint and return attributes later for
0 ; RUN: opt -place-safepoints -S < %s | FileCheck %s
1
2 declare void @f()
3 declare i32 @personality_function()
4
5 define void @test_id() gc "statepoint-example" {
6 ; CHECK-LABEL: @test_id(
7 entry:
8 ; CHECK-LABEL: entry:
9 ; CHECK: invoke i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 100, i32 0, void ()* @f
10 invoke void @f() "statepoint-id"="100" to label %normal_return unwind label %exceptional_return
11
12 normal_return:
13 ret void
14
15 exceptional_return:
16 %landing_pad4 = landingpad {i8*, i32} personality i32 ()* @personality_function cleanup
17 ret void
18 }
19
20 define void @test_num_patch_bytes() gc "statepoint-example" {
21 ; CHECK-LABEL: @test_num_patch_bytes(
22 entry:
23 ; CHECK-LABEL: entry:
24 ; CHECK: invoke i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 99, void ()* null,
25 invoke void @f() "statepoint-num-patch-bytes"="99" to label %normal_return unwind label %exceptional_return
26
27 normal_return:
28 ret void
29
30 exceptional_return:
31 %landing_pad4 = landingpad {i8*, i32} personality i32 ()* @personality_function cleanup
32 ret void
33 }
34
35 declare void @do_safepoint()
36 define void @gc.safepoint_poll() {
37 entry:
38 call void @do_safepoint()
39 ret void
40 }
41
42 ; CHECK-NOT: statepoint-id
43 ; CHECK-NOT: statepoint-num-patch_bytes