1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-06-03 07:29:37 +00:00

Added ASM optimization removing jumps / branches to next instruction.

This commit is contained in:
jespergravgaard 2017-05-21 13:40:56 +02:00
parent 39e5b5a894
commit a565a0bea7
8 changed files with 95 additions and 4 deletions

View File

@ -32,7 +32,7 @@ public class AsmFragment {
*/
private String signature;
public AsmFragment(StatementConditionalJump conditionalJump, SymbolTable symbols, ControlFlowGraph graph, ControlFlowBlock block) {
public AsmFragment(StatementConditionalJump conditionalJump, ControlFlowBlock block, SymbolTable symbols, ControlFlowGraph graph) {
this.bindings = new HashMap<>();
this.symbols = symbols;
StringBuilder signature = new StringBuilder();

View File

@ -15,6 +15,14 @@ public class AsmInstruction implements AsmLine {
this.invocationCountEstimate = invocationCountEstimate;
}
public String getParameter() {
return parameter;
}
public AsmInstructionType getType() {
return type;
}
@Override
public int getLineBytes() {
return type.getBytes();

View File

@ -11,6 +11,8 @@ public class AsmInstructionType {
private double cycles;
private boolean jump;
public AsmInstructionType(int opcode, String mnemnonic, AsmAddressingMode addressingMode, double cycles) {
this.opcode = opcode;
this.mnemnonic = mnemnonic;
@ -38,4 +40,16 @@ public class AsmInstructionType {
return addressingMode.getAsm(mnemnonic, parameter);
}
/**
* Tells if the instruction is a jump or a branch (and the parameter is therefore a label or destination address)
* @return true if the instruction is a jump/branch
*/
public boolean isJump() {
return jump;
}
void setJump(boolean jump) {
this.jump = jump;
}
}

View File

@ -322,7 +322,20 @@ public class AsmInstuctionSet {
add(0xfd, "SBC", abx, 4.5);
add(0xfe, "INC", abx, 7.0);
add(0xff, "ISC", abx, 7.0);
for (AsmInstructionType instruction : instructions) {
switch(instruction.getMnemnonic()) {
case "jmp":
case "beq":
case "bne":
case "bcc":
case "bcs":
case "bvc":
case "bvs":
case "bmi":
case "bpl":
instruction.setJump(true);
}
}
}
public AsmInstructionType getType(String mnemonic, AsmAddressingMode addressingMode) {

View File

@ -9,6 +9,10 @@ public class AsmLabel implements AsmLine {
this.label = label;
}
public String getLabel() {
return label;
}
@Override
public int getLineBytes() {
return 0;

View File

@ -50,7 +50,7 @@ public class Pass4CodeGeneration {
asm.addComment(statement + " // " + asmFragment.getSignature());
asmFragment.generate(asm);
} else if (statement instanceof StatementConditionalJump) {
AsmFragment asmFragment = new AsmFragment((StatementConditionalJump) statement, symbols, graph, block);
AsmFragment asmFragment = new AsmFragment((StatementConditionalJump) statement, block, symbols, graph);
asm.addComment(statement + " // " + asmFragment.getSignature());
asmFragment.generate(asm);
} else {

View File

@ -0,0 +1,50 @@
package dk.camelot64.kickc.icl;
import dk.camelot64.kickc.asm.AsmInstruction;
import dk.camelot64.kickc.asm.AsmLabel;
import dk.camelot64.kickc.asm.AsmLine;
import dk.camelot64.kickc.asm.AsmProgram;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/** Optimize assembler code by removing jumps to labels immediately following the jump */
public class Pass5NextJumpElimination {
private AsmProgram program;
public Pass5NextJumpElimination(AsmProgram program) {
this.program = program;
}
public boolean optimize() {
List<AsmLine> remove = new ArrayList<>();
AsmInstruction candidate = null;
for (AsmLine line : program.getLines()) {
if(candidate!=null) {
if(line instanceof AsmLabel) {
if(((AsmLabel) line).getLabel().equals(candidate.getParameter())) {
remove.add(candidate);
candidate = null;
}
}
}
if(line instanceof AsmInstruction) {
candidate = null;
AsmInstruction instruction = (AsmInstruction) line;
if(instruction.getType().isJump()) {
candidate = instruction;
}
}
}
for (Iterator<AsmLine> iterator = program.getLines().iterator(); iterator.hasNext(); ) {
AsmLine line = iterator.next();
if (remove.contains(line)) {
System.out.println("Removing jump to next instruction "+line.getAsm());
iterator.remove();
}
}
return remove.size()>0;
}
}

View File

@ -68,8 +68,10 @@ public class Main {
pass3RegisterAllocation.allocate();
Pass4CodeGeneration pass4CodeGeneration = new Pass4CodeGeneration(controlFlowGraph, symbolTable);
AsmProgram asmProgram = pass4CodeGeneration.generate();
Pass5NextJumpElimination pass5NextJumpElimination = new Pass5NextJumpElimination(asmProgram);
pass5NextJumpElimination.optimize();
System.out.println("SYMBOLS");
System.out.println(symbolTable.toString());