[PATCH] D14666: Lower statepoints with multi-def targets.
Pat Gavlin via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 13 13:40:24 PST 2015
pgavlin created this revision.
pgavlin added reviewers: reames, sanjoy.
pgavlin added a subscriber: llvm-commits.
Herald added a subscriber: sanjoy.
Statepoint lowering currently expects that the target method of a statepoint only defines a single value. This precludes using statepoints with ABIs that return values in multiple registers (e.g. the SysV AMD64 ABI). This change adds support for lowering statepoints with mutli-def targets.
http://reviews.llvm.org/D14666
Files:
lib/CodeGen/SelectionDAG/StatepointLowering.cpp
test/CodeGen/X86/statepoint-call-lowering.ll
Index: test/CodeGen/X86/statepoint-call-lowering.ll
===================================================================
--- test/CodeGen/X86/statepoint-call-lowering.ll
+++ test/CodeGen/X86/statepoint-call-lowering.ll
@@ -5,10 +5,13 @@
target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"
+%struct = type { i64, i64 }
+
declare zeroext i1 @return_i1()
declare zeroext i32 @return_i32()
declare i32* @return_i32ptr()
declare float @return_float()
+declare %struct @return_struct()
declare void @varargf(i32, ...)
define i1 @test_i1_return() gc "statepoint-example" {
@@ -61,12 +64,24 @@
ret float %call1
}
+define %struct @test_struct_return() gc "statepoint-example" {
+; CHECK-LABEL: test_struct_return
+; CHECK: pushq %rax
+; CHECK: callq return_struct
+; CHECK: popq %rcx
+; CHECK: retq
+entry:
+ %safepoint_token = tail call i32 (i64, i32, %struct ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_structf(i64 0, i32 0, %struct ()* @return_struct, i32 0, i32 0, i32 0, i32 0)
+ %call1 = call %struct @llvm.experimental.gc.result.struct(i32 %safepoint_token)
+ ret %struct %call1
+}
+
define i1 @test_relocate(i32 addrspace(1)* %a) gc "statepoint-example" {
; CHECK-LABEL: test_relocate
; Check that an ununsed relocate has no code-generation impact
; CHECK: pushq %rax
; CHECK: callq return_i1
-; CHECK-NEXT: .Ltmp9:
+; CHECK-NEXT: .Ltmp11:
; CHECK-NEXT: popq %rdx
; CHECK-NEXT: retq
entry:
@@ -137,6 +152,9 @@
declare i32 @llvm.experimental.gc.statepoint.p0f_f32f(i64, i32, float ()*, i32, i32, ...)
declare float @llvm.experimental.gc.result.f32(i32)
+declare i32 @llvm.experimental.gc.statepoint.p0f_structf(i64, i32, %struct ()*, i32, i32, ...)
+declare %struct @llvm.experimental.gc.result.struct(i32)
+
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidi32varargf(i64, i32, void (i32, ...)*, i32, i32, ...)
declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32)
Index: lib/CodeGen/SelectionDAG/StatepointLowering.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/StatepointLowering.cpp
+++ lib/CodeGen/SelectionDAG/StatepointLowering.cpp
@@ -333,13 +333,17 @@
// ch, glue = callseq_end ch, glue
// get_return_value ch, glue
//
- // get_return_value can either be a CopyFromReg to grab the return value from
- // %RAX, or it can be a LOAD to load a value returned by reference via a stack
- // slot.
-
- if (HasDef && (CallEnd->getOpcode() == ISD::CopyFromReg ||
- CallEnd->getOpcode() == ISD::LOAD))
- CallEnd = CallEnd->getOperand(0).getNode();
+ // get_return_value can either be a sequence of CopyFromReg instructions
+ // to grab the return value from the return register(s), or it can be a LOAD
+ // to load a value returned by reference via a stack slot.
+
+ if (HasDef) {
+ if (CallEnd->getOpcode() == ISD::LOAD)
+ CallEnd = CallEnd->getOperand(0).getNode();
+ else
+ while (CallEnd->getOpcode() == ISD::CopyFromReg)
+ CallEnd = CallEnd->getOperand(0).getNode();
+ }
assert(CallEnd->getOpcode() == ISD::CALLSEQ_END && "expected!");
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D14666.40175.patch
Type: text/x-patch
Size: 3184 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151113/54e39ec4/attachment.bin>
More information about the llvm-commits
mailing list