diff --git a/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValueIterator.java b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValueIterator.java index 57ee27081..b14dd2ef7 100644 --- a/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValueIterator.java +++ b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValueIterator.java @@ -267,7 +267,8 @@ public class ProgramValueIterator { value instanceof StructZero || value instanceof Label || value instanceof LabelRef || - value instanceof StackPullValue + value instanceof StackPullValue || + value instanceof StackPushValue ) { // No sub values } else { diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeInference.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeInference.java index 5887408d8..c254ef4b2 100644 --- a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeInference.java +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeInference.java @@ -125,6 +125,8 @@ public class SymbolTypeInference { return ((ConstantStructValue) rValue).getStructType(); } else if(rValue instanceof StackPullValue) { return ((StackPullValue) rValue).getType(); + } else if(rValue instanceof StackPushValue) { + return ((StackPushValue) rValue).getType(); } if(type == null) { throw new InternalError("Cannot infer type for " + rValue.toString()); diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java index 8c88cff5b..d0e0f8fdc 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java @@ -850,39 +850,6 @@ public class Pass4CodeGeneration { } } asm.addInstruction("jsr", AsmAddressingMode.ABS, call.getProcedure().getFullName(), false); - } else if(statement instanceof StatementCallPrepare) { - StatementCallPrepare call = (StatementCallPrepare) statement; - Procedure procedure = getScope().getProcedure(call.getProcedure()); - if(Procedure.CallingConvention.STACK_CALL.equals(procedure.getCallingConvention())) { - // Push parameters to the stack - List callParameters = call.getParameters(); - List procParameters = procedure.getParameters(); - for(int i = 0; i < procParameters.size(); i++) { - if(i > 0) - asm.startChunk(block.getScope(), statement.getIndex(), statement.toString(program, verboseAliveInfo)); - Variable procParameter = procParameters.get(i); - RValue callParameter = callParameters.get(i); - SymbolType parameterType = procParameter.getType(); - AsmFragmentInstanceSpecFactory asmFragmentInstanceSpecFactory = new AsmFragmentInstanceSpecFactory(new StackPushValue(parameterType), callParameter, program, block.getScope()); - ensureEncoding(asm, asmFragmentInstanceSpecFactory); - generateAsm(asm, asmFragmentInstanceSpecFactory.getAsmFragmentInstanceSpec()); - asm.getCurrentChunk().setSubStatementIdx(i); - asm.getCurrentChunk().setSubStatementId(procParameter.toString(program)); - } - // Push additional bytes if needed - long stackFrameByteSize = CallingConventionStack.getStackFrameByteSize(procedure); - long parametersByteSize = CallingConventionStack.getParametersByteSize(procedure); - if(stackFrameByteSize > parametersByteSize) { - if(procParameters.size() > 0) - asm.startChunk(block.getScope(), statement.getIndex(), statement.toString(program, verboseAliveInfo)); - // Add padding to the stack to make room for the return value - String pushSignature = "_stackpushbyte_" + (stackFrameByteSize - parametersByteSize); - AsmFragmentInstanceSpec pushFragmentInstanceSpec = new AsmFragmentInstanceSpec(program, pushSignature, new LinkedHashMap<>(), block.getScope()); - generateAsm(asm, pushFragmentInstanceSpec); - - } - } - //throw new RuntimeException("E!"); } else if(statement instanceof StatementCallExecute) { StatementCallExecute call = (StatementCallExecute) statement; Procedure procedure = getScope().getProcedure(call.getProcedure()); diff --git a/src/main/java/dk/camelot64/kickc/passes/PassNCallingConventionStack.java b/src/main/java/dk/camelot64/kickc/passes/PassNCallingConventionStack.java index 28f05e1ff..e2aa0d141 100644 --- a/src/main/java/dk/camelot64/kickc/passes/PassNCallingConventionStack.java +++ b/src/main/java/dk/camelot64/kickc/passes/PassNCallingConventionStack.java @@ -143,6 +143,40 @@ public class PassNCallingConventionStack extends Pass2SsaOptimization { } } + // Convert callprepare(xxx,yyy,) stackpush(type)=xxx, ...; + for(ControlFlowBlock block : getGraph().getAllBlocks()) { + ListIterator stmtIt = block.getStatements().listIterator(); + while(stmtIt.hasNext()) { + Statement statement = stmtIt.next(); + if(statement instanceof StatementCallPrepare) { + final StatementCallPrepare call = (StatementCallPrepare) statement; + Procedure procedure = getScope().getProcedure(call.getProcedure()); + if(Procedure.CallingConvention.STACK_CALL.equals(procedure.getCallingConvention())) { + stmtIt.previous(); + final StatementSource source = call.getSource(); + final List comments = call.getComments(); + final List parameterDefs = procedure.getParameters(); + for(int i=0;i parametersByteSize) { + // Add padding to the stack to make room for the return value + stmtIt.add(new StatementExprSideEffect( new StackPushBytes(new ConstantInteger(stackPadBytes)), source, comments)); + } + stmtIt.next(); + stmtIt.remove(); + } + } + } + } + + return false; } @@ -185,7 +219,7 @@ public class PassNCallingConventionStack extends Pass2SsaOptimization { * @param symbolType The type of the value * @param source The source line * @param comments The comments - * @param stmtIt The statment iterator used to add statements to. + * @param stmtIt The statement iterator used to add statements to. */ private void generateStackPullValues(RValue value, SymbolType symbolType, StatementSource source, List comments, ListIterator stmtIt) { if(!(value instanceof ValueList) || !(symbolType instanceof SymbolTypeStruct)) { @@ -206,4 +240,32 @@ public class PassNCallingConventionStack extends Pass2SsaOptimization { } } + /** + * Generate stack push stackpull(type)=xxx assignments + * + * @param value The value to push + * @param symbolType The type of the value + * @param source The source line + * @param comments The comments + * @param stmtIt The statement iterator used to add statements to. + */ + private void generateStackPushValues(RValue value, SymbolType symbolType, StatementSource source, List comments, ListIterator stmtIt) { + if(!(value instanceof ValueList) || !(symbolType instanceof SymbolTypeStruct)) { + // A simple value to put on the stack + final StatementAssignment stackPull = new StatementAssignment(new StackPushValue(symbolType), value, false, source, comments); + stmtIt.add(stackPull); + getLog().append("Calling convention " + Procedure.CallingConvention.STACK_CALL + " adding stack push " + stackPull); + } else { + // A struct to put on the stack + final List memberValues = ((ValueList) value).getList(); + final StructDefinition structDefinition = ((SymbolTypeStruct) symbolType).getStructDefinition(getScope()); + final List memberVars = new ArrayList<>(structDefinition.getAllVars(false)); + for(int i = 0; i < memberVars.size(); i++) { + final Variable memberVar = memberVars.get(i); + final RValue memberValue = memberValues.get(i); + generateStackPushValues(memberValue, memberVar.getType(), source, comments, stmtIt); + } + } + } + } diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index 95292bd66..8a3c429ae 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -281,7 +281,7 @@ public class TestPrograms { @Test public void testProcedureCallingConventionStack11() throws IOException, URISyntaxException { - compileAndCompare("procedure-callingconvention-stack-11"); //, log().verboseCreateSsa().verboseSSAOptimize()); + compileAndCompare("procedure-callingconvention-stack-11"); } @Test diff --git a/src/test/ref/procedure-callingconvention-stack-0.cfg b/src/test/ref/procedure-callingconvention-stack-0.cfg index a8451b52f..b14df2c66 100644 --- a/src/test/ref/procedure-callingconvention-stack-0.cfg +++ b/src/test/ref/procedure-callingconvention-stack-0.cfg @@ -10,23 +10,24 @@ (void()) main() main: scope:[main] from @1 - [4] callprepare plus (byte) '0' (byte) 7 - [5] callexecute plus + [4] stackpush(byte) ← (byte) '0' + [5] stackpush(byte) ← (byte) 7 + [6] callexecute plus sideeffect stackpullbytes((number) 1) - [7] (byte~) main::$0 ← stackpull(byte) - [8] *((const byte*) SCREEN) ← (byte~) main::$0 + [8] (byte~) main::$0 ← stackpull(byte) + [9] *((const byte*) SCREEN) ← (byte~) main::$0 to:main::@return main::@return: scope:[main] from main - [9] return + [10] return to:@return __stackcall (byte()) plus((byte) plus::a , (byte) plus::b) plus: scope:[plus] from - [10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) - [11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) - [12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 + [11] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) + [12] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) + [13] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 to:plus::@return plus::@return: scope:[plus] from plus - [13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 - [14] return + [14] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 + [15] return to:@return diff --git a/src/test/ref/procedure-callingconvention-stack-0.log b/src/test/ref/procedure-callingconvention-stack-0.log index a3969cfb8..43967ba21 100644 --- a/src/test/ref/procedure-callingconvention-stack-0.log +++ b/src/test/ref/procedure-callingconvention-stack-0.log @@ -5,6 +5,8 @@ Calling convention STACK_CALL replacing param((byte) plus::a) with stackidx(byte Calling convention STACK_CALL replacing param((byte) plus::b) with stackidx(byte,(const byte) plus::OFFSET_STACK_B) Calling convention STACK_CALL adding stack return stackidx(byte,plus::OFFSET_STACK_RETURN) ← plus::return Calling convention STACK_CALL adding stack pull main::$0 ← stackpull(byte) +Calling convention STACK_CALL adding stack push stackpush(byte) ← '0' +Calling convention STACK_CALL adding stack push stackpush(byte) ← 7 CONTROL FLOW GRAPH SSA @begin: scope:[] from @@ -12,7 +14,8 @@ CONTROL FLOW GRAPH SSA (void()) main() main: scope:[main] from @2 - callprepare plus (byte) '0' (number) 7 + stackpush(byte) ← (byte) '0' + stackpush(byte) ← (number) 7 callexecute plus sideeffect stackpullbytes((number) 1) (byte~) main::$0 ← stackpull(byte) @@ -65,9 +68,11 @@ __stackcall (byte()) plus((byte) plus::a , (byte) plus::b) (byte) plus::return#0 (byte) plus::return#1 -Adding number conversion cast (unumber) 7 in callprepare plus (byte) '0' (number) 7 +Adding number conversion cast (unumber) 7 in stackpush(byte) ← (number) 7 Adding number conversion cast (unumber) 0 in *((const byte*) SCREEN + (number) 0) ← (byte~) main::$0 Successful SSA optimization PassNAddNumberTypeConversions +Inlining cast stackpush(byte) ← (unumber)(number) 7 +Successful SSA optimization Pass2InlineCast Simplifying constant pointer cast (byte*) 1024 Simplifying constant integer cast 7 Simplifying constant integer cast 0 @@ -77,7 +82,7 @@ Finalized unsigned number type (byte) 0 Successful SSA optimization PassNFinalizeNumberTypeConversions Alias (byte) plus::return#0 = (byte~) plus::$0 (byte) plus::return#1 Successful SSA optimization Pass2AliasElimination -Simplifying expression containing zero SCREEN in [4] *((const byte*) SCREEN + (byte) 0) ← (byte~) main::$0 +Simplifying expression containing zero SCREEN in [5] *((const byte*) SCREEN + (byte) 0) ← (byte~) main::$0 Successful SSA optimization PassNSimplifyExpressionWithZero Adding NOP phi() at start of @begin Adding NOP phi() at start of @2 @@ -85,7 +90,7 @@ Adding NOP phi() at start of @3 Adding NOP phi() at start of @end CALL GRAPH Calls in [] to main:2 -Calls in [main] to plus:6 +Calls in [main] to plus:7 Created 0 initial phi equivalence classes Coalesced down to 0 phi equivalence classes @@ -108,25 +113,26 @@ FINAL CONTROL FLOW GRAPH (void()) main() main: scope:[main] from @1 - [4] callprepare plus (byte) '0' (byte) 7 - [5] callexecute plus + [4] stackpush(byte) ← (byte) '0' + [5] stackpush(byte) ← (byte) 7 + [6] callexecute plus sideeffect stackpullbytes((number) 1) - [7] (byte~) main::$0 ← stackpull(byte) - [8] *((const byte*) SCREEN) ← (byte~) main::$0 + [8] (byte~) main::$0 ← stackpull(byte) + [9] *((const byte*) SCREEN) ← (byte~) main::$0 to:main::@return main::@return: scope:[main] from main - [9] return + [10] return to:@return __stackcall (byte()) plus((byte) plus::a , (byte) plus::b) plus: scope:[plus] from - [10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) - [11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) - [12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 + [11] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) + [12] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) + [13] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 to:plus::@return plus::@return: scope:[plus] from plus - [13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 - [14] return + [14] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 + [15] return to:@return @@ -184,26 +190,26 @@ __bend: // main main: { .label __0 = 2 - // [4] callprepare plus (byte) '0' (byte) 7 [(byte) plus::a#0] -- _stackpushbyte_=vbuc1 + // [4] stackpush(byte) ← (byte) '0' -- _stackpushbyte_=vbuc1 lda #'0' pha - // [4] callprepare plus (byte) '0' (byte) 7 [(byte) plus::b#1] -- _stackpushbyte_=vbuc1 + // [5] stackpush(byte) ← (byte) 7 -- _stackpushbyte_=vbuc1 lda #7 pha - // [5] callexecute plus -- jsr + // [6] callexecute plus -- jsr jsr plus // sideeffect stackpullbytes((number) 1) -- _stackpullbyte_1 pla - // [7] (byte~) main::$0 ← stackpull(byte) -- vbuz1=_stackpullbyte_ + // [8] (byte~) main::$0 ← stackpull(byte) -- vbuz1=_stackpullbyte_ pla sta.z __0 - // [8] *((const byte*) SCREEN) ← (byte~) main::$0 -- _deref_pbuc1=vbuz1 + // [9] *((const byte*) SCREEN) ← (byte~) main::$0 -- _deref_pbuc1=vbuz1 lda.z __0 sta SCREEN jmp __breturn // main::@return __breturn: - // [9] return + // [10] return rts } // plus @@ -215,15 +221,15 @@ plus: { .label a = 3 .label b = 4 .label return = 5 - // [10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 + // [11] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_A,x sta.z a - // [11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuz1=_stackidxbyte_vbuc1 + // [12] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuz1=_stackidxbyte_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_B,x sta.z b - // [12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuz1=vbuz2_plus_vbuz3 + // [13] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuz1=vbuz2_plus_vbuz3 lda.z a clc adc.z b @@ -231,32 +237,34 @@ plus: { jmp __breturn // plus::@return __breturn: - // [13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuz1 + // [14] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuz1 lda.z return tsx sta STACK_BASE+OFFSET_STACK_RETURN,x - // [14] return + // [15] return rts } // File Data REGISTER UPLIFT POTENTIAL REGISTERS -Statement [4] callprepare plus (byte) '0' (byte) 7 [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [4] stackpush(byte) ← (byte) '0' [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [5] stackpush(byte) ← (byte) 7 [ ] ( main:2 [ ] ) always clobbers reg byte a Statement sideeffect stackpullbytes((number) 1) always clobbers reg byte a -Statement [7] (byte~) main::$0 ← stackpull(byte) [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a -Statement [10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:5 [ plus::a#0 ] ) always clobbers reg byte a reg byte x -Statement [11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:5 [ plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x +Statement [8] (byte~) main::$0 ← stackpull(byte) [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a +Statement [11] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:6 [ plus::a#0 ] ) always clobbers reg byte a reg byte x +Statement [12] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:6 [ plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x Removing always clobbered register reg byte a as potential for zp[1]:3 [ plus::a#0 ] Removing always clobbered register reg byte x as potential for zp[1]:3 [ plus::a#0 ] -Statement [12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ plus::return#0 ] ( main:2::plus:5 [ plus::return#0 ] ) always clobbers reg byte a -Statement [13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 [ ] ( main:2::plus:5 [ ] ) always clobbers reg byte x -Statement [4] callprepare plus (byte) '0' (byte) 7 [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [13] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ plus::return#0 ] ( main:2::plus:6 [ plus::return#0 ] ) always clobbers reg byte a +Statement [14] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 [ ] ( main:2::plus:6 [ ] ) always clobbers reg byte x +Statement [4] stackpush(byte) ← (byte) '0' [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [5] stackpush(byte) ← (byte) 7 [ ] ( main:2 [ ] ) always clobbers reg byte a Statement sideeffect stackpullbytes((number) 1) always clobbers reg byte a -Statement [7] (byte~) main::$0 ← stackpull(byte) [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a -Statement [10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:5 [ plus::a#0 ] ) always clobbers reg byte a reg byte x -Statement [11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:5 [ plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x -Statement [12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ plus::return#0 ] ( main:2::plus:5 [ plus::return#0 ] ) always clobbers reg byte a -Statement [13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 [ ] ( main:2::plus:5 [ ] ) always clobbers reg byte x +Statement [8] (byte~) main::$0 ← stackpull(byte) [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a +Statement [11] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:6 [ plus::a#0 ] ) always clobbers reg byte a reg byte x +Statement [12] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:6 [ plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x +Statement [13] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ plus::return#0 ] ( main:2::plus:6 [ plus::return#0 ] ) always clobbers reg byte a +Statement [14] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 [ ] ( main:2::plus:6 [ ] ) always clobbers reg byte x Potential registers zp[1]:2 [ main::$0 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y , Potential registers zp[1]:3 [ plus::a#0 ] : zp[1]:3 , reg byte y , Potential registers zp[1]:4 [ plus::b#0 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y , @@ -300,24 +308,24 @@ __bend_from___b1: __bend: // main main: { - // [4] callprepare plus (byte) '0' (byte) 7 [(byte) plus::a#0] -- _stackpushbyte_=vbuc1 + // [4] stackpush(byte) ← (byte) '0' -- _stackpushbyte_=vbuc1 lda #'0' pha - // [4] callprepare plus (byte) '0' (byte) 7 [(byte) plus::b#1] -- _stackpushbyte_=vbuc1 + // [5] stackpush(byte) ← (byte) 7 -- _stackpushbyte_=vbuc1 lda #7 pha - // [5] callexecute plus -- jsr + // [6] callexecute plus -- jsr jsr plus // sideeffect stackpullbytes((number) 1) -- _stackpullbyte_1 pla - // [7] (byte~) main::$0 ← stackpull(byte) -- vbuaa=_stackpullbyte_ + // [8] (byte~) main::$0 ← stackpull(byte) -- vbuaa=_stackpullbyte_ pla - // [8] *((const byte*) SCREEN) ← (byte~) main::$0 -- _deref_pbuc1=vbuaa + // [9] *((const byte*) SCREEN) ← (byte~) main::$0 -- _deref_pbuc1=vbuaa sta SCREEN jmp __breturn // main::@return __breturn: - // [9] return + // [10] return rts } // plus @@ -327,23 +335,23 @@ plus: { .const OFFSET_STACK_B = 0 .const OFFSET_STACK_RETURN = 1 .label a = 2 - // [10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 + // [11] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_A,x sta.z a - // [11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1 + // [12] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_B,x - // [12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa + // [13] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa clc adc.z a jmp __breturn // plus::@return __breturn: - // [13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa + // [14] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa tsx sta STACK_BASE+OFFSET_STACK_RETURN,x - // [14] return + // [15] return rts } // File Data @@ -416,24 +424,24 @@ Score: 67 // main main: { // plus('0', 7) - // [4] callprepare plus (byte) '0' (byte) 7 [(byte) plus::a#0] -- _stackpushbyte_=vbuc1 + // [4] stackpush(byte) ← (byte) '0' -- _stackpushbyte_=vbuc1 lda #'0' pha - // [4] callprepare plus (byte) '0' (byte) 7 [(byte) plus::b#1] -- _stackpushbyte_=vbuc1 + // [5] stackpush(byte) ← (byte) 7 -- _stackpushbyte_=vbuc1 lda #7 pha - // [5] callexecute plus -- jsr + // [6] callexecute plus -- jsr jsr plus // sideeffect stackpullbytes((number) 1) -- _stackpullbyte_1 pla - // [7] (byte~) main::$0 ← stackpull(byte) -- vbuaa=_stackpullbyte_ + // [8] (byte~) main::$0 ← stackpull(byte) -- vbuaa=_stackpullbyte_ pla // SCREEN[0] = plus('0', 7) - // [8] *((const byte*) SCREEN) ← (byte~) main::$0 -- _deref_pbuc1=vbuaa + // [9] *((const byte*) SCREEN) ← (byte~) main::$0 -- _deref_pbuc1=vbuaa sta SCREEN // main::@return // } - // [9] return + // [10] return rts } // plus @@ -443,23 +451,23 @@ plus: { .const OFFSET_STACK_B = 0 .const OFFSET_STACK_RETURN = 1 .label a = 2 - // [10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 + // [11] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_A,x sta.z a - // [11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1 + // [12] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_B,x // return a+b; - // [12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa + // [13] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa clc adc.z a // plus::@return // } - // [13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa + // [14] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa tsx sta STACK_BASE+OFFSET_STACK_RETURN,x - // [14] return + // [15] return rts } // File Data diff --git a/src/test/ref/procedure-callingconvention-stack-1.cfg b/src/test/ref/procedure-callingconvention-stack-1.cfg index a8451b52f..b14df2c66 100644 --- a/src/test/ref/procedure-callingconvention-stack-1.cfg +++ b/src/test/ref/procedure-callingconvention-stack-1.cfg @@ -10,23 +10,24 @@ (void()) main() main: scope:[main] from @1 - [4] callprepare plus (byte) '0' (byte) 7 - [5] callexecute plus + [4] stackpush(byte) ← (byte) '0' + [5] stackpush(byte) ← (byte) 7 + [6] callexecute plus sideeffect stackpullbytes((number) 1) - [7] (byte~) main::$0 ← stackpull(byte) - [8] *((const byte*) SCREEN) ← (byte~) main::$0 + [8] (byte~) main::$0 ← stackpull(byte) + [9] *((const byte*) SCREEN) ← (byte~) main::$0 to:main::@return main::@return: scope:[main] from main - [9] return + [10] return to:@return __stackcall (byte()) plus((byte) plus::a , (byte) plus::b) plus: scope:[plus] from - [10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) - [11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) - [12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 + [11] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) + [12] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) + [13] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 to:plus::@return plus::@return: scope:[plus] from plus - [13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 - [14] return + [14] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 + [15] return to:@return diff --git a/src/test/ref/procedure-callingconvention-stack-1.log b/src/test/ref/procedure-callingconvention-stack-1.log index a3969cfb8..43967ba21 100644 --- a/src/test/ref/procedure-callingconvention-stack-1.log +++ b/src/test/ref/procedure-callingconvention-stack-1.log @@ -5,6 +5,8 @@ Calling convention STACK_CALL replacing param((byte) plus::a) with stackidx(byte Calling convention STACK_CALL replacing param((byte) plus::b) with stackidx(byte,(const byte) plus::OFFSET_STACK_B) Calling convention STACK_CALL adding stack return stackidx(byte,plus::OFFSET_STACK_RETURN) ← plus::return Calling convention STACK_CALL adding stack pull main::$0 ← stackpull(byte) +Calling convention STACK_CALL adding stack push stackpush(byte) ← '0' +Calling convention STACK_CALL adding stack push stackpush(byte) ← 7 CONTROL FLOW GRAPH SSA @begin: scope:[] from @@ -12,7 +14,8 @@ CONTROL FLOW GRAPH SSA (void()) main() main: scope:[main] from @2 - callprepare plus (byte) '0' (number) 7 + stackpush(byte) ← (byte) '0' + stackpush(byte) ← (number) 7 callexecute plus sideeffect stackpullbytes((number) 1) (byte~) main::$0 ← stackpull(byte) @@ -65,9 +68,11 @@ __stackcall (byte()) plus((byte) plus::a , (byte) plus::b) (byte) plus::return#0 (byte) plus::return#1 -Adding number conversion cast (unumber) 7 in callprepare plus (byte) '0' (number) 7 +Adding number conversion cast (unumber) 7 in stackpush(byte) ← (number) 7 Adding number conversion cast (unumber) 0 in *((const byte*) SCREEN + (number) 0) ← (byte~) main::$0 Successful SSA optimization PassNAddNumberTypeConversions +Inlining cast stackpush(byte) ← (unumber)(number) 7 +Successful SSA optimization Pass2InlineCast Simplifying constant pointer cast (byte*) 1024 Simplifying constant integer cast 7 Simplifying constant integer cast 0 @@ -77,7 +82,7 @@ Finalized unsigned number type (byte) 0 Successful SSA optimization PassNFinalizeNumberTypeConversions Alias (byte) plus::return#0 = (byte~) plus::$0 (byte) plus::return#1 Successful SSA optimization Pass2AliasElimination -Simplifying expression containing zero SCREEN in [4] *((const byte*) SCREEN + (byte) 0) ← (byte~) main::$0 +Simplifying expression containing zero SCREEN in [5] *((const byte*) SCREEN + (byte) 0) ← (byte~) main::$0 Successful SSA optimization PassNSimplifyExpressionWithZero Adding NOP phi() at start of @begin Adding NOP phi() at start of @2 @@ -85,7 +90,7 @@ Adding NOP phi() at start of @3 Adding NOP phi() at start of @end CALL GRAPH Calls in [] to main:2 -Calls in [main] to plus:6 +Calls in [main] to plus:7 Created 0 initial phi equivalence classes Coalesced down to 0 phi equivalence classes @@ -108,25 +113,26 @@ FINAL CONTROL FLOW GRAPH (void()) main() main: scope:[main] from @1 - [4] callprepare plus (byte) '0' (byte) 7 - [5] callexecute plus + [4] stackpush(byte) ← (byte) '0' + [5] stackpush(byte) ← (byte) 7 + [6] callexecute plus sideeffect stackpullbytes((number) 1) - [7] (byte~) main::$0 ← stackpull(byte) - [8] *((const byte*) SCREEN) ← (byte~) main::$0 + [8] (byte~) main::$0 ← stackpull(byte) + [9] *((const byte*) SCREEN) ← (byte~) main::$0 to:main::@return main::@return: scope:[main] from main - [9] return + [10] return to:@return __stackcall (byte()) plus((byte) plus::a , (byte) plus::b) plus: scope:[plus] from - [10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) - [11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) - [12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 + [11] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) + [12] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) + [13] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 to:plus::@return plus::@return: scope:[plus] from plus - [13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 - [14] return + [14] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 + [15] return to:@return @@ -184,26 +190,26 @@ __bend: // main main: { .label __0 = 2 - // [4] callprepare plus (byte) '0' (byte) 7 [(byte) plus::a#0] -- _stackpushbyte_=vbuc1 + // [4] stackpush(byte) ← (byte) '0' -- _stackpushbyte_=vbuc1 lda #'0' pha - // [4] callprepare plus (byte) '0' (byte) 7 [(byte) plus::b#1] -- _stackpushbyte_=vbuc1 + // [5] stackpush(byte) ← (byte) 7 -- _stackpushbyte_=vbuc1 lda #7 pha - // [5] callexecute plus -- jsr + // [6] callexecute plus -- jsr jsr plus // sideeffect stackpullbytes((number) 1) -- _stackpullbyte_1 pla - // [7] (byte~) main::$0 ← stackpull(byte) -- vbuz1=_stackpullbyte_ + // [8] (byte~) main::$0 ← stackpull(byte) -- vbuz1=_stackpullbyte_ pla sta.z __0 - // [8] *((const byte*) SCREEN) ← (byte~) main::$0 -- _deref_pbuc1=vbuz1 + // [9] *((const byte*) SCREEN) ← (byte~) main::$0 -- _deref_pbuc1=vbuz1 lda.z __0 sta SCREEN jmp __breturn // main::@return __breturn: - // [9] return + // [10] return rts } // plus @@ -215,15 +221,15 @@ plus: { .label a = 3 .label b = 4 .label return = 5 - // [10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 + // [11] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_A,x sta.z a - // [11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuz1=_stackidxbyte_vbuc1 + // [12] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuz1=_stackidxbyte_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_B,x sta.z b - // [12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuz1=vbuz2_plus_vbuz3 + // [13] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuz1=vbuz2_plus_vbuz3 lda.z a clc adc.z b @@ -231,32 +237,34 @@ plus: { jmp __breturn // plus::@return __breturn: - // [13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuz1 + // [14] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuz1 lda.z return tsx sta STACK_BASE+OFFSET_STACK_RETURN,x - // [14] return + // [15] return rts } // File Data REGISTER UPLIFT POTENTIAL REGISTERS -Statement [4] callprepare plus (byte) '0' (byte) 7 [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [4] stackpush(byte) ← (byte) '0' [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [5] stackpush(byte) ← (byte) 7 [ ] ( main:2 [ ] ) always clobbers reg byte a Statement sideeffect stackpullbytes((number) 1) always clobbers reg byte a -Statement [7] (byte~) main::$0 ← stackpull(byte) [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a -Statement [10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:5 [ plus::a#0 ] ) always clobbers reg byte a reg byte x -Statement [11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:5 [ plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x +Statement [8] (byte~) main::$0 ← stackpull(byte) [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a +Statement [11] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:6 [ plus::a#0 ] ) always clobbers reg byte a reg byte x +Statement [12] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:6 [ plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x Removing always clobbered register reg byte a as potential for zp[1]:3 [ plus::a#0 ] Removing always clobbered register reg byte x as potential for zp[1]:3 [ plus::a#0 ] -Statement [12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ plus::return#0 ] ( main:2::plus:5 [ plus::return#0 ] ) always clobbers reg byte a -Statement [13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 [ ] ( main:2::plus:5 [ ] ) always clobbers reg byte x -Statement [4] callprepare plus (byte) '0' (byte) 7 [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [13] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ plus::return#0 ] ( main:2::plus:6 [ plus::return#0 ] ) always clobbers reg byte a +Statement [14] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 [ ] ( main:2::plus:6 [ ] ) always clobbers reg byte x +Statement [4] stackpush(byte) ← (byte) '0' [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [5] stackpush(byte) ← (byte) 7 [ ] ( main:2 [ ] ) always clobbers reg byte a Statement sideeffect stackpullbytes((number) 1) always clobbers reg byte a -Statement [7] (byte~) main::$0 ← stackpull(byte) [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a -Statement [10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:5 [ plus::a#0 ] ) always clobbers reg byte a reg byte x -Statement [11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:5 [ plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x -Statement [12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ plus::return#0 ] ( main:2::plus:5 [ plus::return#0 ] ) always clobbers reg byte a -Statement [13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 [ ] ( main:2::plus:5 [ ] ) always clobbers reg byte x +Statement [8] (byte~) main::$0 ← stackpull(byte) [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a +Statement [11] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:6 [ plus::a#0 ] ) always clobbers reg byte a reg byte x +Statement [12] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:6 [ plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x +Statement [13] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ plus::return#0 ] ( main:2::plus:6 [ plus::return#0 ] ) always clobbers reg byte a +Statement [14] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 [ ] ( main:2::plus:6 [ ] ) always clobbers reg byte x Potential registers zp[1]:2 [ main::$0 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y , Potential registers zp[1]:3 [ plus::a#0 ] : zp[1]:3 , reg byte y , Potential registers zp[1]:4 [ plus::b#0 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y , @@ -300,24 +308,24 @@ __bend_from___b1: __bend: // main main: { - // [4] callprepare plus (byte) '0' (byte) 7 [(byte) plus::a#0] -- _stackpushbyte_=vbuc1 + // [4] stackpush(byte) ← (byte) '0' -- _stackpushbyte_=vbuc1 lda #'0' pha - // [4] callprepare plus (byte) '0' (byte) 7 [(byte) plus::b#1] -- _stackpushbyte_=vbuc1 + // [5] stackpush(byte) ← (byte) 7 -- _stackpushbyte_=vbuc1 lda #7 pha - // [5] callexecute plus -- jsr + // [6] callexecute plus -- jsr jsr plus // sideeffect stackpullbytes((number) 1) -- _stackpullbyte_1 pla - // [7] (byte~) main::$0 ← stackpull(byte) -- vbuaa=_stackpullbyte_ + // [8] (byte~) main::$0 ← stackpull(byte) -- vbuaa=_stackpullbyte_ pla - // [8] *((const byte*) SCREEN) ← (byte~) main::$0 -- _deref_pbuc1=vbuaa + // [9] *((const byte*) SCREEN) ← (byte~) main::$0 -- _deref_pbuc1=vbuaa sta SCREEN jmp __breturn // main::@return __breturn: - // [9] return + // [10] return rts } // plus @@ -327,23 +335,23 @@ plus: { .const OFFSET_STACK_B = 0 .const OFFSET_STACK_RETURN = 1 .label a = 2 - // [10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 + // [11] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_A,x sta.z a - // [11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1 + // [12] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_B,x - // [12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa + // [13] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa clc adc.z a jmp __breturn // plus::@return __breturn: - // [13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa + // [14] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa tsx sta STACK_BASE+OFFSET_STACK_RETURN,x - // [14] return + // [15] return rts } // File Data @@ -416,24 +424,24 @@ Score: 67 // main main: { // plus('0', 7) - // [4] callprepare plus (byte) '0' (byte) 7 [(byte) plus::a#0] -- _stackpushbyte_=vbuc1 + // [4] stackpush(byte) ← (byte) '0' -- _stackpushbyte_=vbuc1 lda #'0' pha - // [4] callprepare plus (byte) '0' (byte) 7 [(byte) plus::b#1] -- _stackpushbyte_=vbuc1 + // [5] stackpush(byte) ← (byte) 7 -- _stackpushbyte_=vbuc1 lda #7 pha - // [5] callexecute plus -- jsr + // [6] callexecute plus -- jsr jsr plus // sideeffect stackpullbytes((number) 1) -- _stackpullbyte_1 pla - // [7] (byte~) main::$0 ← stackpull(byte) -- vbuaa=_stackpullbyte_ + // [8] (byte~) main::$0 ← stackpull(byte) -- vbuaa=_stackpullbyte_ pla // SCREEN[0] = plus('0', 7) - // [8] *((const byte*) SCREEN) ← (byte~) main::$0 -- _deref_pbuc1=vbuaa + // [9] *((const byte*) SCREEN) ← (byte~) main::$0 -- _deref_pbuc1=vbuaa sta SCREEN // main::@return // } - // [9] return + // [10] return rts } // plus @@ -443,23 +451,23 @@ plus: { .const OFFSET_STACK_B = 0 .const OFFSET_STACK_RETURN = 1 .label a = 2 - // [10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 + // [11] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_A,x sta.z a - // [11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1 + // [12] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_B,x // return a+b; - // [12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa + // [13] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa clc adc.z a // plus::@return // } - // [13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa + // [14] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa tsx sta STACK_BASE+OFFSET_STACK_RETURN,x - // [14] return + // [15] return rts } // File Data diff --git a/src/test/ref/procedure-callingconvention-stack-10.cfg b/src/test/ref/procedure-callingconvention-stack-10.cfg index 04dc7c350..edd6c0543 100644 --- a/src/test/ref/procedure-callingconvention-stack-10.cfg +++ b/src/test/ref/procedure-callingconvention-stack-10.cfg @@ -2,7 +2,7 @@ [0] (byte) idx ← (byte) 0 to:@1 @1: scope:[] from @begin - [1] callprepare main + [1] phi() [2] callexecute main to:@end @end: scope:[] from @1 @@ -47,14 +47,16 @@ main::@return: scope:[main] from main::@1 [22] return to:@return main::@2: scope:[main] from main::@1 - [23] callprepare get (byte) main::i - [24] callexecute get - [25] (byte~) main::$1_x ← stackpull(byte) - [26] (byte~) main::$1_y ← stackpull(byte) - [27] *((byte*)&(struct Point) main::p) ← (byte~) main::$1_x - [28] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_y - [29] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) - [30] callexecute print + [23] stackpush(byte) ← (byte) main::i + sideeffect stackpushbytes((number) 1) + [25] callexecute get + [26] (byte~) main::$1_x ← stackpull(byte) + [27] (byte~) main::$1_y ← stackpull(byte) + [28] *((byte*)&(struct Point) main::p) ← (byte~) main::$1_x + [29] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_y + [30] stackpush(byte) ← *((byte*)&(struct Point) main::p) + [31] stackpush(byte) ← *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) + [32] callexecute print sideeffect stackpullbytes((number) 2) - [32] (byte) main::i ← ++ (byte) main::i + [34] (byte) main::i ← ++ (byte) main::i to:main::@1 diff --git a/src/test/ref/procedure-callingconvention-stack-10.log b/src/test/ref/procedure-callingconvention-stack-10.log index e7bcb254a..6fcf68698 100644 --- a/src/test/ref/procedure-callingconvention-stack-10.log +++ b/src/test/ref/procedure-callingconvention-stack-10.log @@ -43,6 +43,9 @@ Calling convention STACK_CALL adding stack return stackidx(byte,get::OFFSET_STAC Calling convention STACK_CALL adding stack return stackidx(byte,get::OFFSET_STACK_RETURN+OFFSET_STRUCT_POINT_Y) ← get::return_y Calling convention STACK_CALL adding stack pull main::$1_x ← stackpull(byte) Calling convention STACK_CALL adding stack pull main::$1_y ← stackpull(byte) +Calling convention STACK_CALL adding stack push stackpush(byte) ← main::i +Calling convention STACK_CALL adding stack push stackpush(byte) ← *((byte*)&main::p+OFFSET_STRUCT_POINT_X) +Calling convention STACK_CALL adding stack push stackpush(byte) ← *((byte*)&main::p+OFFSET_STRUCT_POINT_Y) CONTROL FLOW GRAPH SSA @begin: scope:[] from @@ -58,14 +61,16 @@ main::@1: scope:[main] from main main::@2 if((bool~) main::$0) goto main::@2 to:main::@return main::@2: scope:[main] from main::@1 - callprepare get (byte) main::i + stackpush(byte) ← (byte) main::i + sideeffect stackpushbytes((number) 1) callexecute get (byte~) main::$1_x ← stackpull(byte) (byte~) main::$1_y ← stackpull(byte) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_X) ← (byte~) main::$1_x *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_y (struct Point) main::p ← struct-unwound {*((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y)} - callprepare print *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_X) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) + stackpush(byte) ← *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_X) + stackpush(byte) ← *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) callexecute print sideeffect stackpullbytes((number) 2) (byte) main::i ← ++ (byte) main::i @@ -106,7 +111,6 @@ print::@return: scope:[print] from print return to:@return @3: scope:[] from @begin - callprepare main callexecute main to:@end @end: scope:[] from @3 @@ -173,30 +177,32 @@ Alias (byte) get::return_y#0 = (byte) get::return_y#1 Successful SSA optimization Pass2AliasElimination Simple Condition (bool~) main::$0 [3] if((byte) main::i<(byte) 5) goto main::@2 Successful SSA optimization Pass2ConditionalJumpSimplification -Removing C-classic struct-unwound assignment [10] (struct Point) main::p ← struct-unwound {*((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y)} -Removing C-classic struct-unwound assignment [20] (struct Point) get::p ← struct-unwound {*((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_Y)} -Simplifying constant evaluating to zero (const byte) get::OFFSET_STACK_RETURN+(const byte) OFFSET_STRUCT_POINT_X in [24] stackidx(byte,(const byte) get::OFFSET_STACK_RETURN+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) get::return_x#0 +Removing C-classic struct-unwound assignment [11] (struct Point) main::p ← struct-unwound {*((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y)} +Removing C-classic struct-unwound assignment [22] (struct Point) get::p ← struct-unwound {*((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_Y)} +Simplifying constant evaluating to zero (const byte) get::OFFSET_STACK_RETURN+(const byte) OFFSET_STRUCT_POINT_X in [26] stackidx(byte,(const byte) get::OFFSET_STACK_RETURN+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) get::return_x#0 Successful SSA optimization PassNSimplifyConstantZero -Simplifying expression containing zero (byte*)&main::p in [8] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_X) ← (byte~) main::$1_x -Simplifying expression containing zero (byte*)&main::p in [11] callprepare print *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_X) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) -Simplifying expression containing zero (byte*)&get::p in [18] *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) get::i#0 -Simplifying expression containing zero (byte*)&get::p in [21] (byte) get::return_x#0 ← *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_X) -Simplifying expression containing zero OFFSET_STRUCT_POINT_Y in [25] stackidx(byte,(const byte) get::OFFSET_STACK_RETURN+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_y#0 +Simplifying expression containing zero (byte*)&main::p in [9] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_X) ← (byte~) main::$1_x +Simplifying expression containing zero (byte*)&main::p in [12] stackpush(byte) ← *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_X) +Simplifying expression containing zero (byte*)&get::p in [20] *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) get::i#0 +Simplifying expression containing zero (byte*)&get::p in [23] (byte) get::return_x#0 ← *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_X) +Simplifying expression containing zero OFFSET_STRUCT_POINT_Y in [27] stackidx(byte,(const byte) get::OFFSET_STACK_RETURN+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_y#0 Successful SSA optimization PassNSimplifyExpressionWithZero -Eliminating unused variable (struct Point) get::return#0 and assignment [20] (struct Point) get::return#0 ← struct-unwound {(byte) get::return_x#0, (byte) get::return_y#0} +Eliminating unused variable (struct Point) get::return#0 and assignment [22] (struct Point) get::return#0 ← struct-unwound {(byte) get::return_x#0, (byte) get::return_y#0} Eliminating unused constant (const byte) get::OFFSET_STACK_RETURN Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X Successful SSA optimization PassNEliminateUnusedVars -Rewriting division to use shift [15] (byte~) get::$0 ← (byte) get::i#0 / (byte) 2 +Rewriting division to use shift [17] (byte~) get::$0 ← (byte) get::i#0 / (byte) 2 Successful SSA optimization Pass2MultiplyToShiftRewriting +Adding NOP phi() at start of @3 Adding NOP phi() at start of @end CALL GRAPH Calls in [] to main:2 -Calls in [main] to get:24 print:30 +Calls in [main] to get:25 print:32 Created 0 initial phi equivalence classes Coalesced down to 0 phi equivalence classes Renumbering block @3 to @1 +Adding NOP phi() at start of @1 Adding NOP phi() at start of @end FINAL CONTROL FLOW GRAPH @@ -204,7 +210,7 @@ FINAL CONTROL FLOW GRAPH [0] (byte) idx ← (byte) 0 to:@1 @1: scope:[] from @begin - [1] callprepare main + [1] phi() [2] callexecute main to:@end @end: scope:[] from @1 @@ -249,16 +255,18 @@ main::@return: scope:[main] from main::@1 [22] return to:@return main::@2: scope:[main] from main::@1 - [23] callprepare get (byte) main::i - [24] callexecute get - [25] (byte~) main::$1_x ← stackpull(byte) - [26] (byte~) main::$1_y ← stackpull(byte) - [27] *((byte*)&(struct Point) main::p) ← (byte~) main::$1_x - [28] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_y - [29] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) - [30] callexecute print + [23] stackpush(byte) ← (byte) main::i + sideeffect stackpushbytes((number) 1) + [25] callexecute get + [26] (byte~) main::$1_x ← stackpull(byte) + [27] (byte~) main::$1_y ← stackpull(byte) + [28] *((byte*)&(struct Point) main::p) ← (byte~) main::$1_x + [29] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_y + [30] stackpush(byte) ← *((byte*)&(struct Point) main::p) + [31] stackpush(byte) ← *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) + [32] callexecute print sideeffect stackpullbytes((number) 2) - [32] (byte) main::i ← ++ (byte) main::i + [34] (byte) main::i ← ++ (byte) main::i to:main::@1 null depth in calling loop Loop head: main::@1 tails: main::@2 blocks: main::@2 main::@1 in scope print @@ -277,11 +285,11 @@ __stackcall (struct Point()) get((byte) get::i) (byte) get::return_x#0 2.0 (byte) get::return_y (byte) get::return_y#0 2.0 -(byte) idx loadstore 0.6666666666666666 +(byte) idx loadstore 0.6086956521739131 __stackcall (void()) main() (byte~) main::$1_x 11.0 (byte~) main::$1_y 11.0 -(byte) main::i loadstore 2.9166666666666665 +(byte) main::i loadstore 3.2857142857142856 (struct Point) main::p loadstore __stackcall (void()) print((byte) print::p_x , (byte) print::p_y) (byte) print::p_x @@ -347,10 +355,11 @@ __bbegin: // [0] (byte) idx ← (byte) 0 -- vbuz1=vbuc1 lda #0 sta.z idx + // [1] phi from @begin to @1 [phi:@begin->@1] +__b1_from___bbegin: jmp __b1 // @1 __b1: - // [1] callprepare main // [2] callexecute main -- jsr jsr main // [3] phi from @1 to @end [phi:@1->@end] @@ -457,37 +466,37 @@ main: { rts // main::@2 __b2: - // [23] callprepare get (byte) main::i [(byte) get::i#0] -- _stackpushbyte_=vbuz1 + // [23] stackpush(byte) ← (byte) main::i -- _stackpushbyte_=vbuz1 lda.z i pha - // [23] callprepare get (byte) main::i -- _stackpushbyte_1 + // sideeffect stackpushbytes((number) 1) -- _stackpushbyte_1 pha - // [24] callexecute get -- jsr + // [25] callexecute get -- jsr jsr get - // [25] (byte~) main::$1_x ← stackpull(byte) -- vbuz1=_stackpullbyte_ + // [26] (byte~) main::$1_x ← stackpull(byte) -- vbuz1=_stackpullbyte_ pla sta.z __1_x - // [26] (byte~) main::$1_y ← stackpull(byte) -- vbuz1=_stackpullbyte_ + // [27] (byte~) main::$1_y ← stackpull(byte) -- vbuz1=_stackpullbyte_ pla sta.z __1_y - // [27] *((byte*)&(struct Point) main::p) ← (byte~) main::$1_x -- _deref_pbuc1=vbuz1 + // [28] *((byte*)&(struct Point) main::p) ← (byte~) main::$1_x -- _deref_pbuc1=vbuz1 lda.z __1_x sta.z p - // [28] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_y -- _deref_pbuc1=vbuz1 + // [29] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_y -- _deref_pbuc1=vbuz1 lda.z __1_y sta p+OFFSET_STRUCT_POINT_Y - // [29] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) [(byte) print::p_x#0] -- _stackpushbyte_=_deref_pbuc1 + // [30] stackpush(byte) ← *((byte*)&(struct Point) main::p) -- _stackpushbyte_=_deref_pbuc1 lda.z p pha - // [29] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) [(byte) print::p_y#1] -- _stackpushbyte_=_deref_pbuc1 + // [31] stackpush(byte) ← *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) -- _stackpushbyte_=_deref_pbuc1 lda p+OFFSET_STRUCT_POINT_Y pha - // [30] callexecute print -- jsr + // [32] callexecute print -- jsr jsr print // sideeffect stackpullbytes((number) 2) -- _stackpullbyte_2 pla pla - // [32] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1 + // [34] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1 inc.z i jmp __b1 } @@ -495,43 +504,45 @@ main: { REGISTER UPLIFT POTENTIAL REGISTERS Statement [0] (byte) idx ← (byte) 0 [ idx get::p main::p ] ( [ idx get::p main::p ] ) always clobbers reg byte a -Statement [4] (byte) print::p_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_X) [ idx print::p_x#0 ] ( main:2::print:30 [ get::p main::i main::p idx print::p_x#0 ] ) always clobbers reg byte a reg byte x -Statement [5] (byte) print::p_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_Y) [ idx print::p_x#0 print::p_y#0 ] ( main:2::print:30 [ get::p main::i main::p idx print::p_x#0 print::p_y#0 ] ) always clobbers reg byte a reg byte x +Statement [4] (byte) print::p_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_X) [ idx print::p_x#0 ] ( main:2::print:32 [ get::p main::i main::p idx print::p_x#0 ] ) always clobbers reg byte a reg byte x +Statement [5] (byte) print::p_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_Y) [ idx print::p_x#0 print::p_y#0 ] ( main:2::print:32 [ get::p main::i main::p idx print::p_x#0 print::p_y#0 ] ) always clobbers reg byte a reg byte x Removing always clobbered register reg byte a as potential for zp[1]:3 [ print::p_x#0 ] Removing always clobbered register reg byte x as potential for zp[1]:3 [ print::p_x#0 ] -Statement [6] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_x#0 [ idx print::p_y#0 ] ( main:2::print:30 [ get::p main::i main::p idx print::p_y#0 ] ) always clobbers reg byte a reg byte y +Statement [6] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_x#0 [ idx print::p_y#0 ] ( main:2::print:32 [ get::p main::i main::p idx print::p_y#0 ] ) always clobbers reg byte a reg byte y Removing always clobbered register reg byte a as potential for zp[1]:4 [ print::p_y#0 ] Removing always clobbered register reg byte y as potential for zp[1]:4 [ print::p_y#0 ] -Statement [8] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_y#0 [ idx ] ( main:2::print:30 [ get::p main::i main::p idx ] ) always clobbers reg byte a reg byte y -Statement [11] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I) [ get::i#0 get::p ] ( main:2::get:24 [ idx main::i main::p get::i#0 get::p ] ) always clobbers reg byte a reg byte x -Statement [12] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1 [ get::i#0 get::$0 get::p ] ( main:2::get:24 [ idx main::i main::p get::i#0 get::$0 get::p ] ) always clobbers reg byte a +Statement [8] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_y#0 [ idx ] ( main:2::print:32 [ get::p main::i main::p idx ] ) always clobbers reg byte a reg byte y +Statement [11] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I) [ get::i#0 get::p ] ( main:2::get:25 [ idx main::i main::p get::i#0 get::p ] ) always clobbers reg byte a reg byte x +Statement [12] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1 [ get::i#0 get::$0 get::p ] ( main:2::get:25 [ idx main::i main::p get::i#0 get::$0 get::p ] ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:5 [ get::i#0 ] -Statement [17] stackidx(byte,(byte) 0) ← (byte) get::return_x#0 [ get::p get::return_y#0 ] ( main:2::get:24 [ idx main::i main::p get::p get::return_y#0 ] ) always clobbers reg byte x +Statement [17] stackidx(byte,(byte) 0) ← (byte) get::return_x#0 [ get::p get::return_y#0 ] ( main:2::get:25 [ idx main::i main::p get::p get::return_y#0 ] ) always clobbers reg byte x Removing always clobbered register reg byte x as potential for zp[1]:8 [ get::return_y#0 ] -Statement [18] stackidx(byte,(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_y#0 [ get::p ] ( main:2::get:24 [ idx main::i main::p get::p ] ) always clobbers reg byte x +Statement [18] stackidx(byte,(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_y#0 [ get::p ] ( main:2::get:25 [ idx main::i main::p get::p ] ) always clobbers reg byte x Statement [20] (byte) main::i ← (byte) 0 [ idx get::p main::i main::p ] ( main:2 [ idx get::p main::i main::p ] ) always clobbers reg byte a Statement [21] if((byte) main::i<(byte) 5) goto main::@2 [ idx get::p main::i main::p ] ( main:2 [ idx get::p main::i main::p ] ) always clobbers reg byte a -Statement [23] callprepare get (byte) main::i [ idx get::p main::i main::p ] ( main:2 [ idx get::p main::i main::p ] ) always clobbers reg byte a -Statement [25] (byte~) main::$1_x ← stackpull(byte) [ idx get::p main::i main::$1_x main::p ] ( main:2 [ idx get::p main::i main::$1_x main::p ] ) always clobbers reg byte a -Statement [26] (byte~) main::$1_y ← stackpull(byte) [ idx get::p main::i main::$1_x main::$1_y main::p ] ( main:2 [ idx get::p main::i main::$1_x main::$1_y main::p ] ) always clobbers reg byte a +Statement [23] stackpush(byte) ← (byte) main::i [ idx get::p main::i main::p ] ( main:2 [ idx get::p main::i main::p ] ) always clobbers reg byte a +Statement [26] (byte~) main::$1_x ← stackpull(byte) [ idx get::p main::i main::$1_x main::p ] ( main:2 [ idx get::p main::i main::$1_x main::p ] ) always clobbers reg byte a +Statement [27] (byte~) main::$1_y ← stackpull(byte) [ idx get::p main::i main::$1_x main::$1_y main::p ] ( main:2 [ idx get::p main::i main::$1_x main::$1_y main::p ] ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:10 [ main::$1_x ] -Statement [29] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) [ idx get::p main::i main::p ] ( main:2 [ idx get::p main::i main::p ] ) always clobbers reg byte a +Statement [30] stackpush(byte) ← *((byte*)&(struct Point) main::p) [ idx get::p main::i main::p ] ( main:2 [ idx get::p main::i main::p ] ) always clobbers reg byte a +Statement [31] stackpush(byte) ← *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) [ idx get::p main::i main::p ] ( main:2 [ idx get::p main::i main::p ] ) always clobbers reg byte a Statement sideeffect stackpullbytes((number) 2) always clobbers reg byte a Statement [0] (byte) idx ← (byte) 0 [ idx get::p main::p ] ( [ idx get::p main::p ] ) always clobbers reg byte a -Statement [4] (byte) print::p_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_X) [ idx print::p_x#0 ] ( main:2::print:30 [ get::p main::i main::p idx print::p_x#0 ] ) always clobbers reg byte a reg byte x -Statement [5] (byte) print::p_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_Y) [ idx print::p_x#0 print::p_y#0 ] ( main:2::print:30 [ get::p main::i main::p idx print::p_x#0 print::p_y#0 ] ) always clobbers reg byte a reg byte x -Statement [6] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_x#0 [ idx print::p_y#0 ] ( main:2::print:30 [ get::p main::i main::p idx print::p_y#0 ] ) always clobbers reg byte a reg byte y -Statement [8] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_y#0 [ idx ] ( main:2::print:30 [ get::p main::i main::p idx ] ) always clobbers reg byte a reg byte y -Statement [11] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I) [ get::i#0 get::p ] ( main:2::get:24 [ idx main::i main::p get::i#0 get::p ] ) always clobbers reg byte a reg byte x -Statement [12] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1 [ get::i#0 get::$0 get::p ] ( main:2::get:24 [ idx main::i main::p get::i#0 get::$0 get::p ] ) always clobbers reg byte a -Statement [17] stackidx(byte,(byte) 0) ← (byte) get::return_x#0 [ get::p get::return_y#0 ] ( main:2::get:24 [ idx main::i main::p get::p get::return_y#0 ] ) always clobbers reg byte x -Statement [18] stackidx(byte,(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_y#0 [ get::p ] ( main:2::get:24 [ idx main::i main::p get::p ] ) always clobbers reg byte x +Statement [4] (byte) print::p_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_X) [ idx print::p_x#0 ] ( main:2::print:32 [ get::p main::i main::p idx print::p_x#0 ] ) always clobbers reg byte a reg byte x +Statement [5] (byte) print::p_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_Y) [ idx print::p_x#0 print::p_y#0 ] ( main:2::print:32 [ get::p main::i main::p idx print::p_x#0 print::p_y#0 ] ) always clobbers reg byte a reg byte x +Statement [6] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_x#0 [ idx print::p_y#0 ] ( main:2::print:32 [ get::p main::i main::p idx print::p_y#0 ] ) always clobbers reg byte a reg byte y +Statement [8] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_y#0 [ idx ] ( main:2::print:32 [ get::p main::i main::p idx ] ) always clobbers reg byte a reg byte y +Statement [11] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I) [ get::i#0 get::p ] ( main:2::get:25 [ idx main::i main::p get::i#0 get::p ] ) always clobbers reg byte a reg byte x +Statement [12] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1 [ get::i#0 get::$0 get::p ] ( main:2::get:25 [ idx main::i main::p get::i#0 get::$0 get::p ] ) always clobbers reg byte a +Statement [17] stackidx(byte,(byte) 0) ← (byte) get::return_x#0 [ get::p get::return_y#0 ] ( main:2::get:25 [ idx main::i main::p get::p get::return_y#0 ] ) always clobbers reg byte x +Statement [18] stackidx(byte,(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_y#0 [ get::p ] ( main:2::get:25 [ idx main::i main::p get::p ] ) always clobbers reg byte x Statement [20] (byte) main::i ← (byte) 0 [ idx get::p main::i main::p ] ( main:2 [ idx get::p main::i main::p ] ) always clobbers reg byte a Statement [21] if((byte) main::i<(byte) 5) goto main::@2 [ idx get::p main::i main::p ] ( main:2 [ idx get::p main::i main::p ] ) always clobbers reg byte a -Statement [23] callprepare get (byte) main::i [ idx get::p main::i main::p ] ( main:2 [ idx get::p main::i main::p ] ) always clobbers reg byte a -Statement [25] (byte~) main::$1_x ← stackpull(byte) [ idx get::p main::i main::$1_x main::p ] ( main:2 [ idx get::p main::i main::$1_x main::p ] ) always clobbers reg byte a -Statement [26] (byte~) main::$1_y ← stackpull(byte) [ idx get::p main::i main::$1_x main::$1_y main::p ] ( main:2 [ idx get::p main::i main::$1_x main::$1_y main::p ] ) always clobbers reg byte a -Statement [29] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) [ idx get::p main::i main::p ] ( main:2 [ idx get::p main::i main::p ] ) always clobbers reg byte a +Statement [23] stackpush(byte) ← (byte) main::i [ idx get::p main::i main::p ] ( main:2 [ idx get::p main::i main::p ] ) always clobbers reg byte a +Statement [26] (byte~) main::$1_x ← stackpull(byte) [ idx get::p main::i main::$1_x main::p ] ( main:2 [ idx get::p main::i main::$1_x main::p ] ) always clobbers reg byte a +Statement [27] (byte~) main::$1_y ← stackpull(byte) [ idx get::p main::i main::$1_x main::$1_y main::p ] ( main:2 [ idx get::p main::i main::$1_x main::$1_y main::p ] ) always clobbers reg byte a +Statement [30] stackpush(byte) ← *((byte*)&(struct Point) main::p) [ idx get::p main::i main::p ] ( main:2 [ idx get::p main::i main::p ] ) always clobbers reg byte a +Statement [31] stackpush(byte) ← *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) [ idx get::p main::i main::p ] ( main:2 [ idx get::p main::i main::p ] ) always clobbers reg byte a Statement sideeffect stackpullbytes((number) 2) always clobbers reg byte a Potential registers zp[1]:2 [ idx ] : zp[1]:2 , Potential registers zp[1]:3 [ print::p_x#0 ] : zp[1]:3 , reg byte y , @@ -547,10 +558,10 @@ Potential registers zp[2]:12 [ main::p ] : zp[2]:12 , Potential registers zp[2]:14 [ get::p ] : zp[2]:14 , REGISTER UPLIFT SCOPES -Uplift Scope [main] 11: zp[1]:10 [ main::$1_x ] 11: zp[1]:11 [ main::$1_y ] 2.92: zp[1]:9 [ main::i ] 0: zp[2]:12 [ main::p ] +Uplift Scope [main] 11: zp[1]:10 [ main::$1_x ] 11: zp[1]:11 [ main::$1_y ] 3.29: zp[1]:9 [ main::i ] 0: zp[2]:12 [ main::p ] Uplift Scope [get] 3: zp[1]:5 [ get::i#0 ] 2: zp[1]:6 [ get::$0 ] 2: zp[1]:7 [ get::return_x#0 ] 2: zp[1]:8 [ get::return_y#0 ] 0: zp[2]:14 [ get::p ] Uplift Scope [print] 2: zp[1]:3 [ print::p_x#0 ] 1.33: zp[1]:4 [ print::p_y#0 ] -Uplift Scope [] 0.67: zp[1]:2 [ idx ] +Uplift Scope [] 0.61: zp[1]:2 [ idx ] Uplift Scope [Point] Uplifting [main] best 937 combination reg byte x [ main::$1_x ] reg byte a [ main::$1_y ] zp[1]:9 [ main::i ] zp[2]:12 [ main::p ] @@ -587,10 +598,11 @@ __bbegin: // [0] (byte) idx ← (byte) 0 -- vbuz1=vbuc1 lda #0 sta.z idx + // [1] phi from @begin to @1 [phi:@begin->@1] +__b1_from___bbegin: jmp __b1 // @1 __b1: - // [1] callprepare main // [2] callexecute main -- jsr jsr main // [3] phi from @1 to @end [phi:@1->@end] @@ -684,34 +696,34 @@ main: { rts // main::@2 __b2: - // [23] callprepare get (byte) main::i [(byte) get::i#0] -- _stackpushbyte_=vbuz1 + // [23] stackpush(byte) ← (byte) main::i -- _stackpushbyte_=vbuz1 lda.z i pha - // [23] callprepare get (byte) main::i -- _stackpushbyte_1 + // sideeffect stackpushbytes((number) 1) -- _stackpushbyte_1 pha - // [24] callexecute get -- jsr + // [25] callexecute get -- jsr jsr get - // [25] (byte~) main::$1_x ← stackpull(byte) -- vbuxx=_stackpullbyte_ + // [26] (byte~) main::$1_x ← stackpull(byte) -- vbuxx=_stackpullbyte_ pla tax - // [26] (byte~) main::$1_y ← stackpull(byte) -- vbuaa=_stackpullbyte_ + // [27] (byte~) main::$1_y ← stackpull(byte) -- vbuaa=_stackpullbyte_ pla - // [27] *((byte*)&(struct Point) main::p) ← (byte~) main::$1_x -- _deref_pbuc1=vbuxx + // [28] *((byte*)&(struct Point) main::p) ← (byte~) main::$1_x -- _deref_pbuc1=vbuxx stx.z p - // [28] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_y -- _deref_pbuc1=vbuaa + // [29] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_y -- _deref_pbuc1=vbuaa sta p+OFFSET_STRUCT_POINT_Y - // [29] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) [(byte) print::p_x#0] -- _stackpushbyte_=_deref_pbuc1 + // [30] stackpush(byte) ← *((byte*)&(struct Point) main::p) -- _stackpushbyte_=_deref_pbuc1 lda.z p pha - // [29] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) [(byte) print::p_y#1] -- _stackpushbyte_=_deref_pbuc1 + // [31] stackpush(byte) ← *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) -- _stackpushbyte_=_deref_pbuc1 lda p+OFFSET_STRUCT_POINT_Y pha - // [30] callexecute print -- jsr + // [32] callexecute print -- jsr jsr print // sideeffect stackpullbytes((number) 2) -- _stackpullbyte_2 pla pla - // [32] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1 + // [34] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1 inc.z i jmp __b1 } @@ -729,6 +741,7 @@ Removing instruction ldx.z p Replacing instruction ldy p+OFFSET_STRUCT_POINT_Y with TAY Replacing instruction lda.z p with TXA Succesful ASM optimization Pass5UnnecesaryLoadElimination +Removing instruction __b1_from___bbegin: Removing instruction __bend_from___b1: Succesful ASM optimization Pass5RedundantLabelElimination Removing instruction __b1: @@ -761,14 +774,14 @@ __stackcall (struct Point()) get((byte) get::i) (byte) get::return_x#0 reg byte x 2.0 (byte) get::return_y (byte) get::return_y#0 reg byte y 2.0 -(byte) idx loadstore zp[1]:2 0.6666666666666666 +(byte) idx loadstore zp[1]:2 0.6086956521739131 __stackcall (void()) main() (byte~) main::$1_x reg byte x 11.0 (byte~) main::$1_y reg byte a 11.0 (label) main::@1 (label) main::@2 (label) main::@return -(byte) main::i loadstore zp[1]:3 2.9166666666666665 +(byte) main::i loadstore zp[1]:3 3.2857142857142856 (struct Point) main::p loadstore zp[2]:4 __stackcall (void()) print((byte) print::p_x , (byte) print::p_y) (label) print::@return @@ -814,8 +827,8 @@ __bbegin: // [0] (byte) idx ← (byte) 0 -- vbuz1=vbuc1 lda #0 sta.z idx + // [1] phi from @begin to @1 [phi:@begin->@1] // @1 - // [1] callprepare main // [2] callexecute main -- jsr jsr main rts @@ -913,37 +926,37 @@ main: { // main::@2 __b2: // get(i) - // [23] callprepare get (byte) main::i [(byte) get::i#0] -- _stackpushbyte_=vbuz1 + // [23] stackpush(byte) ← (byte) main::i -- _stackpushbyte_=vbuz1 lda.z i pha - // [23] callprepare get (byte) main::i -- _stackpushbyte_1 + // sideeffect stackpushbytes((number) 1) -- _stackpushbyte_1 pha - // [24] callexecute get -- jsr + // [25] callexecute get -- jsr jsr get - // [25] (byte~) main::$1_x ← stackpull(byte) -- vbuxx=_stackpullbyte_ + // [26] (byte~) main::$1_x ← stackpull(byte) -- vbuxx=_stackpullbyte_ pla tax - // [26] (byte~) main::$1_y ← stackpull(byte) -- vbuaa=_stackpullbyte_ + // [27] (byte~) main::$1_y ← stackpull(byte) -- vbuaa=_stackpullbyte_ pla // p = get(i) - // [27] *((byte*)&(struct Point) main::p) ← (byte~) main::$1_x -- _deref_pbuc1=vbuxx + // [28] *((byte*)&(struct Point) main::p) ← (byte~) main::$1_x -- _deref_pbuc1=vbuxx stx.z p - // [28] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_y -- _deref_pbuc1=vbuaa + // [29] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_y -- _deref_pbuc1=vbuaa sta p+OFFSET_STRUCT_POINT_Y // print(p) - // [29] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) [(byte) print::p_x#0] -- _stackpushbyte_=_deref_pbuc1 + // [30] stackpush(byte) ← *((byte*)&(struct Point) main::p) -- _stackpushbyte_=_deref_pbuc1 txa pha - // [29] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) [(byte) print::p_y#1] -- _stackpushbyte_=_deref_pbuc1 + // [31] stackpush(byte) ← *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) -- _stackpushbyte_=_deref_pbuc1 lda p+OFFSET_STRUCT_POINT_Y pha - // [30] callexecute print -- jsr + // [32] callexecute print -- jsr jsr print // sideeffect stackpullbytes((number) 2) -- _stackpullbyte_2 pla pla // for(char i=0;i<5;i++) - // [32] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1 + // [34] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1 inc.z i jmp __b1 } diff --git a/src/test/ref/procedure-callingconvention-stack-10.sym b/src/test/ref/procedure-callingconvention-stack-10.sym index 7f5036206..326231d1d 100644 --- a/src/test/ref/procedure-callingconvention-stack-10.sym +++ b/src/test/ref/procedure-callingconvention-stack-10.sym @@ -18,14 +18,14 @@ __stackcall (struct Point()) get((byte) get::i) (byte) get::return_x#0 reg byte x 2.0 (byte) get::return_y (byte) get::return_y#0 reg byte y 2.0 -(byte) idx loadstore zp[1]:2 0.6666666666666666 +(byte) idx loadstore zp[1]:2 0.6086956521739131 __stackcall (void()) main() (byte~) main::$1_x reg byte x 11.0 (byte~) main::$1_y reg byte a 11.0 (label) main::@1 (label) main::@2 (label) main::@return -(byte) main::i loadstore zp[1]:3 2.9166666666666665 +(byte) main::i loadstore zp[1]:3 3.2857142857142856 (struct Point) main::p loadstore zp[2]:4 __stackcall (void()) print((byte) print::p_x , (byte) print::p_y) (label) print::@return diff --git a/src/test/ref/procedure-callingconvention-stack-2.cfg b/src/test/ref/procedure-callingconvention-stack-2.cfg index a37b6ee12..8f6785d17 100644 --- a/src/test/ref/procedure-callingconvention-stack-2.cfg +++ b/src/test/ref/procedure-callingconvention-stack-2.cfg @@ -10,23 +10,24 @@ (void()) main() main: scope:[main] from @1 - [4] callprepare plus (word) $1234 (word) $2345 - [5] callexecute plus + [4] stackpush(word) ← (word) $1234 + [5] stackpush(word) ← (word) $2345 + [6] callexecute plus sideeffect stackpullbytes((number) 2) - [7] (word~) main::$0 ← stackpull(word) - [8] *((const word*) SCREEN) ← (word~) main::$0 + [8] (word~) main::$0 ← stackpull(word) + [9] *((const word*) SCREEN) ← (word~) main::$0 to:main::@return main::@return: scope:[main] from main - [9] return + [10] return to:@return __stackcall (word()) plus((word) plus::a , (word) plus::b) plus: scope:[plus] from - [10] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) - [11] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) - [12] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 + [11] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) + [12] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) + [13] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 to:plus::@return plus::@return: scope:[plus] from plus - [13] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 - [14] return + [14] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 + [15] return to:@return diff --git a/src/test/ref/procedure-callingconvention-stack-2.log b/src/test/ref/procedure-callingconvention-stack-2.log index ef2c7c4a5..cd8bcfa50 100644 --- a/src/test/ref/procedure-callingconvention-stack-2.log +++ b/src/test/ref/procedure-callingconvention-stack-2.log @@ -6,6 +6,8 @@ Calling convention STACK_CALL replacing param((word) plus::a) with stackidx(word Calling convention STACK_CALL replacing param((word) plus::b) with stackidx(word,(const byte) plus::OFFSET_STACK_B) Calling convention STACK_CALL adding stack return stackidx(word,plus::OFFSET_STACK_RETURN) ← plus::return Calling convention STACK_CALL adding stack pull main::$0 ← stackpull(word) +Calling convention STACK_CALL adding stack push stackpush(word) ← $1234 +Calling convention STACK_CALL adding stack push stackpush(word) ← $2345 CONTROL FLOW GRAPH SSA @begin: scope:[] from @@ -13,7 +15,8 @@ CONTROL FLOW GRAPH SSA (void()) main() main: scope:[main] from @2 - callprepare plus (number) $1234 (number) $2345 + stackpush(word) ← (number) $1234 + stackpush(word) ← (number) $2345 callexecute plus sideeffect stackpullbytes((number) 2) (word~) main::$0 ← stackpull(word) @@ -69,11 +72,14 @@ __stackcall (word()) plus((word) plus::a , (word) plus::b) (word) plus::return#0 (word) plus::return#1 -Adding number conversion cast (unumber) $1234 in callprepare plus (number) $1234 (number) $2345 -Adding number conversion cast (unumber) $2345 in callprepare plus (unumber)(number) $1234 (number) $2345 +Adding number conversion cast (unumber) $1234 in stackpush(word) ← (number) $1234 +Adding number conversion cast (unumber) $2345 in stackpush(word) ← (number) $2345 Adding number conversion cast (unumber) 0 in (number~) main::$1 ← (number) 0 * (const byte) SIZEOF_WORD Adding number conversion cast (unumber) main::$1 in (number~) main::$1 ← (unumber)(number) 0 * (const byte) SIZEOF_WORD Successful SSA optimization PassNAddNumberTypeConversions +Inlining cast stackpush(word) ← (unumber)(number) $1234 +Inlining cast stackpush(word) ← (unumber)(number) $2345 +Successful SSA optimization Pass2InlineCast Simplifying constant pointer cast (word*) 1024 Simplifying constant integer cast $1234 Simplifying constant integer cast $2345 @@ -86,13 +92,13 @@ Successful SSA optimization PassNFinalizeNumberTypeConversions Inferred type updated to byte in (unumber~) main::$1 ← (byte) 0 * (const byte) SIZEOF_WORD Alias (word) plus::return#0 = (word~) plus::$0 (word) plus::return#1 Successful SSA optimization Pass2AliasElimination -Constant right-side identified [4] (byte~) main::$1 ← (byte) 0 * (const byte) SIZEOF_WORD +Constant right-side identified [5] (byte~) main::$1 ← (byte) 0 * (const byte) SIZEOF_WORD Successful SSA optimization Pass2ConstantRValueConsolidation Constant (const byte) main::$1 = 0*SIZEOF_WORD Successful SSA optimization Pass2ConstantIdentification Simplifying constant evaluating to zero (byte) 0*(const byte) SIZEOF_WORD in Successful SSA optimization PassNSimplifyConstantZero -Simplifying expression containing zero SCREEN in [5] *((const word*) SCREEN + (const byte) main::$1) ← (word~) main::$0 +Simplifying expression containing zero SCREEN in [6] *((const word*) SCREEN + (const byte) main::$1) ← (word~) main::$0 Successful SSA optimization PassNSimplifyExpressionWithZero Eliminating unused constant (const byte) main::$1 Eliminating unused constant (const byte) SIZEOF_WORD @@ -103,7 +109,7 @@ Adding NOP phi() at start of @3 Adding NOP phi() at start of @end CALL GRAPH Calls in [] to main:2 -Calls in [main] to plus:6 +Calls in [main] to plus:7 Created 0 initial phi equivalence classes Coalesced down to 0 phi equivalence classes @@ -126,25 +132,26 @@ FINAL CONTROL FLOW GRAPH (void()) main() main: scope:[main] from @1 - [4] callprepare plus (word) $1234 (word) $2345 - [5] callexecute plus + [4] stackpush(word) ← (word) $1234 + [5] stackpush(word) ← (word) $2345 + [6] callexecute plus sideeffect stackpullbytes((number) 2) - [7] (word~) main::$0 ← stackpull(word) - [8] *((const word*) SCREEN) ← (word~) main::$0 + [8] (word~) main::$0 ← stackpull(word) + [9] *((const word*) SCREEN) ← (word~) main::$0 to:main::@return main::@return: scope:[main] from main - [9] return + [10] return to:@return __stackcall (word()) plus((word) plus::a , (word) plus::b) plus: scope:[plus] from - [10] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) - [11] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) - [12] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 + [11] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) + [12] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) + [13] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 to:plus::@return plus::@return: scope:[plus] from plus - [13] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 - [14] return + [14] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 + [15] return to:@return @@ -202,27 +209,27 @@ __bend: // main main: { .label __0 = 2 - // [4] callprepare plus (word) $1234 (word) $2345 [(word) plus::a#0] -- _stackpushword_=vwuc1 + // [4] stackpush(word) ← (word) $1234 -- _stackpushword_=vwuc1 lda #>$1234 pha lda #<$1234 pha - // [4] callprepare plus (word) $1234 (word) $2345 [(word) plus::b#1] -- _stackpushword_=vwuc1 + // [5] stackpush(word) ← (word) $2345 -- _stackpushword_=vwuc1 lda #>$2345 pha lda #<$2345 pha - // [5] callexecute plus -- jsr + // [6] callexecute plus -- jsr jsr plus // sideeffect stackpullbytes((number) 2) -- _stackpullbyte_2 pla pla - // [7] (word~) main::$0 ← stackpull(word) -- vwuz1=_stackpullword_ + // [8] (word~) main::$0 ← stackpull(word) -- vwuz1=_stackpullword_ pla sta.z __0 pla sta.z __0+1 - // [8] *((const word*) SCREEN) ← (word~) main::$0 -- _deref_pwuc1=vwuz1 + // [9] *((const word*) SCREEN) ← (word~) main::$0 -- _deref_pwuc1=vwuz1 lda.z __0 sta SCREEN lda.z __0+1 @@ -230,7 +237,7 @@ main: { jmp __breturn // main::@return __breturn: - // [9] return + // [10] return rts } // plus @@ -242,19 +249,19 @@ plus: { .label a = 4 .label b = 6 .label return = 8 - // [10] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1 + // [11] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_A,x sta.z a lda STACK_BASE+OFFSET_STACK_A+1,x sta.z a+1 - // [11] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) -- vwuz1=_stackidxword_vbuc1 + // [12] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) -- vwuz1=_stackidxword_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_B,x sta.z b lda STACK_BASE+OFFSET_STACK_B+1,x sta.z b+1 - // [12] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 -- vwuz1=vwuz2_plus_vwuz3 + // [13] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 -- vwuz1=vwuz2_plus_vwuz3 lda.z a clc adc.z b @@ -265,26 +272,27 @@ plus: { jmp __breturn // plus::@return __breturn: - // [13] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 -- _stackidxword_vbuc1=vwuz1 + // [14] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 -- _stackidxword_vbuc1=vwuz1 tsx lda.z return sta STACK_BASE+OFFSET_STACK_RETURN,x lda.z return+1 sta STACK_BASE+OFFSET_STACK_RETURN+1,x - // [14] return + // [15] return rts } // File Data REGISTER UPLIFT POTENTIAL REGISTERS -Statement [4] callprepare plus (word) $1234 (word) $2345 [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [4] stackpush(word) ← (word) $1234 [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [5] stackpush(word) ← (word) $2345 [ ] ( main:2 [ ] ) always clobbers reg byte a Statement sideeffect stackpullbytes((number) 2) always clobbers reg byte a -Statement [7] (word~) main::$0 ← stackpull(word) [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a -Statement [8] *((const word*) SCREEN) ← (word~) main::$0 [ ] ( main:2 [ ] ) always clobbers reg byte a -Statement [10] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:5 [ plus::a#0 ] ) always clobbers reg byte a reg byte x -Statement [11] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:5 [ plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x -Statement [12] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 [ plus::return#0 ] ( main:2::plus:5 [ plus::return#0 ] ) always clobbers reg byte a -Statement [13] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 [ ] ( main:2::plus:5 [ ] ) always clobbers reg byte a reg byte x +Statement [8] (word~) main::$0 ← stackpull(word) [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a +Statement [9] *((const word*) SCREEN) ← (word~) main::$0 [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [11] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:6 [ plus::a#0 ] ) always clobbers reg byte a reg byte x +Statement [12] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:6 [ plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x +Statement [13] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 [ plus::return#0 ] ( main:2::plus:6 [ plus::return#0 ] ) always clobbers reg byte a +Statement [14] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 [ ] ( main:2::plus:6 [ ] ) always clobbers reg byte a reg byte x Potential registers zp[2]:2 [ main::$0 ] : zp[2]:2 , Potential registers zp[2]:4 [ plus::a#0 ] : zp[2]:4 , Potential registers zp[2]:6 [ plus::b#0 ] : zp[2]:6 , @@ -330,27 +338,27 @@ __bend: // main main: { .label __0 = 2 - // [4] callprepare plus (word) $1234 (word) $2345 [(word) plus::a#0] -- _stackpushword_=vwuc1 + // [4] stackpush(word) ← (word) $1234 -- _stackpushword_=vwuc1 lda #>$1234 pha lda #<$1234 pha - // [4] callprepare plus (word) $1234 (word) $2345 [(word) plus::b#1] -- _stackpushword_=vwuc1 + // [5] stackpush(word) ← (word) $2345 -- _stackpushword_=vwuc1 lda #>$2345 pha lda #<$2345 pha - // [5] callexecute plus -- jsr + // [6] callexecute plus -- jsr jsr plus // sideeffect stackpullbytes((number) 2) -- _stackpullbyte_2 pla pla - // [7] (word~) main::$0 ← stackpull(word) -- vwuz1=_stackpullword_ + // [8] (word~) main::$0 ← stackpull(word) -- vwuz1=_stackpullword_ pla sta.z __0 pla sta.z __0+1 - // [8] *((const word*) SCREEN) ← (word~) main::$0 -- _deref_pwuc1=vwuz1 + // [9] *((const word*) SCREEN) ← (word~) main::$0 -- _deref_pwuc1=vwuz1 lda.z __0 sta SCREEN lda.z __0+1 @@ -358,7 +366,7 @@ main: { jmp __breturn // main::@return __breturn: - // [9] return + // [10] return rts } // plus @@ -370,19 +378,19 @@ plus: { .label a = 2 .label b = 4 .label return = 2 - // [10] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1 + // [11] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_A,x sta.z a lda STACK_BASE+OFFSET_STACK_A+1,x sta.z a+1 - // [11] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) -- vwuz1=_stackidxword_vbuc1 + // [12] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) -- vwuz1=_stackidxword_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_B,x sta.z b lda STACK_BASE+OFFSET_STACK_B+1,x sta.z b+1 - // [12] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 -- vwuz1=vwuz1_plus_vwuz2 + // [13] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 -- vwuz1=vwuz1_plus_vwuz2 lda.z return clc adc.z b @@ -393,13 +401,13 @@ plus: { jmp __breturn // plus::@return __breturn: - // [13] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 -- _stackidxword_vbuc1=vwuz1 + // [14] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 -- _stackidxword_vbuc1=vwuz1 tsx lda.z return sta STACK_BASE+OFFSET_STACK_RETURN,x lda.z return+1 sta STACK_BASE+OFFSET_STACK_RETURN+1,x - // [14] return + // [15] return rts } // File Data @@ -471,35 +479,35 @@ Score: 146 main: { .label __0 = 2 // plus(0x1234, 0x2345) - // [4] callprepare plus (word) $1234 (word) $2345 [(word) plus::a#0] -- _stackpushword_=vwuc1 + // [4] stackpush(word) ← (word) $1234 -- _stackpushword_=vwuc1 lda #>$1234 pha lda #<$1234 pha - // [4] callprepare plus (word) $1234 (word) $2345 [(word) plus::b#1] -- _stackpushword_=vwuc1 + // [5] stackpush(word) ← (word) $2345 -- _stackpushword_=vwuc1 lda #>$2345 pha lda #<$2345 pha - // [5] callexecute plus -- jsr + // [6] callexecute plus -- jsr jsr plus // sideeffect stackpullbytes((number) 2) -- _stackpullbyte_2 pla pla - // [7] (word~) main::$0 ← stackpull(word) -- vwuz1=_stackpullword_ + // [8] (word~) main::$0 ← stackpull(word) -- vwuz1=_stackpullword_ pla sta.z __0 pla sta.z __0+1 // SCREEN[0] = plus(0x1234, 0x2345) - // [8] *((const word*) SCREEN) ← (word~) main::$0 -- _deref_pwuc1=vwuz1 + // [9] *((const word*) SCREEN) ← (word~) main::$0 -- _deref_pwuc1=vwuz1 lda.z __0 sta SCREEN lda.z __0+1 sta SCREEN+1 // main::@return // } - // [9] return + // [10] return rts } // plus @@ -511,20 +519,20 @@ plus: { .label a = 2 .label b = 4 .label return = 2 - // [10] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1 + // [11] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_A,x sta.z a lda STACK_BASE+OFFSET_STACK_A+1,x sta.z a+1 - // [11] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) -- vwuz1=_stackidxword_vbuc1 + // [12] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) -- vwuz1=_stackidxword_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_B,x sta.z b lda STACK_BASE+OFFSET_STACK_B+1,x sta.z b+1 // return a+b; - // [12] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 -- vwuz1=vwuz1_plus_vwuz2 + // [13] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 -- vwuz1=vwuz1_plus_vwuz2 lda.z return clc adc.z b @@ -534,13 +542,13 @@ plus: { sta.z return+1 // plus::@return // } - // [13] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 -- _stackidxword_vbuc1=vwuz1 + // [14] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 -- _stackidxword_vbuc1=vwuz1 tsx lda.z return sta STACK_BASE+OFFSET_STACK_RETURN,x lda.z return+1 sta STACK_BASE+OFFSET_STACK_RETURN+1,x - // [14] return + // [15] return rts } // File Data diff --git a/src/test/ref/procedure-callingconvention-stack-3.cfg b/src/test/ref/procedure-callingconvention-stack-3.cfg index cb1edf1ee..d4b642d31 100644 --- a/src/test/ref/procedure-callingconvention-stack-3.cfg +++ b/src/test/ref/procedure-callingconvention-stack-3.cfg @@ -10,23 +10,24 @@ (void()) main() main: scope:[main] from @1 - [4] callprepare plus (byte) '0' (byte) 7 - [5] callexecute plus + [4] stackpush(word) ← (byte) '0' + [5] stackpush(word) ← (byte) 7 + [6] callexecute plus sideeffect stackpullbytes((number) 2) - [7] (word~) main::$0 ← stackpull(word) - [8] *((const word*) SCREEN) ← (word~) main::$0 + [8] (word~) main::$0 ← stackpull(word) + [9] *((const word*) SCREEN) ← (word~) main::$0 to:main::@return main::@return: scope:[main] from main - [9] return + [10] return to:@return __stackcall (word()) plus((word) plus::a , (word) plus::b) plus: scope:[plus] from - [10] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) - [11] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) - [12] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 + [11] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) + [12] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) + [13] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 to:plus::@return plus::@return: scope:[plus] from plus - [13] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 - [14] return + [14] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 + [15] return to:@return diff --git a/src/test/ref/procedure-callingconvention-stack-3.log b/src/test/ref/procedure-callingconvention-stack-3.log index ed1cf51a8..81bb44e36 100644 --- a/src/test/ref/procedure-callingconvention-stack-3.log +++ b/src/test/ref/procedure-callingconvention-stack-3.log @@ -6,6 +6,8 @@ Calling convention STACK_CALL replacing param((word) plus::a) with stackidx(word Calling convention STACK_CALL replacing param((word) plus::b) with stackidx(word,(const byte) plus::OFFSET_STACK_B) Calling convention STACK_CALL adding stack return stackidx(word,plus::OFFSET_STACK_RETURN) ← plus::return Calling convention STACK_CALL adding stack pull main::$0 ← stackpull(word) +Calling convention STACK_CALL adding stack push stackpush(word) ← '0' +Calling convention STACK_CALL adding stack push stackpush(word) ← 7 CONTROL FLOW GRAPH SSA @begin: scope:[] from @@ -13,7 +15,8 @@ CONTROL FLOW GRAPH SSA (void()) main() main: scope:[main] from @2 - callprepare plus (byte) '0' (number) 7 + stackpush(word) ← (byte) '0' + stackpush(word) ← (number) 7 callexecute plus sideeffect stackpullbytes((number) 2) (word~) main::$0 ← stackpull(word) @@ -69,10 +72,12 @@ __stackcall (word()) plus((word) plus::a , (word) plus::b) (word) plus::return#0 (word) plus::return#1 -Adding number conversion cast (unumber) 7 in callprepare plus (byte) '0' (number) 7 +Adding number conversion cast (unumber) 7 in stackpush(word) ← (number) 7 Adding number conversion cast (unumber) 0 in (number~) main::$1 ← (number) 0 * (const byte) SIZEOF_WORD Adding number conversion cast (unumber) main::$1 in (number~) main::$1 ← (unumber)(number) 0 * (const byte) SIZEOF_WORD Successful SSA optimization PassNAddNumberTypeConversions +Inlining cast stackpush(word) ← (unumber)(number) 7 +Successful SSA optimization Pass2InlineCast Simplifying constant pointer cast (word*) 1024 Simplifying constant integer cast 7 Simplifying constant integer cast 0 @@ -83,13 +88,13 @@ Successful SSA optimization PassNFinalizeNumberTypeConversions Inferred type updated to byte in (unumber~) main::$1 ← (byte) 0 * (const byte) SIZEOF_WORD Alias (word) plus::return#0 = (word~) plus::$0 (word) plus::return#1 Successful SSA optimization Pass2AliasElimination -Constant right-side identified [4] (byte~) main::$1 ← (byte) 0 * (const byte) SIZEOF_WORD +Constant right-side identified [5] (byte~) main::$1 ← (byte) 0 * (const byte) SIZEOF_WORD Successful SSA optimization Pass2ConstantRValueConsolidation Constant (const byte) main::$1 = 0*SIZEOF_WORD Successful SSA optimization Pass2ConstantIdentification Simplifying constant evaluating to zero (byte) 0*(const byte) SIZEOF_WORD in Successful SSA optimization PassNSimplifyConstantZero -Simplifying expression containing zero SCREEN in [5] *((const word*) SCREEN + (const byte) main::$1) ← (word~) main::$0 +Simplifying expression containing zero SCREEN in [6] *((const word*) SCREEN + (const byte) main::$1) ← (word~) main::$0 Successful SSA optimization PassNSimplifyExpressionWithZero Eliminating unused constant (const byte) main::$1 Eliminating unused constant (const byte) SIZEOF_WORD @@ -100,7 +105,7 @@ Adding NOP phi() at start of @3 Adding NOP phi() at start of @end CALL GRAPH Calls in [] to main:2 -Calls in [main] to plus:6 +Calls in [main] to plus:7 Created 0 initial phi equivalence classes Coalesced down to 0 phi equivalence classes @@ -123,25 +128,26 @@ FINAL CONTROL FLOW GRAPH (void()) main() main: scope:[main] from @1 - [4] callprepare plus (byte) '0' (byte) 7 - [5] callexecute plus + [4] stackpush(word) ← (byte) '0' + [5] stackpush(word) ← (byte) 7 + [6] callexecute plus sideeffect stackpullbytes((number) 2) - [7] (word~) main::$0 ← stackpull(word) - [8] *((const word*) SCREEN) ← (word~) main::$0 + [8] (word~) main::$0 ← stackpull(word) + [9] *((const word*) SCREEN) ← (word~) main::$0 to:main::@return main::@return: scope:[main] from main - [9] return + [10] return to:@return __stackcall (word()) plus((word) plus::a , (word) plus::b) plus: scope:[plus] from - [10] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) - [11] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) - [12] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 + [11] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) + [12] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) + [13] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 to:plus::@return plus::@return: scope:[plus] from plus - [13] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 - [14] return + [14] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 + [15] return to:@return @@ -202,27 +208,27 @@ __bend: // main main: { .label __0 = 2 - // [4] callprepare plus (byte) '0' (byte) 7 [(word) plus::a#0] -- _stackpushword_=vbuc1 + // [4] stackpush(word) ← (byte) '0' -- _stackpushword_=vbuc1 lda #0 pha lda #<'0' pha - // [4] callprepare plus (byte) '0' (byte) 7 [(word) plus::b#1] -- _stackpushword_=vbuc1 + // [5] stackpush(word) ← (byte) 7 -- _stackpushword_=vbuc1 lda #0 pha lda #<7 pha - // [5] callexecute plus -- jsr + // [6] callexecute plus -- jsr jsr plus // sideeffect stackpullbytes((number) 2) -- _stackpullbyte_2 pla pla - // [7] (word~) main::$0 ← stackpull(word) -- vwuz1=_stackpullword_ + // [8] (word~) main::$0 ← stackpull(word) -- vwuz1=_stackpullword_ pla sta.z __0 pla sta.z __0+1 - // [8] *((const word*) SCREEN) ← (word~) main::$0 -- _deref_pwuc1=vwuz1 + // [9] *((const word*) SCREEN) ← (word~) main::$0 -- _deref_pwuc1=vwuz1 lda.z __0 sta SCREEN lda.z __0+1 @@ -230,7 +236,7 @@ main: { jmp __breturn // main::@return __breturn: - // [9] return + // [10] return rts } // plus @@ -242,19 +248,19 @@ plus: { .label a = 4 .label b = 6 .label return = 8 - // [10] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1 + // [11] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_A,x sta.z a lda STACK_BASE+OFFSET_STACK_A+1,x sta.z a+1 - // [11] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) -- vwuz1=_stackidxword_vbuc1 + // [12] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) -- vwuz1=_stackidxword_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_B,x sta.z b lda STACK_BASE+OFFSET_STACK_B+1,x sta.z b+1 - // [12] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 -- vwuz1=vwuz2_plus_vwuz3 + // [13] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 -- vwuz1=vwuz2_plus_vwuz3 lda.z a clc adc.z b @@ -265,26 +271,27 @@ plus: { jmp __breturn // plus::@return __breturn: - // [13] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 -- _stackidxword_vbuc1=vwuz1 + // [14] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 -- _stackidxword_vbuc1=vwuz1 tsx lda.z return sta STACK_BASE+OFFSET_STACK_RETURN,x lda.z return+1 sta STACK_BASE+OFFSET_STACK_RETURN+1,x - // [14] return + // [15] return rts } // File Data REGISTER UPLIFT POTENTIAL REGISTERS -Statement [4] callprepare plus (byte) '0' (byte) 7 [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [4] stackpush(word) ← (byte) '0' [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [5] stackpush(word) ← (byte) 7 [ ] ( main:2 [ ] ) always clobbers reg byte a Statement sideeffect stackpullbytes((number) 2) always clobbers reg byte a -Statement [7] (word~) main::$0 ← stackpull(word) [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a -Statement [8] *((const word*) SCREEN) ← (word~) main::$0 [ ] ( main:2 [ ] ) always clobbers reg byte a -Statement [10] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:5 [ plus::a#0 ] ) always clobbers reg byte a reg byte x -Statement [11] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:5 [ plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x -Statement [12] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 [ plus::return#0 ] ( main:2::plus:5 [ plus::return#0 ] ) always clobbers reg byte a -Statement [13] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 [ ] ( main:2::plus:5 [ ] ) always clobbers reg byte a reg byte x +Statement [8] (word~) main::$0 ← stackpull(word) [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a +Statement [9] *((const word*) SCREEN) ← (word~) main::$0 [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [11] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:6 [ plus::a#0 ] ) always clobbers reg byte a reg byte x +Statement [12] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:6 [ plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x +Statement [13] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 [ plus::return#0 ] ( main:2::plus:6 [ plus::return#0 ] ) always clobbers reg byte a +Statement [14] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 [ ] ( main:2::plus:6 [ ] ) always clobbers reg byte a reg byte x Potential registers zp[2]:2 [ main::$0 ] : zp[2]:2 , Potential registers zp[2]:4 [ plus::a#0 ] : zp[2]:4 , Potential registers zp[2]:6 [ plus::b#0 ] : zp[2]:6 , @@ -333,27 +340,27 @@ __bend: // main main: { .label __0 = 2 - // [4] callprepare plus (byte) '0' (byte) 7 [(word) plus::a#0] -- _stackpushword_=vbuc1 + // [4] stackpush(word) ← (byte) '0' -- _stackpushword_=vbuc1 lda #0 pha lda #<'0' pha - // [4] callprepare plus (byte) '0' (byte) 7 [(word) plus::b#1] -- _stackpushword_=vbuc1 + // [5] stackpush(word) ← (byte) 7 -- _stackpushword_=vbuc1 lda #0 pha lda #<7 pha - // [5] callexecute plus -- jsr + // [6] callexecute plus -- jsr jsr plus // sideeffect stackpullbytes((number) 2) -- _stackpullbyte_2 pla pla - // [7] (word~) main::$0 ← stackpull(word) -- vwuz1=_stackpullword_ + // [8] (word~) main::$0 ← stackpull(word) -- vwuz1=_stackpullword_ pla sta.z __0 pla sta.z __0+1 - // [8] *((const word*) SCREEN) ← (word~) main::$0 -- _deref_pwuc1=vwuz1 + // [9] *((const word*) SCREEN) ← (word~) main::$0 -- _deref_pwuc1=vwuz1 lda.z __0 sta SCREEN lda.z __0+1 @@ -361,7 +368,7 @@ main: { jmp __breturn // main::@return __breturn: - // [9] return + // [10] return rts } // plus @@ -373,19 +380,19 @@ plus: { .label a = 2 .label b = 4 .label return = 2 - // [10] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1 + // [11] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_A,x sta.z a lda STACK_BASE+OFFSET_STACK_A+1,x sta.z a+1 - // [11] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) -- vwuz1=_stackidxword_vbuc1 + // [12] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) -- vwuz1=_stackidxword_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_B,x sta.z b lda STACK_BASE+OFFSET_STACK_B+1,x sta.z b+1 - // [12] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 -- vwuz1=vwuz1_plus_vwuz2 + // [13] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 -- vwuz1=vwuz1_plus_vwuz2 lda.z return clc adc.z b @@ -396,13 +403,13 @@ plus: { jmp __breturn // plus::@return __breturn: - // [13] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 -- _stackidxword_vbuc1=vwuz1 + // [14] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 -- _stackidxword_vbuc1=vwuz1 tsx lda.z return sta STACK_BASE+OFFSET_STACK_RETURN,x lda.z return+1 sta STACK_BASE+OFFSET_STACK_RETURN+1,x - // [14] return + // [15] return rts } // File Data @@ -477,35 +484,35 @@ Score: 146 main: { .label __0 = 2 // plus('0', 7) - // [4] callprepare plus (byte) '0' (byte) 7 [(word) plus::a#0] -- _stackpushword_=vbuc1 + // [4] stackpush(word) ← (byte) '0' -- _stackpushword_=vbuc1 lda #0 pha lda #<'0' pha - // [4] callprepare plus (byte) '0' (byte) 7 [(word) plus::b#1] -- _stackpushword_=vbuc1 + // [5] stackpush(word) ← (byte) 7 -- _stackpushword_=vbuc1 lda #0 pha lda #<7 pha - // [5] callexecute plus -- jsr + // [6] callexecute plus -- jsr jsr plus // sideeffect stackpullbytes((number) 2) -- _stackpullbyte_2 pla pla - // [7] (word~) main::$0 ← stackpull(word) -- vwuz1=_stackpullword_ + // [8] (word~) main::$0 ← stackpull(word) -- vwuz1=_stackpullword_ pla sta.z __0 pla sta.z __0+1 // SCREEN[0] = plus('0', 7) - // [8] *((const word*) SCREEN) ← (word~) main::$0 -- _deref_pwuc1=vwuz1 + // [9] *((const word*) SCREEN) ← (word~) main::$0 -- _deref_pwuc1=vwuz1 lda.z __0 sta SCREEN lda.z __0+1 sta SCREEN+1 // main::@return // } - // [9] return + // [10] return rts } // plus @@ -517,20 +524,20 @@ plus: { .label a = 2 .label b = 4 .label return = 2 - // [10] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1 + // [11] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_A,x sta.z a lda STACK_BASE+OFFSET_STACK_A+1,x sta.z a+1 - // [11] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) -- vwuz1=_stackidxword_vbuc1 + // [12] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) -- vwuz1=_stackidxword_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_B,x sta.z b lda STACK_BASE+OFFSET_STACK_B+1,x sta.z b+1 // return a+b; - // [12] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 -- vwuz1=vwuz1_plus_vwuz2 + // [13] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 -- vwuz1=vwuz1_plus_vwuz2 lda.z return clc adc.z b @@ -540,13 +547,13 @@ plus: { sta.z return+1 // plus::@return // } - // [13] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 -- _stackidxword_vbuc1=vwuz1 + // [14] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 -- _stackidxword_vbuc1=vwuz1 tsx lda.z return sta STACK_BASE+OFFSET_STACK_RETURN,x lda.z return+1 sta STACK_BASE+OFFSET_STACK_RETURN+1,x - // [14] return + // [15] return rts } // File Data diff --git a/src/test/ref/procedure-callingconvention-stack-4.cfg b/src/test/ref/procedure-callingconvention-stack-4.cfg index ca628f513..9fdd7d0a7 100644 --- a/src/test/ref/procedure-callingconvention-stack-4.cfg +++ b/src/test/ref/procedure-callingconvention-stack-4.cfg @@ -15,26 +15,27 @@ main: scope:[main] from @1 main::@1: scope:[main] from main main::@1 [5] (byte) main::a#2 ← phi( main/(byte) 0 main::@1/(byte) main::a#1 ) [6] (byte) main::v#0 ← (byte) main::a#2 + (byte) 1 - [7] callprepare plus (byte) '0' (byte) main::v#0 - [8] callexecute plus + [7] stackpush(byte) ← (byte) '0' + [8] stackpush(byte) ← (byte) main::v#0 + [9] callexecute plus sideeffect stackpullbytes((number) 1) - [10] (byte) main::w#0 ← stackpull(byte) - [11] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 - [12] *((const byte*) SCREEN) ← (byte~) main::$2 - [13] (byte) main::a#1 ← ++ (byte) main::a#2 - [14] if((byte) main::a#1!=(byte) 2) goto main::@1 + [11] (byte) main::w#0 ← stackpull(byte) + [12] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 + [13] *((const byte*) SCREEN) ← (byte~) main::$2 + [14] (byte) main::a#1 ← ++ (byte) main::a#2 + [15] if((byte) main::a#1!=(byte) 2) goto main::@1 to:main::@return main::@return: scope:[main] from main::@1 - [15] return + [16] return to:@return __stackcall (byte()) plus((byte) plus::a , (byte) plus::b) plus: scope:[plus] from - [16] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) - [17] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) - [18] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 + [17] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) + [18] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) + [19] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 to:plus::@return plus::@return: scope:[plus] from plus - [19] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 - [20] return + [20] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 + [21] return to:@return diff --git a/src/test/ref/procedure-callingconvention-stack-4.log b/src/test/ref/procedure-callingconvention-stack-4.log index b1c18ff33..f495a8a00 100644 --- a/src/test/ref/procedure-callingconvention-stack-4.log +++ b/src/test/ref/procedure-callingconvention-stack-4.log @@ -6,6 +6,8 @@ Calling convention STACK_CALL replacing param((byte) plus::a) with stackidx(byte Calling convention STACK_CALL replacing param((byte) plus::b) with stackidx(byte,(const byte) plus::OFFSET_STACK_B) Calling convention STACK_CALL adding stack return stackidx(byte,plus::OFFSET_STACK_RETURN) ← plus::return Calling convention STACK_CALL adding stack pull main::$1 ← stackpull(byte) +Calling convention STACK_CALL adding stack push stackpush(byte) ← '0' +Calling convention STACK_CALL adding stack push stackpush(byte) ← main::v CONTROL FLOW GRAPH SSA @begin: scope:[] from @@ -22,7 +24,8 @@ main::@1: scope:[main] from main main::@1 (byte) main::a#2 ← phi( main/(byte) main::a#0 main::@1/(byte) main::a#1 ) (number~) main::$0 ← (byte) main::a#2 + (number) 1 (byte) main::v#0 ← (number~) main::$0 - callprepare plus (byte) '0' (byte) main::v#0 + stackpush(byte) ← (byte) '0' + stackpush(byte) ← (byte) main::v#0 callexecute plus sideeffect stackpullbytes((number) 1) (byte~) main::$1 ← stackpull(byte) @@ -130,16 +133,16 @@ Identical Phi Values (byte) i#8 (byte) i#0 Identical Phi Values (byte) i#1 (byte) i#8 Identical Phi Values (byte) i#3 (byte) i#1 Successful SSA optimization Pass2IdenticalPhiElimination -Simple Condition (bool~) main::$3 [13] if((byte) main::a#1!=rangelast(0,1)) goto main::@1 +Simple Condition (bool~) main::$3 [14] if((byte) main::a#1!=rangelast(0,1)) goto main::@1 Successful SSA optimization Pass2ConditionalJumpSimplification Constant (const byte) i#0 = 0 Constant (const byte) main::a#0 = 0 Successful SSA optimization Pass2ConstantIdentification -Resolved ranged next value [11] main::a#1 ← ++ main::a#2 to ++ -Resolved ranged comparison value [13] if(main::a#1!=rangelast(0,1)) goto main::@1 to (number) 2 -Simplifying expression containing zero SCREEN in [10] *((const byte*) SCREEN + (const byte) i#0) ← (byte~) main::$2 +Resolved ranged next value [12] main::a#1 ← ++ main::a#2 to ++ +Resolved ranged comparison value [14] if(main::a#1!=rangelast(0,1)) goto main::@1 to (number) 2 +Simplifying expression containing zero SCREEN in [11] *((const byte*) SCREEN + (const byte) i#0) ← (byte~) main::$2 Successful SSA optimization PassNSimplifyExpressionWithZero -Eliminating unused variable (byte) i#2 and assignment [14] (byte) i#2 ← ++ (byte) i#6 +Eliminating unused variable (byte) i#2 and assignment [15] (byte) i#2 ← ++ (byte) i#6 Eliminating unused constant (const byte) i#0 Successful SSA optimization PassNEliminateUnusedVars Eliminating unused variable - keeping the phi block (byte) i#6 @@ -161,10 +164,10 @@ Adding NOP phi() at start of @end Adding NOP phi() at start of main CALL GRAPH Calls in [] to main:2 -Calls in [main] to plus:9 +Calls in [main] to plus:10 Created 1 initial phi equivalence classes -Coalesced [17] main::a#3 ← main::a#1 +Coalesced [18] main::a#3 ← main::a#1 Coalesced down to 1 phi equivalence classes Culled Empty Block (label) @3 Culled Empty Block (label) main::@3 @@ -192,28 +195,29 @@ main: scope:[main] from @1 main::@1: scope:[main] from main main::@1 [5] (byte) main::a#2 ← phi( main/(byte) 0 main::@1/(byte) main::a#1 ) [6] (byte) main::v#0 ← (byte) main::a#2 + (byte) 1 - [7] callprepare plus (byte) '0' (byte) main::v#0 - [8] callexecute plus + [7] stackpush(byte) ← (byte) '0' + [8] stackpush(byte) ← (byte) main::v#0 + [9] callexecute plus sideeffect stackpullbytes((number) 1) - [10] (byte) main::w#0 ← stackpull(byte) - [11] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 - [12] *((const byte*) SCREEN) ← (byte~) main::$2 - [13] (byte) main::a#1 ← ++ (byte) main::a#2 - [14] if((byte) main::a#1!=(byte) 2) goto main::@1 + [11] (byte) main::w#0 ← stackpull(byte) + [12] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 + [13] *((const byte*) SCREEN) ← (byte~) main::$2 + [14] (byte) main::a#1 ← ++ (byte) main::a#2 + [15] if((byte) main::a#1!=(byte) 2) goto main::@1 to:main::@return main::@return: scope:[main] from main::@1 - [15] return + [16] return to:@return __stackcall (byte()) plus((byte) plus::a , (byte) plus::b) plus: scope:[plus] from - [16] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) - [17] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) - [18] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 + [17] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) + [18] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) + [19] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 to:plus::@return plus::@return: scope:[plus] from plus - [19] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 - [20] return + [20] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 + [21] return to:@return @@ -223,7 +227,7 @@ VARIABLE REGISTER WEIGHTS (byte~) main::$2 22.0 (byte) main::a (byte) main::a#1 16.5 -(byte) main::a#2 5.5 +(byte) main::a#2 4.888888888888889 (byte) main::v (byte) main::v#0 11.0 (byte) main::w @@ -310,37 +314,37 @@ main: { ldy.z a iny sty.z v - // [7] callprepare plus (byte) '0' (byte) main::v#0 [(byte) plus::a#0] -- _stackpushbyte_=vbuc1 + // [7] stackpush(byte) ← (byte) '0' -- _stackpushbyte_=vbuc1 lda #'0' pha - // [7] callprepare plus (byte) '0' (byte) main::v#0 [(byte) plus::b#1] -- _stackpushbyte_=vbuz1 + // [8] stackpush(byte) ← (byte) main::v#0 -- _stackpushbyte_=vbuz1 lda.z v pha - // [8] callexecute plus -- jsr + // [9] callexecute plus -- jsr jsr plus // sideeffect stackpullbytes((number) 1) -- _stackpullbyte_1 pla - // [10] (byte) main::w#0 ← stackpull(byte) -- vbuz1=_stackpullbyte_ + // [11] (byte) main::w#0 ← stackpull(byte) -- vbuz1=_stackpullbyte_ pla sta.z w - // [11] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 -- vbuz1=vbuz2_plus_vbuz3 + // [12] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 -- vbuz1=vbuz2_plus_vbuz3 lda.z w clc adc.z a sta.z __2 - // [12] *((const byte*) SCREEN) ← (byte~) main::$2 -- _deref_pbuc1=vbuz1 + // [13] *((const byte*) SCREEN) ← (byte~) main::$2 -- _deref_pbuc1=vbuz1 lda.z __2 sta SCREEN - // [13] (byte) main::a#1 ← ++ (byte) main::a#2 -- vbuz1=_inc_vbuz1 + // [14] (byte) main::a#1 ← ++ (byte) main::a#2 -- vbuz1=_inc_vbuz1 inc.z a - // [14] if((byte) main::a#1!=(byte) 2) goto main::@1 -- vbuz1_neq_vbuc1_then_la1 + // [15] if((byte) main::a#1!=(byte) 2) goto main::@1 -- vbuz1_neq_vbuc1_then_la1 lda #2 cmp.z a bne __b1_from___b1 jmp __breturn // main::@return __breturn: - // [15] return + // [16] return rts } // plus @@ -352,15 +356,15 @@ plus: { .label a = 6 .label b = 7 .label return = 8 - // [16] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 + // [17] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_A,x sta.z a - // [17] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuz1=_stackidxbyte_vbuc1 + // [18] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuz1=_stackidxbyte_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_B,x sta.z b - // [18] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuz1=vbuz2_plus_vbuz3 + // [19] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuz1=vbuz2_plus_vbuz3 lda.z a clc adc.z b @@ -368,38 +372,41 @@ plus: { jmp __breturn // plus::@return __breturn: - // [19] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuz1 + // [20] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuz1 lda.z return tsx sta STACK_BASE+OFFSET_STACK_RETURN,x - // [20] return + // [21] return rts } // File Data REGISTER UPLIFT POTENTIAL REGISTERS -Statement [7] callprepare plus (byte) '0' (byte) main::v#0 [ main::a#2 ] ( main:2 [ main::a#2 ] ) always clobbers reg byte a +Statement [7] stackpush(byte) ← (byte) '0' [ main::a#2 main::v#0 ] ( main:2 [ main::a#2 main::v#0 ] ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::a#2 main::a#1 ] +Removing always clobbered register reg byte a as potential for zp[1]:3 [ main::v#0 ] +Statement [8] stackpush(byte) ← (byte) main::v#0 [ main::a#2 ] ( main:2 [ main::a#2 ] ) always clobbers reg byte a Statement sideeffect stackpullbytes((number) 1) always clobbers reg byte a -Statement [10] (byte) main::w#0 ← stackpull(byte) [ main::a#2 main::w#0 ] ( main:2 [ main::a#2 main::w#0 ] ) always clobbers reg byte a -Statement [11] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 [ main::a#2 main::$2 ] ( main:2 [ main::a#2 main::$2 ] ) always clobbers reg byte a -Statement [16] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:8 [ main::a#2 plus::a#0 ] ) always clobbers reg byte a reg byte x +Statement [11] (byte) main::w#0 ← stackpull(byte) [ main::a#2 main::w#0 ] ( main:2 [ main::a#2 main::w#0 ] ) always clobbers reg byte a +Statement [12] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 [ main::a#2 main::$2 ] ( main:2 [ main::a#2 main::$2 ] ) always clobbers reg byte a +Statement [17] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:9 [ main::a#2 plus::a#0 ] ) always clobbers reg byte a reg byte x Removing always clobbered register reg byte x as potential for zp[1]:2 [ main::a#2 main::a#1 ] -Statement [17] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:8 [ main::a#2 plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x +Statement [18] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:9 [ main::a#2 plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x Removing always clobbered register reg byte a as potential for zp[1]:6 [ plus::a#0 ] Removing always clobbered register reg byte x as potential for zp[1]:6 [ plus::a#0 ] -Statement [18] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ plus::return#0 ] ( main:2::plus:8 [ main::a#2 plus::return#0 ] ) always clobbers reg byte a -Statement [19] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 [ ] ( main:2::plus:8 [ main::a#2 ] ) always clobbers reg byte x -Statement [7] callprepare plus (byte) '0' (byte) main::v#0 [ main::a#2 ] ( main:2 [ main::a#2 ] ) always clobbers reg byte a +Statement [19] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ plus::return#0 ] ( main:2::plus:9 [ main::a#2 plus::return#0 ] ) always clobbers reg byte a +Statement [20] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 [ ] ( main:2::plus:9 [ main::a#2 ] ) always clobbers reg byte x +Statement [7] stackpush(byte) ← (byte) '0' [ main::a#2 main::v#0 ] ( main:2 [ main::a#2 main::v#0 ] ) always clobbers reg byte a +Statement [8] stackpush(byte) ← (byte) main::v#0 [ main::a#2 ] ( main:2 [ main::a#2 ] ) always clobbers reg byte a Statement sideeffect stackpullbytes((number) 1) always clobbers reg byte a -Statement [10] (byte) main::w#0 ← stackpull(byte) [ main::a#2 main::w#0 ] ( main:2 [ main::a#2 main::w#0 ] ) always clobbers reg byte a -Statement [11] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 [ main::a#2 main::$2 ] ( main:2 [ main::a#2 main::$2 ] ) always clobbers reg byte a -Statement [16] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:8 [ main::a#2 plus::a#0 ] ) always clobbers reg byte a reg byte x -Statement [17] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:8 [ main::a#2 plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x -Statement [18] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ plus::return#0 ] ( main:2::plus:8 [ main::a#2 plus::return#0 ] ) always clobbers reg byte a -Statement [19] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 [ ] ( main:2::plus:8 [ main::a#2 ] ) always clobbers reg byte x +Statement [11] (byte) main::w#0 ← stackpull(byte) [ main::a#2 main::w#0 ] ( main:2 [ main::a#2 main::w#0 ] ) always clobbers reg byte a +Statement [12] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 [ main::a#2 main::$2 ] ( main:2 [ main::a#2 main::$2 ] ) always clobbers reg byte a +Statement [17] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:9 [ main::a#2 plus::a#0 ] ) always clobbers reg byte a reg byte x +Statement [18] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:9 [ main::a#2 plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x +Statement [19] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ plus::return#0 ] ( main:2::plus:9 [ main::a#2 plus::return#0 ] ) always clobbers reg byte a +Statement [20] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 [ ] ( main:2::plus:9 [ main::a#2 ] ) always clobbers reg byte x Potential registers zp[1]:2 [ main::a#2 main::a#1 ] : zp[1]:2 , reg byte y , -Potential registers zp[1]:3 [ main::v#0 ] : zp[1]:3 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:3 [ main::v#0 ] : zp[1]:3 , reg byte x , reg byte y , Potential registers zp[1]:4 [ main::w#0 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y , Potential registers zp[1]:5 [ main::$2 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y , Potential registers zp[1]:6 [ plus::a#0 ] : zp[1]:6 , reg byte y , @@ -407,12 +414,11 @@ Potential registers zp[1]:7 [ plus::b#0 ] : zp[1]:7 , reg byte a , reg byte x , Potential registers zp[1]:8 [ plus::return#0 ] : zp[1]:8 , reg byte a , reg byte x , reg byte y , REGISTER UPLIFT SCOPES -Uplift Scope [main] 22: zp[1]:2 [ main::a#2 main::a#1 ] 22: zp[1]:4 [ main::w#0 ] 22: zp[1]:5 [ main::$2 ] 11: zp[1]:3 [ main::v#0 ] +Uplift Scope [main] 22: zp[1]:4 [ main::w#0 ] 22: zp[1]:5 [ main::$2 ] 21.39: zp[1]:2 [ main::a#2 main::a#1 ] 11: zp[1]:3 [ main::v#0 ] Uplift Scope [plus] 4: zp[1]:7 [ plus::b#0 ] 4: zp[1]:8 [ plus::return#0 ] 2: zp[1]:6 [ plus::a#0 ] Uplift Scope [] -Uplifting [main] best 661 combination reg byte y [ main::a#2 main::a#1 ] reg byte a [ main::w#0 ] reg byte a [ main::$2 ] reg byte x [ main::v#0 ] -Limited combination testing to 100 combinations of 128 possible. +Uplifting [main] best 661 combination reg byte a [ main::w#0 ] reg byte a [ main::$2 ] reg byte y [ main::a#2 main::a#1 ] reg byte x [ main::v#0 ] Uplifting [plus] best 649 combination reg byte a [ plus::b#0 ] reg byte a [ plus::return#0 ] zp[1]:6 [ plus::a#0 ] Uplifting [] best 649 combination Attempting to uplift remaining variables inzp[1]:6 [ plus::a#0 ] @@ -463,33 +469,33 @@ main: { tya tax inx - // [7] callprepare plus (byte) '0' (byte) main::v#0 [(byte) plus::a#0] -- _stackpushbyte_=vbuc1 + // [7] stackpush(byte) ← (byte) '0' -- _stackpushbyte_=vbuc1 lda #'0' pha - // [7] callprepare plus (byte) '0' (byte) main::v#0 [(byte) plus::b#1] -- _stackpushbyte_=vbuxx + // [8] stackpush(byte) ← (byte) main::v#0 -- _stackpushbyte_=vbuxx txa pha - // [8] callexecute plus -- jsr + // [9] callexecute plus -- jsr jsr plus // sideeffect stackpullbytes((number) 1) -- _stackpullbyte_1 pla - // [10] (byte) main::w#0 ← stackpull(byte) -- vbuaa=_stackpullbyte_ + // [11] (byte) main::w#0 ← stackpull(byte) -- vbuaa=_stackpullbyte_ pla - // [11] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 -- vbuaa=vbuaa_plus_vbuyy + // [12] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 -- vbuaa=vbuaa_plus_vbuyy sty.z $ff clc adc.z $ff - // [12] *((const byte*) SCREEN) ← (byte~) main::$2 -- _deref_pbuc1=vbuaa + // [13] *((const byte*) SCREEN) ← (byte~) main::$2 -- _deref_pbuc1=vbuaa sta SCREEN - // [13] (byte) main::a#1 ← ++ (byte) main::a#2 -- vbuyy=_inc_vbuyy + // [14] (byte) main::a#1 ← ++ (byte) main::a#2 -- vbuyy=_inc_vbuyy iny - // [14] if((byte) main::a#1!=(byte) 2) goto main::@1 -- vbuyy_neq_vbuc1_then_la1 + // [15] if((byte) main::a#1!=(byte) 2) goto main::@1 -- vbuyy_neq_vbuc1_then_la1 cpy #2 bne __b1_from___b1 jmp __breturn // main::@return __breturn: - // [15] return + // [16] return rts } // plus @@ -499,23 +505,23 @@ plus: { .const OFFSET_STACK_B = 0 .const OFFSET_STACK_RETURN = 1 .label a = 2 - // [16] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 + // [17] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_A,x sta.z a - // [17] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1 + // [18] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_B,x - // [18] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa + // [19] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa clc adc.z a jmp __breturn // plus::@return __breturn: - // [19] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa + // [20] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa tsx sta STACK_BASE+OFFSET_STACK_RETURN,x - // [20] return + // [21] return rts } // File Data @@ -560,7 +566,7 @@ FINAL SYMBOL TABLE (label) main::@return (byte) main::a (byte) main::a#1 reg byte y 16.5 -(byte) main::a#2 reg byte y 5.5 +(byte) main::a#2 reg byte y 4.888888888888889 (byte) main::v (byte) main::v#0 reg byte x 11.0 (byte) main::w @@ -621,36 +627,36 @@ main: { tax inx // plus('0', v) - // [7] callprepare plus (byte) '0' (byte) main::v#0 [(byte) plus::a#0] -- _stackpushbyte_=vbuc1 + // [7] stackpush(byte) ← (byte) '0' -- _stackpushbyte_=vbuc1 lda #'0' pha - // [7] callprepare plus (byte) '0' (byte) main::v#0 [(byte) plus::b#1] -- _stackpushbyte_=vbuxx + // [8] stackpush(byte) ← (byte) main::v#0 -- _stackpushbyte_=vbuxx txa pha - // [8] callexecute plus -- jsr + // [9] callexecute plus -- jsr jsr plus // sideeffect stackpullbytes((number) 1) -- _stackpullbyte_1 pla // w = plus('0', v) - // [10] (byte) main::w#0 ← stackpull(byte) -- vbuaa=_stackpullbyte_ + // [11] (byte) main::w#0 ← stackpull(byte) -- vbuaa=_stackpullbyte_ pla // w+a - // [11] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 -- vbuaa=vbuaa_plus_vbuyy + // [12] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 -- vbuaa=vbuaa_plus_vbuyy sty.z $ff clc adc.z $ff // SCREEN[i] = w+a - // [12] *((const byte*) SCREEN) ← (byte~) main::$2 -- _deref_pbuc1=vbuaa + // [13] *((const byte*) SCREEN) ← (byte~) main::$2 -- _deref_pbuc1=vbuaa sta SCREEN // for(char a:0..1) - // [13] (byte) main::a#1 ← ++ (byte) main::a#2 -- vbuyy=_inc_vbuyy + // [14] (byte) main::a#1 ← ++ (byte) main::a#2 -- vbuyy=_inc_vbuyy iny - // [14] if((byte) main::a#1!=(byte) 2) goto main::@1 -- vbuyy_neq_vbuc1_then_la1 + // [15] if((byte) main::a#1!=(byte) 2) goto main::@1 -- vbuyy_neq_vbuc1_then_la1 cpy #2 bne __b1 // main::@return // } - // [15] return + // [16] return rts } // plus @@ -660,23 +666,23 @@ plus: { .const OFFSET_STACK_B = 0 .const OFFSET_STACK_RETURN = 1 .label a = 2 - // [16] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 + // [17] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_A,x sta.z a - // [17] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1 + // [18] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1 tsx lda STACK_BASE+OFFSET_STACK_B,x // return a+b; - // [18] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa + // [19] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa clc adc.z a // plus::@return // } - // [19] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa + // [20] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa tsx sta STACK_BASE+OFFSET_STACK_RETURN,x - // [20] return + // [21] return rts } // File Data diff --git a/src/test/ref/procedure-callingconvention-stack-4.sym b/src/test/ref/procedure-callingconvention-stack-4.sym index ad8773595..157f2011b 100644 --- a/src/test/ref/procedure-callingconvention-stack-4.sym +++ b/src/test/ref/procedure-callingconvention-stack-4.sym @@ -10,7 +10,7 @@ (label) main::@return (byte) main::a (byte) main::a#1 reg byte y 16.5 -(byte) main::a#2 reg byte y 5.5 +(byte) main::a#2 reg byte y 4.888888888888889 (byte) main::v (byte) main::v#0 reg byte x 11.0 (byte) main::w diff --git a/src/test/ref/procedure-callingconvention-stack-5.cfg b/src/test/ref/procedure-callingconvention-stack-5.cfg index 82676c346..e7127030e 100644 --- a/src/test/ref/procedure-callingconvention-stack-5.cfg +++ b/src/test/ref/procedure-callingconvention-stack-5.cfg @@ -10,11 +10,11 @@ (void()) main() main: scope:[main] from @1 - [4] callprepare next + sideeffect stackpushbytes((number) 2) [5] callexecute next [6] (signed word~) main::$0 ← stackpull(signed word) [7] *((const signed word*) SCREEN) ← (signed word~) main::$0 - [8] callprepare next + sideeffect stackpushbytes((number) 2) [9] callexecute next [10] (signed word~) main::$1 ← stackpull(signed word) [11] *((const signed word*) SCREEN+(byte) 1*(const byte) SIZEOF_SIGNED_WORD) ← (signed word~) main::$1 diff --git a/src/test/ref/procedure-callingconvention-stack-5.log b/src/test/ref/procedure-callingconvention-stack-5.log index 1f3e590a2..d4abab2a3 100644 --- a/src/test/ref/procedure-callingconvention-stack-5.log +++ b/src/test/ref/procedure-callingconvention-stack-5.log @@ -14,12 +14,12 @@ CONTROL FLOW GRAPH SSA (void()) main() main: scope:[main] from @2 (signed word) current#7 ← phi( @2/(signed word) current#8 ) - callprepare next + sideeffect stackpushbytes((number) 2) callexecute next (signed word~) main::$0 ← stackpull(signed word) (number~) main::$2 ← (number) 0 * (const byte) SIZEOF_SIGNED_WORD *((const signed word*) SCREEN + (number~) main::$2) ← (signed word~) main::$0 - callprepare next + sideeffect stackpushbytes((number) 2) callexecute next (signed word~) main::$1 ← stackpull(signed word) (number~) main::$3 ← (number) 1 * (const byte) SIZEOF_SIGNED_WORD @@ -159,11 +159,11 @@ FINAL CONTROL FLOW GRAPH (void()) main() main: scope:[main] from @1 - [4] callprepare next + sideeffect stackpushbytes((number) 2) [5] callexecute next [6] (signed word~) main::$0 ← stackpull(signed word) [7] *((const signed word*) SCREEN) ← (signed word~) main::$0 - [8] callprepare next + sideeffect stackpushbytes((number) 2) [9] callexecute next [10] (signed word~) main::$1 ← stackpull(signed word) [11] *((const signed word*) SCREEN+(byte) 1*(const byte) SIZEOF_SIGNED_WORD) ← (signed word~) main::$1 @@ -240,7 +240,7 @@ __bend: main: { .label __0 = 4 .label __1 = 6 - // [4] callprepare next -- _stackpushbyte_2 + // sideeffect stackpushbytes((number) 2) -- _stackpushbyte_2 pha pha // [5] callexecute next -- jsr @@ -255,7 +255,7 @@ main: { sta SCREEN lda.z __0+1 sta SCREEN+1 - // [8] callprepare next -- _stackpushbyte_2 + // sideeffect stackpushbytes((number) 2) -- _stackpushbyte_2 pha pha // [9] callexecute next -- jsr @@ -355,7 +355,7 @@ __bend: main: { .label __0 = 2 .label __1 = 4 - // [4] callprepare next -- _stackpushbyte_2 + // sideeffect stackpushbytes((number) 2) -- _stackpushbyte_2 pha pha // [5] callexecute next -- jsr @@ -370,7 +370,7 @@ main: { sta SCREEN lda.z __0+1 sta SCREEN+1 - // [8] callprepare next -- _stackpushbyte_2 + // sideeffect stackpushbytes((number) 2) -- _stackpushbyte_2 pha pha // [9] callexecute next -- jsr @@ -479,7 +479,7 @@ main: { .label __0 = 2 .label __1 = 4 // next() - // [4] callprepare next -- _stackpushbyte_2 + // sideeffect stackpushbytes((number) 2) -- _stackpushbyte_2 pha pha // [5] callexecute next -- jsr @@ -496,7 +496,7 @@ main: { lda.z __0+1 sta SCREEN+1 // next() - // [8] callprepare next -- _stackpushbyte_2 + // sideeffect stackpushbytes((number) 2) -- _stackpushbyte_2 pha pha // [9] callexecute next -- jsr diff --git a/src/test/ref/procedure-callingconvention-stack-7.asm b/src/test/ref/procedure-callingconvention-stack-7.asm index 88e261da7..6ced63854 100644 --- a/src/test/ref/procedure-callingconvention-stack-7.asm +++ b/src/test/ref/procedure-callingconvention-stack-7.asm @@ -1,12 +1,9 @@ // Test a procedure with calling convention stack // Illustrates live ranges for main::val and printline::i .pc = $801 "Basic" -:BasicUpstart(__bbegin) +:BasicUpstart(main) .pc = $80d "Program" .label SCREEN = $400 -__bbegin: - jsr main - rts printline: { .label i = 2 // i=0 diff --git a/src/test/ref/procedure-callingconvention-stack-7.cfg b/src/test/ref/procedure-callingconvention-stack-7.cfg index cb5adafe9..71ee443b2 100644 --- a/src/test/ref/procedure-callingconvention-stack-7.cfg +++ b/src/test/ref/procedure-callingconvention-stack-7.cfg @@ -2,7 +2,7 @@ [0] phi() to:@1 @1: scope:[] from @begin - [1] callprepare main + [1] phi() [2] callexecute main to:@end @end: scope:[] from @1 @@ -27,10 +27,9 @@ __stackcall (void()) main() main: scope:[main] from [9] (byte) main::val ← (byte) 0 [10] (byte) main::val ← *((const byte*) SCREEN) - [11] callprepare printline - [12] callexecute printline - [13] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val + [11] callexecute printline + [12] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val to:main::@return main::@return: scope:[main] from main - [14] return + [13] return to:@return diff --git a/src/test/ref/procedure-callingconvention-stack-7.log b/src/test/ref/procedure-callingconvention-stack-7.log index acf5803e7..85fde0357 100644 --- a/src/test/ref/procedure-callingconvention-stack-7.log +++ b/src/test/ref/procedure-callingconvention-stack-7.log @@ -14,7 +14,6 @@ __stackcall (void()) main() main: scope:[main] from (byte) main::val ← (byte) 0 (byte) main::val ← *((const byte*) SCREEN) - callprepare printline callexecute printline *((const byte*) SCREEN + (number) $50) ← (byte) main::val to:main::@return @@ -38,7 +37,6 @@ printline::@return: scope:[printline] from printline::@1 return to:@return @2: scope:[] from @begin - callprepare main callexecute main to:@end @end: scope:[] from @2 @@ -68,20 +66,22 @@ Successful SSA optimization PassNCastSimplification Finalized unsigned number type (byte) $50 Finalized unsigned number type (byte) $28 Successful SSA optimization PassNFinalizeNumberTypeConversions -Simple Condition (bool~) printline::$0 [8] if((byte) printline::i<(byte) $28) goto printline::@2 +Simple Condition (bool~) printline::$0 [7] if((byte) printline::i<(byte) $28) goto printline::@2 Successful SSA optimization Pass2ConditionalJumpSimplification Consolidated array index constant in *(SCREEN+$50) Successful SSA optimization Pass2ConstantAdditionElimination Adding NOP phi() at start of @begin +Adding NOP phi() at start of @2 Adding NOP phi() at start of @end CALL GRAPH Calls in [] to main:2 -Calls in [main] to printline:12 +Calls in [main] to printline:11 Created 0 initial phi equivalence classes Coalesced down to 0 phi equivalence classes Renumbering block @2 to @1 Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 Adding NOP phi() at start of @end FINAL CONTROL FLOW GRAPH @@ -89,7 +89,7 @@ FINAL CONTROL FLOW GRAPH [0] phi() to:@1 @1: scope:[] from @begin - [1] callprepare main + [1] phi() [2] callexecute main to:@end @end: scope:[] from @1 @@ -114,18 +114,17 @@ __stackcall (void()) main() main: scope:[main] from [9] (byte) main::val ← (byte) 0 [10] (byte) main::val ← *((const byte*) SCREEN) - [11] callprepare printline - [12] callexecute printline - [13] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val + [11] callexecute printline + [12] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val to:main::@return main::@return: scope:[main] from main - [14] return + [13] return to:@return VARIABLE REGISTER WEIGHTS __stackcall (void()) main() -(byte) main::val loadstore 2.0 +(byte) main::val loadstore 3.0 __stackcall (void()) printline() (byte) printline::i loadstore 11.5 @@ -151,10 +150,11 @@ Target platform is c64basic / MOS6502X .label SCREEN = $400 // @begin __bbegin: + // [1] phi from @begin to @1 [phi:@begin->@1] +__b1_from___bbegin: jmp __b1 // @1 __b1: - // [1] callprepare main // [2] callexecute main -- jsr jsr main // [3] phi from @1 to @end [phi:@1->@end] @@ -199,42 +199,41 @@ main: { // [10] (byte) main::val ← *((const byte*) SCREEN) -- vbuz1=_deref_pbuc1 lda SCREEN sta.z val - // [11] callprepare printline - // [12] callexecute printline -- jsr + // [11] callexecute printline -- jsr jsr printline - // [13] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val -- _deref_pbuc1=vbuz1 + // [12] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val -- _deref_pbuc1=vbuz1 lda.z val sta SCREEN+$50 jmp __breturn // main::@return __breturn: - // [14] return + // [13] return rts } // File Data REGISTER UPLIFT POTENTIAL REGISTERS -Statement [4] (byte) printline::i ← (byte) 0 [ printline::i ] ( main:2::printline:12 [ main::val printline::i ] ) always clobbers reg byte a -Statement [5] if((byte) printline::i<(byte) $28) goto printline::@2 [ printline::i ] ( main:2::printline:12 [ main::val printline::i ] ) always clobbers reg byte a -Statement [7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' [ printline::i ] ( main:2::printline:12 [ main::val printline::i ] ) always clobbers reg byte a reg byte y +Statement [4] (byte) printline::i ← (byte) 0 [ printline::i ] ( main:2::printline:11 [ main::val printline::i ] ) always clobbers reg byte a +Statement [5] if((byte) printline::i<(byte) $28) goto printline::@2 [ printline::i ] ( main:2::printline:11 [ main::val printline::i ] ) always clobbers reg byte a +Statement [7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' [ printline::i ] ( main:2::printline:11 [ main::val printline::i ] ) always clobbers reg byte a reg byte y Statement [9] (byte) main::val ← (byte) 0 [ ] ( main:2 [ ] ) always clobbers reg byte a Statement [10] (byte) main::val ← *((const byte*) SCREEN) [ main::val ] ( main:2 [ main::val ] ) always clobbers reg byte a -Statement [13] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [12] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val [ ] ( main:2 [ ] ) always clobbers reg byte a Potential registers zp[1]:2 [ printline::i ] : zp[1]:2 , Potential registers zp[1]:3 [ main::val ] : zp[1]:3 , REGISTER UPLIFT SCOPES Uplift Scope [printline] 11.5: zp[1]:2 [ printline::i ] -Uplift Scope [main] 2: zp[1]:3 [ main::val ] +Uplift Scope [main] 3: zp[1]:3 [ main::val ] Uplift Scope [] -Uplifting [printline] best 372 combination zp[1]:2 [ printline::i ] -Uplifting [main] best 372 combination zp[1]:3 [ main::val ] -Uplifting [] best 372 combination +Uplifting [printline] best 345 combination zp[1]:2 [ printline::i ] +Uplifting [main] best 345 combination zp[1]:3 [ main::val ] +Uplifting [] best 345 combination Attempting to uplift remaining variables inzp[1]:2 [ printline::i ] -Uplifting [printline] best 372 combination zp[1]:2 [ printline::i ] +Uplifting [printline] best 345 combination zp[1]:2 [ printline::i ] Attempting to uplift remaining variables inzp[1]:3 [ main::val ] -Uplifting [main] best 372 combination zp[1]:3 [ main::val ] +Uplifting [main] best 345 combination zp[1]:3 [ main::val ] ASSEMBLER BEFORE OPTIMIZATION // File Comments @@ -248,10 +247,11 @@ ASSEMBLER BEFORE OPTIMIZATION .label SCREEN = $400 // @begin __bbegin: + // [1] phi from @begin to @1 [phi:@begin->@1] +__b1_from___bbegin: jmp __b1 // @1 __b1: - // [1] callprepare main // [2] callexecute main -- jsr jsr main // [3] phi from @1 to @end [phi:@1->@end] @@ -296,16 +296,15 @@ main: { // [10] (byte) main::val ← *((const byte*) SCREEN) -- vbuz1=_deref_pbuc1 lda SCREEN sta.z val - // [11] callprepare printline - // [12] callexecute printline -- jsr + // [11] callexecute printline -- jsr jsr printline - // [13] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val -- _deref_pbuc1=vbuz1 + // [12] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val -- _deref_pbuc1=vbuz1 lda.z val sta SCREEN+$50 jmp __breturn // main::@return __breturn: - // [14] return + // [13] return rts } // File Data @@ -317,6 +316,7 @@ Removing instruction jmp __b1 Removing instruction jmp __breturn Removing instruction jmp __breturn Succesful ASM optimization Pass5NextJumpElimination +Removing instruction __b1_from___bbegin: Removing instruction __b1: Removing instruction __bend_from___b1: Succesful ASM optimization Pass5RedundantLabelElimination @@ -324,8 +324,11 @@ Removing instruction __bend: Removing instruction __breturn: Removing instruction __breturn: Succesful ASM optimization Pass5UnusedLabelElimination -Adding RTS to root block -Succesful ASM optimization Pass5AddMainRts +Updating BasicUpstart to call main directly +Removing instruction jsr main +Succesful ASM optimization Pass5SkipBegin +Removing instruction __bbegin: +Succesful ASM optimization Pass5UnusedLabelElimination FINAL SYMBOL TABLE (label) @1 @@ -334,7 +337,7 @@ FINAL SYMBOL TABLE (const byte*) SCREEN = (byte*) 1024 __stackcall (void()) main() (label) main::@return -(byte) main::val loadstore zp[1]:3 2.0 +(byte) main::val loadstore zp[1]:3 3.0 __stackcall (void()) printline() (label) printline::@1 (label) printline::@2 @@ -346,24 +349,21 @@ zp[1]:3 [ main::val ] FINAL ASSEMBLER -Score: 309 +Score: 297 // File Comments // Test a procedure with calling convention stack // Illustrates live ranges for main::val and printline::i // Upstart .pc = $801 "Basic" -:BasicUpstart(__bbegin) +:BasicUpstart(main) .pc = $80d "Program" // Global Constants & labels .label SCREEN = $400 // @begin -__bbegin: + // [1] phi from @begin to @1 [phi:@begin->@1] // @1 - // [1] callprepare main // [2] callexecute main -- jsr - jsr main - rts // [3] phi from @1 to @end [phi:@1->@end] // @end // printline @@ -408,16 +408,15 @@ main: { lda SCREEN sta.z val // printline() - // [11] callprepare printline - // [12] callexecute printline -- jsr + // [11] callexecute printline -- jsr jsr printline // SCREEN[80] = val - // [13] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val -- _deref_pbuc1=vbuz1 + // [12] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val -- _deref_pbuc1=vbuz1 lda.z val sta SCREEN+$50 // main::@return // } - // [14] return + // [13] return rts } // File Data diff --git a/src/test/ref/procedure-callingconvention-stack-7.sym b/src/test/ref/procedure-callingconvention-stack-7.sym index 46fa4aa36..498bea49a 100644 --- a/src/test/ref/procedure-callingconvention-stack-7.sym +++ b/src/test/ref/procedure-callingconvention-stack-7.sym @@ -4,7 +4,7 @@ (const byte*) SCREEN = (byte*) 1024 __stackcall (void()) main() (label) main::@return -(byte) main::val loadstore zp[1]:3 2.0 +(byte) main::val loadstore zp[1]:3 3.0 __stackcall (void()) printline() (label) printline::@1 (label) printline::@2 diff --git a/src/test/ref/procedure-callingconvention-stack-8.cfg b/src/test/ref/procedure-callingconvention-stack-8.cfg index 86ae4a1fd..f192268d5 100644 --- a/src/test/ref/procedure-callingconvention-stack-8.cfg +++ b/src/test/ref/procedure-callingconvention-stack-8.cfg @@ -2,7 +2,7 @@ [0] (byte) val ← (byte) 0 to:@1 @1: scope:[] from @begin - [1] callprepare main + [1] phi() [2] callexecute main to:@end @end: scope:[] from @1 @@ -26,10 +26,9 @@ printline::@2: scope:[printline] from printline::@1 __stackcall (void()) main() main: scope:[main] from [9] (byte) val ← (byte) '-' - [10] callprepare printline - [11] callexecute printline - [12] *((const byte*) SCREEN+(byte) $50) ← (byte) val + [10] callexecute printline + [11] *((const byte*) SCREEN+(byte) $50) ← (byte) val to:main::@return main::@return: scope:[main] from main - [13] return + [12] return to:@return diff --git a/src/test/ref/procedure-callingconvention-stack-8.log b/src/test/ref/procedure-callingconvention-stack-8.log index 16c70eecf..a3ca7bfed 100644 --- a/src/test/ref/procedure-callingconvention-stack-8.log +++ b/src/test/ref/procedure-callingconvention-stack-8.log @@ -14,7 +14,6 @@ CONTROL FLOW GRAPH SSA __stackcall (void()) main() main: scope:[main] from (byte) val ← (byte) '-' - callprepare printline callexecute printline *((const byte*) SCREEN + (number) $50) ← (byte) val to:main::@return @@ -38,7 +37,6 @@ printline::@return: scope:[printline] from printline::@1 return to:@return @2: scope:[] from @begin - callprepare main callexecute main to:@end @end: scope:[] from @2 @@ -68,18 +66,20 @@ Successful SSA optimization PassNCastSimplification Finalized unsigned number type (byte) $50 Finalized unsigned number type (byte) $28 Successful SSA optimization PassNFinalizeNumberTypeConversions -Simple Condition (bool~) printline::$0 [8] if((byte) printline::i<(byte) $28) goto printline::@2 +Simple Condition (bool~) printline::$0 [7] if((byte) printline::i<(byte) $28) goto printline::@2 Successful SSA optimization Pass2ConditionalJumpSimplification Consolidated array index constant in *(SCREEN+$50) Successful SSA optimization Pass2ConstantAdditionElimination +Adding NOP phi() at start of @2 Adding NOP phi() at start of @end CALL GRAPH Calls in [] to main:2 -Calls in [main] to printline:11 +Calls in [main] to printline:10 Created 0 initial phi equivalence classes Coalesced down to 0 phi equivalence classes Renumbering block @2 to @1 +Adding NOP phi() at start of @1 Adding NOP phi() at start of @end FINAL CONTROL FLOW GRAPH @@ -87,7 +87,7 @@ FINAL CONTROL FLOW GRAPH [0] (byte) val ← (byte) 0 to:@1 @1: scope:[] from @begin - [1] callprepare main + [1] phi() [2] callexecute main to:@end @end: scope:[] from @1 @@ -111,12 +111,11 @@ printline::@2: scope:[printline] from printline::@1 __stackcall (void()) main() main: scope:[main] from [9] (byte) val ← (byte) '-' - [10] callprepare printline - [11] callexecute printline - [12] *((const byte*) SCREEN+(byte) $50) ← (byte) val + [10] callexecute printline + [11] *((const byte*) SCREEN+(byte) $50) ← (byte) val to:main::@return main::@return: scope:[main] from main - [13] return + [12] return to:@return @@ -124,7 +123,7 @@ VARIABLE REGISTER WEIGHTS __stackcall (void()) main() __stackcall (void()) printline() (byte) printline::i loadstore 11.5 -(byte) val loadstore 2.0 +(byte) val loadstore 3.0 Initial phi equivalence classes Added variable val to live range equivalence class [ val ] @@ -152,10 +151,11 @@ __bbegin: // [0] (byte) val ← (byte) 0 -- vbuz1=vbuc1 lda #0 sta.z val + // [1] phi from @begin to @1 [phi:@begin->@1] +__b1_from___bbegin: jmp __b1 // @1 __b1: - // [1] callprepare main // [2] callexecute main -- jsr jsr main // [3] phi from @1 to @end [phi:@1->@end] @@ -196,33 +196,32 @@ main: { // [9] (byte) val ← (byte) '-' -- vbuz1=vbuc1 lda #'-' sta.z val - // [10] callprepare printline - // [11] callexecute printline -- jsr + // [10] callexecute printline -- jsr jsr printline - // [12] *((const byte*) SCREEN+(byte) $50) ← (byte) val -- _deref_pbuc1=vbuz1 + // [11] *((const byte*) SCREEN+(byte) $50) ← (byte) val -- _deref_pbuc1=vbuz1 lda.z val sta SCREEN+$50 jmp __breturn // main::@return __breturn: - // [13] return + // [12] return rts } // File Data REGISTER UPLIFT POTENTIAL REGISTERS Statement [0] (byte) val ← (byte) 0 [ ] ( [ ] ) always clobbers reg byte a -Statement [4] (byte) printline::i ← (byte) 0 [ printline::i ] ( main:2::printline:11 [ val printline::i ] ) always clobbers reg byte a -Statement [5] if((byte) printline::i<(byte) $28) goto printline::@2 [ printline::i ] ( main:2::printline:11 [ val printline::i ] ) always clobbers reg byte a -Statement [7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' [ printline::i ] ( main:2::printline:11 [ val printline::i ] ) always clobbers reg byte a reg byte y +Statement [4] (byte) printline::i ← (byte) 0 [ printline::i ] ( main:2::printline:10 [ val printline::i ] ) always clobbers reg byte a +Statement [5] if((byte) printline::i<(byte) $28) goto printline::@2 [ printline::i ] ( main:2::printline:10 [ val printline::i ] ) always clobbers reg byte a +Statement [7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' [ printline::i ] ( main:2::printline:10 [ val printline::i ] ) always clobbers reg byte a reg byte y Statement [9] (byte) val ← (byte) '-' [ val ] ( main:2 [ val ] ) always clobbers reg byte a -Statement [12] *((const byte*) SCREEN+(byte) $50) ← (byte) val [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [11] *((const byte*) SCREEN+(byte) $50) ← (byte) val [ ] ( main:2 [ ] ) always clobbers reg byte a Potential registers zp[1]:2 [ val ] : zp[1]:2 , Potential registers zp[1]:3 [ printline::i ] : zp[1]:3 , REGISTER UPLIFT SCOPES Uplift Scope [printline] 11.5: zp[1]:3 [ printline::i ] -Uplift Scope [] 2: zp[1]:2 [ val ] +Uplift Scope [] 3: zp[1]:2 [ val ] Uplift Scope [main] Uplifting [printline] best 343 combination zp[1]:3 [ printline::i ] @@ -249,10 +248,11 @@ __bbegin: // [0] (byte) val ← (byte) 0 -- vbuz1=vbuc1 lda #0 sta.z val + // [1] phi from @begin to @1 [phi:@begin->@1] +__b1_from___bbegin: jmp __b1 // @1 __b1: - // [1] callprepare main // [2] callexecute main -- jsr jsr main // [3] phi from @1 to @end [phi:@1->@end] @@ -293,16 +293,15 @@ main: { // [9] (byte) val ← (byte) '-' -- vbuz1=vbuc1 lda #'-' sta.z val - // [10] callprepare printline - // [11] callexecute printline -- jsr + // [10] callexecute printline -- jsr jsr printline - // [12] *((const byte*) SCREEN+(byte) $50) ← (byte) val -- _deref_pbuc1=vbuz1 + // [11] *((const byte*) SCREEN+(byte) $50) ← (byte) val -- _deref_pbuc1=vbuz1 lda.z val sta SCREEN+$50 jmp __breturn // main::@return __breturn: - // [13] return + // [12] return rts } // File Data @@ -314,6 +313,7 @@ Removing instruction jmp __b1 Removing instruction jmp __breturn Removing instruction jmp __breturn Succesful ASM optimization Pass5NextJumpElimination +Removing instruction __b1_from___bbegin: Removing instruction __bend_from___b1: Succesful ASM optimization Pass5RedundantLabelElimination Removing instruction __b1: @@ -336,7 +336,7 @@ __stackcall (void()) printline() (label) printline::@2 (label) printline::@return (byte) printline::i loadstore zp[1]:3 11.5 -(byte) val loadstore zp[1]:2 2.0 +(byte) val loadstore zp[1]:2 3.0 zp[1]:2 [ val ] zp[1]:3 [ printline::i ] @@ -361,8 +361,8 @@ __bbegin: // [0] (byte) val ← (byte) 0 -- vbuz1=vbuc1 lda #0 sta.z val + // [1] phi from @begin to @1 [phi:@begin->@1] // @1 - // [1] callprepare main // [2] callexecute main -- jsr jsr main rts @@ -405,16 +405,15 @@ main: { lda #'-' sta.z val // printline() - // [10] callprepare printline - // [11] callexecute printline -- jsr + // [10] callexecute printline -- jsr jsr printline // SCREEN[80] = val - // [12] *((const byte*) SCREEN+(byte) $50) ← (byte) val -- _deref_pbuc1=vbuz1 + // [11] *((const byte*) SCREEN+(byte) $50) ← (byte) val -- _deref_pbuc1=vbuz1 lda.z val sta SCREEN+$50 // main::@return // } - // [13] return + // [12] return rts } // File Data diff --git a/src/test/ref/procedure-callingconvention-stack-8.sym b/src/test/ref/procedure-callingconvention-stack-8.sym index bacdce28e..967207a07 100644 --- a/src/test/ref/procedure-callingconvention-stack-8.sym +++ b/src/test/ref/procedure-callingconvention-stack-8.sym @@ -9,7 +9,7 @@ __stackcall (void()) printline() (label) printline::@2 (label) printline::@return (byte) printline::i loadstore zp[1]:3 11.5 -(byte) val loadstore zp[1]:2 2.0 +(byte) val loadstore zp[1]:2 3.0 zp[1]:2 [ val ] zp[1]:3 [ printline::i ] diff --git a/src/test/ref/procedure-callingconvention-stack-9.cfg b/src/test/ref/procedure-callingconvention-stack-9.cfg index e66c13921..ea6c94b20 100644 --- a/src/test/ref/procedure-callingconvention-stack-9.cfg +++ b/src/test/ref/procedure-callingconvention-stack-9.cfg @@ -2,7 +2,7 @@ [0] (byte) val ← (byte) 0 to:@1 @1: scope:[] from @begin - [1] callprepare main + [1] phi() [2] callexecute main to:@end @end: scope:[] from @1 @@ -39,7 +39,7 @@ printval::@return: scope:[printval] from printval __stackcall (void()) ival() ival: scope:[ival] from - [13] callprepare incval + [13] phi() [14] callexecute incval to:ival::@return ival::@return: scope:[ival] from ival @@ -48,7 +48,7 @@ ival::@return: scope:[ival] from ival __stackcall (void()) pval() pval: scope:[pval] from - [16] callprepare printval + [16] phi() [17] callexecute printval to:pval::@return pval::@return: scope:[pval] from pval @@ -60,15 +60,13 @@ main: scope:[main] from [19] (byte) main::i ← (byte) 0 to:main::@1 main::@1: scope:[main] from main main::@1 - [20] callprepare pval + [20] phi() [21] callexecute pval - [22] callprepare printother - [23] callexecute printother - [24] callprepare ival - [25] callexecute ival - [26] (byte) main::i ← ++ (byte) main::i - [27] if((byte) main::i!=(byte) 6) goto main::@1 + [22] callexecute printother + [23] callexecute ival + [24] (byte) main::i ← ++ (byte) main::i + [25] if((byte) main::i!=(byte) 6) goto main::@1 to:main::@return main::@return: scope:[main] from main::@1 - [28] return + [26] return to:@return diff --git a/src/test/ref/procedure-callingconvention-stack-9.log b/src/test/ref/procedure-callingconvention-stack-9.log index 57ff1873b..29222644f 100644 --- a/src/test/ref/procedure-callingconvention-stack-9.log +++ b/src/test/ref/procedure-callingconvention-stack-9.log @@ -22,11 +22,8 @@ main: scope:[main] from (byte) main::i ← (byte) 0 to:main::@1 main::@1: scope:[main] from main main::@1 - callprepare pval callexecute pval - callprepare printother callexecute printother - callprepare ival callexecute ival (byte) main::i ← (byte) main::i + rangenext(0,5) (bool~) main::$3 ← (byte) main::i != rangelast(0,5) @@ -38,7 +35,6 @@ main::@return: scope:[main] from main::@1 __stackcall (void()) pval() pval: scope:[pval] from - callprepare printval callexecute printval to:pval::@return pval::@return: scope:[pval] from pval @@ -47,7 +43,6 @@ pval::@return: scope:[pval] from pval __stackcall (void()) ival() ival: scope:[ival] from - callprepare incval callexecute incval to:ival::@return ival::@return: scope:[ival] from ival @@ -84,7 +79,6 @@ printother::@return: scope:[printother] from printother::@1 return to:@return @6: scope:[] from @begin - callprepare main callexecute main to:@end @end: scope:[] from @6 @@ -124,14 +118,14 @@ Successful SSA optimization PassNCastSimplification Finalized unsigned number type (byte) 0 Finalized unsigned number type (byte) $28 Successful SSA optimization PassNFinalizeNumberTypeConversions -Simple Condition (bool~) main::$3 [10] if((byte) main::i!=rangelast(0,5)) goto main::@1 -Simple Condition (bool~) printother::$1 [26] if((byte) printother::i!=rangelast(0,5)) goto printother::@1 +Simple Condition (bool~) main::$3 [7] if((byte) main::i!=rangelast(0,5)) goto main::@1 +Simple Condition (bool~) printother::$1 [21] if((byte) printother::i!=rangelast(0,5)) goto printother::@1 Successful SSA optimization Pass2ConditionalJumpSimplification -Resolved ranged next value [8] main::i ← ++ main::i to ++ -Resolved ranged comparison value [10] if(main::i!=rangelast(0,5)) goto main::@1 to (number) 6 -Resolved ranged next value [24] printother::i ← ++ printother::i to ++ -Resolved ranged comparison value [26] if(printother::i!=rangelast(0,5)) goto printother::@1 to (number) 6 -Simplifying expression containing zero SCREEN in [18] *((const byte*) SCREEN + (byte) 0) ← (byte) val +Resolved ranged next value [5] main::i ← ++ main::i to ++ +Resolved ranged comparison value [7] if(main::i!=rangelast(0,5)) goto main::@1 to (number) 6 +Resolved ranged next value [19] printother::i ← ++ printother::i to ++ +Resolved ranged comparison value [21] if(printother::i!=rangelast(0,5)) goto printother::@1 to (number) 6 +Simplifying expression containing zero SCREEN in [13] *((const byte*) SCREEN + (byte) 0) ← (byte) val Successful SSA optimization PassNSimplifyExpressionWithZero Adding number conversion cast (unumber) 6 in if((byte) main::i!=(number) 6) goto main::@1 Adding number conversion cast (unumber) 6 in if((byte) printother::i!=(number) 6) goto printother::@1 @@ -142,24 +136,32 @@ Successful SSA optimization PassNCastSimplification Finalized unsigned number type (byte) 6 Finalized unsigned number type (byte) 6 Successful SSA optimization PassNFinalizeNumberTypeConversions +Adding NOP phi() at start of @6 Adding NOP phi() at start of @end +Adding NOP phi() at start of ival +Adding NOP phi() at start of pval +Adding NOP phi() at start of main::@1 CALL GRAPH Calls in [] to main:2 Calls in [ival] to incval:14 Calls in [pval] to printval:17 -Calls in [main] to pval:21 printother:23 ival:25 +Calls in [main] to pval:21 printother:22 ival:23 Created 0 initial phi equivalence classes Coalesced down to 0 phi equivalence classes Renumbering block @6 to @1 +Adding NOP phi() at start of @1 Adding NOP phi() at start of @end +Adding NOP phi() at start of ival +Adding NOP phi() at start of pval +Adding NOP phi() at start of main::@1 FINAL CONTROL FLOW GRAPH @begin: scope:[] from [0] (byte) val ← (byte) 0 to:@1 @1: scope:[] from @begin - [1] callprepare main + [1] phi() [2] callexecute main to:@end @end: scope:[] from @1 @@ -196,7 +198,7 @@ printval::@return: scope:[printval] from printval __stackcall (void()) ival() ival: scope:[ival] from - [13] callprepare incval + [13] phi() [14] callexecute incval to:ival::@return ival::@return: scope:[ival] from ival @@ -205,7 +207,7 @@ ival::@return: scope:[ival] from ival __stackcall (void()) pval() pval: scope:[pval] from - [16] callprepare printval + [16] phi() [17] callexecute printval to:pval::@return pval::@return: scope:[pval] from pval @@ -217,17 +219,15 @@ main: scope:[main] from [19] (byte) main::i ← (byte) 0 to:main::@1 main::@1: scope:[main] from main main::@1 - [20] callprepare pval + [20] phi() [21] callexecute pval - [22] callprepare printother - [23] callexecute printother - [24] callprepare ival - [25] callexecute ival - [26] (byte) main::i ← ++ (byte) main::i - [27] if((byte) main::i!=(byte) 6) goto main::@1 + [22] callexecute printother + [23] callexecute ival + [24] (byte) main::i ← ++ (byte) main::i + [25] if((byte) main::i!=(byte) 6) goto main::@1 to:main::@return main::@return: scope:[main] from main::@1 - [28] return + [26] return to:@return null depth in calling loop Loop head: main::@1 tails: main::@1 blocks: main::@1 in scope printother @@ -240,12 +240,12 @@ VARIABLE REGISTER WEIGHTS __stackcall (void()) incval() __stackcall (void()) ival() __stackcall (void()) main() -(byte) main::i loadstore 3.8888888888888893 +(byte) main::i loadstore 5.0 __stackcall (void()) printother() (byte) printother::i loadstore 14.25 __stackcall (void()) printval() __stackcall (void()) pval() -(byte) val loadstore 0.38095238095238093 +(byte) val loadstore 0.42105263157894735 Initial phi equivalence classes Added variable val to live range equivalence class [ val ] @@ -276,10 +276,11 @@ __bbegin: // [0] (byte) val ← (byte) 0 -- vbuz1=vbuc1 lda #0 sta.z val + // [1] phi from @begin to @1 [phi:@begin->@1] +__b1_from___bbegin: jmp __b1 // @1 __b1: - // [1] callprepare main // [2] callexecute main -- jsr jsr main // [3] phi from @1 to @end [phi:@1->@end] @@ -334,7 +335,6 @@ printval: { } // ival ival: { - // [13] callprepare incval // [14] callexecute incval -- jsr jsr incval jmp __breturn @@ -345,7 +345,6 @@ ival: { } // pval pval: { - // [16] callprepare printval // [17] callexecute printval -- jsr jsr printval jmp __breturn @@ -360,66 +359,66 @@ main: { // [19] (byte) main::i ← (byte) 0 -- vbuz1=vbuc1 lda #0 sta.z i + // [20] phi from main main::@1 to main::@1 [phi:main/main::@1->main::@1] + __b1_from_main: + __b1_from___b1: jmp __b1 // main::@1 __b1: - // [20] callprepare pval // [21] callexecute pval -- jsr jsr pval - // [22] callprepare printother - // [23] callexecute printother -- jsr + // [22] callexecute printother -- jsr jsr printother - // [24] callprepare ival - // [25] callexecute ival -- jsr + // [23] callexecute ival -- jsr jsr ival - // [26] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1 + // [24] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1 inc.z i - // [27] if((byte) main::i!=(byte) 6) goto main::@1 -- vbuz1_neq_vbuc1_then_la1 + // [25] if((byte) main::i!=(byte) 6) goto main::@1 -- vbuz1_neq_vbuc1_then_la1 lda #6 cmp.z i - bne __b1 + bne __b1_from___b1 jmp __breturn // main::@return __breturn: - // [28] return + // [26] return rts } // File Data REGISTER UPLIFT POTENTIAL REGISTERS Statement [0] (byte) val ← (byte) 0 [ val ] ( [ val ] ) always clobbers reg byte a -Statement [4] (byte) printother::i ← (byte) 0 [ printother::i ] ( main:2::printother:23 [ val main::i printother::i ] ) always clobbers reg byte a -Statement [5] *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) ← ++ *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) [ printother::i ] ( main:2::printother:23 [ val main::i printother::i ] ) always clobbers reg byte x -Statement [7] if((byte) printother::i!=(byte) 6) goto printother::@1 [ printother::i ] ( main:2::printother:23 [ val main::i printother::i ] ) always clobbers reg byte a +Statement [4] (byte) printother::i ← (byte) 0 [ printother::i ] ( main:2::printother:22 [ val main::i printother::i ] ) always clobbers reg byte a +Statement [5] *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) ← ++ *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) [ printother::i ] ( main:2::printother:22 [ val main::i printother::i ] ) always clobbers reg byte x +Statement [7] if((byte) printother::i!=(byte) 6) goto printother::@1 [ printother::i ] ( main:2::printother:22 [ val main::i printother::i ] ) always clobbers reg byte a Statement [11] *((const byte*) SCREEN) ← (byte) val [ val ] ( main:2::pval:21::printval:17 [ main::i val ] ) always clobbers reg byte a Statement [19] (byte) main::i ← (byte) 0 [ val main::i ] ( main:2 [ val main::i ] ) always clobbers reg byte a -Statement [27] if((byte) main::i!=(byte) 6) goto main::@1 [ val main::i ] ( main:2 [ val main::i ] ) always clobbers reg byte a +Statement [25] if((byte) main::i!=(byte) 6) goto main::@1 [ val main::i ] ( main:2 [ val main::i ] ) always clobbers reg byte a Potential registers zp[1]:2 [ val ] : zp[1]:2 , Potential registers zp[1]:3 [ printother::i ] : zp[1]:3 , Potential registers zp[1]:4 [ main::i ] : zp[1]:4 , REGISTER UPLIFT SCOPES Uplift Scope [printother] 14.25: zp[1]:3 [ printother::i ] -Uplift Scope [main] 3.89: zp[1]:4 [ main::i ] -Uplift Scope [] 0.38: zp[1]:2 [ val ] +Uplift Scope [main] 5: zp[1]:4 [ main::i ] +Uplift Scope [] 0.42: zp[1]:2 [ val ] Uplift Scope [pval] Uplift Scope [ival] Uplift Scope [printval] Uplift Scope [incval] -Uplifting [printother] best 695 combination zp[1]:3 [ printother::i ] -Uplifting [main] best 695 combination zp[1]:4 [ main::i ] -Uplifting [] best 695 combination zp[1]:2 [ val ] -Uplifting [pval] best 695 combination -Uplifting [ival] best 695 combination -Uplifting [printval] best 695 combination -Uplifting [incval] best 695 combination +Uplifting [printother] best 722 combination zp[1]:3 [ printother::i ] +Uplifting [main] best 722 combination zp[1]:4 [ main::i ] +Uplifting [] best 722 combination zp[1]:2 [ val ] +Uplifting [pval] best 722 combination +Uplifting [ival] best 722 combination +Uplifting [printval] best 722 combination +Uplifting [incval] best 722 combination Attempting to uplift remaining variables inzp[1]:3 [ printother::i ] -Uplifting [printother] best 695 combination zp[1]:3 [ printother::i ] +Uplifting [printother] best 722 combination zp[1]:3 [ printother::i ] Attempting to uplift remaining variables inzp[1]:4 [ main::i ] -Uplifting [main] best 695 combination zp[1]:4 [ main::i ] +Uplifting [main] best 722 combination zp[1]:4 [ main::i ] Attempting to uplift remaining variables inzp[1]:2 [ val ] -Uplifting [] best 695 combination zp[1]:2 [ val ] +Uplifting [] best 722 combination zp[1]:2 [ val ] ASSEMBLER BEFORE OPTIMIZATION // File Comments @@ -437,10 +436,11 @@ __bbegin: // [0] (byte) val ← (byte) 0 -- vbuz1=vbuc1 lda #0 sta.z val + // [1] phi from @begin to @1 [phi:@begin->@1] +__b1_from___bbegin: jmp __b1 // @1 __b1: - // [1] callprepare main // [2] callexecute main -- jsr jsr main // [3] phi from @1 to @end [phi:@1->@end] @@ -495,7 +495,6 @@ printval: { } // ival ival: { - // [13] callprepare incval // [14] callexecute incval -- jsr jsr incval jmp __breturn @@ -506,7 +505,6 @@ ival: { } // pval pval: { - // [16] callprepare printval // [17] callexecute printval -- jsr jsr printval jmp __breturn @@ -521,28 +519,28 @@ main: { // [19] (byte) main::i ← (byte) 0 -- vbuz1=vbuc1 lda #0 sta.z i + // [20] phi from main main::@1 to main::@1 [phi:main/main::@1->main::@1] + __b1_from_main: + __b1_from___b1: jmp __b1 // main::@1 __b1: - // [20] callprepare pval // [21] callexecute pval -- jsr jsr pval - // [22] callprepare printother - // [23] callexecute printother -- jsr + // [22] callexecute printother -- jsr jsr printother - // [24] callprepare ival - // [25] callexecute ival -- jsr + // [23] callexecute ival -- jsr jsr ival - // [26] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1 + // [24] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1 inc.z i - // [27] if((byte) main::i!=(byte) 6) goto main::@1 -- vbuz1_neq_vbuc1_then_la1 + // [25] if((byte) main::i!=(byte) 6) goto main::@1 -- vbuz1_neq_vbuc1_then_la1 lda #6 cmp.z i - bne __b1 + bne __b1_from___b1 jmp __breturn // main::@return __breturn: - // [28] return + // [26] return rts } // File Data @@ -559,7 +557,11 @@ Removing instruction jmp __breturn Removing instruction jmp __b1 Removing instruction jmp __breturn Succesful ASM optimization Pass5NextJumpElimination +Replacing label __b1_from___b1 with __b1 +Removing instruction __b1_from___bbegin: Removing instruction __bend_from___b1: +Removing instruction __b1_from_main: +Removing instruction __b1_from___b1: Succesful ASM optimization Pass5RedundantLabelElimination Removing instruction __b1: Removing instruction __bend: @@ -585,7 +587,7 @@ __stackcall (void()) ival() __stackcall (void()) main() (label) main::@1 (label) main::@return -(byte) main::i loadstore zp[1]:4 3.8888888888888893 +(byte) main::i loadstore zp[1]:4 5.0 __stackcall (void()) printother() (label) printother::@1 (label) printother::@return @@ -594,7 +596,7 @@ __stackcall (void()) printval() (label) printval::@return __stackcall (void()) pval() (label) pval::@return -(byte) val loadstore zp[1]:2 0.38095238095238093 +(byte) val loadstore zp[1]:2 0.42105263157894735 zp[1]:2 [ val ] zp[1]:3 [ printother::i ] @@ -620,8 +622,8 @@ __bbegin: // [0] (byte) val ← (byte) 0 -- vbuz1=vbuc1 lda #0 sta.z val + // [1] phi from @begin to @1 [phi:@begin->@1] // @1 - // [1] callprepare main // [2] callexecute main -- jsr jsr main rts @@ -676,7 +678,6 @@ printval: { // ival ival: { // incval() - // [13] callprepare incval // [14] callexecute incval -- jsr jsr incval // ival::@return @@ -687,7 +688,6 @@ ival: { // pval pval: { // printval() - // [16] callprepare printval // [17] callexecute printval -- jsr jsr printval // pval::@return @@ -702,30 +702,28 @@ main: { // [19] (byte) main::i ← (byte) 0 -- vbuz1=vbuc1 lda #0 sta.z i + // [20] phi from main main::@1 to main::@1 [phi:main/main::@1->main::@1] // main::@1 __b1: // pval() - // [20] callprepare pval // [21] callexecute pval -- jsr jsr pval // printother() - // [22] callprepare printother - // [23] callexecute printother -- jsr + // [22] callexecute printother -- jsr jsr printother // ival() - // [24] callprepare ival - // [25] callexecute ival -- jsr + // [23] callexecute ival -- jsr jsr ival // for(char i:0..5) - // [26] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1 + // [24] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1 inc.z i - // [27] if((byte) main::i!=(byte) 6) goto main::@1 -- vbuz1_neq_vbuc1_then_la1 + // [25] if((byte) main::i!=(byte) 6) goto main::@1 -- vbuz1_neq_vbuc1_then_la1 lda #6 cmp.z i bne __b1 // main::@return // } - // [28] return + // [26] return rts } // File Data diff --git a/src/test/ref/procedure-callingconvention-stack-9.sym b/src/test/ref/procedure-callingconvention-stack-9.sym index 878ab6e64..a0d32093f 100644 --- a/src/test/ref/procedure-callingconvention-stack-9.sym +++ b/src/test/ref/procedure-callingconvention-stack-9.sym @@ -9,7 +9,7 @@ __stackcall (void()) ival() __stackcall (void()) main() (label) main::@1 (label) main::@return -(byte) main::i loadstore zp[1]:4 3.8888888888888893 +(byte) main::i loadstore zp[1]:4 5.0 __stackcall (void()) printother() (label) printother::@1 (label) printother::@return @@ -18,7 +18,7 @@ __stackcall (void()) printval() (label) printval::@return __stackcall (void()) pval() (label) pval::@return -(byte) val loadstore zp[1]:2 0.38095238095238093 +(byte) val loadstore zp[1]:2 0.42105263157894735 zp[1]:2 [ val ] zp[1]:3 [ printother::i ]