diff options
| author | Philip Reames <listmail@philipreames.com> | 2015-04-10 21:48:25 +0000 |
|---|---|---|
| committer | Philip Reames <listmail@philipreames.com> | 2015-04-10 21:48:25 +0000 |
| commit | 8531d8c491aca1209f0ce9c4431a263c9c54c589 (patch) | |
| tree | 10446595a540f0db727316cfd85da4ca0c4eae26 /llvm/test/Transforms/RewriteStatepointsForGC/live-vector.ll | |
| parent | 8330835197d3e2f459fdf6a5978c79aa59372948 (diff) | |
| download | bcm5719-llvm-8531d8c491aca1209f0ce9c4431a263c9c54c589.tar.gz bcm5719-llvm-8531d8c491aca1209f0ce9c4431a263c9c54c589.zip | |
[RewriteStatepointsForGC] Limited support for vectors of pointers
This patch adds limited support for inserting explicit relocations when there's a vector of pointers live over the statepoint. This doesn't handle the case where the vector contains a mix of base and non-base pointers; that's future work.
The current implementation just scalarizes the vector over the gc.statepoint before doing the explicit rewrite. An alternate approach would be to plumb the vector all the way though the backend lowering, but doing that appears challenging. In particular, the size of the indirect spill slot is currently assumed to be sizeof(pointer) throughout the backend.
In practice, this is enough to allow running the SLP and Loop vectorizers before RewriteStatepointsForGC.
Differential Revision: http://reviews.llvm.org/D8671
llvm-svn: 234647
Diffstat (limited to 'llvm/test/Transforms/RewriteStatepointsForGC/live-vector.ll')
| -rw-r--r-- | llvm/test/Transforms/RewriteStatepointsForGC/live-vector.ll | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/llvm/test/Transforms/RewriteStatepointsForGC/live-vector.ll b/llvm/test/Transforms/RewriteStatepointsForGC/live-vector.ll new file mode 100644 index 00000000000..555f05e576c --- /dev/null +++ b/llvm/test/Transforms/RewriteStatepointsForGC/live-vector.ll @@ -0,0 +1,87 @@ +; Test that we can correctly handle vectors of pointers in statepoint +; rewriting. Currently, we scalarize, but that's an implementation detail. +; RUN: opt %s -rewrite-statepoints-for-gc -S | FileCheck %s + +; A non-vector relocation for comparison +define i64 addrspace(1)* @test(i64 addrspace(1)* %obj) gc "statepoint-example" { +; CHECK-LABEL: test +; CHECK: gc.statepoint +; CHECK-NEXT: gc.relocate +; CHECK-NEXT: ret i64 addrspace(1)* %obj.relocated +entry: + %safepoint_token = call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0) + ret i64 addrspace(1)* %obj +} + +; A base vector from a argument +define <2 x i64 addrspace(1)*> @test2(<2 x i64 addrspace(1)*> %obj) gc "statepoint-example" { +; CHECK-LABEL: test2 +; CHECK: extractelement +; CHECK-NEXT: extractelement +; CHECK-NEXT: gc.statepoint +; CHECK-NEXT: gc.relocate +; CHECK-NEXT: gc.relocate +; CHECK-NEXT: insertelement +; CHECK-NEXT: insertelement +; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %5 +entry: + %safepoint_token = call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0) + ret <2 x i64 addrspace(1)*> %obj +} + +; A base vector from a load +define <2 x i64 addrspace(1)*> @test3(<2 x i64 addrspace(1)*>* %ptr) gc "statepoint-example" { +; CHECK-LABEL: test3 +; CHECK: load +; CHECK-NEXT: extractelement +; CHECK-NEXT: extractelement +; CHECK-NEXT: gc.statepoint +; CHECK-NEXT: gc.relocate +; CHECK-NEXT: gc.relocate +; CHECK-NEXT: insertelement +; CHECK-NEXT: insertelement +; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %5 +entry: + %obj = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr + %safepoint_token = call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0) + ret <2 x i64 addrspace(1)*> %obj +} + +declare i32 @fake_personality_function() + +; When a statepoint is an invoke rather than a call +define <2 x i64 addrspace(1)*> @test4(<2 x i64 addrspace(1)*>* %ptr) gc "statepoint-example" { +; CHECK-LABEL: test4 +; CHECK: load +; CHECK-NEXT: extractelement +; CHECK-NEXT: extractelement +; CHECK-NEXT: gc.statepoint +entry: + %obj = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr + invoke i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0) + to label %normal_return unwind label %exceptional_return + +; CHECK-LABEL: normal_return: +; CHECK: gc.relocate +; CHECK-NEXT: gc.relocate +; CHECK-NEXT: insertelement +; CHECK-NEXT: insertelement +; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %6 +normal_return: ; preds = %entry + ret <2 x i64 addrspace(1)*> %obj + +; CHECK-LABEL: exceptional_return: +; CHECK: gc.relocate +; CHECK-NEXT: gc.relocate +; CHECK-NEXT: insertelement +; CHECK-NEXT: insertelement +; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %10 +exceptional_return: ; preds = %entry + %landing_pad4 = landingpad { i8*, i32 } personality i32 ()* @fake_personality_function + cleanup + ret <2 x i64 addrspace(1)*> %obj +} + +declare void @do_safepoint() + +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...) |

