# Pin: W65816StackSlotCleanup's temp-slot forwarding (Pass 2.4) and its # never-read store sweep (Pass 2.5). # # The far-pointer staging inserters move a pointer word to $E0 / $E2 through # a fresh stack object: `STAfi src, T ; ... ; LDAfi T ; STA_DP $E2`. With the # word in an IMG register and A live, the store alone cost # `pha ; lda dp ; sta n,s ; pla`. The reload now reads the IMG word itself # (LDAimg, `lda dp` after expansion) and the store, read by nothing any more, # goes; so do stores to objects nothing ever read (consecutive-deref CSE left # those behind: CoreMark's list reversal paid two pairs per node). # # forward: IMG word unchanged between store and reload: forwarded, # store dropped. # img_redefined: the IMG register is written in between: both stay. # dp_touched: a direct-page access to the IMG word in between: both stay. # two_reads: the slot is read twice: both stay. # never_read: a store to an object nothing reads: dropped. # addr_taken: an ADDframe of the object counts as a read: kept. # # RUN: llc -mtriple=w65816 -run-pass=w65816-stack-slot-cleanup -o - %s | FileCheck %s --- | target triple = "w65816" define void @forward() { ret void } define void @img_redefined() { ret void } define void @dp_touched() { ret void } define void @two_reads() { ret void } define void @never_read() { ret void } define void @addr_taken() { ret void } ... --- # CHECK-LABEL: name: forward # CHECK: $img0 = COPY $x # CHECK-NOT: STAfi # CHECK-NOT: LDAfi # CHECK: $a = LDAimg $img0 # CHECK-NEXT: STA_DP 226 name: forward tracksRegLiveness: false stack: - { id: 0, size: 2, alignment: 1 } body: | bb.0: $img0 = COPY $x STAfi $img0, %stack.0, 0, implicit-def dead $a $a = LDAi16imm 7 STA_DP 224, implicit $a dead $a = LDAfi %stack.0, 0 STA_DP 226 RTL ... --- # CHECK-LABEL: name: img_redefined # CHECK: STAfi $img0, %stack.0, 0 # CHECK: $a = LDAfi %stack.0, 0 name: img_redefined tracksRegLiveness: false stack: - { id: 0, size: 2, alignment: 1 } body: | bb.0: $img0 = COPY $x STAfi $img0, %stack.0, 0, implicit-def dead $a $img0 = COPY $y $a = LDAfi %stack.0, 0 STA_DP 226, implicit $a RTL ... --- # CHECK-LABEL: name: dp_touched # CHECK: STAfi $img1, %stack.0, 0 # CHECK: $a = LDAfi %stack.0, 0 name: dp_touched tracksRegLiveness: false stack: - { id: 0, size: 2, alignment: 1 } body: | bb.0: $img1 = COPY $x STAfi $img1, %stack.0, 0, implicit-def dead $a INC_DP 210 $a = LDAfi %stack.0, 0 STA_DP 226, implicit $a RTL ... --- # CHECK-LABEL: name: two_reads # CHECK: STAfi $img0, %stack.0, 0 # CHECK: $a = LDAfi %stack.0, 0 # CHECK: $a = LDAfi %stack.0, 0 name: two_reads tracksRegLiveness: false stack: - { id: 0, size: 2, alignment: 1 } body: | bb.0: $img0 = COPY $x STAfi $img0, %stack.0, 0, implicit-def dead $a $a = LDAfi %stack.0, 0 STA_DP 224, implicit $a $a = LDAi16imm 1 STA_DP 228, implicit $a $a = LDAfi %stack.0, 0 STA_DP 226, implicit $a RTL ... --- # CHECK-LABEL: name: never_read # CHECK: $a = LDAi16imm 5 # CHECK-NOT: STAfi # CHECK: RTL name: never_read tracksRegLiveness: false stack: - { id: 0, size: 2, alignment: 1 } body: | bb.0: $a = LDAi16imm 5 STAfi $a, %stack.0, 0, implicit-def $a RTL ... --- # CHECK-LABEL: name: addr_taken # CHECK: STAfi $a, %stack.0, 0 # CHECK: $a = ADDframe %stack.0, 0 name: addr_taken tracksRegLiveness: false stack: - { id: 0, size: 2, alignment: 1 } body: | bb.0: $a = LDAi16imm 5 STAfi $a, %stack.0, 0, implicit-def $a $a = ADDframe %stack.0, 0 RTL ...