diff --git a/src/main/java/dk/camelot64/kickc/Compiler.java b/src/main/java/dk/camelot64/kickc/Compiler.java index 3b643b110..9b0362173 100644 --- a/src/main/java/dk/camelot64/kickc/Compiler.java +++ b/src/main/java/dk/camelot64/kickc/Compiler.java @@ -151,7 +151,6 @@ public class Compiler { new Pass1GenerateControlFlowGraph(program).execute(); new Pass1ResolveForwardReferences(program).execute(); new Pass1UnwindBlockScopes(program).execute(); - new Pass1TypeInference(program).execute(); if(getLog().isVerbosePass1CreateSsa()) { @@ -375,6 +374,7 @@ public class Compiler { // Phi mem coalesce removes as many variables introduced by phi lifting as possible - as long as their live ranges do not overlap new Pass3PhiMemCoalesce(program).step(); new Pass2CullEmptyBlocks(program).step(); + new PassNRenumberLabels(program).execute(); new PassNBlockSequencePlanner(program).step(); new Pass3AddNopBeforeCallOns(program).generate(); new PassNStatementIndices(program).execute(); diff --git a/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValue.java b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValue.java index bbadebdd5..a6499b3d9 100644 --- a/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValue.java +++ b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValue.java @@ -634,6 +634,26 @@ public abstract class ProgramValue { } } + public static class PhiValuePredecessor extends ProgramValue { + private final StatementPhiBlock.PhiVariable phiVariable; + private final int i; + + PhiValuePredecessor(StatementPhiBlock.PhiVariable phiVariable, int i) { + this.phiVariable = phiVariable; + this.i = i; + } + + @Override + public Value get() { + return phiVariable.getValues().get(i).getPredecessor(); + } + + @Override + public void set(Value value) { + phiVariable.getValues().get(i).setPredecessor((LabelRef) value); + } + } + /** * LValue as part of an assignment statement (or a call). */ 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 fff65cc8f..cbfe5bc53 100644 --- a/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValueIterator.java +++ b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValueIterator.java @@ -118,6 +118,7 @@ public class ProgramValueIterator { for(StatementPhiBlock.PhiVariable phiVariable : ((StatementPhiBlock) statement).getPhiVariables()) { int size = phiVariable.getValues().size(); for(int i = 0; i < size; i++) { + execute(new ProgramValue.PhiValuePredecessor(phiVariable, i), handler, statement, statementsIt, block); execute(new ProgramValue.PhiValue(phiVariable, i), handler, statement, statementsIt, block); } execute(new ProgramValue.PhiVariable(phiVariable), handler, statement, statementsIt, block); diff --git a/src/main/java/dk/camelot64/kickc/model/symbols/Scope.java b/src/main/java/dk/camelot64/kickc/model/symbols/Scope.java index 379c56f76..78982f4b9 100644 --- a/src/main/java/dk/camelot64/kickc/model/symbols/Scope.java +++ b/src/main/java/dk/camelot64/kickc/model/symbols/Scope.java @@ -362,6 +362,14 @@ public abstract class Scope implements Symbol { return symbols.values(); } + /** + * Set the value of the counter used to number intermediate labels + * @param intermediateLabelCount The new counter value + */ + public void setIntermediateLabelCount(int intermediateLabelCount) { + this.intermediateLabelCount = intermediateLabelCount; + } + @Override public boolean equals(Object o) { if(this == o) { diff --git a/src/main/java/dk/camelot64/kickc/passes/PassNRenumberLabels.java b/src/main/java/dk/camelot64/kickc/passes/PassNRenumberLabels.java new file mode 100644 index 000000000..ff538f911 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/PassNRenumberLabels.java @@ -0,0 +1,74 @@ +package dk.camelot64.kickc.passes; + +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.iterator.ProgramValueIterator; +import dk.camelot64.kickc.model.symbols.Label; +import dk.camelot64.kickc.model.symbols.Scope; +import dk.camelot64.kickc.model.symbols.Symbol; +import dk.camelot64.kickc.model.values.LabelRef; +import dk.camelot64.kickc.model.values.Value; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * Renumber all labels in the program + */ +public class PassNRenumberLabels extends Pass2SsaOptimization { + + public PassNRenumberLabels(Program program) { + super(program); + } + + @Override + public boolean step() { + Map renamed = new LinkedHashMap<>(); + renumberLabels(getScope(), renamed); + for(Scope scope : getScope().getAllScopes(true)) { + renumberLabels(scope, renamed); + } + ProgramValueIterator.execute(getGraph(), (programValue, currentStmt, stmtIt, currentBlock) -> { + Value value = programValue.get(); + if(value instanceof LabelRef) { + LabelRef newLabelRef = renamed.get(value); + if(newLabelRef!=null) { + programValue.set(newLabelRef); + } + } + } + ); + return false; + } + + private void renumberLabels(Scope scope, Map renamed) { + int labelIdx = 1; + List