135 lines
3.6 KiB
YAML
135 lines
3.6 KiB
YAML
# 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
|
|
...
|