# Pin: W65816FrameLowering::orderFrameObjects lays a large frame out with # its most-used objects nearest S. A slot more than 0xFF bytes above S is # out of `off,s` reach, so every access to it goes through the $F6 frame # pointer (`sty $fa ; ldy #off ; lda [$f6],y ; ldy $fa`, 18 cycles against # 5). In creation order the 2-byte scalar below sat on top of the 300-byte # array it was created before; by access density (direct accesses, 8x per # loop level, per byte) it now sits at S+1 and the array, reached only # through the address ADDframe builds, goes on top. # # pha_pinned: an object accessed past its end is the PHA-bracket idiom # (W65816ImgCalleeSave saves IMG8..15 with `pha ; lda dp ; sta slot+2,s ; # pla`), whose +2 holds only stack-relative: through $F6, which the PHA does # not move, it addresses the neighbour. Such objects stay nearest S however # rarely they are used. The first cut sorted runtime snprintf's IMG8 save # slot out of reach: `format` restored IMG8 from its neighbour and fprintf # wrote nothing (the smoke test's GS/OS fflush check). # # RUN: llc -mtriple=w65816 -run-pass=prologepilog -o - %s | FileCheck %s # RUN: env W65816_DISABLE_FRAME_ORDER=1 llc -mtriple=w65816 -run-pass=prologepilog -o - %s | FileCheck %s --check-prefix=CREATION --- | target triple = "w65816" define void @hot_near() { ret void } define void @pha_pinned() { ret void } ... --- # CHECK-LABEL: name: hot_near # CHECK-NOT: DPIndLongY 246 # CHECK: STA_StackRel 1 # CHECK-NOT: DPIndLongY 246 # CHECK: LDA_StackRel 1 # CREATION-LABEL: name: hot_near # CREATION: STA_DPIndLongY 246 name: hot_near tracksRegLiveness: false stack: - { id: 0, size: 2, alignment: 1 } - { id: 1, size: 300, alignment: 1 } body: | bb.0: $a = ADDframe %stack.1, 0 STAfi $a, %stack.0, 0, implicit-def $a $a = LDAi16imm 0 $a = LDAfi %stack.0, 0 RTL ... --- # CHECK-LABEL: name: pha_pinned # CHECK: PHA # CHECK-NEXT: LDA_DP 192 # CHECK-NEXT: STA_StackRel 3 # CHECK-NEXT: PLA # The array's 20 loop accesses outweigh the save slot's one (by density), # which alone would sort the slot above the array, out of reach. name: pha_pinned tracksRegLiveness: false stack: - { id: 0, size: 2, alignment: 1 } - { id: 1, size: 300, alignment: 1 } body: | bb.0: successors: %bb.1 PHA implicit $a LDA_DP 192, implicit-def $a STAfi $a, %stack.0, 2, implicit-def $a PLA implicit-def $a bb.1: successors: %bb.1, %bb.2 $a = LDAfi %stack.1, 0 $a = LDAfi %stack.1, 2 $a = LDAfi %stack.1, 4 $a = LDAfi %stack.1, 6 $a = LDAfi %stack.1, 8 $a = LDAfi %stack.1, 10 $a = LDAfi %stack.1, 12 $a = LDAfi %stack.1, 14 $a = LDAfi %stack.1, 16 $a = LDAfi %stack.1, 18 $a = LDAfi %stack.1, 20 $a = LDAfi %stack.1, 22 $a = LDAfi %stack.1, 24 $a = LDAfi %stack.1, 26 $a = LDAfi %stack.1, 28 $a = LDAfi %stack.1, 30 $a = LDAfi %stack.1, 32 $a = LDAfi %stack.1, 34 $a = LDAfi %stack.1, 36 $a = LDAfi %stack.1, 38 CMPi16imm $a, 0, implicit-def $p BNE %bb.1, implicit $p bb.2: RTL ...