From 01e833681ac100297288fc1e8c1c59236f9ce816 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Thu, 23 May 2019 12:02:52 +0200 Subject: [PATCH] Improved planned sequence for A->B->C sequences where B is conditional successor of A. --- .../java/dk/camelot64/kickc/Compiler.java | 2 +- .../passes/PassNBlockSequencePlanner.java | 22 ++++++-- src/test/ref/bool-ifs.asm | 16 +++--- src/test/ref/bool-vars.asm | 18 +++---- src/test/ref/complex-conditional-problem.asm | 6 +-- src/test/ref/complex/tetris/tetris.asm | 54 +++++++++---------- .../multiplexer/simple-multiplexer.asm | 17 +++--- src/test/ref/loop-break-continue.asm | 12 ++--- src/test/ref/loop-break-nested.asm | 14 ++--- src/test/ref/loop-continue.asm | 6 +-- .../simple-multiplexer-irq.asm | 20 +++---- src/test/ref/no-recursion-heavy.asm | 3 ++ src/test/ref/sandbox.asm | 48 +++++++++-------- src/test/ref/signed-words.asm | 6 +-- src/test/ref/travis1.asm | 22 ++++---- 15 files changed, 143 insertions(+), 123 deletions(-) diff --git a/src/main/java/dk/camelot64/kickc/Compiler.java b/src/main/java/dk/camelot64/kickc/Compiler.java index 84bd51381..ae353382c 100644 --- a/src/main/java/dk/camelot64/kickc/Compiler.java +++ b/src/main/java/dk/camelot64/kickc/Compiler.java @@ -377,7 +377,7 @@ public class Compiler { new Pass3AssertConstants(program).check(); new Pass3AssertArrayLengths(program).check(); new Pass3AssertNoMulDivMod(program).check(); - new PassNBlockSequencePlanner(program).step(); + //new PassNBlockSequencePlanner(program).step(); // Phi lifting ensures that all variables in phi-blocks are in different live range equivalence classes new Pass3PhiLifting(program).perform(); new PassNBlockSequencePlanner(program).step(); diff --git a/src/main/java/dk/camelot64/kickc/passes/PassNBlockSequencePlanner.java b/src/main/java/dk/camelot64/kickc/passes/PassNBlockSequencePlanner.java index 810de150a..f020476a6 100644 --- a/src/main/java/dk/camelot64/kickc/passes/PassNBlockSequencePlanner.java +++ b/src/main/java/dk/camelot64/kickc/passes/PassNBlockSequencePlanner.java @@ -39,11 +39,25 @@ public class PassNBlockSequencePlanner extends Pass2SsaOptimization { if(block.getCallSuccessor() != null) { pushTodo(getGraph().getCallSuccessor(block)); } - if(block.getConditionalSuccessor() != null) { + ControlFlowBlock conditionalSuccessor = getGraph().getConditionalSuccessor(block); + ControlFlowBlock defaultSuccessor = getGraph().getDefaultSuccessor(block); + if(conditionalSuccessor != null && defaultSuccessor != null) { + // Both conditional and default successor + if(conditionalSuccessor.getDefaultSuccessor().equals(defaultSuccessor.getLabel())) { + // Best sequence is cond->default (resulting in better code locality) + pushTodo(defaultSuccessor); + pushTodo(getGraph().getConditionalSuccessor(block)); + } else { + // Best sequence is default->cond + pushTodo(getGraph().getConditionalSuccessor(block)); + pushTodo(defaultSuccessor); + } + } else if(conditionalSuccessor != null) { + // Only a conditional successor pushTodo(getGraph().getConditionalSuccessor(block)); - } - if(getGraph().getDefaultSuccessor(block) != null) { - pushTodo(getGraph().getDefaultSuccessor(block)); + } else if(defaultSuccessor != null) { + // Only a default successor + pushTodo(defaultSuccessor); } } diff --git a/src/test/ref/bool-ifs.asm b/src/test/ref/bool-ifs.asm index 0fc00115b..ef375b6fe 100644 --- a/src/test/ref/bool-ifs.asm +++ b/src/test/ref/bool-ifs.asm @@ -17,6 +17,10 @@ bool_complex: { and #1 cpx #$a bcc b6 + jmp b5 + b6: + cmp #0 + beq b2 b5: cpx #$a bcc b4 @@ -34,10 +38,6 @@ bool_complex: { lda #' ' sta screen,x jmp b3 - b6: - cmp #0 - beq b2 - jmp b5 } bool_not: { .label screen = $450 @@ -91,6 +91,10 @@ bool_and: { and #1 cpx #$a bcc b5 + jmp b4 + b5: + cmp #0 + beq b2 b4: lda #' ' sta screen,x @@ -99,10 +103,6 @@ bool_and: { cpx #$15 bne b1 rts - b5: - cmp #0 - beq b2 - jmp b4 b2: lda #'*' sta screen,x diff --git a/src/test/ref/bool-vars.asm b/src/test/ref/bool-vars.asm index 8d19ed6d0..65d8b579c 100644 --- a/src/test/ref/bool-vars.asm +++ b/src/test/ref/bool-vars.asm @@ -31,6 +31,11 @@ bool_complex: { lda o1 cmp #0 bne b6 + jmp b5 + b6: + lda o2 + cmp #0 + bne b2 b5: lda o1 cmp #0 @@ -50,11 +55,6 @@ bool_complex: { lda #' ' sta screen,x jmp b3 - b6: - lda o2 - cmp #0 - bne b2 - jmp b5 } bool_not: { .label screen = $450 @@ -108,6 +108,10 @@ bool_and: { and #1 cpx #$a bcc b5 + jmp b4 + b5: + cmp #0 + beq b2 b4: lda #' ' sta screen,x @@ -116,10 +120,6 @@ bool_and: { cpx #$15 bne b1 rts - b5: - cmp #0 - beq b2 - jmp b4 b2: lda #'*' sta screen,x diff --git a/src/test/ref/complex-conditional-problem.asm b/src/test/ref/complex-conditional-problem.asm index ec0d49551..46436158b 100644 --- a/src/test/ref/complex-conditional-problem.asm +++ b/src/test/ref/complex-conditional-problem.asm @@ -11,10 +11,10 @@ main: { bcs b3 cmp #$40 bcc b3 + jmp b2 + b3: + lda #0 b2: sta SCREEN jmp b1 - b3: - lda #0 - jmp b2 } diff --git a/src/test/ref/complex/tetris/tetris.asm b/src/test/ref/complex/tetris/tetris.asm index 663c44f97..f0383be1a 100644 --- a/src/test/ref/complex/tetris/tetris.asm +++ b/src/test/ref/complex/tetris/tetris.asm @@ -145,18 +145,18 @@ .label current_xpos_59 = $a .label current_piece_gfx_64 = 5 .label current_piece_char_68 = $b - .label render_screen_render_69 = 9 - .label current_xpos_130 = $a - .label current_xpos_131 = $a - .label current_piece_gfx_120 = 5 - .label current_piece_gfx_121 = 5 - .label current_piece_char_108 = $b - .label current_piece_char_109 = $b - .label current_piece_100 = 5 + .label render_screen_render_68 = 9 + .label current_xpos_127 = $a + .label current_xpos_128 = $a + .label current_piece_gfx_117 = 5 + .label current_piece_gfx_118 = 5 + .label current_piece_char_105 = $b + .label current_piece_char_106 = $b .label current_piece_101 = 5 .label current_piece_102 = 5 .label current_piece_103 = 5 .label current_piece_104 = 5 + .label current_piece_105 = 5 bbegin: // The screen currently being showed to the user. $00 for screen 1 / $20 for screen 2. lda #0 @@ -192,13 +192,13 @@ main: { jsr render_playfield ldx current_ypos lda current_xpos - sta current_xpos_130 + sta current_xpos_127 lda current_piece_gfx - sta current_piece_gfx_120 + sta current_piece_gfx_117 lda current_piece_gfx+1 - sta current_piece_gfx_120+1 + sta current_piece_gfx_117+1 lda current_piece_char - sta current_piece_char_108 + sta current_piece_char_105 lda #$20 sta render_screen_render_33 jsr render_moving @@ -250,15 +250,15 @@ main: { jsr render_playfield ldx current_ypos lda render_screen_render - sta render_screen_render_69 + sta render_screen_render_68 lda current_xpos - sta current_xpos_131 + sta current_xpos_128 lda current_piece_gfx - sta current_piece_gfx_121 + sta current_piece_gfx_118 lda current_piece_gfx+1 - sta current_piece_gfx_121+1 + sta current_piece_gfx_118+1 lda current_piece_char - sta current_piece_char_109 + sta current_piece_char_106 jsr render_moving lda render_screen_render ldx next_piece_idx @@ -608,9 +608,9 @@ play_move_rotate: { sta play_collision.ypos ldx orientation lda current_piece - sta current_piece_103 + sta current_piece_104 lda current_piece+1 - sta current_piece_103+1 + sta current_piece_104+1 jsr play_collision cmp #COLLISION_NONE bne b4 @@ -738,9 +738,9 @@ play_move_leftright: { sta play_collision.ypos ldx current_orientation lda current_piece - sta current_piece_102 + sta current_piece_103 lda current_piece+1 - sta current_piece_102+1 + sta current_piece_103+1 jsr play_collision cmp #COLLISION_NONE bne b3 @@ -759,9 +759,9 @@ play_move_leftright: { sta play_collision.ypos ldx current_orientation lda current_piece - sta current_piece_101 + sta current_piece_102 lda current_piece+1 - sta current_piece_101+1 + sta current_piece_102+1 jsr play_collision cmp #COLLISION_NONE bne b3 @@ -804,9 +804,9 @@ play_move_down: { sta play_collision.xpos ldx current_orientation lda current_piece - sta current_piece_100 + sta current_piece_101 lda current_piece+1 - sta current_piece_100+1 + sta current_piece_101+1 jsr play_collision cmp #COLLISION_NONE beq b10 @@ -858,9 +858,9 @@ play_spawn_current: { lda current_ypos sta play_collision.ypos lda current_piece_gfx - sta current_piece_104 + sta current_piece_105 lda current_piece_gfx+1 - sta current_piece_104+1 + sta current_piece_105+1 ldx #0 jsr play_collision cmp #COLLISION_PLAYFIELD diff --git a/src/test/ref/examples/multiplexer/simple-multiplexer.asm b/src/test/ref/examples/multiplexer/simple-multiplexer.asm index ab1e3bf7b..cfcef75d5 100644 --- a/src/test/ref/examples/multiplexer/simple-multiplexer.asm +++ b/src/test/ref/examples/multiplexer/simple-multiplexer.asm @@ -142,10 +142,11 @@ plexShowSprite: { asl plex_sprite_msb lda plex_sprite_msb cmp #0 - bne breturn + bne b5 lda #1 sta plex_sprite_msb - breturn: + rts + b5: rts b1: lda SPRITES_XMSB @@ -185,6 +186,12 @@ plexSort: { dex cpx #$ff bne b5 + jmp b4 + b5: + lda nxt_y + ldy PLEX_SORTED_IDX,x + cmp PLEX_YPOS,y + bcc b3 b4: inx lda nxt_idx @@ -202,12 +209,6 @@ plexSort: { cpx #8 bne plexFreePrepare1_b1 rts - b5: - lda nxt_y - ldy PLEX_SORTED_IDX,x - cmp PLEX_YPOS,y - bcc b3 - jmp b4 } // Initialize the program init: { diff --git a/src/test/ref/loop-break-continue.asm b/src/test/ref/loop-break-continue.asm index 1ff20050e..c7a50bd37 100644 --- a/src/test/ref/loop-break-continue.asm +++ b/src/test/ref/loop-break-continue.asm @@ -19,11 +19,7 @@ main: { lda str,x cmp #' ' bne b3 - b4: - inx - cpx #0 - bne b1 - rts + jmp b4 b3: lda str,x ldy #0 @@ -32,6 +28,10 @@ main: { bne !+ inc screen+1 !: - jmp b4 + b4: + inx + cpx #0 + bne b1 + rts str: .text "hello brave new world@" } diff --git a/src/test/ref/loop-break-nested.asm b/src/test/ref/loop-break-nested.asm index 86284b28d..eb7d4bbcc 100644 --- a/src/test/ref/loop-break-nested.asm +++ b/src/test/ref/loop-break-nested.asm @@ -20,6 +20,13 @@ main: { lda (line),y cmp #'a' bne b3 + jmp b4 + b3: + lda #'a' + sta (line),y + iny + cpy #$28 + bne b2 b4: lda #$28 clc @@ -37,11 +44,4 @@ main: { bcc b1 !: rts - b3: - lda #'a' - sta (line),y - iny - cpy #$28 - bne b2 - jmp b4 } diff --git a/src/test/ref/loop-continue.asm b/src/test/ref/loop-continue.asm index c5abdab71..fe08e6e87 100644 --- a/src/test/ref/loop-continue.asm +++ b/src/test/ref/loop-continue.asm @@ -9,12 +9,12 @@ main: { lda SCREEN,x cmp #' ' bne b2 + jmp b3 + b2: + inc SCREEN,x b3: inx cpx #$28*6+1 bne b1 rts - b2: - inc SCREEN,x - jmp b3 } diff --git a/src/test/ref/multiplexer-irq/simple-multiplexer-irq.asm b/src/test/ref/multiplexer-irq/simple-multiplexer-irq.asm index 32a1fc283..d8dee23c8 100644 --- a/src/test/ref/multiplexer-irq/simple-multiplexer-irq.asm +++ b/src/test/ref/multiplexer-irq/simple-multiplexer-irq.asm @@ -130,6 +130,12 @@ plexSort: { dex cpx #$ff bne b6 + jmp b4 + b6: + lda nxt_y + ldy PLEX_SORTED_IDX,x + cmp PLEX_YPOS,y + bcc b3 b4: inx lda nxt_idx @@ -154,12 +160,6 @@ plexSort: { bne plexFreePrepare1_b1 sta plex_free_next rts - b6: - lda nxt_y - ldy PLEX_SORTED_IDX,x - cmp PLEX_YPOS,y - bcc b3 - jmp b4 } // Initialize the program init: { @@ -242,6 +242,10 @@ plex_irq: { lda plex_show_idx cmp #PLEX_COUNT bcc b7 + jmp b4 + b7: + cpx _4 + bcc b3 b4: lda #IRQ_RASTER sta IRQ_STATUS @@ -257,10 +261,6 @@ plex_irq: { b1: stx RASTER jmp b2 - b7: - cpx _4 - bcc b3 - jmp b4 } // Show the next sprite. // plexSort() prepares showing the sprites diff --git a/src/test/ref/no-recursion-heavy.asm b/src/test/ref/no-recursion-heavy.asm index 9b94f1c33..a64e0d602 100644 --- a/src/test/ref/no-recursion-heavy.asm +++ b/src/test/ref/no-recursion-heavy.asm @@ -270,5 +270,8 @@ fc: { cmp #7 cmp #8 cmp #9 + bne b10 + rts + b10: rts } diff --git a/src/test/ref/sandbox.asm b/src/test/ref/sandbox.asm index 7abbd0312..0c0bcc277 100644 --- a/src/test/ref/sandbox.asm +++ b/src/test/ref/sandbox.asm @@ -202,9 +202,16 @@ myprintf: { rts b3: cpx #'1' - bcc !b37+ - jmp b37 - !b37: + bcs b37 + jmp b4 + b37: + cpx #'9' + bcs !b23+ + jmp b23 + !b23: + bne !b23+ + jmp b23 + !b23: b4: cpx #'-' bne b5 @@ -280,6 +287,11 @@ myprintf: { lda bTrailing cmp #0 beq b39 + jmp b15 + b39: + lda b + cmp bDigits + bcc b16 b15: ldx #0 b19: @@ -309,18 +321,13 @@ myprintf: { cmp bDigits bcc b21 jmp b22 - b39: - lda b - cmp bDigits - bcc b16 - jmp b15 b16: lda bLeadZero cmp #0 - beq b14 + beq b17 lda #'0' jmp b18 - b14: + b17: lda #' ' b18: ldy bLen @@ -341,11 +348,6 @@ myprintf: { sta strTemp,y inc bLen jmp b22 - b37: - cpx #'9' - bcc b23 - beq b23 - jmp b4 b23: txa axs #'0' @@ -392,13 +394,7 @@ myprintf: { b28: cpx #$41 bcs b41 - b30: - // swap 0x41 / 0x61 when in lower case mode - ldy bLen - txa - sta strTemp,y - inc bLen - jmp b27 + jmp b30 b41: cpx #$5a+1 bcc b35 @@ -406,7 +402,13 @@ myprintf: { b35: txa axs #-[$20] - jmp b30 + b30: + // swap 0x41 / 0x61 when in lower case mode + ldy bLen + txa + sta strTemp,y + inc bLen + jmp b27 buf6: .fill 6, 0 } // utoa(word zeropage($12) value, byte* zeropage($14) dst) diff --git a/src/test/ref/signed-words.asm b/src/test/ref/signed-words.asm index 1f3826b81..cd5577b6e 100644 --- a/src/test/ref/signed-words.asm +++ b/src/test/ref/signed-words.asm @@ -22,7 +22,7 @@ .label yvel_10 = 6 .label xvel = 2 .label yvel_12 = 6 - .label yvel_22 = 6 + .label yvel_21 = 6 main: { jsr init lda #$64 @@ -93,9 +93,9 @@ anim: { sta yvel+1 b3: lda yvel - sta yvel_22 + sta yvel_21 lda yvel+1 - sta yvel_22+1 + sta yvel_21+1 lda #0 sta ypos sta ypos+1 diff --git a/src/test/ref/travis1.asm b/src/test/ref/travis1.asm index a73fc4f30..12531614c 100644 --- a/src/test/ref/travis1.asm +++ b/src/test/ref/travis1.asm @@ -22,6 +22,17 @@ main: { jsr game_ready cmp #0 bne b3 + jmp b2 + b3: + lda print_line_cursor + sta print_char_cursor + lda print_line_cursor+1 + sta print_char_cursor+1 + lda #str + sta print_str_ln.str+1 + jsr print_str_ln b2: inc i lda #6 @@ -34,17 +45,6 @@ main: { lda print_line_cursor+1 sta print_char_cursor+1 jmp b1 - b3: - lda print_line_cursor - sta print_char_cursor - lda print_line_cursor+1 - sta print_char_cursor+1 - lda #str - sta print_str_ln.str+1 - jsr print_str_ln - jmp b2 str: .text "ready!@" } // Print a zero-terminated string followed by a newline