mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-12 03:32:10 +00:00
RewriteStatepointsForGC pass emits an alloca for each GC pointer which will be relocated. It then inserts stores after def and all relocations, and inserts loads before each use as well. In the end, mem2reg is used to update IR with relocations in SSA form. However, there is a problem with inserting stores for values defined by invoke instructions. The code didn't expect a def was a terminator instruction, and inserting instructions after these terminators resulted in malformed IR. This patch fixes this problem by handling invoke instructions as a special case. If the def is an invoke instruction, the store will be inserted at the beginning of the normal destination block. Since return value from invoke instruction does not dominate the unwind destination block, no action is needed there. Patch by: Chen Li Differential Revision: http://reviews.llvm.org/D7923 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@231183 91177308-0d34-0410-b5e6-96231b3b80d8
34 lines
1.1 KiB
LLVM
34 lines
1.1 KiB
LLVM
;; RUN: opt -rewrite-statepoints-for-gc -verify -S < %s | FileCheck %s
|
|
|
|
;; This test is to verify that RewriteStatepointsForGC correctly relocates values
|
|
;; defined by invoke instruction results.
|
|
|
|
declare i64* addrspace(1)* @non_gc_call()
|
|
|
|
declare void @gc_call()
|
|
|
|
declare i32* @fake_personality_function()
|
|
|
|
; Function Attrs: nounwind
|
|
define i64* addrspace(1)* @test() gc "statepoint-example" {
|
|
entry:
|
|
%obj = invoke i64* addrspace(1)* @non_gc_call()
|
|
to label %normal_dest unwind label %unwind_dest
|
|
|
|
unwind_dest:
|
|
%lpad = landingpad { i8*, i32 } personality i32* ()* @fake_personality_function
|
|
cleanup
|
|
resume { i8*, i32 } undef
|
|
|
|
normal_dest:
|
|
;; CHECK-LABEL: normal_dest:
|
|
;; CHECK-NEXT: gc.statepoint
|
|
;; CHECK-NEXT: %obj.relocated = call coldcc i64* addrspace(1)*
|
|
%safepoint_token = call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @gc_call, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
|
ret i64* addrspace(1)* %obj
|
|
}
|
|
|
|
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
|
|
|
|
|