1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-09-08 17:54:40 +00:00

Better label naming when creating intermediate labels

This commit is contained in:
jespergravgaard 2017-07-21 12:18:05 +02:00
parent 88c7ed453a
commit 122cef4e30
17 changed files with 985 additions and 373 deletions

View File

@ -61,7 +61,7 @@ public class Procedure extends Scope {
public List<Variable> getParameters() {
ArrayList<Variable> parameters = new ArrayList<>();
for (String name : parameterNames) {
parameters.add(getScope().getVariable(name));
parameters.add(this.getVariable(name));
}
return parameters;
}
@ -133,4 +133,24 @@ public class Procedure extends Scope {
public ProcedureRef getRef() {
return new ProcedureRef(this.getFullName());
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
Procedure procedure = (Procedure) o;
if (returnType != null ? !returnType.equals(procedure.returnType) : procedure.returnType != null) return false;
return parameterNames != null ? parameterNames.equals(procedure.parameterNames) : procedure.parameterNames == null;
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + (returnType != null ? returnType.hashCode() : 0);
result = 31 * result + (parameterNames != null ? parameterNames.hashCode() : 0);
return result;
}
}

View File

@ -1,12 +1,18 @@
package dk.camelot64.kickc.icl;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
/** A reference to a procedure */
public class ProcedureRef extends SymbolRef {
public ProcedureRef(String fullName) {
@JsonCreator
public ProcedureRef( @JsonProperty("fullName") String fullName) {
super(fullName);
}
@JsonIgnore
public LabelRef getLabelRef() {
return new LabelRef(getFullName());
}

View File

@ -16,7 +16,7 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonSubTypes.Type(value = StatementJump.class, name = "jump"),
@JsonSubTypes.Type(value = StatementLabel.class, name = "label"),
@JsonSubTypes.Type(value = StatementCall.class, name = "call"),
@JsonSubTypes.Type(value = StatementCall.class, name = "return"),
@JsonSubTypes.Type(value = StatementReturn.class, name = "return"),
@JsonSubTypes.Type(value = StatementProcedureBegin.class, name = "procbegin"),
@JsonSubTypes.Type(value = StatementProcedureEnd.class, name = "procend")
})

View File

@ -1,5 +1,9 @@
package dk.camelot64.kickc.icl;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
/**
@ -16,13 +20,28 @@ public class StatementCall implements StatementLValue {
private List<RValue> parameters;
private boolean parametersByAssignment;
public StatementCall(LValue lValue, String procedureName, List<RValue> parameters) {
public StatementCall(
LValue lValue, String procedureName, List<RValue> parameters) {
this.lValue = lValue;
this.procedureName = procedureName;
this.parameters = parameters;
this.parametersByAssignment = false;
}
@JsonCreator
StatementCall(
@JsonProperty("lValue") LValue lValue,
@JsonProperty("procedureName") String procedureName,
@JsonProperty("procedure") ProcedureRef procedure,
@JsonProperty("parameters") List<RValue> parameters,
@JsonProperty("parametersByAssignment") boolean parametersByAssignment) {
this.lValue = lValue;
this.procedureName = procedureName;
this.procedure = procedure;
this.parameters = parameters;
this.parametersByAssignment = parametersByAssignment;
}
public LValue getlValue() {
return lValue;
}
@ -51,6 +70,7 @@ public class StatementCall implements StatementLValue {
this.parameters = parameters;
}
@JsonIgnore
public int getNumParameters() {
return parameters.size();
}
@ -124,4 +144,28 @@ public class StatementCall implements StatementLValue {
}
return res.toString();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
StatementCall that = (StatementCall) o;
if (parametersByAssignment != that.parametersByAssignment) return false;
if (lValue != null ? !lValue.equals(that.lValue) : that.lValue != null) return false;
if (!procedureName.equals(that.procedureName)) return false;
if (procedure != null ? !procedure.equals(that.procedure) : that.procedure != null) return false;
return parameters != null ? parameters.equals(that.parameters) : that.parameters == null;
}
@Override
public int hashCode() {
int result = lValue != null ? lValue.hashCode() : 0;
result = 31 * result + procedureName.hashCode();
result = 31 * result + (procedure != null ? procedure.hashCode() : 0);
result = 31 * result + (parameters != null ? parameters.hashCode() : 0);
result = 31 * result + (parametersByAssignment ? 1 : 0);
return result;
}
}

View File

@ -1,5 +1,8 @@
package dk.camelot64.kickc.icl;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Return Statement inside procedure in Single Static Assignment Form.
*/
@ -8,7 +11,8 @@ public class StatementReturn implements Statement {
/** Return value. May be null if not returning a value. */
private RValue value;
public StatementReturn(RValue value) {
@JsonCreator
public StatementReturn( @JsonProperty("value") RValue value) {
this.value = value;
}
@ -32,4 +36,19 @@ public class StatementReturn implements Statement {
@Override
public String getAsString() {
return "return "+(value==null?"":value.getAsString()); }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
StatementReturn that = (StatementReturn) o;
return value != null ? value.equals(that.value) : that.value == null;
}
@Override
public int hashCode() {
return value != null ? value.hashCode() : 0;
}
}

View File

@ -67,7 +67,7 @@ public class Pass1GenerateControlFlowGraph {
} else if(statement instanceof StatementProcedureEnd) {
// Procedure strategy implemented is currently variable-based transfer of parameters/return values
currentBlock.setDefaultSuccessor(new Label("@RETURN", scope, false).getRef());
ControlFlowBlock nextBlock = getOrCreateBlock(currentBlockScope.addLabelIntermediate().getRef());
ControlFlowBlock nextBlock = getOrCreateBlock(scope.addLabelIntermediate().getRef());
blockStack.pop();
ControlFlowBlock prevBlock = blockStack.pop();
prevBlock.setDefaultSuccessor(nextBlock.getLabel());

View File

@ -39,19 +39,28 @@ public class TestCompilationOutput extends TestCase {
tester.testFile("bresenham");
}
public void testSumMin() throws IOException, URISyntaxException {
TestCompilationOutput tester = new TestCompilationOutput();
tester.testFile("summin");
}
private void testFile(String fileName) throws IOException, URISyntaxException {
String inputPath = testPath + fileName + ".kc";
System.out.println("Testing output for "+inputPath);
CharStream input = CharStreams.fromFileName(inputPath);
Compiler compiler = new Compiler();
Compiler.CompilationResult output = compiler.compile(input);
assertOutput(fileName, ".asm", output.getAsmProgram().toString(false));
assertOutput(fileName, ".sym", output.getSymbols().getSymbolTableContents());
assertOutput(fileName, ".cfg", output.getGraph().getAsTypedString(output.getSymbols()));
assertOutput(fileName, ".log", output.getLog().toString());
boolean success = true;
success &= testOutput(fileName, ".asm", output.getAsmProgram().toString(false));
success &= testOutput(fileName, ".sym", output.getSymbols().getSymbolTableContents());
success &= testOutput(fileName, ".cfg", output.getGraph().getAsTypedString(output.getSymbols()));
success &= testOutput(fileName, ".log", output.getLog().toString());
if(!success) {
fail("Output does not match reference!");
}
}
private void assertOutput(
private boolean testOutput(
String fileName,
String extension,
String outputString) throws IOException, URISyntaxException {
@ -61,7 +70,8 @@ public class TestCompilationOutput extends TestCase {
refLines = loadReferenceLines(fileName, extension);
} catch (Exception e) {
writeOutputFile(fileName, extension, outputString);
fail("Error loading reference."+e.getMessage());
System.out.println("Reference file not found "+refPath+fileName+extension);
return false;
}
// Split output into outLines
List<String> outLines = getOutLines(outputString);
@ -71,14 +81,16 @@ public class TestCompilationOutput extends TestCase {
String refLine = refLines.get(i);
if(!outLine.equals(refLine)) {
writeOutputFile(fileName, extension, outputString);
fail(
System.out.println(
"Output does not match reference on line "+i+"\n"+
"Reference: "+refLine+"\n"+
"Output: "+outLine
);
return false;
}
}
}
return true;
}
private List<String> getOutLines(String outputString) throws IOException {

File diff suppressed because one or more lines are too long

View File

@ -6,7 +6,7 @@ main:
main__B2_from_main:
ldx #25
jmp main__B2
main__B2_from_B12:
main__B2_from_B11:
ldx #25
main__B2_from_B6:
main__B2:
@ -24,10 +24,10 @@ main__B6:
bne main__B2_from_B6
main__B7:
jsr flip
main__B11:
main__B10:
jsr plot
main__B12:
jmp main__B2_from_B12
main__B11:
jmp main__B2_from_B11
main__Breturn:
rts
plot:

View File

@ -4,8 +4,8 @@
main: from @BEGIN
call prepare param-assignment
to:main::@2
main::@2: from main main::@12 main::@6
(byte) main::c#2 ← phi( main/(byte) 25 main::@6/(byte) main::c#1 main::@12/(byte) 25 )
main::@2: from main main::@11 main::@6
(byte) main::c#2 ← phi( main/(byte) 25 main::@6/(byte) main::c#1 main::@11/(byte) 25 )
to:main::@3
main::@3: from main::@2 main::@3
(byte~) main::$1 ← * (word) 53266
@ -21,14 +21,14 @@ main::@6: from main::@4
to:main::@7
main::@7: from main::@6
call flip param-assignment
to:main::@11
main::@11: from main::@7
to:main::@10
main::@10: from main::@7
call plot param-assignment
to:main::@12
main::@12: from main::@11
to:main::@11
main::@11: from main::@10
if(true) goto main::@2
to:main::@return
main::@return: from main::@12
main::@return: from main::@11
return
to:@RETURN
prepare: from main
@ -75,7 +75,7 @@ flip::@3: from flip::@3 flip::@4
flip::@return: from flip::@3
return
to:@RETURN
plot: from main::@11
plot: from main::@10
to:plot::@1
plot::@1: from plot plot::@3
(byte) plot::y#2 ← phi( plot/(byte) 16 plot::@3/(byte) plot::y#1 )

File diff suppressed because it is too large Load Diff

View File

@ -34,8 +34,8 @@
(void()) main()
(byte~) main::$1 reg byte a
(byte~) main::$3 reg byte a
(label) main::@10
(label) main::@11
(label) main::@12
(label) main::@2
(label) main::@3
(label) main::@4

View File

@ -0,0 +1,22 @@
BBEGIN:
sum_from_BBEGIN:
lda #2
sta 3
lda #1
sta 2
jsr sum
B2:
sum_from_B2:
lda #13
sta 3
lda #9
sta 2
jsr sum
BEND:
sum:
lda 2
clc
adc 3
sta 4
sum__Breturn:
rts

View File

@ -0,0 +1,15 @@
@BEGIN: from
call sum param-assignment
to:@2
@2: from @BEGIN
call sum param-assignment
to:@END
sum: from @2 @BEGIN
(byte) sum::b#2 ← phi( @2/(byte) 13 @BEGIN/(byte) 2 )
(byte) sum::a#2 ← phi( @2/(byte) 9 @BEGIN/(byte) 1 )
(byte) s1#0 ← (byte) sum::a#2 + (byte) sum::b#2
to:sum::@return
sum::@return: from sum
return (byte) s1#0
to:@RETURN
@END: from @2

View File

@ -0,0 +1,440 @@
byte s1=sum(1,2);
byte s2=sum(9,13);
byte sum(byte a, byte b) {
return a+b;
}
PROGRAM
(byte~) $0 ← call sum (byte) 1 (byte) 2
(byte) s1 ← (byte~) $0
(byte~) $1 ← call sum (byte) 9 (byte) 13
(byte) s2 ← (byte~) $1
proc (byte()) sum((byte) sum::a , (byte) sum::b)
(byte~) sum::$0 ← (byte) sum::a + (byte) sum::b
(byte) sum::return ← (byte~) sum::$0
goto sum::@return
sum::@return:
(byte) sum::return ← (byte) sum::return
return (byte) sum::return
endproc // sum()
SYMBOLS
(byte~) $0
(byte~) $1
(byte) s1
(byte) s2
(byte()) sum((byte) sum::a , (byte) sum::b)
(byte~) sum::$0
(label) sum::@return
(byte) sum::a
(byte) sum::b
(byte) sum::return
INITIAL CONTROL FLOW GRAPH
@BEGIN: from
(byte~) $0 ← call sum (byte) 1 (byte) 2
(byte) s1 ← (byte~) $0
(byte~) $1 ← call sum (byte) 9 (byte) 13
(byte) s2 ← (byte~) $1
to:@1
sum: from
(byte~) sum::$0 ← (byte) sum::a + (byte) sum::b
(byte) sum::return ← (byte~) sum::$0
to:sum::@return
sum::@return: from sum sum::@1
(byte) sum::return ← (byte) sum::return
return (byte) sum::return
to:@RETURN
sum::@1: from
to:sum::@return
@1: from @BEGIN
to:@END
@END: from @1
CONTROL FLOW GRAPH WITH ASSIGNMENT CALL
@BEGIN: from
(byte) sum::a ← (byte) 1
(byte) sum::b ← (byte) 2
(byte) sum::return ← call sum param-assignment
to:@2
@2: from @BEGIN
(byte~) $0 ← (byte) sum::return
(byte) s1 ← (byte~) $0
(byte) sum::a ← (byte) 9
(byte) sum::b ← (byte) 13
(byte) sum::return ← call sum param-assignment
to:@3
@3: from @2
(byte~) $1 ← (byte) sum::return
(byte) s2 ← (byte~) $1
to:@1
sum: from @2 @BEGIN
(byte~) sum::$0 ← (byte) sum::a + (byte) sum::b
(byte) sum::return ← (byte~) sum::$0
to:sum::@return
sum::@return: from sum sum::@1
(byte) sum::return ← (byte) sum::return
return (byte) sum::return
to:@RETURN
sum::@1: from
to:sum::@return
@1: from @3
to:@END
@END: from @1
Completing Phi functions...
Completing Phi functions...
CONTROL FLOW GRAPH SSA
@BEGIN: from
(byte) sum::a#0 ← (byte) 1
(byte) sum::b#0 ← (byte) 2
(byte) sum::return#0 ← call sum param-assignment
to:@2
@2: from @BEGIN
(byte) sum::return#4 ← phi( @BEGIN/(byte) sum::return#0 )
(byte~) $0 ← (byte) sum::return#4
(byte) s1#0 ← (byte~) $0
(byte) sum::a#1 ← (byte) 9
(byte) sum::b#1 ← (byte) 13
(byte) sum::return#1 ← call sum param-assignment
to:@3
@3: from @2
(byte) sum::return#5 ← phi( @2/(byte) sum::return#1 )
(byte~) $1 ← (byte) sum::return#5
(byte) s2#0 ← (byte~) $1
to:@1
sum: from @2 @BEGIN
(byte) sum::b#2 ← phi( @2/(byte) sum::b#1 @BEGIN/(byte) sum::b#0 )
(byte) sum::a#2 ← phi( @2/(byte) sum::a#1 @BEGIN/(byte) sum::a#0 )
(byte~) sum::$0 ← (byte) sum::a#2 + (byte) sum::b#2
(byte) sum::return#2 ← (byte~) sum::$0
to:sum::@return
sum::@return: from sum sum::@1
(byte) sum::return#6 ← phi( sum/(byte) sum::return#2 sum::@1/(byte) sum::return#7 )
(byte) sum::return#3 ← (byte) sum::return#6
return (byte) sum::return#3
to:@RETURN
sum::@1: from
(byte) sum::return#7 ← phi( )
to:sum::@return
@1: from @3
to:@END
@END: from @1
CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN
@BEGIN: from
(byte) sum::a#0 ← (byte) 1
(byte) sum::b#0 ← (byte) 2
call sum param-assignment
(byte) sum::return#0 ← (byte) sum::return#3
to:@2
@2: from @BEGIN
(byte) sum::return#4 ← phi( @BEGIN/(byte) sum::return#0 )
(byte~) $0 ← (byte) sum::return#4
(byte) s1#0 ← (byte~) $0
(byte) sum::a#1 ← (byte) 9
(byte) sum::b#1 ← (byte) 13
call sum param-assignment
(byte) sum::return#1 ← (byte) sum::return#3
to:@3
@3: from @2
(byte) sum::return#5 ← phi( @2/(byte) sum::return#1 )
(byte~) $1 ← (byte) sum::return#5
(byte) s2#0 ← (byte~) $1
to:@1
sum: from @2 @BEGIN
(byte) sum::b#2 ← phi( @2/(byte) sum::b#1 @BEGIN/(byte) sum::b#0 )
(byte) sum::a#2 ← phi( @2/(byte) sum::a#1 @BEGIN/(byte) sum::a#0 )
(byte~) sum::$0 ← (byte) sum::a#2 + (byte) sum::b#2
(byte) sum::return#2 ← (byte~) sum::$0
to:sum::@return
sum::@return: from sum sum::@1
(byte) sum::return#6 ← phi( sum/(byte) sum::return#2 sum::@1/(byte) sum::return#7 )
(byte) sum::return#3 ← (byte) sum::return#6
return (byte) sum::return#3
to:@RETURN
sum::@1: from
(byte) sum::return#7 ← phi( )
to:sum::@return
@1: from @3
to:@END
@END: from @1
Culled Empty Block (label) @1
Succesful SSA optimization Pass2CullEmptyBlocks
CONTROL FLOW GRAPH
@BEGIN: from
(byte) sum::a#0 ← (byte) 1
(byte) sum::b#0 ← (byte) 2
call sum param-assignment
(byte) sum::return#0 ← (byte) sum::return#3
to:@2
@2: from @BEGIN
(byte) sum::return#4 ← phi( @BEGIN/(byte) sum::return#0 )
(byte~) $0 ← (byte) sum::return#4
(byte) s1#0 ← (byte~) $0
(byte) sum::a#1 ← (byte) 9
(byte) sum::b#1 ← (byte) 13
call sum param-assignment
(byte) sum::return#1 ← (byte) sum::return#3
to:@3
@3: from @2
(byte) sum::return#5 ← phi( @2/(byte) sum::return#1 )
(byte~) $1 ← (byte) sum::return#5
(byte) s2#0 ← (byte~) $1
to:@END
sum: from @2 @BEGIN
(byte) sum::b#2 ← phi( @2/(byte) sum::b#1 @BEGIN/(byte) sum::b#0 )
(byte) sum::a#2 ← phi( @2/(byte) sum::a#1 @BEGIN/(byte) sum::a#0 )
(byte~) sum::$0 ← (byte) sum::a#2 + (byte) sum::b#2
(byte) sum::return#2 ← (byte~) sum::$0
to:sum::@return
sum::@return: from sum sum::@1
(byte) sum::return#6 ← phi( sum/(byte) sum::return#2 sum::@1/(byte) sum::return#7 )
(byte) sum::return#3 ← (byte) sum::return#6
return (byte) sum::return#3
to:@RETURN
sum::@1: from
(byte) sum::return#7 ← phi( )
to:sum::@return
@END: from @3
Constant (byte) sum::a#0 (byte) 1
Constant (byte) sum::b#0 (byte) 2
Constant (byte) sum::a#1 (byte) 9
Constant (byte) sum::b#1 (byte) 13
Succesful SSA optimization Pass2ConstantPropagation
CONTROL FLOW GRAPH
@BEGIN: from
call sum param-assignment
(byte) sum::return#0 ← (byte) sum::return#3
to:@2
@2: from @BEGIN
(byte) sum::return#4 ← phi( @BEGIN/(byte) sum::return#0 )
(byte~) $0 ← (byte) sum::return#4
(byte) s1#0 ← (byte~) $0
call sum param-assignment
(byte) sum::return#1 ← (byte) sum::return#3
to:@3
@3: from @2
(byte) sum::return#5 ← phi( @2/(byte) sum::return#1 )
(byte~) $1 ← (byte) sum::return#5
(byte) s2#0 ← (byte~) $1
to:@END
sum: from @2 @BEGIN
(byte) sum::b#2 ← phi( @2/(byte) 13 @BEGIN/(byte) 2 )
(byte) sum::a#2 ← phi( @2/(byte) 9 @BEGIN/(byte) 1 )
(byte~) sum::$0 ← (byte) sum::a#2 + (byte) sum::b#2
(byte) sum::return#2 ← (byte~) sum::$0
to:sum::@return
sum::@return: from sum sum::@1
(byte) sum::return#6 ← phi( sum/(byte) sum::return#2 sum::@1/(byte) sum::return#7 )
(byte) sum::return#3 ← (byte) sum::return#6
return (byte) sum::return#3
to:@RETURN
sum::@1: from
(byte) sum::return#7 ← phi( )
to:sum::@return
@END: from @3
Alias (byte) s1#0 = (byte) sum::return#0 (byte) sum::return#3 (byte) sum::return#4 (byte~) $0 (byte) sum::return#1 (byte) sum::return#5 (byte~) $1 (byte) s2#0 (byte) sum::return#6
Alias (byte) sum::return#2 = (byte~) sum::$0
Succesful SSA optimization Pass2AliasElimination
CONTROL FLOW GRAPH
@BEGIN: from
call sum param-assignment
to:@2
@2: from @BEGIN
call sum param-assignment
to:@3
@3: from @2
to:@END
sum: from @2 @BEGIN
(byte) sum::b#2 ← phi( @2/(byte) 13 @BEGIN/(byte) 2 )
(byte) sum::a#2 ← phi( @2/(byte) 9 @BEGIN/(byte) 1 )
(byte) sum::return#2 ← (byte) sum::a#2 + (byte) sum::b#2
to:sum::@return
sum::@return: from sum sum::@1
(byte) s1#0 ← phi( sum/(byte) sum::return#2 sum::@1/(byte) sum::return#7 )
return (byte) s1#0
to:@RETURN
sum::@1: from
(byte) sum::return#7 ← phi( )
to:sum::@return
@END: from @3
Redundant Phi (byte) sum::return#7 VOID
Succesful SSA optimization Pass2RedundantPhiElimination
CONTROL FLOW GRAPH
@BEGIN: from
call sum param-assignment
to:@2
@2: from @BEGIN
call sum param-assignment
to:@3
@3: from @2
to:@END
sum: from @2 @BEGIN
(byte) sum::b#2 ← phi( @2/(byte) 13 @BEGIN/(byte) 2 )
(byte) sum::a#2 ← phi( @2/(byte) 9 @BEGIN/(byte) 1 )
(byte) sum::return#2 ← (byte) sum::a#2 + (byte) sum::b#2
to:sum::@return
sum::@return: from sum sum::@1
(byte) s1#0 ← phi( sum/(byte) sum::return#2 )
return (byte) s1#0
to:@RETURN
sum::@1: from
to:sum::@return
@END: from @3
Culled Empty Block (label) @3
Culled Empty Block (label) sum::@1
Succesful SSA optimization Pass2CullEmptyBlocks
CONTROL FLOW GRAPH
@BEGIN: from
call sum param-assignment
to:@2
@2: from @BEGIN
call sum param-assignment
to:@END
sum: from @2 @BEGIN
(byte) sum::b#2 ← phi( @2/(byte) 13 @BEGIN/(byte) 2 )
(byte) sum::a#2 ← phi( @2/(byte) 9 @BEGIN/(byte) 1 )
(byte) sum::return#2 ← (byte) sum::a#2 + (byte) sum::b#2
to:sum::@return
sum::@return: from sum
(byte) s1#0 ← phi( sum/(byte) sum::return#2 )
return (byte) s1#0
to:@RETURN
@END: from @2
Alias (byte) s1#0 = (byte) sum::return#2
Succesful SSA optimization Pass2AliasElimination
CONTROL FLOW GRAPH
@BEGIN: from
call sum param-assignment
to:@2
@2: from @BEGIN
call sum param-assignment
to:@END
sum: from @2 @BEGIN
(byte) sum::b#2 ← phi( @2/(byte) 13 @BEGIN/(byte) 2 )
(byte) sum::a#2 ← phi( @2/(byte) 9 @BEGIN/(byte) 1 )
(byte) s1#0 ← (byte) sum::a#2 + (byte) sum::b#2
to:sum::@return
sum::@return: from sum
return (byte) s1#0
to:@RETURN
@END: from @2
INITIAL ASM
BBEGIN:
sum_from_BBEGIN:
// (byte) sum::b#2 = (byte) 2 // zpby1=coby1
lda #2
sta 3
// (byte) sum::a#2 = (byte) 1 // zpby1=coby1
lda #1
sta 2
jsr sum
jmp B2
B2:
sum_from_B2:
// (byte) sum::b#2 = (byte) 13 // zpby1=coby1
lda #13
sta 3
// (byte) sum::a#2 = (byte) 9 // zpby1=coby1
lda #9
sta 2
jsr sum
jmp BEND
BEND:
sum:
// (byte) s1#0 ← (byte) sum::a#2 + (byte) sum::b#2 // zpby1=zpby2_plus_zpby3
lda 2
clc
adc 3
sta 4
jmp sum__Breturn
sum__Breturn:
rts
Removing instruction jmp B2
Removing instruction jmp BEND
Removing instruction jmp sum__Breturn
Succesful ASM optimization Pass4NextJumpElimination
ASSEMBLER
BBEGIN:
sum_from_BBEGIN:
// (byte) sum::b#2 = (byte) 2 // zpby1=coby1
lda #2
sta 3
// (byte) sum::a#2 = (byte) 1 // zpby1=coby1
lda #1
sta 2
jsr sum
B2:
sum_from_B2:
// (byte) sum::b#2 = (byte) 13 // zpby1=coby1
lda #13
sta 3
// (byte) sum::a#2 = (byte) 9 // zpby1=coby1
lda #9
sta 2
jsr sum
BEND:
sum:
// (byte) s1#0 ← (byte) sum::a#2 + (byte) sum::b#2 // zpby1=zpby2_plus_zpby3
lda 2
clc
adc 3
sta 4
sum__Breturn:
rts
FINAL SYMBOL TABLE
(label) @2
(label) @BEGIN
(label) @END
(byte) s1
(byte) s1#0 zp byte:4
(byte) s2
(byte()) sum((byte) sum::a , (byte) sum::b)
(label) sum::@return
(byte) sum::a
(byte) sum::a#2 zp byte:2
(byte) sum::b
(byte) sum::b#2 zp byte:3
(byte) sum::return
FINAL CODE
BBEGIN:
sum_from_BBEGIN:
// (byte) sum::b#2 = (byte) 2 // zpby1=coby1
lda #2
sta 3
// (byte) sum::a#2 = (byte) 1 // zpby1=coby1
lda #1
sta 2
jsr sum
B2:
sum_from_B2:
// (byte) sum::b#2 = (byte) 13 // zpby1=coby1
lda #13
sta 3
// (byte) sum::a#2 = (byte) 9 // zpby1=coby1
lda #9
sta 2
jsr sum
BEND:
sum:
// (byte) s1#0 ← (byte) sum::a#2 + (byte) sum::b#2 // zpby1=zpby2_plus_zpby3
lda 2
clc
adc 3
sta 4
sum__Breturn:
rts

View File

@ -0,0 +1,14 @@
(label) @2
(label) @BEGIN
(label) @END
(byte) s1
(byte) s1#0 zp byte:4
(byte) s2
(byte()) sum((byte) sum::a , (byte) sum::b)
(label) sum::@return
(byte) sum::a
(byte) sum::a#2 zp byte:2
(byte) sum::b
(byte) sum::b#2 zp byte:3
(byte) sum::return

View File

@ -0,0 +1,5 @@
byte s1=sum(1,2);
byte s2=sum(9,13);
byte sum(byte a, byte b) {
return a+b;
}