mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-04-08 14:37:40 +00:00
#815 more procedure compilation
This commit is contained in:
parent
adb9688acb
commit
185bd439e4
@ -191,7 +191,7 @@ public class Compiler {
|
||||
pass2FinalizeAllNumbers();
|
||||
|
||||
//getLog().append("\nCONTROL FLOW GRAPH PASS 2");
|
||||
//getLog().append(program.getGraph().toString(program));
|
||||
//getLog().append(program.prettyControlFlowGraph());
|
||||
|
||||
//getLog().append("SYMBOL TABLE PASS 2");
|
||||
//getLog().append(program.getScope().toString(program, null));
|
||||
@ -213,7 +213,7 @@ public class Compiler {
|
||||
new Pass1GenerateControlFlowGraph(program).execute();
|
||||
if(getLog().isVerbosePass1CreateSsa()) {
|
||||
getLog().append("FIRST CONTROL FLOW GRAPH");
|
||||
getLog().append(program.getGraph().toString(program));
|
||||
getLog().append(program.prettyControlFlowGraph());
|
||||
}
|
||||
new Pass1ResolveForwardReferences(program).execute();
|
||||
new Pass1ByteXIntrinsicRewrite(program).execute();
|
||||
@ -248,7 +248,7 @@ public class Compiler {
|
||||
|
||||
if(getLog().isVerbosePass1CreateSsa()) {
|
||||
getLog().append("CONTROL FLOW GRAPH BEFORE SIZEOF FIX");
|
||||
getLog().append(program.getGraph().toString(program));
|
||||
getLog().append(program.prettyControlFlowGraph());
|
||||
}
|
||||
|
||||
new Pass1PointerSizeofFix(program).execute(); // After this point in the code all pointer math is byte-based
|
||||
@ -262,7 +262,7 @@ public class Compiler {
|
||||
|
||||
if(getLog().isVerbosePass1CreateSsa()) {
|
||||
getLog().append("CONTROL FLOW GRAPH AFTER UNWIND");
|
||||
getLog().append(program.getGraph().toString(program));
|
||||
getLog().append(program.prettyControlFlowGraph());
|
||||
}
|
||||
|
||||
new PassNDeInlineCastValues(program, true).execute();
|
||||
@ -275,7 +275,7 @@ public class Compiler {
|
||||
|
||||
if(getLog().isVerbosePass1CreateSsa()) {
|
||||
getLog().append("CONTROL FLOW GRAPH BEFORE INLINING");
|
||||
getLog().append(program.getGraph().toString(program));
|
||||
getLog().append(program.prettyControlFlowGraph());
|
||||
}
|
||||
new Pass1ProcedureInline(program).execute();
|
||||
new PassNStatementIndices(program).step();
|
||||
@ -285,7 +285,7 @@ public class Compiler {
|
||||
|
||||
if(getLog().isVerbosePass1CreateSsa()) {
|
||||
getLog().append("INITIAL CONTROL FLOW GRAPH");
|
||||
getLog().append(program.getGraph().toString(program));
|
||||
getLog().append(program.prettyControlFlowGraph());
|
||||
}
|
||||
|
||||
new Pass1EliminateUncalledProcedures(program).execute();
|
||||
@ -306,14 +306,14 @@ public class Compiler {
|
||||
new Pass1CallStackVarConvert(program).execute();
|
||||
if(getLog().isVerbosePass1CreateSsa()) {
|
||||
getLog().append("PROCEDURE CALLS");
|
||||
getLog().append(program.getGraph().toString(program));
|
||||
getLog().append(program.prettyControlFlowGraph());
|
||||
}
|
||||
new Pass1CallStack(program).execute();
|
||||
new Pass1CallVar(program).execute();
|
||||
new Pass1CallPhiParameters(program).execute();
|
||||
if(getLog().isVerbosePass1CreateSsa()) {
|
||||
getLog().append("PROCEDURE PARAMETERS");
|
||||
getLog().append(program.getGraph().toString(program));
|
||||
getLog().append(program.prettyControlFlowGraph());
|
||||
}
|
||||
new PassNUnwindLValueLists(program).execute();
|
||||
new Pass1GenerateSingleStaticAssignmentForm(program).execute();
|
||||
@ -326,7 +326,7 @@ public class Compiler {
|
||||
|
||||
|
||||
getLog().append("\nCONTROL FLOW GRAPH SSA");
|
||||
getLog().append(program.getGraph().toString(program));
|
||||
getLog().append(program.prettyControlFlowGraph());
|
||||
|
||||
getLog().append("SYMBOL TABLE SSA");
|
||||
getLog().append(program.getScope().toStringVars(program, false));
|
||||
@ -457,7 +457,7 @@ public class Compiler {
|
||||
|
||||
if(getLog().isVerboseLoopUnroll()) {
|
||||
getLog().append("CONTROL FLOW GRAPH BEFORE UNROLLING");
|
||||
getLog().append(program.getGraph().toString(program));
|
||||
getLog().append(program.prettyControlFlowGraph());
|
||||
}
|
||||
|
||||
boolean unrolled;
|
||||
@ -466,7 +466,7 @@ public class Compiler {
|
||||
if(unrolled) {
|
||||
if(getLog().isVerboseLoopUnroll()) {
|
||||
getLog().append("UNROLLED CONTROL FLOW GRAPH");
|
||||
getLog().append(program.getGraph().toString(program));
|
||||
getLog().append(program.prettyControlFlowGraph());
|
||||
}
|
||||
pass2Optimize();
|
||||
new Pass2LoopUnrollAssertComplete(program).step();
|
||||
@ -552,7 +552,7 @@ public class Compiler {
|
||||
getLog().append("Successful SSA optimization " + optimization.getClass().getSimpleName() + "");
|
||||
if(getLog().isVerboseSSAOptimize()) {
|
||||
getLog().append("CONTROL FLOW GRAPH");
|
||||
getLog().append(program.getGraph().toString(program));
|
||||
getLog().append(program.prettyControlFlowGraph());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -575,7 +575,7 @@ public class Compiler {
|
||||
new Pass3PhiLifting(program).perform();
|
||||
new PassNBlockSequencePlanner(program).step();
|
||||
//getLog().append("CONTROL FLOW GRAPH - PHI LIFTED");
|
||||
//getLog().append(program.getGraph().toString(program));
|
||||
//getLog().append(program.prettyControlFlowGraph());
|
||||
pass2AssertSSA();
|
||||
new Pass3AddNopBeforeCallOns(program).generate();
|
||||
new PassNStatementIndices(program).execute();
|
||||
@ -596,17 +596,17 @@ public class Compiler {
|
||||
|
||||
if(getLog().isVerboseSSAOptimize()) {
|
||||
getLog().append("CONTROL FLOW GRAPH");
|
||||
getLog().append(program.getGraph().toString(program));
|
||||
getLog().append(program.prettyControlFlowGraph());
|
||||
}
|
||||
new PassNCullEmptyBlocks(program, false).step();
|
||||
if(getLog().isVerboseSSAOptimize()) {
|
||||
getLog().append("CONTROL FLOW GRAPH");
|
||||
getLog().append(program.getGraph().toString(program));
|
||||
getLog().append(program.prettyControlFlowGraph());
|
||||
}
|
||||
new PassNRenumberLabels(program, false).execute();
|
||||
if(getLog().isVerboseSSAOptimize()) {
|
||||
getLog().append("CONTROL FLOW GRAPH");
|
||||
getLog().append(program.getGraph().toString(program));
|
||||
getLog().append(program.prettyControlFlowGraph());
|
||||
}
|
||||
new PassNBlockSequencePlanner(program).step();
|
||||
new Pass3AddNopBeforeCallOns(program).generate();
|
||||
@ -624,12 +624,12 @@ public class Compiler {
|
||||
|
||||
// program.getLiveRangeVariablesEffective();
|
||||
// getLog().append("CONTROL FLOW GRAPH - LIVE RANGES FOUND");
|
||||
// getLog().append(program.getGraph().toString(program));
|
||||
// getLog().append(program.prettyControlFlowGraph());
|
||||
|
||||
program.getLiveRangeVariablesEffective();
|
||||
|
||||
getLog().append("\nFINAL CONTROL FLOW GRAPH");
|
||||
getLog().append(program.getGraph().toString(program));
|
||||
getLog().append(program.prettyControlFlowGraph());
|
||||
|
||||
}
|
||||
|
||||
|
@ -175,8 +175,7 @@ public class ControlFlowBlock {
|
||||
}
|
||||
|
||||
|
||||
public String toString(Program program) {
|
||||
ControlFlowGraph graph = program.getGraph();
|
||||
public String toString(Program program, ControlFlowGraph graph) {
|
||||
StringBuffer out = new StringBuffer();
|
||||
|
||||
if(isProcedureEntry(program)) {
|
||||
|
@ -187,7 +187,7 @@ public class ControlFlowGraph {
|
||||
public String toString(Program program) {
|
||||
StringBuffer out = new StringBuffer();
|
||||
for(ControlFlowBlock block : getAllBlocks()) {
|
||||
out.append(block.toString(program));
|
||||
out.append(block.toString(program, this));
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
@ -223,6 +223,17 @@ public class ControlFlowGraph {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all statement indices,
|
||||
*/
|
||||
public void clearStatementIndices() {
|
||||
for(ControlFlowBlock block : getAllBlocks()) {
|
||||
for(Statement statement : block.getStatements()) {
|
||||
statement.setIndex(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all blocks that are part of the execution of a specific scope. (mostly a procedure)
|
||||
*
|
||||
@ -239,20 +250,6 @@ public class ControlFlowGraph {
|
||||
return scopeBlocks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information about the size of the program
|
||||
*
|
||||
* @return Size information
|
||||
*/
|
||||
public String getSizeInfo() {
|
||||
StringBuilder sizeInfo = new StringBuilder();
|
||||
sizeInfo.append("SIZE blocks " + getAllBlocks().size()).append("\n");
|
||||
int numStmt = getAllBlocks().stream().mapToInt(block -> block.getStatements().size()).sum();
|
||||
sizeInfo.append("SIZE statements " + numStmt).append("\n");
|
||||
int numPhiVars = getAllBlocks().stream().mapToInt(value -> value.getStatements().stream().mapToInt(value1 -> (value1 instanceof StatementPhiBlock) ? ((StatementPhiBlock) value1).getPhiVariables().size() : 0).sum()).sum();
|
||||
sizeInfo.append("SIZE phi variables " + numPhiVars).append("\n");
|
||||
return sizeInfo.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all statements executed between two statements (none of these are included in the result)
|
||||
|
@ -1,5 +1,6 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.values.ProcedureRef;
|
||||
|
||||
/**
|
||||
@ -14,6 +15,9 @@ public class ProcedureCompilation {
|
||||
/** The statements of the procedure. */
|
||||
private StatementSequence statementSequence;
|
||||
|
||||
/** The control flow graph of the procedure. */
|
||||
private ControlFlowGraph graph;
|
||||
|
||||
public ProcedureCompilation(ProcedureRef procedureRef) {
|
||||
this.procedureRef = procedureRef;
|
||||
this.statementSequence = new StatementSequence();
|
||||
@ -27,4 +31,12 @@ public class ProcedureCompilation {
|
||||
return statementSequence;
|
||||
}
|
||||
|
||||
public ControlFlowGraph getGraph() {
|
||||
return graph;
|
||||
}
|
||||
|
||||
public void setGraph(ControlFlowGraph graph) {
|
||||
this.graph = graph;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,16 +5,14 @@ import dk.camelot64.kickc.OutputFileManager;
|
||||
import dk.camelot64.kickc.asm.AsmProgram;
|
||||
import dk.camelot64.kickc.fragment.synthesis.AsmFragmentTemplateMasterSynthesizer;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementPhiBlock;
|
||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
import dk.camelot64.kickc.model.values.LabelRef;
|
||||
import dk.camelot64.kickc.model.values.ProcedureRef;
|
||||
import dk.camelot64.kickc.passes.calcs.*;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/** A KickC Intermediate Compiler Language (ICL) Program */
|
||||
public class Program {
|
||||
@ -58,8 +56,6 @@ public class Program {
|
||||
|
||||
/** The main scope. PASS 0-5 (DYNAMIC) */
|
||||
private ProgramScope scope;
|
||||
/** The control flow graph. PASS 1-5 (DYNAMIC) */
|
||||
private ControlFlowGraph graph;
|
||||
/** The procedure that starts the execution of the program. (Default: _start() which calls _init() and main() ) */
|
||||
private ProcedureRef startProcedure;
|
||||
|
||||
@ -69,8 +65,8 @@ public class Program {
|
||||
/** Cached information about calls. PASS 1-4 (CACHED ON-DEMAND) */
|
||||
private CallGraph callGraph;
|
||||
|
||||
/** The procedures being compiled. */
|
||||
private final Map<ProcedureRef, ProcedureCompilation> procedureCompilations;
|
||||
/** The procedures being compiled. PASS 1-5 (DYNAMIC)*/
|
||||
private final LinkedHashMap<ProcedureRef, ProcedureCompilation> procedureCompilations;
|
||||
|
||||
/** Variables modified inside procedures. PASS 1 (STATIC) */
|
||||
private ProcedureModifiedVars procedureModifiedVars;
|
||||
@ -82,9 +78,6 @@ public class Program {
|
||||
/** The 6502 ASM program. PASS 4-5 (DYNAMIC) */
|
||||
private AsmProgram asm;
|
||||
|
||||
/** A saved program snapshot that can be rolled back. Used to store the (DYNAMIC) state of the program while trying out a potential optimization. PASS 2 (DYNAMIC) */
|
||||
private ProgramSnapshot snapshot;
|
||||
|
||||
/** Cached information about the variables referenced by blocks/statements. PASS 1-4 (CACHED ON-DEMAND) */
|
||||
private VariableReferenceInfos variableReferenceInfos;
|
||||
/** Cached information about the closure of all block successors. */
|
||||
@ -137,7 +130,6 @@ public class Program {
|
||||
* Clears all data that is only used in PASS 2-4
|
||||
*/
|
||||
public void endPass4() {
|
||||
this.snapshot = null;
|
||||
this.mainFileComments = null;
|
||||
this.callGraph = null;
|
||||
this.variableReferenceInfos = null;
|
||||
@ -150,33 +142,18 @@ public class Program {
|
||||
this.registerUpliftProgram = null;
|
||||
}
|
||||
|
||||
/** Save a snapshot of the dynamic parts of the program. */
|
||||
public void snapshotCreate() {
|
||||
if(this.snapshot != null)
|
||||
throw new InternalError("Snapshot already saved!");
|
||||
if(this.liveRangeEquivalenceClassSet != null)
|
||||
throw new InternalError("Compiler Program Snapshot does not support liveRangeEquivalenceClassSet!");
|
||||
this.snapshot = new ProgramSnapshot(scope, graph);
|
||||
}
|
||||
|
||||
/** Restore the snapshot of the dynamic parts of the program. Clear all cached data and the snapshot. */
|
||||
public void snapshotRestore() {
|
||||
this.scope = snapshot.getScope();
|
||||
this.graph = snapshot.getGraph();
|
||||
this.snapshot = null;
|
||||
this.callGraph = null;
|
||||
this.variableReferenceInfos = null;
|
||||
this.dominators = null;
|
||||
this.loopSet = null;
|
||||
this.statementInfos = null;
|
||||
this.symbolInfos = null;
|
||||
this.phiTransitions = null;
|
||||
this.liveRangeVariables = null;
|
||||
this.liveRangeVariablesEffective = null;
|
||||
this.variableRegisterWeights = null;
|
||||
this.registerPotentials = null;
|
||||
this.registerUpliftProgram = null;
|
||||
this.asm = null;
|
||||
/**
|
||||
* Pretty-print the entire control flow graph of all procedures.
|
||||
* @return The pretty-printed control flow graph
|
||||
*/
|
||||
public String prettyControlFlowGraph() {
|
||||
StringBuilder graphPretty = new StringBuilder();
|
||||
for(ProcedureRef procedureRef : procedureCompilations.keySet()) {
|
||||
final ProcedureCompilation procedureCompilation = procedureCompilations.get(procedureRef);
|
||||
graphPretty.append(procedureCompilation.getGraph().toString(this));
|
||||
}
|
||||
return graphPretty.toString();
|
||||
}
|
||||
|
||||
public OutputFileManager getOutputFileManager() {
|
||||
@ -291,14 +268,6 @@ public class Program {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
public ControlFlowGraph getGraph() {
|
||||
return graph;
|
||||
}
|
||||
|
||||
public void setGraph(ControlFlowGraph graph) {
|
||||
this.graph = graph;
|
||||
}
|
||||
|
||||
public ProcedureRef getStartProcedure() {
|
||||
return startProcedure;
|
||||
}
|
||||
@ -413,11 +382,7 @@ public class Program {
|
||||
* Clear index numbers for all statements in the control flow graph.
|
||||
*/
|
||||
public void clearStatementIndices() {
|
||||
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
|
||||
for(Statement statement : block.getStatements()) {
|
||||
statement.setIndex(null);
|
||||
}
|
||||
}
|
||||
procedureCompilations.values().forEach(proc -> proc.getGraph().clearStatementIndices());
|
||||
}
|
||||
|
||||
public SymbolInfos getSymbolInfos() {
|
||||
@ -527,7 +492,14 @@ public class Program {
|
||||
public String getSizeInfo() {
|
||||
StringBuilder sizeInfo = new StringBuilder();
|
||||
sizeInfo.append(getScope().getSizeInfo());
|
||||
sizeInfo.append(getGraph().getSizeInfo());
|
||||
|
||||
final List<ControlFlowBlock> allBlocks = procedureCompilations.values().stream().map(ProcedureCompilation::getGraph).map(ControlFlowGraph::getAllBlocks).flatMap(Collection::stream).toList();
|
||||
sizeInfo.append("SIZE blocks ").append(allBlocks.size()).append("\n");
|
||||
int numStmt = allBlocks.stream().mapToInt(block -> block.getStatements().size()).sum();
|
||||
sizeInfo.append("SIZE statements ").append(numStmt).append("\n");
|
||||
int numPhiVars = allBlocks.stream().mapToInt(value -> value.getStatements().stream().mapToInt(value1 -> (value1 instanceof StatementPhiBlock) ? ((StatementPhiBlock) value1).getPhiVariables().size() : 0).sum()).sum();
|
||||
sizeInfo.append("SIZE phi variables ").append(numPhiVars).append("\n");
|
||||
|
||||
if(variableReferenceInfos != null)
|
||||
sizeInfo.append(variableReferenceInfos.getSizeInfo());
|
||||
if(getLiveRangeEquivalenceClassSet() != null)
|
||||
|
@ -1,57 +0,0 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
|
||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* A snapshot of all dynamic data in a {@link Program}.
|
||||
* Used whenever the compiler need to run an experiment where it may need to roll back to a previous state.
|
||||
*/
|
||||
public class ProgramSnapshot {
|
||||
|
||||
/** The main scope. PASS 0-5 (DYNAMIC) */
|
||||
private ProgramScope scope;
|
||||
/** The control flow graph. PASS 1-5 (DYNAMIC) */
|
||||
private ControlFlowGraph graph;
|
||||
|
||||
public ProgramSnapshot(ProgramScope scope, ControlFlowGraph graph) {
|
||||
this.scope = snapshot(scope);
|
||||
this.graph = snapshot(graph);
|
||||
}
|
||||
|
||||
public ProgramScope getScope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
public ControlFlowGraph getGraph() {
|
||||
return graph;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a deep copy of an object (by using serialization)
|
||||
* @param orig The object tot copy
|
||||
* @return the copy with zero references to the original
|
||||
*/
|
||||
private static <T extends Object> T snapshot(T orig) {
|
||||
if(orig==null) return null;
|
||||
T obj = null;
|
||||
try {
|
||||
// Write the object out to a byte array
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream out = new ObjectOutputStream(bos);
|
||||
out.writeObject(orig);
|
||||
out.flush();
|
||||
out.close();
|
||||
// Make an input stream from the byte array and read a copy of the object back in.
|
||||
ObjectInputStream in = new ObjectInputStream(
|
||||
new ByteArrayInputStream(bos.toByteArray()));
|
||||
obj = (T) in.readObject();
|
||||
}
|
||||
catch(IOException | ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
}
|
@ -16,7 +16,6 @@ import dk.camelot64.kickc.parser.KickCParserBaseVisitor;
|
||||
import dk.camelot64.kickc.passes.utils.SizeOfConstants;
|
||||
import org.antlr.v4.runtime.BufferedTokenStream;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.RuleContext;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
@ -52,7 +51,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
this.scopeStack = new Stack<>();
|
||||
this.currentCallingConvention = initialCallingConvention;
|
||||
this.currentEncoding = defaultEncoding;
|
||||
this.pragmaConstructorFors = new ArrayList();
|
||||
this.pragmaConstructorFors = new ArrayList<>();
|
||||
this.currentInterruptType = defaultInterruptType;
|
||||
scopeStack.push(program.getScope());
|
||||
}
|
||||
@ -241,21 +240,21 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
public Object visitPragma(KickCParser.PragmaContext ctx) {
|
||||
final String pragmaName = ctx.NAME().getText();
|
||||
switch(pragmaName) {
|
||||
case CParser.PRAGMA_TARGET:
|
||||
throw new InternalError("Error! #pragma target() should be handled in preprocessor!");
|
||||
case CParser.PRAGMA_CPU:
|
||||
case CParser.PRAGMA_TARGET ->
|
||||
throw new InternalError("Error! #pragma target() should be handled in preprocessor!");
|
||||
case CParser.PRAGMA_CPU -> {
|
||||
final String cpuName = pragmaParamName(pragmaParamSingle(ctx));
|
||||
TargetCpu cpu = TargetCpu.getTargetCpu(cpuName, false);
|
||||
program.getTargetPlatform().setCpu(cpu);
|
||||
break;
|
||||
case CParser.PRAGMA_VAR_MODEL:
|
||||
}
|
||||
case CParser.PRAGMA_VAR_MODEL -> {
|
||||
final List<KickCParser.PragmaParamContext> pragmaParams = ctx.pragmaParam();
|
||||
List<String> settings = pragmaParams.stream().map(Pass0GenerateStatementSequence::pragmaParamName).collect(Collectors.toList());
|
||||
final VariableBuilderConfig config = VariableBuilderConfig.fromSettings(settings, new StatementSource(ctx));
|
||||
config.setStructModelClassic(program.getTargetPlatform().getVariableBuilderConfig().isStructModelClassic());
|
||||
program.getTargetPlatform().setVariableBuilderConfig(config);
|
||||
break;
|
||||
case CParser.PRAGMA_STRUCT_MODEL:
|
||||
}
|
||||
case CParser.PRAGMA_STRUCT_MODEL -> {
|
||||
final String modelName = pragmaParamName(pragmaParamSingle(ctx));
|
||||
if(modelName.equalsIgnoreCase("classic"))
|
||||
program.getTargetPlatform().getVariableBuilderConfig().setStructModelClassic(true);
|
||||
@ -263,61 +262,52 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
program.getTargetPlatform().getVariableBuilderConfig().setStructModelClassic(true);
|
||||
else
|
||||
throw new CompileError("Unknown struct model " + modelName, new StatementSource(ctx));
|
||||
break;
|
||||
case CParser.PRAGMA_LINKSCRIPT:
|
||||
}
|
||||
case CParser.PRAGMA_LINKSCRIPT -> {
|
||||
final String linkScriptName = pragmaParamString(pragmaParamSingle(ctx));
|
||||
program.getLog().append("Loading link script \"" + linkScriptName + "\"");
|
||||
Path currentPath = cParser.getSourceFolderPath(ctx);
|
||||
final File linkScriptFile = SourceLoader.loadFile(linkScriptName, currentPath, program.getTargetPlatformPaths());
|
||||
program.getTargetPlatform().setLinkScriptFile(linkScriptFile);
|
||||
break;
|
||||
case CParser.PRAGMA_EXTENSION:
|
||||
}
|
||||
case CParser.PRAGMA_EXTENSION -> {
|
||||
String extension = pragmaParamString(pragmaParamSingle(ctx));
|
||||
program.getTargetPlatform().setOutFileExtension(extension);
|
||||
program.getOutputFileManager().setBinaryExtension(extension);
|
||||
break;
|
||||
case CParser.PRAGMA_EMULATOR:
|
||||
}
|
||||
case CParser.PRAGMA_EMULATOR -> {
|
||||
String emuName = pragmaParamString(pragmaParamSingle(ctx));
|
||||
program.getTargetPlatform().setEmulatorCommand(emuName);
|
||||
break;
|
||||
case CParser.PRAGMA_ENCODING:
|
||||
}
|
||||
case CParser.PRAGMA_ENCODING -> {
|
||||
final String encodingName = pragmaParamName(pragmaParamSingle(ctx));
|
||||
try {
|
||||
this.currentEncoding = StringEncoding.fromName(encodingName.toUpperCase(Locale.ENGLISH));
|
||||
} catch(IllegalArgumentException e) {
|
||||
throw new CompileError("Unknown string encoding " + encodingName, new StatementSource(ctx));
|
||||
}
|
||||
break;
|
||||
case CParser.PRAGMA_CODE_SEG:
|
||||
this.currentCodeSegment = pragmaParamName(pragmaParamSingle(ctx));
|
||||
break;
|
||||
case CParser.PRAGMA_DATA_SEG:
|
||||
this.currentDataSegment = pragmaParamName(pragmaParamSingle(ctx));
|
||||
break;
|
||||
case CParser.PRAGMA_RESOURCE:
|
||||
}
|
||||
case CParser.PRAGMA_CODE_SEG -> this.currentCodeSegment = pragmaParamName(pragmaParamSingle(ctx));
|
||||
case CParser.PRAGMA_DATA_SEG -> this.currentDataSegment = pragmaParamName(pragmaParamSingle(ctx));
|
||||
case CParser.PRAGMA_RESOURCE -> {
|
||||
String resourceFileName = pragmaParamString(pragmaParamSingle(ctx));
|
||||
addResourceFile(ctx, resourceFileName);
|
||||
break;
|
||||
case CParser.PRAGMA_START_ADDRESS:
|
||||
}
|
||||
case CParser.PRAGMA_START_ADDRESS -> {
|
||||
Number startAddress = pragmaParamNumber(pragmaParamSingle(ctx));
|
||||
program.getTargetPlatform().setStartAddress(startAddress);
|
||||
break;
|
||||
case CParser.PRAGMA_CALLING:
|
||||
currentCallingConvention = pragmaParamCallingConvention(pragmaParamSingle(ctx));
|
||||
break;
|
||||
case CParser.PRAGMA_INTERRUPT:
|
||||
this.currentInterruptType = pragmaParamName(pragmaParamSingle(ctx));
|
||||
break;
|
||||
case CParser.PRAGMA_ZP_RESERVE:
|
||||
}
|
||||
case CParser.PRAGMA_CALLING -> currentCallingConvention = pragmaParamCallingConvention(pragmaParamSingle(ctx));
|
||||
case CParser.PRAGMA_INTERRUPT -> this.currentInterruptType = pragmaParamName(pragmaParamSingle(ctx));
|
||||
case CParser.PRAGMA_ZP_RESERVE -> {
|
||||
List<Integer> reservedZps = pragmaParamRanges(ctx.pragmaParam());
|
||||
program.addReservedZps(reservedZps);
|
||||
break;
|
||||
case CParser.PRAGMA_CONSTRUCTOR_FOR:
|
||||
}
|
||||
case CParser.PRAGMA_CONSTRUCTOR_FOR -> {
|
||||
this.pragmaConstructorFors.add(ctx);
|
||||
return null;
|
||||
default:
|
||||
program.getLog().append("Warning! Unknown #pragma " + pragmaName);
|
||||
|
||||
}
|
||||
default -> program.getLog().append("Warning! Unknown #pragma " + pragmaName);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -492,7 +482,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
private Procedure declareProcedure(boolean defineProcedure, ParserRuleContext ctx, StatementSource statementSource) {
|
||||
|
||||
Procedure procedure = new Procedure(varDecl.getVarName(), (SymbolTypeProcedure) varDecl.getEffectiveType(), program.getScope(), currentCodeSegment, currentDataSegment, currentCallingConvention);
|
||||
addDirectives(procedure, varDecl.getDeclDirectives(), statementSource);
|
||||
addDirectives(procedure, varDecl.getDeclDirectives());
|
||||
// Check if the declaration matches any existing declaration!
|
||||
final Symbol existingSymbol = program.getScope().getSymbol(procedure.getRef());
|
||||
if(existingSymbol != null) {
|
||||
@ -518,7 +508,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
|
||||
if(defineProcedure) {
|
||||
// Make sure comments, directives and source are from the definition
|
||||
addDirectives(procedure, varDecl.getDeclDirectives(), statementSource);
|
||||
addDirectives(procedure, varDecl.getDeclDirectives());
|
||||
procedure.setComments(ensureUnusedComments(getCommentsSymbol(ctx)));
|
||||
procedure.setDefinitionSource(statementSource);
|
||||
// enter the procedure
|
||||
@ -753,7 +743,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
|
||||
/** ASM Directive specifying clobber registers. */
|
||||
private static class AsmDirectiveClobber implements AsmDirective {
|
||||
private CpuClobber clobber;
|
||||
private final CpuClobber clobber;
|
||||
|
||||
AsmDirectiveClobber(CpuClobber clobber) {
|
||||
this.clobber = clobber;
|
||||
@ -1052,8 +1042,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
// The previous assignment of an intermediate variable that can be modified instead of creating a new statement
|
||||
StatementLValue previousAssignment = null;
|
||||
|
||||
if(initValue instanceof VariableRef) {
|
||||
VariableRef initVarRef = (VariableRef) initValue;
|
||||
if(initValue instanceof VariableRef initVarRef) {
|
||||
if(initVarRef.isIntermediate()) {
|
||||
Statement previousStatement = getPreviousStatement();
|
||||
if(previousStatement instanceof StatementLValue && ((StatementLValue) previousStatement).getlValue().equals(initVarRef)) {
|
||||
@ -1106,7 +1095,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
throw new CompileError("Constant value contains a pre/post-modifier.", statementSource);
|
||||
}
|
||||
if(initValue instanceof ForwardVariableRef) {
|
||||
throw new CompileError("Variable used before being defined " + initValue.toString(), statementSource);
|
||||
throw new CompileError("Variable used before being defined " + initValue, statementSource);
|
||||
}
|
||||
if(!(initValue instanceof ConstantValue))
|
||||
throw new CompileError("Initializer is not a constant value.", statementSource);
|
||||
@ -1166,7 +1155,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
* @param procedure The procedure
|
||||
* @param directives The directives to add
|
||||
*/
|
||||
private void addDirectives(Procedure procedure, List<Directive> directives, StatementSource source) {
|
||||
private void addDirectives(Procedure procedure, List<Directive> directives) {
|
||||
for(Directive directive : directives) {
|
||||
if(directive instanceof Directive.Inline) {
|
||||
procedure.setDeclaredInline(true);
|
||||
@ -1271,7 +1260,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
RValue initValue = (initializer == null) ? null : (RValue) visit(initializer);
|
||||
StatementSource statementSource = new StatementSource(ctx);
|
||||
ConstantValue addressAsConstantValue = getConstInitValue(initValue, initializer, statementSource);
|
||||
ConstantLiteral literal = addressAsConstantValue.calculateLiteral(program.getScope());
|
||||
ConstantLiteral<?> literal = addressAsConstantValue.calculateLiteral(program.getScope());
|
||||
if(literal instanceof ConstantInteger) {
|
||||
Long address = ((ConstantInteger) literal).getValue();
|
||||
return new Directive.Address(addressAsConstantValue, address);
|
||||
@ -1739,9 +1728,8 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
|
||||
private void addLoopBody(KickCParser.StmtContext stmt) {
|
||||
if(stmt != null) {
|
||||
if(stmt instanceof KickCParser.StmtBlockContext) {
|
||||
if(stmt instanceof KickCParser.StmtBlockContext stmtBlockContext) {
|
||||
// Skip the block context and reuse the one created by the for() itself
|
||||
KickCParser.StmtBlockContext stmtBlockContext = (KickCParser.StmtBlockContext) stmt;
|
||||
if(stmtBlockContext.stmtSeq() != null) {
|
||||
this.visit(stmtBlockContext.stmtSeq());
|
||||
}
|
||||
@ -1836,7 +1824,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
private Map<String, SymbolRef> getAsmReferencedSymbolVariables(KickCParser.StmtAsmContext
|
||||
ctx, List<String> definedLabels) {
|
||||
Map<String, SymbolRef> referenced = new LinkedHashMap<>();
|
||||
KickCParserBaseVisitor<Void> findReferenced = new KickCParserBaseVisitor<Void>() {
|
||||
KickCParserBaseVisitor<Void> findReferenced = new KickCParserBaseVisitor<>() {
|
||||
|
||||
@Override
|
||||
public Void visitAsmExprBinary(KickCParser.AsmExprBinaryContext ctx) {
|
||||
@ -1881,7 +1869,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
*/
|
||||
private List<String> getAsmDefinedLabels(KickCParser.StmtAsmContext ctx) {
|
||||
List<String> definedLabels = new ArrayList<>();
|
||||
KickCParserBaseVisitor<Void> findDefinedLabels = new KickCParserBaseVisitor<Void>() {
|
||||
KickCParserBaseVisitor<Void> findDefinedLabels = new KickCParserBaseVisitor<>() {
|
||||
@Override
|
||||
public Void visitAsmLabelName(KickCParser.AsmLabelNameContext ctx) {
|
||||
String label = ctx.ASM_NAME().getText();
|
||||
@ -1932,13 +1920,13 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
|
||||
@Override
|
||||
public Object visitTypeSimple(KickCParser.TypeSimpleContext ctx) {
|
||||
String typeName = "";
|
||||
StringBuilder typeName = new StringBuilder();
|
||||
for(TerminalNode simpleTypeNode : ctx.SIMPLETYPE()) {
|
||||
if(typeName.length() > 0)
|
||||
typeName += " ";
|
||||
typeName += simpleTypeNode.getText();
|
||||
typeName.append(" ");
|
||||
typeName.append(simpleTypeNode.getText());
|
||||
}
|
||||
final SymbolType typeSimple = SymbolType.get(typeName);
|
||||
final SymbolType typeSimple = SymbolType.get(typeName.toString());
|
||||
if(typeSimple == null)
|
||||
throw new CompileError("Unknown type '" + typeName + "'", new StatementSource(ctx));
|
||||
varDecl.setDeclType(typeSimple);
|
||||
@ -2291,12 +2279,11 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
public Object visitExprAssignment(KickCParser.ExprAssignmentContext ctx) {
|
||||
Object val = visit(ctx.expr(0));
|
||||
if(val instanceof ConstantRef) {
|
||||
throw new CompileError("const variable may not be modified " + val.toString(), new StatementSource(ctx));
|
||||
throw new CompileError("const variable may not be modified " + val, new StatementSource(ctx));
|
||||
}
|
||||
if(!(val instanceof LValue)) {
|
||||
if(!(val instanceof LValue lValue)) {
|
||||
throw new CompileError("Illegal assignment Lvalue " + val.toString(), new StatementSource(ctx));
|
||||
}
|
||||
LValue lValue = (LValue) val;
|
||||
if(lValue instanceof VariableRef && ((VariableRef) lValue).isIntermediate()) {
|
||||
// Encountered an intermediate variable. This must be turned into a proper LValue later. Put it into a marker to signify that
|
||||
lValue = new LvalueIntermediate((VariableRef) lValue);
|
||||
@ -2313,10 +2300,9 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
public Object visitExprAssignmentCompound(KickCParser.ExprAssignmentCompoundContext ctx) {
|
||||
// Assignment (rValue/lValue)
|
||||
Object value = visit(ctx.expr(0));
|
||||
if(!(value instanceof LValue)) {
|
||||
if(!(value instanceof LValue lValue)) {
|
||||
throw new CompileError("Illegal assignment Lvalue " + value.toString(), new StatementSource(ctx));
|
||||
}
|
||||
LValue lValue = (LValue) value;
|
||||
if(lValue instanceof VariableRef && ((VariableRef) lValue).isIntermediate()) {
|
||||
// Encountered an intermediate variable. This must be turned into a proper LValue later. Put it into a marker to signify that
|
||||
lValue = new LvalueIntermediate((VariableRef) lValue);
|
||||
|
@ -52,7 +52,7 @@ public class Pass1AddressOfHandling extends Pass2SsaOptimization {
|
||||
*/
|
||||
private void updateAddressOfValue(Value value, Statement currentStmt) {
|
||||
if(value instanceof SymbolRef) {
|
||||
Symbol toSymbol = getScope().getSymbol((SymbolRef) value);
|
||||
Symbol toSymbol = getProgramScope().getSymbol((SymbolRef) value);
|
||||
final String stmtStr = currentStmt == null ? toSymbol.toString(getProgram()) : currentStmt.toString(getProgram(), false);
|
||||
if(toSymbol instanceof Variable) {
|
||||
final Variable variable = (Variable) toSymbol;
|
||||
|
@ -26,7 +26,7 @@ public class Pass1AsmUsesHandling extends Pass2SsaOptimization {
|
||||
// Symbol used in inline ASM or KickAsm
|
||||
final Value value = programValue.get();
|
||||
if(value instanceof SymbolVariableRef) {
|
||||
Variable variable = getScope().getVariable((SymbolVariableRef) value);
|
||||
Variable variable = getProgramScope().getVariable((SymbolVariableRef) value);
|
||||
if(!variable.isKindConstant() && !variable.isVolatile()) {
|
||||
final String stmtStr = currentStmt == null ? value.toString(getProgram()) : currentStmt.toString(getProgram(), false);
|
||||
updateAddressOfVariable(variable, stmtStr);
|
||||
|
@ -22,13 +22,13 @@ public class Pass1AssertInterrupts extends Pass1Base {
|
||||
for(Statement statement : block.getStatements()) {
|
||||
if(statement instanceof StatementCalling) {
|
||||
ProcedureRef procedureRef = ((StatementCalling) statement).getProcedure();
|
||||
Procedure procedure = getScope().getProcedure(procedureRef);
|
||||
Procedure procedure = getProgramScope().getProcedure(procedureRef);
|
||||
if(procedure.getInterruptType()!=null) {
|
||||
throw new CompileError("Interrupts cannot be called.", statement.getSource());
|
||||
}
|
||||
}
|
||||
}
|
||||
for(Procedure procedure : getScope().getAllProcedures(true)) {
|
||||
for(Procedure procedure : getProgramScope().getAllProcedures(true)) {
|
||||
if(procedure.getInterruptType()!=null) {
|
||||
if(procedure.isDeclaredInline()) {
|
||||
throw new CompileError("Interrupts cannot be inlined. " + procedure.toString());
|
||||
|
@ -29,7 +29,7 @@ public class Pass1AssertJumpLabels extends Pass1Base {
|
||||
for(Statement statement : statementSequence.getStatements()) {
|
||||
if(statement instanceof StatementJump) {
|
||||
LabelRef jumpLabel = ((StatementJump) statement).getDestination();
|
||||
Label label = getScope().getLabel(jumpLabel);
|
||||
Label label = getProgramScope().getLabel(jumpLabel);
|
||||
if(label==null) {
|
||||
throw new CompileError("goto label undefined '"+jumpLabel.getLocalName()+"'", statement);
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ public class Pass1AssertNoLValueIntermediate extends Pass1Base {
|
||||
LValue lValue = ((StatementLValue) statement).getlValue();
|
||||
if(lValue instanceof LvalueIntermediate) {
|
||||
VariableRef intermediateVar = ((LvalueIntermediate) lValue).getVariable();
|
||||
final List<VarAssignments.VarAssignment> varAssignments = VarAssignments.get(intermediateVar, getGraph(), getScope());
|
||||
final List<VarAssignments.VarAssignment> varAssignments = VarAssignments.get(intermediateVar, getGraph(), getProgramScope());
|
||||
final VarAssignments.VarAssignment varAssignment = varAssignments.get(0);
|
||||
throw new CompileError("LValue is illegal. " + statement + " - definition of lValue " + varAssignment, varAssignment.getSource());
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ public class Pass1AssertNoLocalAddressArray extends Pass1Base {
|
||||
|
||||
@Override
|
||||
public boolean step() {
|
||||
for(Variable variable : getScope().getAllVars(true)) {
|
||||
for(Variable variable : getProgramScope().getAllVars(true)) {
|
||||
if(!ScopeRef.ROOT.equals(variable.getScope().getRef()) && variable.isArray() && variable.getMemoryAddress()!=null)
|
||||
throw new CompileError("Error! Local array variables with __address() not allowed. "+variable.toString(getProgram()));
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ public class Pass1AssertNoModifyVars extends Pass1Base {
|
||||
if(statement instanceof StatementLValue) {
|
||||
StatementLValue statementLValue = (StatementLValue) statement;
|
||||
if(!statementLValue.isInitialAssignment() && statementLValue.getlValue() instanceof VariableRef) {
|
||||
Variable assignedVar = getScope().getVariable((VariableRef) statementLValue.getlValue());
|
||||
Variable assignedVar = getProgramScope().getVariable((VariableRef) statementLValue.getlValue());
|
||||
if(assignedVar.isNoModify())
|
||||
throw new CompileError("const variable may not be modified! " + assignedVar.toString(), statement);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ public class Pass1AssertNoRecursion extends Pass1Base {
|
||||
@Override
|
||||
public boolean step() {
|
||||
CallGraph callGraph = getProgram().getCallGraph();
|
||||
Collection<Procedure> procedures = getScope().getAllProcedures(true);
|
||||
Collection<Procedure> procedures = getProgramScope().getAllProcedures(true);
|
||||
for(Procedure procedure : procedures) {
|
||||
Collection<ScopeRef> recursiveCalls = callGraph.getRecursiveCalls(procedure.getRef());
|
||||
if(recursiveCalls.contains(procedure.getRef()) && !Procedure.CallingConvention.STACK_CALL.equals(procedure.getCallingConvention())) {
|
||||
|
@ -31,7 +31,7 @@ public class Pass1AssertProcedureCallParameters extends Pass1Base {
|
||||
for(Statement statement : block.getStatements()) {
|
||||
if(statement instanceof StatementCall) {
|
||||
StatementCall call = (StatementCall) statement;
|
||||
Procedure procedure = getScope().getProcedure(call.getProcedure());
|
||||
Procedure procedure = getProgramScope().getProcedure(call.getProcedure());
|
||||
List<Variable> declParameters = procedure.getParameters();
|
||||
List<RValue> callParameters = call.getParameters();
|
||||
if(callParameters.size()!=declParameters.size()) {
|
||||
@ -40,7 +40,7 @@ public class Pass1AssertProcedureCallParameters extends Pass1Base {
|
||||
for(int i = 0; i < declParameters.size(); i++) {
|
||||
Variable declParameter = declParameters.get(i);
|
||||
RValue callParameter = callParameters.get(i);
|
||||
SymbolType callParameterType = SymbolTypeInference.inferType(getScope(), callParameter);
|
||||
SymbolType callParameterType = SymbolTypeInference.inferType(getProgramScope(), callParameter);
|
||||
SymbolType declParameterType = declParameter.getType();
|
||||
|
||||
if(declParameterType instanceof SymbolTypePointer) {
|
||||
|
@ -2,6 +2,7 @@ package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.CompileError;
|
||||
import dk.camelot64.kickc.model.ControlFlowBlock;
|
||||
import dk.camelot64.kickc.model.ProcedureCompilation;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.symbols.Label;
|
||||
import dk.camelot64.kickc.model.symbols.Procedure;
|
||||
@ -17,7 +18,7 @@ public class Pass1AssertProcedureDefined extends Pass1Base {
|
||||
|
||||
@Override
|
||||
public boolean step() {
|
||||
final Collection<Procedure> allProcedures = getScope().getAllProcedures(true);
|
||||
final Collection<Procedure> allProcedures = getProgramScope().getAllProcedures(true);
|
||||
for(Procedure procedure : allProcedures) {
|
||||
if(procedure.isDeclaredIntrinsic()) {
|
||||
if(!Procedure.INTRINSIC_PROCEDURES.contains(procedure.getLocalName()))
|
||||
@ -25,7 +26,10 @@ public class Pass1AssertProcedureDefined extends Pass1Base {
|
||||
continue;
|
||||
}
|
||||
final Label procedureLabel = procedure.getLabel();
|
||||
final ControlFlowBlock procedureBlock = getGraph().getBlock(procedureLabel.getRef());
|
||||
final ProcedureCompilation procedureCompilation = getProgram().getProcedureCompilation(procedure.getRef());
|
||||
if(procedureCompilation == null)
|
||||
throw new CompileError("Error! Function body is never defined: " + procedure.getFullName());
|
||||
final ControlFlowBlock procedureBlock = procedureCompilation.getGraph().getBlock(procedureLabel.getRef());
|
||||
if(procedureBlock == null)
|
||||
throw new CompileError("Error! Function body is never defined: " + procedure.getFullName());
|
||||
}
|
||||
|
@ -28,9 +28,11 @@ public class Pass1AssertReturn extends Pass1Base {
|
||||
for(Procedure procedure : allProcedures) {
|
||||
if(procedure.isDeclaredIntrinsic()) continue;
|
||||
if(procedure.getReturnType() != null && !SymbolType.VOID.equals(procedure.getReturnType())) {
|
||||
final ProcedureCompilation procedureCompilation = getProgram().getProcedureCompilation(procedure.getRef());
|
||||
final ControlFlowGraph graph = procedureCompilation.getGraph();
|
||||
LabelRef entryLabel = procedure.getRef().getLabelRef();
|
||||
ControlFlowBlock entryBlock = getProgram().getGraph().getBlock(entryLabel);
|
||||
assertReturn(entryBlock, new LinkedHashSet<>());
|
||||
ControlFlowBlock entryBlock = graph.getBlock(entryLabel);
|
||||
assertReturn(graph, entryBlock, new LinkedHashSet<>());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@ -43,7 +45,7 @@ public class Pass1AssertReturn extends Pass1Base {
|
||||
* @param block The block to examine
|
||||
* @param visited Blocks already visited
|
||||
*/
|
||||
public void assertReturn(ControlFlowBlock block, Collection<LabelRef> visited) {
|
||||
public void assertReturn(ControlFlowGraph graph, ControlFlowBlock block, Collection<LabelRef> visited) {
|
||||
if(visited.contains(block.getLabel())) {
|
||||
return;
|
||||
}
|
||||
@ -57,15 +59,15 @@ public class Pass1AssertReturn extends Pass1Base {
|
||||
}
|
||||
} else if(statement instanceof StatementConditionalJump) {
|
||||
StatementConditionalJump cond = (StatementConditionalJump) statement;
|
||||
ControlFlowBlock jumpTo = getProgram().getGraph().getBlock(cond.getDestination());
|
||||
assertReturn(jumpTo, visited);
|
||||
ControlFlowBlock jumpTo = graph.getBlock(cond.getDestination());
|
||||
assertReturn(graph, jumpTo, visited);
|
||||
}
|
||||
}
|
||||
ControlFlowBlock successor = getProgram().getGraph().getBlock(block.getDefaultSuccessor());
|
||||
ControlFlowBlock successor = graph.getBlock(block.getDefaultSuccessor());
|
||||
if(successor == null || successor.getLabel().getLocalName().equals(SymbolRef.PROCEXIT_BLOCK_NAME)) {
|
||||
throw new CompileError("Error! Method must end with a return statement. " + block.getScope().toString(getProgram()));
|
||||
} else {
|
||||
assertReturn(successor, visited);
|
||||
assertReturn(graph, successor, visited);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ public class Pass1AssertUsedVars extends Pass1Base {
|
||||
ControlFlowBlock startBlock = getProgram().getGraph().getBlock(new LabelRef(SymbolRef.START_PROC_NAME));
|
||||
final LinkedHashSet<SymbolVariableRef> defined = new LinkedHashSet<>();
|
||||
// Add all variables with an init-value
|
||||
for(Variable var : getScope().getAllVars(true)) {
|
||||
for(Variable var : getProgramScope().getAllVars(true)) {
|
||||
if(var.getInitValue()!=null) {
|
||||
defined.add(var.getRef());
|
||||
}
|
||||
@ -122,7 +122,6 @@ public class Pass1AssertUsedVars extends Pass1Base {
|
||||
* @param predecessor The block jumping into this block (used for phi analysis)
|
||||
* @param referenceInfos Information about assigned/used variables in statements
|
||||
* @param defined Variables already assigned a value at the point of the first execution of the block
|
||||
* @param visited Blocks already visited
|
||||
*/
|
||||
|
||||
private void assertUsedVarsPhi(ControlFlowBlock block, LabelRef predecessor, VariableReferenceInfos referenceInfos, Collection<SymbolVariableRef> defined) {
|
||||
@ -148,7 +147,7 @@ public class Pass1AssertUsedVars extends Pass1Base {
|
||||
throw new CompileError("Variable used before being defined " + usedRef.toString(getProgram()) + " in " + phiBlock.toString(getProgram(), false), phiBlock.getSource());
|
||||
}
|
||||
}
|
||||
// Add all variables fefined by the PHI block
|
||||
// Add all variables defined by the PHI block
|
||||
Collection<VariableRef> defd = referenceInfos.getDefinedVars(phiBlock);
|
||||
for(VariableRef definedRef : defd) {
|
||||
defined.add(definedRef);
|
||||
|
@ -13,7 +13,7 @@ public class Pass1AssertVariableDefined extends Pass1Base {
|
||||
|
||||
@Override
|
||||
public boolean step() {
|
||||
for(Variable var : getScope().getAllVars(true)) {
|
||||
for(Variable var : getProgramScope().getAllVars(true)) {
|
||||
if(var.isDeclarationOnly())
|
||||
throw new CompileError("Error! Variable is declared but never defined: " + var.getFullName());
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.CompileLog;
|
||||
import dk.camelot64.kickc.model.ControlFlowGraph;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
|
||||
@ -37,7 +36,7 @@ public abstract class Pass1Base implements PassStep {
|
||||
return program;
|
||||
}
|
||||
|
||||
public ProgramScope getScope() {
|
||||
public ProgramScope getProgramScope() {
|
||||
return program.getScope();
|
||||
}
|
||||
|
||||
@ -45,9 +44,4 @@ public abstract class Pass1Base implements PassStep {
|
||||
return program.getLog();
|
||||
}
|
||||
|
||||
public ControlFlowGraph getGraph() {
|
||||
return program.getGraph();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ public class Pass1CallStack extends Pass2SsaOptimization {
|
||||
|
||||
// Introduce STACK_OFFSET constants
|
||||
boolean createStackBase = false;
|
||||
for(Procedure procedure : getScope().getAllProcedures(true)) {
|
||||
for(Procedure procedure : getProgramScope().getAllProcedures(true)) {
|
||||
if(Procedure.CallingConvention.STACK_CALL.equals(procedure.getCallingConvention())) {
|
||||
// Introduce the parameter offsets
|
||||
for(Variable parameter : procedure.getParameters()) {
|
||||
@ -52,7 +52,7 @@ public class Pass1CallStack extends Pass2SsaOptimization {
|
||||
|
||||
// Add global STACK_BASE constant
|
||||
if(createStackBase)
|
||||
CallingConventionStack.getStackBaseConstant(getScope());
|
||||
CallingConventionStack.getStackBaseConstant(getProgramScope());
|
||||
|
||||
// Convert param(xxx) to stackidx(PARAM_X) = xxx
|
||||
if(offsetConstants.size() > 0) {
|
||||
@ -61,7 +61,7 @@ public class Pass1CallStack extends Pass2SsaOptimization {
|
||||
// Convert ParamValues to calling-convention specific param-value
|
||||
ParamValue paramValue = (ParamValue) programValue.get();
|
||||
VariableRef parameterRef = paramValue.getParameter();
|
||||
SymbolType parameterType = SymbolTypeInference.inferType(getScope(), paramValue.getParameter());
|
||||
SymbolType parameterType = SymbolTypeInference.inferType(getProgramScope(), paramValue.getParameter());
|
||||
if(offsetConstants.containsKey(parameterRef)) {
|
||||
StackIdxValue stackIdxValue = new StackIdxValue(offsetConstants.get(parameterRef), parameterType);
|
||||
programValue.set(stackIdxValue);
|
||||
@ -77,7 +77,7 @@ public class Pass1CallStack extends Pass2SsaOptimization {
|
||||
while(stmtIt.hasNext()) {
|
||||
Statement statement = stmtIt.next();
|
||||
if(statement instanceof StatementReturn) {
|
||||
final Scope blockScope = getScope().getScope(block.getScope());
|
||||
final Scope blockScope = getProgramScope().getScope(block.getScope());
|
||||
if(blockScope instanceof Procedure) {
|
||||
Procedure procedure = (Procedure) blockScope;
|
||||
final SymbolType returnType = procedure.getReturnType();
|
||||
@ -182,12 +182,12 @@ public class Pass1CallStack extends Pass2SsaOptimization {
|
||||
} else {
|
||||
// A struct to put on the stack
|
||||
final List<RValue> memberValues = ((ValueList) value).getList();
|
||||
final StructDefinition structDefinition = ((SymbolTypeStruct) returnType).getStructDefinition(getScope());
|
||||
final StructDefinition structDefinition = ((SymbolTypeStruct) returnType).getStructDefinition(getProgramScope());
|
||||
final List<Variable> 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);
|
||||
ConstantRef structMemberOffsetConstant = SizeOfConstants.getStructMemberOffsetConstant(getScope(), structDefinition, memberVar.getLocalName());
|
||||
ConstantRef structMemberOffsetConstant = SizeOfConstants.getStructMemberOffsetConstant(getProgramScope(), structDefinition, memberVar.getLocalName());
|
||||
ConstantBinary memberReturnOffsetConstant = new ConstantBinary(stackReturnOffset, Operators.PLUS, structMemberOffsetConstant);
|
||||
generateStackReturnValues(memberValue, memberVar.getType(), memberReturnOffsetConstant, source, comments, stmtIt);
|
||||
}
|
||||
@ -212,7 +212,7 @@ public class Pass1CallStack extends Pass2SsaOptimization {
|
||||
} else {
|
||||
// A struct to put on the stack
|
||||
final List<RValue> memberValues = ((ValueList) value).getList();
|
||||
final StructDefinition structDefinition = ((SymbolTypeStruct) symbolType).getStructDefinition(getScope());
|
||||
final StructDefinition structDefinition = ((SymbolTypeStruct) symbolType).getStructDefinition(getProgramScope());
|
||||
final List<Variable> memberVars = new ArrayList<>(structDefinition.getAllVars(false));
|
||||
for(int i = 0; i < memberVars.size(); i++) {
|
||||
final Variable memberVar = memberVars.get(i);
|
||||
@ -240,7 +240,7 @@ public class Pass1CallStack extends Pass2SsaOptimization {
|
||||
} else {
|
||||
// A struct to put on the stack
|
||||
final List<RValue> memberValues = ((ValueList) value).getList();
|
||||
final StructDefinition structDefinition = ((SymbolTypeStruct) symbolType).getStructDefinition(getScope());
|
||||
final StructDefinition structDefinition = ((SymbolTypeStruct) symbolType).getStructDefinition(getProgramScope());
|
||||
final List<Variable> memberVars = new ArrayList<>(structDefinition.getAllVars(false));
|
||||
for(int i = 0; i < memberVars.size(); i++) {
|
||||
final Variable memberVar = memberVars.get(i);
|
||||
|
@ -31,7 +31,7 @@ public class Pass1CallStackVarConvert extends Pass2SsaOptimization {
|
||||
if(statement instanceof StatementCall) {
|
||||
StatementCall call = (StatementCall) statement;
|
||||
ProcedureRef procedureRef = call.getProcedure();
|
||||
Procedure procedure = getScope().getProcedure(procedureRef);
|
||||
Procedure procedure = getProgramScope().getProcedure(procedureRef);
|
||||
Procedure.CallingConvention callingConvention = procedure.getCallingConvention();
|
||||
if(Procedure.CallingConvention.STACK_CALL.equals(callingConvention) || Procedure.CallingConvention.VAR_CALL.equals(callingConvention)) {
|
||||
boolean hasParamOrReturn = (call.getParameters().size() > 0) || !SymbolType.VOID.equals(procedure.getReturnType());
|
||||
@ -45,7 +45,7 @@ public class Pass1CallStackVarConvert extends Pass2SsaOptimization {
|
||||
StatementCallPointer call = (StatementCallPointer) statement;
|
||||
boolean hasParamOrReturn = call.getNumParameters() > 0 || call.getlValue() != null;
|
||||
//if(hasParamOrReturn) {
|
||||
final SymbolType procType = SymbolTypeInference.inferType(getScope(), call.getProcedure());
|
||||
final SymbolType procType = SymbolTypeInference.inferType(getProgramScope(), call.getProcedure());
|
||||
if(!(procType instanceof SymbolTypeProcedure)) {
|
||||
throw new CompileError("Called object is not a function or function pointer "+call.getProcedure().toString(), call);
|
||||
}
|
||||
|
@ -26,11 +26,11 @@ public class Pass1CallStackVarPrepare extends Pass2SsaOptimization {
|
||||
public boolean step() {
|
||||
|
||||
// Set variables modified in STACK_CALL/VAR_CALL procedures to load/store
|
||||
for(Procedure procedure : getScope().getAllProcedures(true)) {
|
||||
for(Procedure procedure : getProgramScope().getAllProcedures(true)) {
|
||||
if(Procedure.CallingConvention.STACK_CALL.equals(procedure.getCallingConvention()) || Procedure.CallingConvention.VAR_CALL.equals(procedure.getCallingConvention())) {
|
||||
Set<VariableRef> modifiedVars = getProgram().getProcedureModifiedVars().getModifiedVars(procedure.getRef());
|
||||
for(VariableRef modifiedVar : modifiedVars) {
|
||||
final Variable variable = getScope().getVariable(modifiedVar);
|
||||
final Variable variable = getProgramScope().getVariable(modifiedVar);
|
||||
if(variable.isKindPhiMaster()) {
|
||||
getLog().append("Converting variable modified inside "+procedure.getCallingConvention().getName()+" procedure "+procedure.getFullName()+"() to load/store "+variable.toString(getProgram()));
|
||||
variable.setKind(Variable.Kind.LOAD_STORE);
|
||||
@ -40,7 +40,7 @@ public class Pass1CallStackVarPrepare extends Pass2SsaOptimization {
|
||||
}
|
||||
|
||||
// Set all parameter/return variables in VAR_CALL procedures to LOAD/STORE
|
||||
for(Procedure procedure : getScope().getAllProcedures(true)) {
|
||||
for(Procedure procedure : getProgramScope().getAllProcedures(true)) {
|
||||
if(Procedure.CallingConvention.VAR_CALL.equals(procedure.getCallingConvention())) {
|
||||
for(Variable parameter : procedure.getParameters()) {
|
||||
parameter.setKind(Variable.Kind.LOAD_STORE);
|
||||
@ -55,7 +55,7 @@ public class Pass1CallStackVarPrepare extends Pass2SsaOptimization {
|
||||
}
|
||||
|
||||
// Add parameter assignments at start of procedure in STACK_CALL procedures
|
||||
for(Procedure procedure : getScope().getAllProcedures(true)) {
|
||||
for(Procedure procedure : getProgramScope().getAllProcedures(true)) {
|
||||
if(procedure.isDeclaredIntrinsic()) continue;
|
||||
if(Procedure.CallingConvention.STACK_CALL.equals(procedure.getCallingConvention())) {
|
||||
final ControlFlowBlock procedureBlock = getGraph().getBlock(procedure.getLabel().getRef());
|
||||
|
@ -35,7 +35,7 @@ public class Pass1CallVar extends Pass2SsaOptimization {
|
||||
while(stmtIt.hasNext()) {
|
||||
Statement statement = stmtIt.next();
|
||||
if(statement instanceof StatementReturn) {
|
||||
final Scope blockScope = getScope().getScope(block.getScope());
|
||||
final Scope blockScope = getProgramScope().getScope(block.getScope());
|
||||
if(blockScope instanceof Procedure) {
|
||||
Procedure procedure = (Procedure) blockScope;
|
||||
final SymbolType returnType = procedure.getReturnType();
|
||||
@ -55,7 +55,7 @@ public class Pass1CallVar extends Pass2SsaOptimization {
|
||||
Statement statement = stmtIt.next();
|
||||
if(statement instanceof StatementCallFinalize) {
|
||||
final StatementCallFinalize call = (StatementCallFinalize) statement;
|
||||
Procedure procedure = getScope().getProcedure(call.getProcedure());
|
||||
Procedure procedure = getProgramScope().getProcedure(call.getProcedure());
|
||||
if(Procedure.CallingConvention.VAR_CALL.equals(procedure.getCallingConvention())) {
|
||||
final StatementSource source = call.getSource();
|
||||
final List<Comment> comments = call.getComments();
|
||||
@ -77,7 +77,7 @@ public class Pass1CallVar extends Pass2SsaOptimization {
|
||||
Statement statement = stmtIt.next();
|
||||
if(statement instanceof StatementCallPrepare) {
|
||||
final StatementCallPrepare call = (StatementCallPrepare) statement;
|
||||
Procedure procedure = getScope().getProcedure(call.getProcedure());
|
||||
Procedure procedure = getProgramScope().getProcedure(call.getProcedure());
|
||||
if(Procedure.CallingConvention.VAR_CALL.equals(procedure.getCallingConvention())) {
|
||||
stmtIt.previous();
|
||||
final StatementSource source = call.getSource();
|
||||
@ -110,8 +110,8 @@ public class Pass1CallVar extends Pass2SsaOptimization {
|
||||
} else {
|
||||
final CastValue structLValue = new CastValue(returnType, lValue);
|
||||
// A struct to unwind
|
||||
final ValueSource lValueSource = ValueSourceFactory.getValueSource(structLValue, getProgram(), getScope(), currentStmt, stmtIt, null);
|
||||
final ValueSource rValueSource = ValueSourceFactory.getValueSource(returnVar.getRef(), getProgram(), getScope(), currentStmt, stmtIt, null);
|
||||
final ValueSource lValueSource = ValueSourceFactory.getValueSource(structLValue, getProgram(), getProgramScope(), currentStmt, stmtIt, null);
|
||||
final ValueSource rValueSource = ValueSourceFactory.getValueSource(returnVar.getRef(), getProgram(), getProgramScope(), currentStmt, stmtIt, null);
|
||||
Pass1UnwindStructValues.copyValues(lValueSource, rValueSource, null, false, currentStmt, null, stmtIt, getProgram());
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ public class Pass1CallVoidReturns extends Pass2SsaOptimization {
|
||||
for(Statement statement : block.getStatements()) {
|
||||
if(statement instanceof StatementCall) {
|
||||
final ProcedureRef procedureRef = ((StatementCall) statement).getProcedure();
|
||||
final Procedure procedure = getScope().getProcedure(procedureRef);
|
||||
final Procedure procedure = getProgramScope().getProcedure(procedureRef);
|
||||
if(SymbolType.VOID.equals(procedure.getReturnType())) {
|
||||
// Found a call to a VOID returning procedure
|
||||
final LValue lValue = ((StatementCall) statement).getlValue();
|
||||
@ -46,7 +46,7 @@ public class Pass1CallVoidReturns extends Pass2SsaOptimization {
|
||||
throw new CompileError("Function " + procedure.getLocalName() + " does not return a value! ", usage);
|
||||
} else {
|
||||
// Delete the temporary variable
|
||||
final Variable var = getScope().getVar(tmpVar);
|
||||
final Variable var = getProgramScope().getVar(tmpVar);
|
||||
var.getScope().remove(var);
|
||||
// And remove the lValue
|
||||
((StatementCall) statement).setlValue(null);
|
||||
|
@ -40,7 +40,7 @@ public class Pass1EarlyConstantIdentification extends Pass1Base {
|
||||
// Skip variables allocated into memory
|
||||
continue;
|
||||
if(!isParameter(variableRef)) {
|
||||
final List<VarAssignments.VarAssignment> varAssignments = VarAssignments.get(variableRef, getGraph(), getScope());
|
||||
final List<VarAssignments.VarAssignment> varAssignments = VarAssignments.get(variableRef, getGraph(), getProgramScope());
|
||||
if(varAssignments.size() == 1) {
|
||||
final VarAssignments.VarAssignment varAssignment = varAssignments.get(0);
|
||||
if(varAssignment.type.equals(VarAssignments.VarAssignment.Type.STATEMENT_LVALUE)) {
|
||||
@ -112,13 +112,13 @@ public class Pass1EarlyConstantIdentification extends Pass1Base {
|
||||
*/
|
||||
private ConstantValue prepareConstantValue(Variable variable, ConstantValue constantValue) {
|
||||
// Perform type checking
|
||||
SymbolType valueType = SymbolTypeInference.inferType(getScope(), constantValue);
|
||||
SymbolType valueType = SymbolTypeInference.inferType(getProgramScope(), constantValue);
|
||||
SymbolType variableType = variable.getType();
|
||||
|
||||
if(!SymbolTypeConversion.assignmentTypeMatch(variableType, valueType) || SymbolType.NUMBER.equals(valueType)) {
|
||||
ConstantLiteral constantLiteral = null;
|
||||
try {
|
||||
constantLiteral = constantValue.calculateLiteral(getScope());
|
||||
constantLiteral = constantValue.calculateLiteral(getProgramScope());
|
||||
} catch(ConstantNotLiteral e) {
|
||||
// ignore
|
||||
}
|
||||
@ -156,7 +156,7 @@ public class Pass1EarlyConstantIdentification extends Pass1Base {
|
||||
* @return true if the variable is a procedure parameter
|
||||
*/
|
||||
public boolean isParameter(SymbolVariableRef variableRef) {
|
||||
Variable var = getScope().getVariable(variableRef);
|
||||
Variable var = getProgramScope().getVariable(variableRef);
|
||||
Scope varScope = var.getScope();
|
||||
if(varScope instanceof Procedure) {
|
||||
List<Variable> parameters = ((Procedure) varScope).getParameters();
|
||||
|
@ -63,12 +63,12 @@ public class Pass1ExtractInlineStrings extends Pass1Base {
|
||||
// Struct member initialization
|
||||
final ProgramValue.ProgramValueConstantStructMember constantStructMember = (ProgramValue.ProgramValueConstantStructMember) programValue;
|
||||
final SymbolVariableRef memberRef = constantStructMember.getMemberRef();
|
||||
final Variable memberDef = getScope().getVar(memberRef);
|
||||
final Variable memberDef = getProgramScope().getVar(memberRef);
|
||||
if(memberDef.getType() instanceof SymbolTypePointer) {
|
||||
if(((SymbolTypePointer) memberDef.getType()).getArraySpec()==null) {
|
||||
// Member is not an array - create a string.
|
||||
nameHint = memberDef.getFullName().replace("::","_").toLowerCase();
|
||||
Variable strConst = Pass1ExtractInlineStrings.this.createStringConstantVar(getScope(), (ConstantString) programValue.get(), nameHint);
|
||||
Variable strConst = Pass1ExtractInlineStrings.this.createStringConstantVar(getProgramScope(), (ConstantString) programValue.get(), nameHint);
|
||||
programValue.set(strConst.getRef());
|
||||
}
|
||||
}
|
||||
@ -79,7 +79,7 @@ public class Pass1ExtractInlineStrings extends Pass1Base {
|
||||
if(elementType instanceof SymbolTypePointer) {
|
||||
if(((SymbolTypePointer) elementType).getArraySpec()==null) {
|
||||
// Element is not an array - create a string.
|
||||
Variable strConst = Pass1ExtractInlineStrings.this.createStringConstantVar(getScope(), (ConstantString) programValue.get(), null);
|
||||
Variable strConst = Pass1ExtractInlineStrings.this.createStringConstantVar(getProgramScope(), (ConstantString) programValue.get(), null);
|
||||
programValue.set(strConst.getRef());
|
||||
}
|
||||
}
|
||||
|
@ -4,20 +4,16 @@ import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.statements.*;
|
||||
import dk.camelot64.kickc.model.symbols.*;
|
||||
import dk.camelot64.kickc.model.values.LabelRef;
|
||||
import dk.camelot64.kickc.model.values.ProcedureRef;
|
||||
import dk.camelot64.kickc.model.values.ScopeRef;
|
||||
import dk.camelot64.kickc.model.values.SymbolRef;
|
||||
import org.antlr.v4.runtime.RuleContext;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
/** Pass that generates a control flow graph for the program */
|
||||
public class Pass1GenerateControlFlowGraph extends Pass1Base {
|
||||
|
||||
private List<ControlFlowBlock> blocks;
|
||||
|
||||
public Pass1GenerateControlFlowGraph(Program program) {
|
||||
super(program);
|
||||
@ -25,8 +21,7 @@ public class Pass1GenerateControlFlowGraph extends Pass1Base {
|
||||
|
||||
@Override
|
||||
public boolean step() {
|
||||
this.blocks = new ArrayList<>();
|
||||
ProgramScope programScope = getScope();
|
||||
ProgramScope programScope = getProgramScope();
|
||||
final Collection<Procedure> allProcedures = getProgram().getScope().getAllProcedures(true);
|
||||
for(Procedure procedure : allProcedures) {
|
||||
if(procedure.isDeclaredIntrinsic())
|
||||
@ -34,10 +29,13 @@ public class Pass1GenerateControlFlowGraph extends Pass1Base {
|
||||
final ProcedureCompilation procedureCompilation = getProgram().getProcedureCompilation(procedure.getRef());
|
||||
final StatementSequence sequence = procedureCompilation.getStatementSequence();
|
||||
if(sequence.getStatements().size()==0)
|
||||
// Empry procedures should not produce any blocks
|
||||
// Empty procedures should not produce any blocks
|
||||
continue;
|
||||
|
||||
List<ControlFlowBlock> blocks = new ArrayList<>();
|
||||
|
||||
ControlFlowBlock currentBlock = null;
|
||||
ControlFlowBlock procBlock = getOrCreateBlock(procedure.getLabel().getRef(), procedure.getRef());
|
||||
ControlFlowBlock procBlock = getOrCreateBlock(procedure.getLabel().getRef(), procedure.getRef(), blocks);
|
||||
currentBlock = procBlock;
|
||||
for(Statement statement : sequence.getStatements()) {
|
||||
Symbol currentBlockLabel = getProgram().getScope().getSymbol(currentBlock.getLabel());
|
||||
@ -54,21 +52,21 @@ public class Pass1GenerateControlFlowGraph extends Pass1Base {
|
||||
currentBlock.setDefaultSuccessor(new Label(SymbolRef.PROCEXIT_BLOCK_NAME, programScope, false).getRef());
|
||||
} else if(statement instanceof StatementLabel) {
|
||||
StatementLabel statementLabel = (StatementLabel) statement;
|
||||
ControlFlowBlock nextBlock = getOrCreateBlock(statementLabel.getLabel(), currentBlock.getScope());
|
||||
ControlFlowBlock nextBlock = getOrCreateBlock(statementLabel.getLabel(), currentBlock.getScope(), blocks);
|
||||
nextBlock.setComments(statementLabel.getComments());
|
||||
currentBlock.setDefaultSuccessor(nextBlock.getLabel());
|
||||
currentBlock = nextBlock;
|
||||
} else if(statement instanceof StatementJump) {
|
||||
StatementJump statementJump = (StatementJump) statement;
|
||||
ControlFlowBlock jmpBlock = getOrCreateBlock(statementJump.getDestination(), currentBlock.getScope());
|
||||
ControlFlowBlock jmpBlock = getOrCreateBlock(statementJump.getDestination(), currentBlock.getScope(), blocks);
|
||||
currentBlock.setDefaultSuccessor(jmpBlock.getLabel());
|
||||
ControlFlowBlock nextBlock = getOrCreateBlock(currentBlockScope.addLabelIntermediate().getRef(), currentBlock.getScope());
|
||||
ControlFlowBlock nextBlock = getOrCreateBlock(currentBlockScope.addLabelIntermediate().getRef(), currentBlock.getScope(), blocks);
|
||||
currentBlock = nextBlock;
|
||||
} else if(statement instanceof StatementConditionalJump) {
|
||||
currentBlock.addStatement(statement);
|
||||
StatementConditionalJump statementConditionalJump = (StatementConditionalJump) statement;
|
||||
ControlFlowBlock jmpBlock = getOrCreateBlock(statementConditionalJump.getDestination(), currentBlock.getScope());
|
||||
ControlFlowBlock nextBlock = getOrCreateBlock(currentBlockScope.addLabelIntermediate().getRef(), currentBlock.getScope());
|
||||
ControlFlowBlock jmpBlock = getOrCreateBlock(statementConditionalJump.getDestination(), currentBlock.getScope(), blocks);
|
||||
ControlFlowBlock nextBlock = getOrCreateBlock(currentBlockScope.addLabelIntermediate().getRef(), currentBlock.getScope(), blocks);
|
||||
currentBlock.setDefaultSuccessor(nextBlock.getLabel());
|
||||
currentBlock.setConditionalSuccessor(jmpBlock.getLabel());
|
||||
currentBlock = nextBlock;
|
||||
@ -76,18 +74,18 @@ public class Pass1GenerateControlFlowGraph extends Pass1Base {
|
||||
// Procedure strategy implemented is currently variable-based transfer of parameters/return values
|
||||
StatementReturn aReturn = (StatementReturn) statement;
|
||||
currentBlock.addStatement(aReturn);
|
||||
// TODO: Make all returns exit through the same exit-block!
|
||||
} else {
|
||||
currentBlock.addStatement(statement);
|
||||
}
|
||||
}
|
||||
ControlFlowGraph controlFlowGraph = new ControlFlowGraph(blocks);
|
||||
procedureCompilation.setGraph(controlFlowGraph);
|
||||
|
||||
}
|
||||
ControlFlowGraph controlFlowGraph = new ControlFlowGraph(blocks);
|
||||
getProgram().setGraph(controlFlowGraph);
|
||||
return false;
|
||||
}
|
||||
|
||||
private ControlFlowBlock getOrCreateBlock(LabelRef label, ScopeRef scope) {
|
||||
private ControlFlowBlock getOrCreateBlock(LabelRef label, ScopeRef scope, List<ControlFlowBlock> blocks) {
|
||||
for(ControlFlowBlock block : blocks) {
|
||||
if(block.getLabel().equals(label)) {
|
||||
return block;
|
||||
|
@ -80,7 +80,7 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
|
||||
* @param source The statement source - usable for error messages
|
||||
*/
|
||||
private void versionAssignment(VariableRef lValueRef, ProgramValue programLValue, StatementSource source) {
|
||||
Variable assignedVar = getScope().getVariable(lValueRef);
|
||||
Variable assignedVar = getProgramScope().getVariable(lValueRef);
|
||||
if(assignedVar.isKindPhiMaster()) {
|
||||
if(assignedVar.isVolatile())
|
||||
throw new InternalError("Error! Volatiles can not be versioned ", source);
|
||||
@ -132,7 +132,7 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
|
||||
}
|
||||
|
||||
private void updateBlockVersions(VariableRef lValue, Map<Variable, Variable> blockVersions) {
|
||||
Variable variable = Pass1GenerateSingleStaticAssignmentForm.this.getScope().getVariable(lValue);
|
||||
Variable variable = Pass1GenerateSingleStaticAssignmentForm.this.getProgramScope().getVariable(lValue);
|
||||
if(variable.isKindPhiVersion()) {
|
||||
blockVersions.put(variable.getPhiMaster(), variable);
|
||||
}
|
||||
@ -153,7 +153,7 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
|
||||
Map<Variable, Variable> blockNewPhis) {
|
||||
Variable version = null;
|
||||
if(rValue instanceof VariableRef) {
|
||||
Variable rValueVar = getScope().getVariable((VariableRef) rValue);
|
||||
Variable rValueVar = getProgramScope().getVariable((VariableRef) rValue);
|
||||
if(rValueVar.isKindPhiMaster()) {
|
||||
// rValue needs versioning - look for version in statements
|
||||
Variable rSymbol = rValueVar;
|
||||
@ -200,7 +200,7 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
|
||||
for(StatementPhiBlock.PhiVariable phiVariable : phiBlock.getPhiVariables()) {
|
||||
if(phiVariable.isEmpty()) {
|
||||
VariableRef phiLValVarRef = phiVariable.getVariable();
|
||||
Variable versioned = getScope().getVariable(phiLValVarRef);
|
||||
Variable versioned = getProgramScope().getVariable(phiLValVarRef);
|
||||
Variable unversioned = versioned.getPhiMaster();
|
||||
List<ControlFlowBlock> predecessors = getPhiPredecessors(block, getProgram());
|
||||
for(ControlFlowBlock predecessor : predecessors) {
|
||||
@ -295,7 +295,7 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
|
||||
|
||||
private void addSymbolToMap(LValue lValue, ControlFlowBlock block, Map<LabelRef, Map<Variable, Variable>> symbolMap) {
|
||||
if(lValue instanceof VariableRef) {
|
||||
Variable lValueVar = getScope().getVariable((VariableRef) lValue);
|
||||
Variable lValueVar = getProgramScope().getVariable((VariableRef) lValue);
|
||||
if(lValueVar.isKindPhiVersion()) {
|
||||
Variable versioned = lValueVar;
|
||||
LabelRef label = block.getLabel();
|
||||
|
@ -24,7 +24,7 @@ public class Pass1ModifiedVarsAnalysis extends Pass1Base {
|
||||
@Override
|
||||
public boolean step() {
|
||||
Map<ProcedureRef, Set<VariableRef>> modified = new LinkedHashMap<>();
|
||||
Collection<Procedure> allProcedures = getScope().getAllProcedures(true);
|
||||
Collection<Procedure> allProcedures = getProgramScope().getAllProcedures(true);
|
||||
for(Procedure procedure : allProcedures) {
|
||||
Set<VariableRef> modifiedVars = getModifiedVars(procedure, new HashSet<>());
|
||||
modified.put(procedure.getRef(), modifiedVars);
|
||||
@ -60,7 +60,7 @@ public class Pass1ModifiedVarsAnalysis extends Pass1Base {
|
||||
}
|
||||
if(statement instanceof StatementCalling) {
|
||||
ProcedureRef called = ((StatementCalling) statement).getProcedure();
|
||||
Procedure calledProc = getScope().getProcedure(called);
|
||||
Procedure calledProc = getProgramScope().getProcedure(called);
|
||||
modified.addAll(getModifiedVars(calledProc, visited));
|
||||
}
|
||||
}
|
||||
|
@ -69,8 +69,8 @@ public class Pass1PointerSizeofFix extends Pass1Base {
|
||||
getLog().append("Fixing pointer array-indexing " + deref.toString(getProgram()));
|
||||
SymbolVariableRef idx2VarRef = handled.getOrDefault(currentStmt, new LinkedHashMap<>()).get(deref.getIndex());
|
||||
if(idx2VarRef == null) {
|
||||
SymbolType type = SymbolTypeInference.inferType(getScope(), deref.getIndex());
|
||||
Scope scope = getScope().getScope(currentBlock.getScope());
|
||||
SymbolType type = SymbolTypeInference.inferType(getProgramScope(), deref.getIndex());
|
||||
Scope scope = getProgramScope().getScope(currentBlock.getScope());
|
||||
Variable idx2Var = VariableBuilder.createIntermediate(scope, type, getProgram());
|
||||
ConstantRef sizeOfTargetType = SizeOfConstants.getSizeOfConstantVar(getProgram().getScope(), pointerType.getElementType());
|
||||
StatementAssignment idx2 = new StatementAssignment((LValue) idx2Var.getRef(), deref.getIndex(), Operators.MULTIPLY, sizeOfTargetType, true, currentStmt.getSource(), Comment.NO_COMMENTS);
|
||||
@ -107,15 +107,15 @@ public class Pass1PointerSizeofFix extends Pass1Base {
|
||||
if(Operators.PLUS.equals(assignment.getOperator()) || Operators.MINUS.equals(assignment.getOperator())) {
|
||||
boolean isPointerPlusConst = true;
|
||||
if(assignment.getrValue2() instanceof SymbolVariableRef) {
|
||||
Symbol symbolR2 = getScope().getSymbol((SymbolVariableRef) assignment.getrValue2());
|
||||
Symbol symbolR2 = getProgramScope().getSymbol((SymbolVariableRef) assignment.getrValue2());
|
||||
if(symbolR2.getType() instanceof SymbolTypePointer) {
|
||||
// RValue 2 is a pointer
|
||||
isPointerPlusConst = false;
|
||||
if(getLog().isVerboseParse())
|
||||
getLog().append("Fixing pointer addition " + assignment.toString(getProgram(), false));
|
||||
LValue lValue = assignment.getlValue();
|
||||
Scope scope = getScope().getScope(block.getScope());
|
||||
SymbolType type = SymbolTypeInference.inferType(getScope(), assignment.getlValue());
|
||||
Scope scope = getProgramScope().getScope(block.getScope());
|
||||
SymbolType type = SymbolTypeInference.inferType(getProgramScope(), assignment.getlValue());
|
||||
Variable tmpVar = VariableBuilder.createIntermediate(scope, type, getProgram());
|
||||
assignment.setlValue((LValue) tmpVar.getRef());
|
||||
ConstantRef sizeOfTargetType = SizeOfConstants.getSizeOfConstantVar(getProgram().getScope(), pointerType.getElementType());
|
||||
@ -128,8 +128,8 @@ public class Pass1PointerSizeofFix extends Pass1Base {
|
||||
// Adding to a pointer - multiply by sizeof()
|
||||
if(getLog().isVerboseParse())
|
||||
getLog().append("Fixing pointer addition " + assignment.toString(getProgram(), false));
|
||||
Scope scope = getScope().getScope(block.getScope());
|
||||
SymbolType type = SymbolTypeInference.inferType(getScope(), assignment.getrValue2());
|
||||
Scope scope = getProgramScope().getScope(block.getScope());
|
||||
SymbolType type = SymbolTypeInference.inferType(getProgramScope(), assignment.getrValue2());
|
||||
Variable tmpVar = VariableBuilder.createIntermediate(scope, type, getProgram());
|
||||
stmtIt.remove();
|
||||
ConstantRef sizeOfTargetType = SizeOfConstants.getSizeOfConstantVar(getProgram().getScope(), pointerType.getElementType());
|
||||
@ -187,7 +187,7 @@ public class Pass1PointerSizeofFix extends Pass1Base {
|
||||
private SymbolTypePointer getPointerType(RValue pointer) {
|
||||
if(pointer instanceof SymbolVariableRef) {
|
||||
SymbolVariableRef varRef = (SymbolVariableRef) pointer;
|
||||
Variable variable = getScope().getVar(varRef);
|
||||
Variable variable = getProgramScope().getVar(varRef);
|
||||
SymbolType type = variable.getType();
|
||||
if(type instanceof SymbolTypePointer) {
|
||||
return (SymbolTypePointer) type;
|
||||
@ -195,9 +195,9 @@ public class Pass1PointerSizeofFix extends Pass1Base {
|
||||
} else if(pointer instanceof StructMemberRef) {
|
||||
StructMemberRef structMemberRef = (StructMemberRef) pointer;
|
||||
RValue struct = structMemberRef.getStruct();
|
||||
SymbolType structType = SymbolTypeInference.inferType(getScope(), struct);
|
||||
SymbolType structType = SymbolTypeInference.inferType(getProgramScope(), struct);
|
||||
if(structType instanceof SymbolTypeStruct) {
|
||||
StructDefinition structDefinition = ((SymbolTypeStruct) structType).getStructDefinition(getScope());
|
||||
StructDefinition structDefinition = ((SymbolTypeStruct) structType).getStructDefinition(getProgramScope());
|
||||
Variable memberVariable = structDefinition.getMember(structMemberRef.getMemberName());
|
||||
SymbolType memberType = memberVariable.getType();
|
||||
if(memberType instanceof SymbolTypePointer) {
|
||||
|
@ -129,7 +129,7 @@ public class Pass1PrintfIntrinsicRewrite extends Pass2SsaOptimization {
|
||||
final String formatString = ((ConstantString) formatLiteral).getString();
|
||||
final StringEncoding formatEncoding = ((ConstantString) formatLiteral).getEncoding();
|
||||
|
||||
Symbol putcSymbol = getScope().getGlobalSymbol(putcName);
|
||||
Symbol putcSymbol = getProgramScope().getGlobalSymbol(putcName);
|
||||
if(putcSymbol==null)
|
||||
throw new CompileError("Needed printf sub-procedure not found " + putcName + "().", ((Statement) printfCall).getSource());
|
||||
ConstantValue putcRef = new ConstantSymbolPointer(putcSymbol.getRef());
|
||||
@ -209,24 +209,24 @@ public class Pass1PrintfIntrinsicRewrite extends Pass2SsaOptimization {
|
||||
switch(typeField) {
|
||||
case "d":
|
||||
case "i":
|
||||
radix = getScope().getLocalConstant(DECIMAL).getRef();
|
||||
radix = getProgramScope().getLocalConstant(DECIMAL).getRef();
|
||||
signed = true;
|
||||
break;
|
||||
case "u":
|
||||
radix = getScope().getLocalConstant(DECIMAL).getRef();
|
||||
radix = getProgramScope().getLocalConstant(DECIMAL).getRef();
|
||||
signed = false;
|
||||
break;
|
||||
case "x":
|
||||
radix = getScope().getLocalConstant(HEXADECIMAL).getRef();
|
||||
radix = getProgramScope().getLocalConstant(HEXADECIMAL).getRef();
|
||||
signed = false;
|
||||
break;
|
||||
case "X":
|
||||
radix = getScope().getLocalConstant(HEXADECIMAL).getRef();
|
||||
radix = getProgramScope().getLocalConstant(HEXADECIMAL).getRef();
|
||||
signed = false;
|
||||
upperCase = 1l;
|
||||
break;
|
||||
case "o":
|
||||
radix = getScope().getLocalConstant(OCTAL).getRef();
|
||||
radix = getProgramScope().getLocalConstant(OCTAL).getRef();
|
||||
signed = false;
|
||||
break;
|
||||
default:
|
||||
@ -236,7 +236,7 @@ public class Pass1PrintfIntrinsicRewrite extends Pass2SsaOptimization {
|
||||
if(lengthField == null) {
|
||||
// Check if the parameter type is 8-bit or 32-bit
|
||||
RValue paramValue = getParameterValue(parameters, paramIdx, printfCall);
|
||||
SymbolType paramType = SymbolTypeInference.inferType(getScope(), paramValue);
|
||||
SymbolType paramType = SymbolTypeInference.inferType(getProgramScope(), paramValue);
|
||||
if(SymbolType.BYTE.equals(paramType) || SymbolType.SBYTE.equals(paramType)) {
|
||||
// Integer (8bit)
|
||||
printf_number_procedure = signed ? PRINTF_SCHAR : PRINTF_UCHAR;
|
||||
@ -290,7 +290,7 @@ public class Pass1PrintfIntrinsicRewrite extends Pass2SsaOptimization {
|
||||
new ConstantInteger(signAlways, SymbolType.BYTE),
|
||||
new ConstantInteger(zeroPadding, SymbolType.BYTE),
|
||||
new ConstantInteger(upperCase, SymbolType.BYTE),
|
||||
getScope().getLocalConstant(HEXADECIMAL).getRef()
|
||||
getProgramScope().getLocalConstant(HEXADECIMAL).getRef()
|
||||
));
|
||||
addPrintfCall(PRINTF_UINT, Arrays.asList(putcRef, new CastValue(SymbolType.WORD, getParameterValue(parameters, paramIdx, printfCall)), format_number_struct), stmtIt, printfCall);
|
||||
paramIdx++;
|
||||
@ -329,7 +329,7 @@ public class Pass1PrintfIntrinsicRewrite extends Pass2SsaOptimization {
|
||||
*/
|
||||
private void addPrintfCall(String printfProcedureName, List<RValue> printfProcedureParameters, ListIterator<Statement> stmtIt, StatementCall printfCall) {
|
||||
final StatementCall call_printf_str_prefix = new StatementCall(null, printfProcedureName, printfProcedureParameters, printfCall.getSource(), Comment.NO_COMMENTS);
|
||||
final Procedure printfProcedure = getScope().getLocalProcedure(call_printf_str_prefix.getProcedureName());
|
||||
final Procedure printfProcedure = getProgramScope().getLocalProcedure(call_printf_str_prefix.getProcedureName());
|
||||
if(printfProcedure == null) {
|
||||
throw new CompileError("Needed printf sub-procedure not found " + printfProcedureName + "().", printfCall.getSource());
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ public class Pass1ProcedureInline extends Pass1Base {
|
||||
if(statement instanceof StatementCall) {
|
||||
StatementCall call = (StatementCall) statement;
|
||||
ProcedureRef procedureRef = call.getProcedure();
|
||||
Procedure procedure = getScope().getProcedure(procedureRef);
|
||||
Procedure procedure = getProgramScope().getProcedure(procedureRef);
|
||||
if(procedure.isDeclaredInline()) {
|
||||
procedure.setCallingConvention(Procedure.CallingConvention.PHI_CALL);
|
||||
if(procedure.getInterruptType()!=null) {
|
||||
@ -63,7 +63,7 @@ public class Pass1ProcedureInline extends Pass1Base {
|
||||
* @param blocksIt The block iterator pointing to the block containing the call
|
||||
*/
|
||||
private void inlineProcedureCall(StatementCall call, Procedure procedure, ListIterator<Statement> statementsIt, ControlFlowBlock block, ListIterator<ControlFlowBlock> blocksIt) {
|
||||
Scope callScope = getScope().getScope(block.getScope());
|
||||
Scope callScope = getProgramScope().getScope(block.getScope());
|
||||
// Remove call
|
||||
statementsIt.remove();
|
||||
// Find call serial number (handles when multiple calls to the same procedure is made in the call scope)
|
||||
@ -78,7 +78,7 @@ public class Pass1ProcedureInline extends Pass1Base {
|
||||
List<ControlFlowBlock> procedureBlocks = getGraph().getScopeBlocks(procedure.getRef());
|
||||
for(ControlFlowBlock procedureBlock : procedureBlocks) {
|
||||
LabelRef procBlockLabelRef = procedureBlock.getLabel();
|
||||
Symbol procBlockLabel = getScope().getSymbol(procBlockLabelRef);
|
||||
Symbol procBlockLabel = getProgramScope().getSymbol(procBlockLabelRef);
|
||||
Label inlinedBlockLabel;
|
||||
if(procedure.equals(procBlockLabel)) {
|
||||
inlinedBlockLabel = callScope.getLocalLabel(procedure.getLocalName() + serial);
|
||||
@ -119,7 +119,7 @@ public class Pass1ProcedureInline extends Pass1Base {
|
||||
// Remove the tmp var receiving the result
|
||||
LValue lValue = call.getlValue();
|
||||
if(lValue instanceof VariableRef) {
|
||||
callScope.remove(getScope().getVariable((VariableRef) lValue));
|
||||
callScope.remove(getProgramScope().getVariable((VariableRef) lValue));
|
||||
call.setlValue(null);
|
||||
}
|
||||
}
|
||||
@ -147,7 +147,7 @@ public class Pass1ProcedureInline extends Pass1Base {
|
||||
// Set successor of the @return block to the rest block
|
||||
inlinedSuccessor = restBlockLabel.getRef();
|
||||
} else {
|
||||
Label procBlockSuccessor = getScope().getLabel(procBlockSuccessorRef);
|
||||
Label procBlockSuccessor = getProgramScope().getLabel(procBlockSuccessorRef);
|
||||
String inlinedSuccessorName = getInlineSymbolName(procedure, procBlockSuccessor, serial);
|
||||
Label inlinedSuccessorLabel = callScope.getLocalLabel(inlinedSuccessorName);
|
||||
inlinedSuccessor = inlinedSuccessorLabel.getRef();
|
||||
@ -206,7 +206,7 @@ public class Pass1ProcedureInline extends Pass1Base {
|
||||
} else if(procStatement instanceof StatementConditionalJump) {
|
||||
StatementConditionalJump procConditional = (StatementConditionalJump) procStatement;
|
||||
LabelRef procDestinationRef = procConditional.getDestination();
|
||||
Label procDestination = getScope().getLabel(procDestinationRef);
|
||||
Label procDestination = getProgramScope().getLabel(procDestinationRef);
|
||||
Label inlinedDest = procDestination;
|
||||
if(procDestination.getScope().equals(procedure)) {
|
||||
String inlineSymbolName = getInlineSymbolName(procedure, procDestination, serial);
|
||||
@ -251,7 +251,7 @@ public class Pass1ProcedureInline extends Pass1Base {
|
||||
Value rValue = programValue.get();
|
||||
if(rValue instanceof VariableRef) {
|
||||
VariableRef procVarRef = (VariableRef) rValue;
|
||||
Variable procVar = Pass1ProcedureInline.this.getScope().getVariable(procVarRef);
|
||||
Variable procVar = Pass1ProcedureInline.this.getProgramScope().getVariable(procVarRef);
|
||||
if(procVar.getScope().equals(procedure)) {
|
||||
String inlineSymbolName = Pass1ProcedureInline.this.getInlineSymbolName(procedure, procVar, serial);
|
||||
Variable inlineVar = callScope.getLocalVariable(inlineSymbolName);
|
||||
|
@ -25,7 +25,7 @@ public class Pass1Procedures extends Pass2SsaOptimization {
|
||||
if(statement instanceof StatementCall) {
|
||||
StatementCall call = (StatementCall) statement;
|
||||
String procedureName = call.getProcedureName();
|
||||
Scope localScope = (Scope) getScope().getSymbol(block.getScope());
|
||||
Scope localScope = (Scope) getProgramScope().getSymbol(block.getScope());
|
||||
final Symbol procedureSymbol = localScope.findSymbol(procedureName);
|
||||
if(procedureSymbol == null)
|
||||
throw new CompileError("Called procedure not found. " + procedureName, statement.getSource());
|
||||
|
@ -6,7 +6,6 @@ import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
|
||||
import dk.camelot64.kickc.model.symbols.Scope;
|
||||
import dk.camelot64.kickc.model.symbols.Symbol;
|
||||
import dk.camelot64.kickc.model.values.ForwardVariableRef;
|
||||
import dk.camelot64.kickc.model.values.RValue;
|
||||
import dk.camelot64.kickc.model.values.Value;
|
||||
|
||||
/** Pass that resolves all forward variable references - and fails if they cannot be resolved*/
|
||||
@ -22,7 +21,7 @@ public class Pass1ResolveForwardReferences extends Pass1Base {
|
||||
Value rValue = programValue.get();
|
||||
if(rValue instanceof ForwardVariableRef) {
|
||||
String varName = ((ForwardVariableRef) rValue).getName();
|
||||
Scope currentScope = getScope().getScope(currentBlock.getScope());
|
||||
Scope currentScope = getProgramScope().getScope(currentBlock.getScope());
|
||||
Symbol symbol = currentScope.findSymbol(varName);
|
||||
if(symbol!=null) {
|
||||
getLog().append("Resolved forward reference " + varName+" to "+symbol.toString(getProgram()));
|
||||
|
@ -27,7 +27,7 @@ public class Pass1StructTypeSizeFix extends Pass2SsaOptimization {
|
||||
boolean modified = false;
|
||||
|
||||
// Update all types in variables
|
||||
for(Variable variable : getScope().getAllVars(true)) {
|
||||
for(Variable variable : getProgramScope().getAllVars(true)) {
|
||||
modified |= fixStructSize(variable.getType());
|
||||
}
|
||||
|
||||
@ -46,15 +46,15 @@ public class Pass1StructTypeSizeFix extends Pass2SsaOptimization {
|
||||
});
|
||||
|
||||
// Update all SIZEOF_XXX constants
|
||||
for(Scope subScope : getScope().getAllScopes(false)) {
|
||||
for(Scope subScope : getProgramScope().getAllScopes(false)) {
|
||||
if(subScope instanceof StructDefinition) {
|
||||
SymbolTypeStruct typeStruct = new SymbolTypeStruct((StructDefinition) subScope, false, false);
|
||||
StructDefinition structDefinition = typeStruct.getStructDefinition(getScope());
|
||||
int sizeBytes = typeStruct.calculateSizeBytes(structDefinition, getScope());
|
||||
StructDefinition structDefinition = typeStruct.getStructDefinition(getProgramScope());
|
||||
int sizeBytes = typeStruct.calculateSizeBytes(structDefinition, getProgramScope());
|
||||
if(sizeBytes != typeStruct.getSizeBytes()) {
|
||||
getLog().append("Fixing struct type SIZE_OF " + typeStruct.toCDecl() + " to " + sizeBytes);
|
||||
typeStruct.setSizeBytes(sizeBytes);
|
||||
SizeOfConstants.fixSizeOfConstantVar(getScope(), typeStruct);
|
||||
SizeOfConstants.fixSizeOfConstantVar(getProgramScope(), typeStruct);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -71,8 +71,8 @@ public class Pass1StructTypeSizeFix extends Pass2SsaOptimization {
|
||||
private boolean fixStructSize(SymbolType type) {
|
||||
if(type instanceof SymbolTypeStruct) {
|
||||
SymbolTypeStruct typeStruct = (SymbolTypeStruct) type;
|
||||
StructDefinition structDefinition = typeStruct.getStructDefinition(getScope());
|
||||
int sizeBytes = typeStruct.calculateSizeBytes(structDefinition, getScope());
|
||||
StructDefinition structDefinition = typeStruct.getStructDefinition(getProgramScope());
|
||||
int sizeBytes = typeStruct.calculateSizeBytes(structDefinition, getProgramScope());
|
||||
if(sizeBytes != typeStruct.getSizeBytes()) {
|
||||
getLog().append("Fixing struct type size " + type.toCDecl() + " to " + sizeBytes);
|
||||
typeStruct.setSizeBytes(sizeBytes);
|
||||
|
@ -35,7 +35,7 @@ public class Pass1UnrollConditionVariableSsa extends Pass2SsaOptimization {
|
||||
findAllReferencedVars(referencedVars, conditionalJump.getrValue1());
|
||||
findAllReferencedVars(referencedVars, conditionalJump.getrValue2());
|
||||
for(VariableRef referencedVar : referencedVars) {
|
||||
final Variable variable = getScope().getVariable(referencedVar);
|
||||
final Variable variable = getProgramScope().getVariable(referencedVar);
|
||||
if(variable.isKindLoadStore()) {
|
||||
// Convert the variable to versioned if it is load/store
|
||||
getLog().append("Converting unrolled condition variable to single-static-assignment "+variable);
|
||||
@ -60,7 +60,7 @@ public class Pass1UnrollConditionVariableSsa extends Pass2SsaOptimization {
|
||||
for(VariableRef varRef : directReferenced) {
|
||||
if(varRef.isIntermediate()) {
|
||||
// Found an intermediate variable - recurse to the definition
|
||||
final List<VarAssignments.VarAssignment> varAssignments = VarAssignments.get(varRef, getGraph(), getScope());
|
||||
final List<VarAssignments.VarAssignment> varAssignments = VarAssignments.get(varRef, getGraph(), getProgramScope());
|
||||
for(VarAssignments.VarAssignment varAssignment : varAssignments) {
|
||||
if(VarAssignments.VarAssignment.Type.STATEMENT_LVALUE.equals(varAssignment.type)) {
|
||||
if(varAssignment.statementLValue instanceof StatementAssignment) {
|
||||
|
@ -24,7 +24,7 @@ public class Pass1UnwindBlockScopes extends Pass1Base {
|
||||
@Override
|
||||
public boolean step() {
|
||||
Map<SymbolRef, SymbolRef> unwoundSymbols = new LinkedHashMap<>();
|
||||
for(Procedure procedure : getScope().getAllProcedures(true)) {
|
||||
for(Procedure procedure : getProgramScope().getAllProcedures(true)) {
|
||||
for(Scope subScope : procedure.getAllScopes(false)) {
|
||||
unwindSubScope(subScope, procedure, unwoundSymbols);
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ public class Pass1UnwindStructPrepare extends Pass2SsaOptimization {
|
||||
}
|
||||
if(statement instanceof StatementCall) {
|
||||
final StatementCall call = (StatementCall) statement;
|
||||
final Procedure procedure = getScope().getProcedure(call.getProcedure());
|
||||
final Procedure procedure = getProgramScope().getProcedure(call.getProcedure());
|
||||
final List<Variable> paramDefs = procedure.getParameters();
|
||||
final List<RValue> paramVals = call.getParameters();
|
||||
for(int i=0;i<paramDefs.size();i++) {
|
||||
|
@ -72,10 +72,10 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
getProgram(), (programValue, currentStmt, stmtIt, currentBlock) -> {
|
||||
if(programValue.get() instanceof StructMemberRef) {
|
||||
StructMemberRef structMemberRef = (StructMemberRef) programValue.get();
|
||||
final ValueSource structValueSource = ValueSourceFactory.getValueSource(structMemberRef.getStruct(), getProgram(), getScope(), currentStmt, stmtIt, currentBlock);
|
||||
final ValueSource structValueSource = ValueSourceFactory.getValueSource(structMemberRef.getStruct(), getProgram(), getProgramScope(), currentStmt, stmtIt, currentBlock);
|
||||
if(structValueSource != null) {
|
||||
final ValueSource memberUnwinding = structValueSource.getMemberUnwinding(structMemberRef.getMemberName(), getProgram(), getScope(), currentStmt, stmtIt, currentBlock);
|
||||
RValue memberSimpleValue = memberUnwinding.getSimpleValue(getScope());
|
||||
final ValueSource memberUnwinding = structValueSource.getMemberUnwinding(structMemberRef.getMemberName(), getProgram(), getProgramScope(), currentStmt, stmtIt, currentBlock);
|
||||
RValue memberSimpleValue = memberUnwinding.getSimpleValue(getProgramScope());
|
||||
if(getLog().isVerboseStructUnwind())
|
||||
getLog().append("Replacing struct member reference " + structMemberRef.toString(getProgram()) + " with member unwinding reference " + memberSimpleValue.toString(getProgram()));
|
||||
programValue.set(memberSimpleValue);
|
||||
@ -92,7 +92,7 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
* @param call The call to unwind
|
||||
*/
|
||||
private boolean unwindCall(StatementCall call, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock) {
|
||||
final Procedure procedure = getScope().getProcedure(call.getProcedure());
|
||||
final Procedure procedure = getProgramScope().getProcedure(call.getProcedure());
|
||||
|
||||
// Unwind struct value return value
|
||||
|
||||
@ -102,7 +102,7 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
if(procReturnVar != null && procReturnVar.isStructUnwind()) {
|
||||
if(call.getlValue() != null && !(call.getlValue() instanceof ValueList)) {
|
||||
// Return value already unwound - move on
|
||||
final ValueSource valueSource = ValueSourceFactory.getValueSource(call.getlValue(), getProgram(), getScope(), call, stmtIt, currentBlock);
|
||||
final ValueSource valueSource = ValueSourceFactory.getValueSource(call.getlValue(), getProgram(), getProgramScope(), call, stmtIt, currentBlock);
|
||||
RValue unwoundLValue = unwindValue(valueSource, call, stmtIt, currentBlock);
|
||||
if(call.getlValue().equals(unwoundLValue))
|
||||
throw new CompileError("Call return value already unwound", call);
|
||||
@ -128,12 +128,12 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
final SymbolVariableRef unwindingMaster = getProgram().getStructVariableMemberUnwinding().getUnwindingMaster(procParameter.getRef());
|
||||
if(unwindingMaster != null) {
|
||||
// The procedure parameter is unwound
|
||||
final ValueSource parameterSource = ValueSourceFactory.getValueSource(callParameter, getProgram(), getScope(), call, stmtIt, currentBlock);
|
||||
final ValueSource parameterSource = ValueSourceFactory.getValueSource(callParameter, getProgram(), getProgramScope(), call, stmtIt, currentBlock);
|
||||
if(parameterSource != null && parameterSource.isUnwindable())
|
||||
// Passing an unwinding struct value
|
||||
for(String memberName : parameterSource.getMemberNames(getScope())) {
|
||||
ValueSource memberUnwinding = parameterSource.getMemberUnwinding(memberName, getProgram(), getScope(), call, stmtIt, currentBlock);
|
||||
unwoundParameters.add(memberUnwinding.getSimpleValue(getScope()));
|
||||
for(String memberName : parameterSource.getMemberNames(getProgramScope())) {
|
||||
ValueSource memberUnwinding = parameterSource.getMemberUnwinding(memberName, getProgram(), getProgramScope(), call, stmtIt, currentBlock);
|
||||
unwoundParameters.add(memberUnwinding.getSimpleValue(getProgramScope()));
|
||||
unwound = true;
|
||||
anyParameterUnwound = true;
|
||||
idx_proc++;
|
||||
@ -170,11 +170,11 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
if(lValueSource == null) {
|
||||
return null;
|
||||
} else if(lValueSource.isSimple()) {
|
||||
return lValueSource.getSimpleValue(getScope());
|
||||
return lValueSource.getSimpleValue(getProgramScope());
|
||||
} else if(lValueSource.isUnwindable()) {
|
||||
ArrayList<RValue> unwoundMembers = new ArrayList<>();
|
||||
for(String memberName : lValueSource.getMemberNames(getScope())) {
|
||||
ValueSource memberUnwinding = lValueSource.getMemberUnwinding(memberName, getProgram(), getScope(), statement, stmtIt, currentBlock);
|
||||
for(String memberName : lValueSource.getMemberNames(getProgramScope())) {
|
||||
ValueSource memberUnwinding = lValueSource.getMemberUnwinding(memberName, getProgram(), getProgramScope(), statement, stmtIt, currentBlock);
|
||||
unwoundMembers.add(unwindValue(memberUnwinding, statement, stmtIt, currentBlock));
|
||||
}
|
||||
return new ValueList(unwoundMembers);
|
||||
@ -194,10 +194,10 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
if(returnValue == null)
|
||||
return false;
|
||||
if(returnValue instanceof SymbolVariableRef)
|
||||
if(getScope().getVar((SymbolVariableRef) returnValue).isStructClassic())
|
||||
if(getProgramScope().getVar((SymbolVariableRef) returnValue).isStructClassic())
|
||||
return false;
|
||||
boolean unwound = false;
|
||||
final ValueSource valueSource = ValueSourceFactory.getValueSource(returnValue, getProgram(), getScope(), statementReturn, stmtIt, currentBlock);
|
||||
final ValueSource valueSource = ValueSourceFactory.getValueSource(returnValue, getProgram(), getProgramScope(), statementReturn, stmtIt, currentBlock);
|
||||
RValue unwoundValue = unwindValue(valueSource, statementReturn, stmtIt, currentBlock);
|
||||
if(unwoundValue != null && !returnValue.equals(unwoundValue)) {
|
||||
statementReturn.setValue(unwoundValue);
|
||||
@ -214,7 +214,7 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
private boolean unwindStructParameters() {
|
||||
boolean modified = false;
|
||||
// Iterate through all procedures changing parameter lists by unwinding each struct value parameter
|
||||
for(Procedure procedure : getScope().getAllProcedures(true)) {
|
||||
for(Procedure procedure : getProgramScope().getAllProcedures(true)) {
|
||||
ArrayList<String> unwoundParameterNames = new ArrayList<>();
|
||||
boolean procedureUnwound = false;
|
||||
for(Variable parameter : procedure.getParameters()) {
|
||||
|
@ -35,7 +35,7 @@ public class Pass1UnwindStructVariables extends Pass1Base {
|
||||
private boolean unwindStructVariables() {
|
||||
boolean modified = false;
|
||||
// Iterate through all scopes generating member-variables for each struct
|
||||
for(Variable variable : getScope().getAllVariables(true)) {
|
||||
for(Variable variable : getProgramScope().getAllVariables(true)) {
|
||||
if(variable.isStructUnwind()) {
|
||||
StructVariableMemberUnwinding structVariableMemberUnwinding = getProgram().getStructVariableMemberUnwinding();
|
||||
if(structVariableMemberUnwinding.getVariableUnwinding(variable.getRef()) == null) {
|
||||
|
@ -29,11 +29,11 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
|
||||
|
||||
fixAliasSources(aliases);
|
||||
removeAliasAssignments(aliases);
|
||||
replaceVariables(aliases.getReplacements(getScope()));
|
||||
replaceVariables(aliases.getReplacements(getProgramScope()));
|
||||
for(AliasSet aliasSet : aliases.getAliasSets()) {
|
||||
getLog().append("Alias " + aliasSet.toString(getProgram()));
|
||||
}
|
||||
deleteSymbols(getScope(), aliases.getSymbolsToRemove(getScope()));
|
||||
deleteSymbols(getProgramScope(), aliases.getSymbolsToRemove(getProgramScope()));
|
||||
return (aliases.size() > 0);
|
||||
}
|
||||
|
||||
@ -247,7 +247,7 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
|
||||
StatementSource bestSource = null;
|
||||
List<Statement> assignments = new ArrayList<>();
|
||||
for(VariableRef aliasVar : aliasSet.getVars()) {
|
||||
final List<VarAssignments.VarAssignment> varAssignments = VarAssignments.get(aliasVar, getGraph(), getScope());
|
||||
final List<VarAssignments.VarAssignment> varAssignments = VarAssignments.get(aliasVar, getGraph(), getProgramScope());
|
||||
if(varAssignments.size()!=1)
|
||||
continue;
|
||||
final VarAssignments.VarAssignment varAssignment = varAssignments.get(0);
|
||||
|
@ -18,10 +18,6 @@ public class Pass2Base {
|
||||
return program.getLog();
|
||||
}
|
||||
|
||||
public ControlFlowGraph getGraph() {
|
||||
return program.getGraph();
|
||||
}
|
||||
|
||||
public ProgramScope getSymbols() {
|
||||
return program.getScope();
|
||||
}
|
||||
|
@ -40,11 +40,11 @@ public class Pass2ComparisonOptimization extends Pass2SsaOptimization {
|
||||
StatementConditionalJump conditionalJump = (StatementConditionalJump) statement;
|
||||
Operator operator = conditionalJump.getOperator();
|
||||
if(operator!=null && conditionalJump.getrValue2() instanceof ConstantValue) {
|
||||
SymbolType valueType = SymbolTypeInference.inferType(getScope(), conditionalJump.getrValue1());
|
||||
SymbolType valueType = SymbolTypeInference.inferType(getProgramScope(), conditionalJump.getrValue1());
|
||||
ConstantValue constantValue = (ConstantValue) conditionalJump.getrValue2();
|
||||
ConstantLiteral constantLiteral = null;
|
||||
try {
|
||||
constantLiteral = constantValue.calculateLiteral(getScope());
|
||||
constantLiteral = constantValue.calculateLiteral(getProgramScope());
|
||||
} catch(ConstantNotLiteral e) {
|
||||
// Ignore
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ public class Pass2ConditionalAndOrRewriting extends Pass2SsaOptimization {
|
||||
Collection<VariableRef> obsoleteVars = new ArrayList<>();
|
||||
obsoleteVars.add(obsoleteConditionVar);
|
||||
removeAssignments(getGraph(), obsoleteVars);
|
||||
deleteSymbols(getScope(), obsoleteVars);
|
||||
deleteSymbols(getProgramScope(), obsoleteVars);
|
||||
modified = true;
|
||||
} else {
|
||||
done = true;
|
||||
@ -106,7 +106,7 @@ public class Pass2ConditionalAndOrRewriting extends Pass2SsaOptimization {
|
||||
// Found an if with a logical && condition - rewrite to if(c1) if(c2) { xx }
|
||||
getLog().append("Rewriting && if()-condition to two if()s " + conditionAssignment.toString(getProgram(), false));
|
||||
ScopeRef currentScopeRef = block.getScope();
|
||||
Scope currentScope = getScope().getScope(currentScopeRef);
|
||||
Scope currentScope = getProgramScope().getScope(currentScopeRef);
|
||||
// Add a new block containing the second part of the && condition expression
|
||||
Label newBlockLabel = currentScope.addLabelIntermediate();
|
||||
ControlFlowBlock newBlock = new ControlFlowBlock(newBlockLabel.getRef(), currentScopeRef);
|
||||
@ -140,7 +140,7 @@ public class Pass2ConditionalAndOrRewriting extends Pass2SsaOptimization {
|
||||
private void rewriteLogicOr(ControlFlowBlock block, StatementConditionalJump conditional, StatementAssignment conditionAssignment) {
|
||||
getLog().append("Rewriting || if()-condition to two if()s " + conditionAssignment.toString(getProgram(), false));
|
||||
ScopeRef currentScopeRef = block.getScope();
|
||||
Scope currentScope = getScope().getScope(currentScopeRef);
|
||||
Scope currentScope = getProgramScope().getScope(currentScopeRef);
|
||||
// Add a new block containing the second part of the && condition expression
|
||||
Label newBlockLabel = currentScope.addLabelIntermediate();
|
||||
ControlFlowBlock newBlock = new ControlFlowBlock(newBlockLabel.getRef(), currentScopeRef);
|
||||
|
@ -40,7 +40,7 @@ public class Pass2ConditionalJumpSimplification extends Pass2SsaOptimization {
|
||||
simpleConditionVars.add(simpleCondition.conditionVar);
|
||||
}
|
||||
removeAssignments(getGraph(), simpleConditionVars);
|
||||
deleteSymbols(getScope(), simpleConditionVars);
|
||||
deleteSymbols(getProgramScope(), simpleConditionVars);
|
||||
return (simpleConditionVars.size() > 0);
|
||||
}
|
||||
|
||||
@ -129,7 +129,7 @@ public class Pass2ConditionalJumpSimplification extends Pass2SsaOptimization {
|
||||
// Create an intermediate variable copy of the load/store-variable at the position of the condition-variable to preserve the value
|
||||
final ControlFlowBlock conditionDefineBlock = statementInfos.getBlock(simpleCondition.conditionAssignment);
|
||||
final ScopeRef conditionDefineScopeRef = conditionDefineBlock.getScope();
|
||||
final Scope conditionDefineScope = getScope().getScope(conditionDefineScopeRef);
|
||||
final Scope conditionDefineScope = getProgramScope().getScope(conditionDefineScopeRef);
|
||||
SymbolType typeQualified = referencedLoadStoreVariable.getType().getQualified(false, referencedLoadStoreVariable.getType().isNomodify());
|
||||
final Variable intermediateLoadStoreVar = VariableBuilder.createIntermediate(conditionDefineScope, typeQualified, getProgram());
|
||||
final StatementAssignment intermediateLoadStoreAssignment = new StatementAssignment(intermediateLoadStoreVar.getVariableRef(), referencedLoadStoreVariable.getRef(), true, simpleCondition.conditionAssignment.getSource(), Comment.NO_COMMENTS);
|
||||
@ -168,7 +168,7 @@ public class Pass2ConditionalJumpSimplification extends Pass2SsaOptimization {
|
||||
private Collection<Variable> getReferencedLoadStoreVariables(RValue rValue) {
|
||||
return VariableReferenceInfos.getReferencedVars(rValue)
|
||||
.stream()
|
||||
.map(variableRef -> getScope().getVariable(variableRef))
|
||||
.map(variableRef -> getProgramScope().getVariable(variableRef))
|
||||
.filter(Variable::isKindLoadStore)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
|
||||
} else {
|
||||
// Check if the constant is zero
|
||||
try {
|
||||
ConstantLiteral constantLiteral = ((ConstantValue) assignment.getrValue1()).calculateLiteral(getScope());
|
||||
ConstantLiteral constantLiteral = ((ConstantValue) assignment.getrValue1()).calculateLiteral(getProgramScope());
|
||||
if(constantLiteral.getValue().equals(0L)) {
|
||||
getLog().append("Removed zero-constant in assignment " + assignment.getlValue());
|
||||
assignment.setrValue1(null);
|
||||
@ -167,7 +167,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
|
||||
} else {
|
||||
// Check if the constant is zero
|
||||
try {
|
||||
ConstantLiteral constantLiteral = ((ConstantValue) assignment.getrValue2()).calculateLiteral(getScope());
|
||||
ConstantLiteral constantLiteral = ((ConstantValue) assignment.getrValue2()).calculateLiteral(getProgramScope());
|
||||
if(constantLiteral.getValue().equals(0L)) {
|
||||
getLog().append("Removed zero-constant in assignment " + assignment.getlValue());
|
||||
assignment.setrValue2(assignment.getrValue1());
|
||||
@ -193,10 +193,10 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
|
||||
if(getUsages(variable) > 1) {
|
||||
return null;
|
||||
}
|
||||
final Variable var = getScope().getVar(variable);
|
||||
final Variable var = getProgramScope().getVar(variable);
|
||||
if(var.isKindLoadStore())
|
||||
return null;
|
||||
final List<VarAssignments.VarAssignment> varAssignments = VarAssignments.get(variable, getGraph(), getScope());
|
||||
final List<VarAssignments.VarAssignment> varAssignments = VarAssignments.get(variable, getGraph(), getProgramScope());
|
||||
if(varAssignments.size()!=1)
|
||||
return null;
|
||||
final VarAssignments.VarAssignment varAssignment = varAssignments.get(0);
|
||||
@ -208,7 +208,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
|
||||
if(assignment.getOperator() != null && "+".equals(assignment.getOperator().getOperator())) {
|
||||
if(assignment.getrValue1() instanceof ConstantValue) {
|
||||
ConstantValue constant = (ConstantValue) assignment.getrValue1();
|
||||
SymbolType constantType = constant.getType(getScope());
|
||||
SymbolType constantType = constant.getType(getProgramScope());
|
||||
if(SymbolType.isInteger(constantType)) {
|
||||
assignment.setrValue1(null);
|
||||
assignment.setOperator(null);
|
||||
|
@ -39,7 +39,7 @@ public class Pass2ConstantCallPointerIdentification extends Pass2SsaOptimization
|
||||
optimized = true;
|
||||
}
|
||||
} else if(procedure instanceof ConstantRef) {
|
||||
Variable procedureVariable = getScope().getConstant((ConstantRef) procedure);
|
||||
Variable procedureVariable = getProgramScope().getConstant((ConstantRef) procedure);
|
||||
SymbolType procedureVariableType = procedureVariable.getType();
|
||||
if(procedureVariableType instanceof SymbolTypePointer) {
|
||||
if(((SymbolTypePointer) procedureVariableType).getElementType() instanceof SymbolTypeProcedure) {
|
||||
@ -68,7 +68,7 @@ public class Pass2ConstantCallPointerIdentification extends Pass2SsaOptimization
|
||||
if(block.getCallSuccessor()!=null)
|
||||
throw new CompileError("Internal error! Block has two calls!", callPointer);
|
||||
block.setCallSuccessor(constProcedureRef.getLabelRef());
|
||||
final Procedure procedure = getScope().getProcedure(constProcedureRef);
|
||||
final Procedure procedure = getProgramScope().getProcedure(constProcedureRef);
|
||||
procedure.setCallingConvention(Procedure.CallingConvention.STACK_CALL);
|
||||
getLog().append("Replacing constant pointer function " + callPointer.toString(getProgram(), false));
|
||||
}
|
||||
@ -82,7 +82,7 @@ public class Pass2ConstantCallPointerIdentification extends Pass2SsaOptimization
|
||||
*/
|
||||
private ProcedureRef findConstProcedure(RValue procedurePointer) {
|
||||
if(procedurePointer instanceof ConstantRef) {
|
||||
Variable constant = getScope().getConstant((ConstantRef) procedurePointer);
|
||||
Variable constant = getProgramScope().getConstant((ConstantRef) procedurePointer);
|
||||
return findConstProcedure(constant.getInitValue());
|
||||
} else if(procedurePointer instanceof ConstantSymbolPointer) {
|
||||
ConstantSymbolPointer pointer = (ConstantSymbolPointer) procedurePointer;
|
||||
|
@ -49,7 +49,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
|
||||
ConstantVariableValue constVarVal = constants.get(constRef);
|
||||
Scope scope = variable.getScope();
|
||||
ConstantValue constVal = constVarVal.getConstantValue();
|
||||
SymbolType valueType = SymbolTypeInference.inferType(getScope(), constVal);
|
||||
SymbolType valueType = SymbolTypeInference.inferType(getProgramScope(), constVal);
|
||||
SymbolType variableType = variable.getType();
|
||||
|
||||
if(!SymbolType.NUMBER.equals(variableType) && SymbolType.NUMBER.equals(valueType)) {
|
||||
@ -64,7 +64,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
|
||||
else if(!SymbolTypeConversion.assignmentTypeMatch(variableType, valueType)) {
|
||||
ConstantLiteral constantLiteral = null;
|
||||
try {
|
||||
constantLiteral = constVal.calculateLiteral(getScope());
|
||||
constantLiteral = constVal.calculateLiteral(getProgramScope());
|
||||
} catch(ConstantNotLiteral e) {
|
||||
// ignore
|
||||
}
|
||||
@ -141,7 +141,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
|
||||
LValue lValue = assignment.getlValue();
|
||||
if(lValue instanceof VariableRef) {
|
||||
VariableRef varRef = (VariableRef) lValue;
|
||||
Variable var = getScope().getVariable(varRef);
|
||||
Variable var = getProgramScope().getVariable(varRef);
|
||||
if(var.isVolatile() || var.isKindLoadStore())
|
||||
// Do not examine volatiles and non-versioned variables
|
||||
continue;
|
||||
@ -160,7 +160,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
|
||||
StatementPhiBlock.PhiRValue phiRValue = phiVariable.getValues().get(0);
|
||||
if(getConstant(phiRValue.getrValue()) != null) {
|
||||
VariableRef varRef = phiVariable.getVariable();
|
||||
Variable var = getScope().getVariable(varRef);
|
||||
Variable var = getProgramScope().getVariable(varRef);
|
||||
if(var.isVolatile() || var.isKindLoadStore())
|
||||
// Do not examine volatiles and non-versioned variables
|
||||
continue;
|
||||
@ -174,14 +174,14 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
|
||||
}
|
||||
|
||||
// Look for constants among non-versioned variables
|
||||
for(Variable variable : getScope().getAllVariables(true)) {
|
||||
for(Variable variable : getProgramScope().getAllVariables(true)) {
|
||||
if(variable.isVolatile() || !variable.isKindLoadStore())
|
||||
// Do not examine volatiles, non-constants or versioned variables
|
||||
continue;
|
||||
if(variable.getRegister() != null && variable.getRegister().isMem())
|
||||
// Skip variables allocated into memory
|
||||
continue;
|
||||
final List<VarAssignments.VarAssignment> varAssignments = VarAssignments.get(variable.getRef(), getGraph(), getScope());
|
||||
final List<VarAssignments.VarAssignment> varAssignments = VarAssignments.get(variable.getRef(), getGraph(), getProgramScope());
|
||||
if(varAssignments.size() == 1) {
|
||||
final VarAssignments.VarAssignment varAssignment = varAssignments.get(0);
|
||||
if(!VarAssignments.VarAssignment.Type.STATEMENT_LVALUE.equals(varAssignment.type) || !(varAssignment.statementLValue instanceof StatementAssignment))
|
||||
|
@ -2,7 +2,6 @@ package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.ConstantNotLiteral;
|
||||
import dk.camelot64.kickc.model.ControlFlowBlock;
|
||||
import dk.camelot64.kickc.model.InternalError;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.operators.Operator;
|
||||
import dk.camelot64.kickc.model.operators.OperatorBinary;
|
||||
@ -85,15 +84,15 @@ public class Pass2ConstantIfs extends Pass2SsaOptimization {
|
||||
// If all values are constant find the literal condition value
|
||||
if(conditional.getrValue1() == null && operator == null && constValue2 != null) {
|
||||
// Constant condition
|
||||
return constValue2.calculateLiteral(getScope());
|
||||
return constValue2.calculateLiteral(getProgramScope());
|
||||
} else if(conditional.getrValue1() == null && operator != null && constValue2 != null) {
|
||||
// Constant unary condition
|
||||
ConstantValue constVal = Pass2ConstantIdentification.createUnary((OperatorUnary) operator, constValue2);
|
||||
return constVal.calculateLiteral(getScope());
|
||||
return constVal.calculateLiteral(getProgramScope());
|
||||
} else if(constValue1 != null && operator != null && constValue2 != null) {
|
||||
// Constant binary condition
|
||||
ConstantValue constVal = Pass2ConstantIdentification.createBinary(constValue1, (OperatorBinary) operator, constValue2, getScope());
|
||||
return constVal.calculateLiteral(getScope());
|
||||
ConstantValue constVal = Pass2ConstantIdentification.createBinary(constValue1, (OperatorBinary) operator, constValue2, getProgramScope());
|
||||
return constVal.calculateLiteral(getProgramScope());
|
||||
}
|
||||
|
||||
} catch(ConstantNotLiteral e) {
|
||||
@ -183,7 +182,7 @@ public class Pass2ConstantIfs extends Pass2SsaOptimization {
|
||||
ConstantValue constValue = Pass2ConstantIdentification.getConstant(rValue);
|
||||
if(constValue != null) {
|
||||
try {
|
||||
ConstantLiteral constantLiteral = constValue.calculateLiteral(getScope());
|
||||
ConstantLiteral constantLiteral = constValue.calculateLiteral(getProgramScope());
|
||||
if(constantLiteral instanceof ConstantInteger) {
|
||||
Long value = ((ConstantInteger) constantLiteral).getInteger();
|
||||
return new IntValueInterval(value, value);
|
||||
@ -193,7 +192,7 @@ public class Pass2ConstantIfs extends Pass2SsaOptimization {
|
||||
}
|
||||
}
|
||||
// Not constant - find the interval of the type
|
||||
SymbolType symbolType = SymbolTypeInference.inferType(getScope(), rValue);
|
||||
SymbolType symbolType = SymbolTypeInference.inferType(getProgramScope(), rValue);
|
||||
if(symbolType instanceof SymbolTypeIntegerFixed) {
|
||||
SymbolTypeIntegerFixed typeIntegerFixed = (SymbolTypeIntegerFixed) symbolType;
|
||||
return new IntValueInterval(typeIntegerFixed.getMinValue(), typeIntegerFixed.getMaxValue());
|
||||
|
@ -57,7 +57,7 @@ public class Pass2ConstantInlining extends Pass2SsaOptimization {
|
||||
final Set<ConstantRef> inlineRefs = inline.keySet();
|
||||
removeParameters(inlineRefs);
|
||||
// Remove from symbol table
|
||||
deleteSymbols(getScope(), inlineRefs);
|
||||
deleteSymbols(getProgramScope(), inlineRefs);
|
||||
|
||||
|
||||
for(ConstantRef constantRef : inlineRefs) {
|
||||
@ -70,7 +70,7 @@ public class Pass2ConstantInlining extends Pass2SsaOptimization {
|
||||
|
||||
private void removeParameters(Set<ConstantRef> inlineRefs) {
|
||||
for(ConstantRef inlineRef : inlineRefs) {
|
||||
final Scope scope = getScope().getConstant(inlineRef).getScope();
|
||||
final Scope scope = getProgramScope().getConstant(inlineRef).getScope();
|
||||
final Procedure procedure = getProcedure(scope);
|
||||
if(procedure!=null) {
|
||||
final List<Variable> parameters = procedure.getParameters();
|
||||
|
@ -34,7 +34,7 @@ public class Pass2ConstantIntrinsics extends Pass2SsaOptimization {
|
||||
Statement statement = stmtIt.next();
|
||||
if(statement instanceof StatementCall) {
|
||||
final StatementCall call = (StatementCall) statement;
|
||||
final Procedure procedure = getScope().getProcedure(call.getProcedure());
|
||||
final Procedure procedure = getProgramScope().getProcedure(call.getProcedure());
|
||||
if(procedure.isDeclaredIntrinsic()) {
|
||||
if(procedure.getFullName().equals(Pass1ByteXIntrinsicRewrite.INTRINSIC_MAKELONG4)) {
|
||||
List<ConstantValue> constParams = new ArrayList<>();
|
||||
|
@ -37,7 +37,7 @@ public class Pass2ConstantRValueConsolidation extends Pass2SsaOptimization {
|
||||
if(statement instanceof StatementAssignment) {
|
||||
StatementAssignment assignment = (StatementAssignment) statement;
|
||||
if(assignment.getrValue1() != null || assignment.getOperator() != null || !(assignment.getrValue2() instanceof ConstantValue)) {
|
||||
SymbolType lValueType = SymbolTypeInference.inferType(getScope(), assignment.getlValue());
|
||||
SymbolType lValueType = SymbolTypeInference.inferType(getProgramScope(), assignment.getlValue());
|
||||
ConstantValue constant = getConstantAssignmentValue(assignment, lValueType);
|
||||
if(constant != null) {
|
||||
getLog().append("Constant right-side identified " + assignment.toString(getProgram(), false));
|
||||
@ -79,25 +79,25 @@ public class Pass2ConstantRValueConsolidation extends Pass2SsaOptimization {
|
||||
Pass2ConstantIdentification.getConstant(assignment.getrValue1()),
|
||||
(OperatorBinary) assignment.getOperator(),
|
||||
Pass2ConstantIdentification.getConstant(assignment.getrValue2()),
|
||||
getScope());
|
||||
getProgramScope());
|
||||
} else if(Operators.BYTE1.equals(assignment.getOperator()) && assignment.getrValue1() == null) {
|
||||
final SymbolType rVal2Type = SymbolTypeInference.inferType(getScope(), assignment.getrValue2());
|
||||
final SymbolType rVal2Type = SymbolTypeInference.inferType(getProgramScope(), assignment.getrValue2());
|
||||
if(SymbolType.isInteger(rVal2Type) && rVal2Type.getSizeBytes() < 2)
|
||||
return new ConstantInteger(0l, SymbolType.BYTE);
|
||||
} else if(Operators.BYTE2.equals(assignment.getOperator()) && assignment.getrValue1() == null) {
|
||||
final SymbolType rVal2Type = SymbolTypeInference.inferType(getScope(), assignment.getrValue2());
|
||||
final SymbolType rVal2Type = SymbolTypeInference.inferType(getProgramScope(), assignment.getrValue2());
|
||||
if(SymbolType.isInteger(rVal2Type) && rVal2Type.getSizeBytes() < 3)
|
||||
return new ConstantInteger(0l, SymbolType.BYTE);
|
||||
else if(rVal2Type instanceof SymbolTypePointer)
|
||||
return new ConstantInteger(0l, SymbolType.BYTE);
|
||||
} else if(Operators.BYTE3.equals(assignment.getOperator()) && assignment.getrValue1() == null) {
|
||||
final SymbolType rVal2Type = SymbolTypeInference.inferType(getScope(), assignment.getrValue2());
|
||||
final SymbolType rVal2Type = SymbolTypeInference.inferType(getProgramScope(), assignment.getrValue2());
|
||||
if(SymbolType.isInteger(rVal2Type) && rVal2Type.getSizeBytes() < 4)
|
||||
return new ConstantInteger(0l, SymbolType.BYTE);
|
||||
else if(rVal2Type instanceof SymbolTypePointer)
|
||||
return new ConstantInteger(0l, SymbolType.BYTE);
|
||||
} else if(Operators.WORD1.equals(assignment.getOperator()) && assignment.getrValue1() == null) {
|
||||
final SymbolType rVal2Type = SymbolTypeInference.inferType(getScope(), assignment.getrValue2());
|
||||
final SymbolType rVal2Type = SymbolTypeInference.inferType(getProgramScope(), assignment.getrValue2());
|
||||
if(SymbolType.isInteger(rVal2Type) && rVal2Type.getSizeBytes() < 3)
|
||||
return new ConstantInteger(0l, SymbolType.WORD);
|
||||
else if(rVal2Type instanceof SymbolTypePointer)
|
||||
|
@ -69,10 +69,10 @@ public class Pass2ConstantSimplification extends Pass2SsaOptimization {
|
||||
if(Operators.MULTIPLY.equals(binary.getOperator())) {
|
||||
if(binary.getLeft() instanceof ConstantInteger && ((ConstantInteger) binary.getLeft()).getValue() == 0) {
|
||||
getLog().append("Simplifying constant multiply by zero " + binary);
|
||||
programValue.set(new ConstantInteger(0L, binary.getType(getScope())));
|
||||
programValue.set(new ConstantInteger(0L, binary.getType(getProgramScope())));
|
||||
} else if(binary.getRight() instanceof ConstantInteger && ((ConstantInteger) binary.getRight()).getValue() == 0) {
|
||||
getLog().append("Simplifying constant multiply by zero " + binary);
|
||||
programValue.set(new ConstantInteger(0L, binary.getType(getScope())));
|
||||
programValue.set(new ConstantInteger(0L, binary.getType(getProgramScope())));
|
||||
}
|
||||
} else if(Operators.PLUS.equals(binary.getOperator())) {
|
||||
if(binary.getLeft() instanceof ConstantInteger && ((ConstantInteger) binary.getLeft()).getValue() == 0) {
|
||||
|
@ -33,7 +33,7 @@ public class Pass2ConstantStringConsolidation extends Pass2SsaOptimization {
|
||||
boolean modified = false;
|
||||
// Build a map with all constant strings
|
||||
Map<ConstantString, List<Variable>> constantStringMap = new LinkedHashMap<>();
|
||||
for(Variable constVar : getScope().getAllConstants(true)) {
|
||||
for(Variable constVar : getProgramScope().getAllConstants(true)) {
|
||||
ConstantValue constVal = constVar.getInitValue();
|
||||
if(constVal instanceof ConstantString) {
|
||||
ConstantString constString = (ConstantString) constVal;
|
||||
@ -89,7 +89,7 @@ public class Pass2ConstantStringConsolidation extends Pass2SsaOptimization {
|
||||
rootConstant = constantVars.get(0);
|
||||
} else {
|
||||
// Create a new root - and roll around again
|
||||
ProgramScope rootScope = getScope();
|
||||
ProgramScope rootScope = getProgramScope();
|
||||
String localName = getRootName(constantVars);
|
||||
final long stringLength = constString.getStringLength();
|
||||
final ConstantInteger arraySize = new ConstantInteger(stringLength, stringLength<256?SymbolType.BYTE : SymbolType.WORD);
|
||||
@ -117,7 +117,7 @@ public class Pass2ConstantStringConsolidation extends Pass2SsaOptimization {
|
||||
for(Variable constantVar : constantVars) {
|
||||
if(!constantVar.getRef().isIntermediate()) {
|
||||
String candidateName = constantVar.getLocalName();
|
||||
if(getScope().getLocalSymbol(candidateName) == null) {
|
||||
if(getProgramScope().getLocalSymbol(candidateName) == null) {
|
||||
if(constName == null || constName.length() > candidateName.length()) {
|
||||
constName = candidateName;
|
||||
}
|
||||
@ -131,7 +131,7 @@ public class Pass2ConstantStringConsolidation extends Pass2SsaOptimization {
|
||||
int i = 0;
|
||||
do {
|
||||
String candidateName = "string_" + i;
|
||||
if(getScope().getLocalSymbol(candidateName) == null) {
|
||||
if(getProgramScope().getLocalSymbol(candidateName) == null) {
|
||||
return candidateName;
|
||||
}
|
||||
i++;
|
||||
|
@ -4,14 +4,12 @@ import dk.camelot64.kickc.model.Comment;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.VariableBuilder;
|
||||
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
|
||||
import dk.camelot64.kickc.model.operators.OperatorPlus;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.symbols.Scope;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeInference;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypePointer;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@ -30,12 +28,12 @@ public class Pass2DeInlineWordDerefIdx extends Pass2SsaOptimization {
|
||||
if(programValue.get() instanceof PointerDereferenceIndexed) {
|
||||
PointerDereferenceIndexed dereferenceIndexed = (PointerDereferenceIndexed) programValue.get();
|
||||
RValue indexValue = dereferenceIndexed.getIndex();
|
||||
SymbolType indexType = SymbolTypeInference.inferType(getScope(), indexValue);
|
||||
SymbolType indexType = SymbolTypeInference.inferType(getProgramScope(), indexValue);
|
||||
if(indexType.getSizeBytes()>1) {
|
||||
// Index is multiple bytes - de-inline it
|
||||
getLog().append("De-inlining pointer[w] to *(pointer+w) "+currentStmt.toString(getProgram(), false));
|
||||
Scope currentScope = getScope().getScope(currentBlock.getScope());
|
||||
SymbolType pointerType = Operators.PLUS.inferType(SymbolTypeInference.inferType(getScope(), dereferenceIndexed.getPointer()), SymbolTypeInference.inferType(getScope(), dereferenceIndexed.getIndex()));
|
||||
Scope currentScope = getProgramScope().getScope(currentBlock.getScope());
|
||||
SymbolType pointerType = Operators.PLUS.inferType(SymbolTypeInference.inferType(getProgramScope(), dereferenceIndexed.getPointer()), SymbolTypeInference.inferType(getProgramScope(), dereferenceIndexed.getIndex()));
|
||||
Variable tmpVar = VariableBuilder.createIntermediate(currentScope, pointerType, getProgram());
|
||||
stmtIt.previous();
|
||||
StatementAssignment tmpVarAssignment = new StatementAssignment((LValue) tmpVar.getRef(), dereferenceIndexed.getPointer(), Operators.PLUS, indexValue, true, currentStmt.getSource(), Comment.NO_COMMENTS);
|
||||
|
@ -115,7 +115,7 @@ public class Pass2DuplicateRValueIdentification extends Pass2SsaOptimization {
|
||||
}
|
||||
, null, null, null);
|
||||
for(SymbolVariableRef varRef : varRefs) {
|
||||
Variable var = getScope().getVariable(varRef);
|
||||
Variable var = getProgramScope().getVariable(varRef);
|
||||
if(!var.getScope().getRef().equals(scopeRef))
|
||||
return false;
|
||||
}
|
||||
@ -175,7 +175,7 @@ public class Pass2DuplicateRValueIdentification extends Pass2SsaOptimization {
|
||||
ProgramValueHandler loadStoreIdentificator = (programValue, currentStmt, stmtIt, currentBlock) -> {
|
||||
Value value = programValue.get();
|
||||
if(value instanceof VariableRef) {
|
||||
Variable var = getScope().getVar((VariableRef) value);
|
||||
Variable var = getProgramScope().getVar((VariableRef) value);
|
||||
if(var.isKindLoadStore())
|
||||
isLoadStore.set(true);
|
||||
}
|
||||
@ -191,7 +191,7 @@ public class Pass2DuplicateRValueIdentification extends Pass2SsaOptimization {
|
||||
if(programValue.get() instanceof PointerDereference)
|
||||
isVol.set(true);
|
||||
if(programValue.get() instanceof VariableRef) {
|
||||
Variable variable = getScope().getVariable((VariableRef) programValue.get());
|
||||
Variable variable = getProgramScope().getVariable((VariableRef) programValue.get());
|
||||
if(variable.isVolatile())
|
||||
isVol.set(true);
|
||||
}
|
||||
@ -222,11 +222,11 @@ public class Pass2DuplicateRValueIdentification extends Pass2SsaOptimization {
|
||||
if(operator.equals(Operators.WORD0)) return true;
|
||||
if(operator.equals(Operators.WORD1)) return true;
|
||||
if(operator.equals(Operators.PLUS) && rValue2 instanceof ConstantValue) {
|
||||
final SymbolType type1 = SymbolTypeInference.inferType(getScope(), rValue1);
|
||||
final SymbolType type1 = SymbolTypeInference.inferType(getProgramScope(), rValue1);
|
||||
return type1.getSizeBytes() == 1;
|
||||
}
|
||||
if(operator.equals(Operators.PLUS) && rValue1 instanceof ConstantValue) {
|
||||
final SymbolType type2 = SymbolTypeInference.inferType(getScope(), rValue2);
|
||||
final SymbolType type2 = SymbolTypeInference.inferType(getProgramScope(), rValue2);
|
||||
return type2.getSizeBytes() == 1;
|
||||
}
|
||||
return false;
|
||||
|
@ -32,7 +32,7 @@ public class Pass2EliminateUnusedBlocks extends Pass2SsaOptimization {
|
||||
StatementLValue assignment = (StatementLValue) stmt;
|
||||
LValue lValue = assignment.getlValue();
|
||||
if(lValue instanceof VariableRef) {
|
||||
Variable variable = getScope().getVariable((VariableRef) lValue);
|
||||
Variable variable = getProgramScope().getVariable((VariableRef) lValue);
|
||||
if(variable.isKindPhiVersion() || variable.isKindIntermediate()) {
|
||||
getLog().append("Eliminating variable " + lValue.toString(getProgram()) + " from unused block " + block.getLabel());
|
||||
variable.getScope().remove(variable);
|
||||
@ -42,7 +42,7 @@ public class Pass2EliminateUnusedBlocks extends Pass2SsaOptimization {
|
||||
for(StatementPhiBlock.PhiVariable phiVariable : ((StatementPhiBlock) stmt).getPhiVariables()) {
|
||||
VariableRef phiVar = phiVariable.getVariable();
|
||||
getLog().append("Eliminating variable " + phiVar.toString(getProgram()) + " from unused block " + block.getLabel());
|
||||
Variable variable = getScope().getVariable(phiVar);
|
||||
Variable variable = getProgramScope().getVariable(phiVar);
|
||||
variable.getScope().remove(variable);
|
||||
|
||||
}
|
||||
@ -54,10 +54,10 @@ public class Pass2EliminateUnusedBlocks extends Pass2SsaOptimization {
|
||||
|
||||
Set<LabelRef> removedBlocks = new HashSet<>();
|
||||
for(LabelRef unusedBlock : unusedBlocks) {
|
||||
Symbol unusedSymbol = getScope().getSymbol(unusedBlock);
|
||||
Symbol unusedSymbol = getProgramScope().getSymbol(unusedBlock);
|
||||
if(unusedSymbol instanceof Label) {
|
||||
getGraph().remove(unusedBlock);
|
||||
Label label = getScope().getLabel(unusedBlock);
|
||||
Label label = getProgramScope().getLabel(unusedBlock);
|
||||
label.getScope().remove(label);
|
||||
removePhiRValues(unusedBlock, getProgram());
|
||||
removedBlocks.add(unusedBlock);
|
||||
|
@ -37,7 +37,7 @@ public class Pass2IdenticalPhiElimination extends Pass2SsaOptimization {
|
||||
boolean identical = true;
|
||||
for(StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
|
||||
if(phiRValue.getrValue() instanceof SymbolVariableRef) {
|
||||
Variable symbolVar = (Variable) getScope().getSymbol((SymbolVariableRef) phiRValue.getrValue());
|
||||
Variable symbolVar = (Variable) getProgramScope().getSymbol((SymbolVariableRef) phiRValue.getrValue());
|
||||
if(symbolVar.getRegister() != null) { //TODO: Handle register/memory/storage strategy differently!
|
||||
// Do not collapse PHI's for variables with declared registers (this prevents procedure parameters from being turned into constants)
|
||||
identical = false;
|
||||
@ -71,7 +71,7 @@ public class Pass2IdenticalPhiElimination extends Pass2SsaOptimization {
|
||||
RValue alias = phiIdentical.get(var);
|
||||
getLog().append("Identical Phi Values " + var.toString(getProgram()) + " " + alias.toString(getProgram()));
|
||||
}
|
||||
deleteSymbols(getScope(), phiIdentical.keySet());
|
||||
deleteSymbols(getProgramScope(), phiIdentical.keySet());
|
||||
return phiIdentical.size() > 0;
|
||||
}
|
||||
|
||||
|
@ -51,10 +51,10 @@ public class Pass2InlineDerefIdx extends Pass2SsaOptimization {
|
||||
public RValue attemptInlineDeref(RValue pointer) {
|
||||
if(pointer instanceof VariableRef) {
|
||||
VariableRef derefVar = (VariableRef) pointer;
|
||||
final Variable var = getScope().getVar(derefVar);
|
||||
final Variable var = getProgramScope().getVar(derefVar);
|
||||
if(var.isKindLoadStore())
|
||||
return null;
|
||||
final List<VarAssignments.VarAssignment> varAssignments = VarAssignments.get(derefVar, getGraph(), getScope());
|
||||
final List<VarAssignments.VarAssignment> varAssignments = VarAssignments.get(derefVar, getGraph(), getProgramScope());
|
||||
if(varAssignments.size()!=1)
|
||||
return null;
|
||||
final VarAssignments.VarAssignment varAssignment = varAssignments.get(0);
|
||||
@ -90,9 +90,9 @@ public class Pass2InlineDerefIdx extends Pass2SsaOptimization {
|
||||
return null;
|
||||
}
|
||||
if(Operators.PLUS.equals(derefAssignment.getOperator())) {
|
||||
SymbolType derefLeftType = SymbolTypeInference.inferType(getScope(), derefAssignment.getrValue1());
|
||||
SymbolType derefLeftType = SymbolTypeInference.inferType(getProgramScope(), derefAssignment.getrValue1());
|
||||
if(derefLeftType instanceof SymbolTypePointer) {
|
||||
SymbolType derefIndexType = SymbolTypeInference.inferType(getScope(), derefAssignment.getrValue2());
|
||||
SymbolType derefIndexType = SymbolTypeInference.inferType(getProgramScope(), derefAssignment.getrValue2());
|
||||
if(derefIndexType.getSizeBytes()==1) {
|
||||
// Only inline byte-based indices
|
||||
return new PointerDereferenceIndexed(derefAssignment.getrValue1(), derefAssignment.getrValue2());
|
||||
|
@ -142,7 +142,7 @@ public class Pass2LoopHeadConstantIdentification extends Pass2SsaOptimization {
|
||||
isVol.set(true);
|
||||
}
|
||||
if(programValue.get() instanceof VariableRef) {
|
||||
Variable variable = getScope().getVariable((VariableRef) programValue.get());
|
||||
Variable variable = getProgramScope().getVariable((VariableRef) programValue.get());
|
||||
if(variable.isVolatile())
|
||||
isVol.set(true);
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ public class Pass2ModuloToAndRewriting extends Pass2SsaOptimization {
|
||||
*/
|
||||
private ConstantLiteral getConstantLiteral(ConstantValue constantValue) {
|
||||
try {
|
||||
return constantValue.calculateLiteral(getScope());
|
||||
return constantValue.calculateLiteral(getProgramScope());
|
||||
} catch(ConstantNotLiteral e) {
|
||||
return null;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ public class Pass2MultiplyToShiftRewriting extends Pass2SsaOptimization {
|
||||
public boolean step() {
|
||||
boolean optimized = false;
|
||||
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
|
||||
Scope scope = getScope().getScope(block.getScope());
|
||||
Scope scope = getProgramScope().getScope(block.getScope());
|
||||
ListIterator<Statement> stmtIt = block.getStatements().listIterator();
|
||||
while(stmtIt.hasNext()) {
|
||||
Statement statement = stmtIt.next();
|
||||
@ -82,7 +82,7 @@ public class Pass2MultiplyToShiftRewriting extends Pass2SsaOptimization {
|
||||
// Multiplication by constant
|
||||
getLog().append("Rewriting multiplication to use shift and addition" + assignment.toString(getProgram(), false));
|
||||
stmtIt.previous();
|
||||
SymbolType resultType = SymbolTypeInference.inferType(getScope(), varValue);
|
||||
SymbolType resultType = SymbolTypeInference.inferType(getProgramScope(), varValue);
|
||||
long pow2 = (long) power2;
|
||||
long remains = constValue - (1L << pow2);
|
||||
RValue building = varValue;
|
||||
@ -150,7 +150,7 @@ public class Pass2MultiplyToShiftRewriting extends Pass2SsaOptimization {
|
||||
if(rValue instanceof ConstantValue) {
|
||||
ConstantValue constantValue = (ConstantValue) rValue;
|
||||
try {
|
||||
final ConstantLiteral constantLiteral = constantValue.calculateLiteral(getScope());
|
||||
final ConstantLiteral constantLiteral = constantValue.calculateLiteral(getProgramScope());
|
||||
if(constantLiteral instanceof ConstantInteger)
|
||||
return ((ConstantInteger) constantLiteral).getInteger();
|
||||
} catch(ConstantNotLiteral e) {
|
||||
|
@ -49,12 +49,12 @@ public class Pass2NopCastInlining extends Pass2SsaOptimization {
|
||||
// TODO: Handle constant values?
|
||||
if(assignment.getOperator() == null && assignment.getrValue2() instanceof CastValue) {
|
||||
CastValue castValue = (CastValue) assignment.getrValue2();
|
||||
SymbolType subValType = SymbolTypeInference.inferType(getScope(), castValue.getValue());
|
||||
SymbolType subValType = SymbolTypeInference.inferType(getProgramScope(), castValue.getValue());
|
||||
final SymbolType castToType = castValue.getToType();
|
||||
boolean isNopCast = isNopCast(castToType, subValType);
|
||||
if(isNopCast && assignment.getlValue() instanceof VariableRef) {
|
||||
|
||||
final Variable assignmentVar = getScope().getVariable((VariableRef) assignment.getlValue());
|
||||
final Variable assignmentVar = getProgramScope().getVariable((VariableRef) assignment.getlValue());
|
||||
if(assignmentVar.isKindLoadStore())
|
||||
continue;
|
||||
|
||||
@ -76,7 +76,7 @@ public class Pass2NopCastInlining extends Pass2SsaOptimization {
|
||||
// 3. Delete the cast variable
|
||||
delete.add((SymbolRef) castValue.getValue());
|
||||
// Change the type of the assignment variable
|
||||
Variable castVar = getScope().getVariable((VariableRef) castValue.getValue());
|
||||
Variable castVar = getProgramScope().getVariable((VariableRef) castValue.getValue());
|
||||
// Copy type qualifiers from the variable being assigned
|
||||
SymbolType qualifiedType = castVar.getType().getQualified(assignmentVar.getType().isVolatile(), assignmentVar.getType().isNomodify());
|
||||
assignmentVar.setType(qualifiedType);
|
||||
@ -124,7 +124,7 @@ public class Pass2NopCastInlining extends Pass2SsaOptimization {
|
||||
// 2. Perform second replace
|
||||
replaceVariables(replace2);
|
||||
// 3. Delete unused symbols
|
||||
deleteSymbols(getScope(), delete);
|
||||
deleteSymbols(getProgramScope(), delete);
|
||||
}
|
||||
|
||||
return (replace1.size() > 0);
|
||||
|
@ -35,8 +35,8 @@ public class Pass2RangeResolving extends Pass2SsaOptimization {
|
||||
RangeValue rangeValue = (RangeValue) value;
|
||||
if(rangeValue.getRangeFirst() instanceof ConstantValue && rangeValue.getRangeLast() instanceof ConstantValue) {
|
||||
// Range value with constant first & last found - resolve it
|
||||
ConstantLiteral firstLiteral = ((ConstantValue) rangeValue.getRangeFirst()).calculateLiteral(getScope());
|
||||
ConstantLiteral lastLiteral = ((ConstantValue) rangeValue.getRangeLast()).calculateLiteral(getScope());
|
||||
ConstantLiteral firstLiteral = ((ConstantValue) rangeValue.getRangeFirst()).calculateLiteral(getProgramScope());
|
||||
ConstantLiteral lastLiteral = ((ConstantValue) rangeValue.getRangeLast()).calculateLiteral(getProgramScope());
|
||||
if(!(firstLiteral instanceof ConstantEnumerable)) {
|
||||
throw new CompileError("Ranged for() has non-integer first value in the range " + currentStmt.getSource().toString(), currentStmt);
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public class Pass2UnaryNotSimplification extends Pass2SsaOptimization {
|
||||
public boolean step() {
|
||||
final List<VariableRef> unusedComparisons = optimizeUnaryNots();
|
||||
removeAssignments(getGraph(), unusedComparisons);
|
||||
deleteSymbols(getScope(), unusedComparisons);
|
||||
deleteSymbols(getProgramScope(), unusedComparisons);
|
||||
return (unusedComparisons.size() > 0);
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ public class Pass3PhiMemCoalesce extends Pass2SsaOptimization {
|
||||
phiMemCoalescer.visitGraph(getGraph());
|
||||
removeAssignments(getGraph(), phiMemCoalescer.getRemove());
|
||||
replaceVariables(phiMemCoalescer.getReplace());
|
||||
deleteSymbols(getScope(), phiMemCoalescer.getRemove());
|
||||
deleteSymbols(getProgramScope(), phiMemCoalescer.getRemove());
|
||||
getLog().append("Coalesced down to " + phiEquivalenceClasses.size() + " phi equivalence classes");
|
||||
return false;
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ public class PassNAddBooleanCasts extends Pass2SsaOptimization {
|
||||
StatementConditionalJump conditionalJump = (StatementConditionalJump) currentStmt;
|
||||
if(conditionalJump.getOperator() == null) {
|
||||
RValue rValue2 = conditionalJump.getrValue2();
|
||||
SymbolType type = SymbolTypeInference.inferType(getScope(), rValue2);
|
||||
SymbolType type = SymbolTypeInference.inferType(getProgramScope(), rValue2);
|
||||
if(SymbolType.isInteger(type) || type instanceof SymbolTypePointer) {
|
||||
// Found integer condition - add boolean cast
|
||||
if(!pass1)
|
||||
@ -57,14 +57,14 @@ public class PassNAddBooleanCasts extends Pass2SsaOptimization {
|
||||
if(Operators.LOGIC_NOT.equals(programExpression.getOperator())) {
|
||||
ProgramExpressionUnary unaryExpression = (ProgramExpressionUnary) programExpression;
|
||||
RValue operand = unaryExpression.getOperand();
|
||||
SymbolType operandType = SymbolTypeInference.inferType(getScope(), operand);
|
||||
SymbolType operandType = SymbolTypeInference.inferType(getProgramScope(), operand);
|
||||
if(SymbolType.isInteger(operandType) || operandType instanceof SymbolTypePointer) {
|
||||
if(!pass1)
|
||||
getLog().append("Warning! Adding boolean cast to non-boolean sub-expression " + operand.toString(getProgram()));
|
||||
if(operand instanceof ConstantValue) {
|
||||
unaryExpression.setOperand(new ConstantBinary(new ConstantInteger(0L, SymbolType.NUMBER), Operators.NEQ, (ConstantValue) operand));
|
||||
} else {
|
||||
SymbolType type = SymbolTypeInference.inferType(getScope(), operand);
|
||||
SymbolType type = SymbolTypeInference.inferType(getProgramScope(), operand);
|
||||
Variable tmpVar = addBooleanCast(operand, type, currentStmt, stmtIt, currentBlock);
|
||||
unaryExpression.setOperand(tmpVar.getRef());
|
||||
}
|
||||
@ -75,7 +75,7 @@ public class PassNAddBooleanCasts extends Pass2SsaOptimization {
|
||||
}
|
||||
|
||||
private Variable addBooleanCast(RValue rValue, SymbolType rValueType, Statement currentStmt, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock) {
|
||||
Scope currentScope = getScope().getScope(currentBlock.getScope());
|
||||
Scope currentScope = getProgramScope().getScope(currentBlock.getScope());
|
||||
stmtIt.previous();
|
||||
Variable tmpVar = VariableBuilder.createIntermediate(currentScope, SymbolType.BOOLEAN, getProgram());
|
||||
// Go straight to xxx!=0 instead of casting to bool
|
||||
|
@ -27,7 +27,7 @@ public class PassNAddNumberTypeConversions extends Pass2SsaOptimization {
|
||||
ProgramExpressionBinary binary = (ProgramExpressionBinary) binaryExpression;
|
||||
RValue left = binary.getLeft();
|
||||
RValue right = binary.getRight();
|
||||
SymbolType castType = SymbolTypeConversion.getNumberCastType(left, right, getScope(), currentStmt);
|
||||
SymbolType castType = SymbolTypeConversion.getNumberCastType(left, right, getProgramScope(), currentStmt);
|
||||
if(castType != null) {
|
||||
// Convert both left and right to the found type
|
||||
SymbolType leftType = SymbolTypeInference.inferType(getProgram().getScope(), left);
|
||||
|
@ -74,7 +74,7 @@ public class PassNAddTypeConversionAssignment extends Pass2SsaOptimization {
|
||||
for(Statement statement : block.getStatements()) {
|
||||
if(statement instanceof StatementCallPointer) {
|
||||
RValue procedure = ((StatementCallPointer) statement).getProcedure();
|
||||
SymbolType procType = SymbolTypeInference.inferType(getScope(), procedure);
|
||||
SymbolType procType = SymbolTypeInference.inferType(getProgramScope(), procedure);
|
||||
if(procType instanceof SymbolTypePointer && ((SymbolTypePointer) procType).getElementType() instanceof SymbolTypeProcedure) {
|
||||
// Allow calling pointer to procedure directly
|
||||
// Add an automatic dereference to a pointer to procedure
|
||||
|
@ -30,7 +30,7 @@ public class PassNAssertConstantModification extends Pass2SsaOptimization {
|
||||
LValue lValue = ((StatementLValue) statement).getlValue();
|
||||
if(lValue instanceof VariableRef) {
|
||||
VariableRef variableRef = (VariableRef) lValue;
|
||||
Variable variable = getScope().getVariable(variableRef);
|
||||
Variable variable = getProgramScope().getVariable(variableRef);
|
||||
if(variable.isKindConstant() || variable.isNoModify()) {
|
||||
if(assigned.contains(variableRef)) {
|
||||
throw new CompileError("const variable may not be modified "+variable.toString(getProgram()), statement.getSource());
|
||||
|
@ -25,10 +25,10 @@ public class PassNAssertStructMembers extends Pass2SsaOptimization {
|
||||
ProgramValueIterator.execute(getGraph(), (programValue, currentStmt, stmtIt, currentBlock) -> {
|
||||
if(programValue.get() instanceof StructMemberRef) {
|
||||
StructMemberRef structMemberRef = (StructMemberRef) programValue.get();
|
||||
SymbolType type = SymbolTypeInference.inferType(getScope(), structMemberRef.getStruct());
|
||||
SymbolType type = SymbolTypeInference.inferType(getProgramScope(), structMemberRef.getStruct());
|
||||
if(type instanceof SymbolTypeStruct) {
|
||||
SymbolTypeStruct structType = (SymbolTypeStruct) type;
|
||||
StructDefinition structDefinition = structType.getStructDefinition(getScope());
|
||||
StructDefinition structDefinition = structType.getStructDefinition(getProgramScope());
|
||||
Variable member = structDefinition.getMember(structMemberRef.getMemberName());
|
||||
if(member==null) {
|
||||
throw new CompileError("Unknown struct member "+structMemberRef.getMemberName()+" in struct "+ structType.toCDecl(), currentStmt);
|
||||
|
@ -79,7 +79,7 @@ public class PassNBlockSequencePlanner extends Pass2SsaOptimization {
|
||||
|
||||
void pushTodo(ControlFlowBlock block) {
|
||||
LabelRef blockRef = block.getLabel();
|
||||
Scope blockScope = getScope().getSymbol(blockRef).getScope();
|
||||
Scope blockScope = getProgramScope().getSymbol(blockRef).getScope();
|
||||
for(ScopeTodo todoScope : todoScopes) {
|
||||
if(todoScope.scope.equals(blockScope)) {
|
||||
todoScope.pushTodo(block);
|
||||
@ -93,7 +93,7 @@ public class PassNBlockSequencePlanner extends Pass2SsaOptimization {
|
||||
|
||||
void pushCallTodo(ControlFlowBlock block) {
|
||||
LabelRef blockRef = block.getLabel();
|
||||
Scope blockScope = getScope().getSymbol(blockRef).getScope();
|
||||
Scope blockScope = getProgramScope().getSymbol(blockRef).getScope();
|
||||
for(ScopeTodo todoScope : todoScopes) {
|
||||
if(todoScope.scope.equals(blockScope)) {
|
||||
todoScope.addTodo(block);
|
||||
|
@ -8,7 +8,6 @@ import dk.camelot64.kickc.model.types.*;
|
||||
import dk.camelot64.kickc.model.values.ConstantInteger;
|
||||
import dk.camelot64.kickc.model.values.ConstantPointer;
|
||||
import dk.camelot64.kickc.model.values.RValue;
|
||||
import dk.camelot64.kickc.passes.Pass2SsaOptimization;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
@ -31,7 +30,7 @@ public class PassNCastSimplification extends Pass2SsaOptimization {
|
||||
OperatorCast operatorCast = (OperatorCast) programExpression.getOperator();
|
||||
ProgramExpressionUnary unary = (ProgramExpressionUnary) programExpression;
|
||||
SymbolType castType = operatorCast.getToType();
|
||||
SymbolType operandType = SymbolTypeInference.inferType(getScope(), ((ProgramExpressionUnary) programExpression).getOperand());
|
||||
SymbolType operandType = SymbolTypeInference.inferType(getProgramScope(), ((ProgramExpressionUnary) programExpression).getOperand());
|
||||
RValue unaryOperand = unary.getOperand();
|
||||
if(!SymbolTypeConversion.assignmentCastNeeded(castType, operandType)) {
|
||||
// Cast Not needed
|
||||
|
@ -102,7 +102,7 @@ public class PassNCullEmptyBlocks extends Pass2SsaOptimization {
|
||||
}
|
||||
getGraph().getAllBlocks().remove(removeBlock);
|
||||
LabelRef removeBlockLabelRef = removeBlock.getLabel();
|
||||
Label removeBlockLabel = getScope().getLabel(removeBlockLabelRef);
|
||||
Label removeBlockLabel = getProgramScope().getLabel(removeBlockLabelRef);
|
||||
removeBlockLabel.getScope().remove(removeBlockLabel);
|
||||
if(!pass1)
|
||||
getLog().append("Culled Empty Block " + removeBlockLabel.toString(getProgram()));
|
||||
|
@ -51,7 +51,7 @@ public class PassNDeInlineCastValues extends Pass2SsaOptimization {
|
||||
final CastValue castValue = (CastValue) castProgramValue.get();
|
||||
if(!pass1)
|
||||
getLog().append("De-inlining cast " + castValue.toString());
|
||||
final Scope scope = getScope().getScope(currentBlock.getScope());
|
||||
final Scope scope = getProgramScope().getScope(currentBlock.getScope());
|
||||
SymbolType toType = castValue.getToType();
|
||||
final Variable tmpVar = VariableBuilder.createIntermediate(scope, toType, getProgram());
|
||||
castProgramValue.set(tmpVar.getRef());
|
||||
|
@ -28,7 +28,7 @@ public class PassNEliminateEmptyProcedure extends Pass2SsaOptimization {
|
||||
|
||||
@Override
|
||||
public boolean step() {
|
||||
final Collection<Procedure> allProcedures = getScope().getAllProcedures(true);
|
||||
final Collection<Procedure> allProcedures = getProgramScope().getAllProcedures(true);
|
||||
boolean optimized = false;
|
||||
for(Procedure procedure : allProcedures) {
|
||||
if(procedure.isDeclaredIntrinsic()) continue;
|
||||
|
@ -22,11 +22,11 @@ public class PassNEliminateUnusedConstructors extends Pass2SsaOptimization {
|
||||
boolean optimized = false;
|
||||
// Find all used constructors
|
||||
Set<ProcedureRef> allConstructors = new LinkedHashSet<>();
|
||||
for(Procedure procedure : getScope().getAllProcedures(true)) {
|
||||
for(Procedure procedure : getProgramScope().getAllProcedures(true)) {
|
||||
allConstructors.addAll(procedure.getConstructorRefs());
|
||||
}
|
||||
|
||||
Procedure startProc = getScope().getLocalProcedure(SymbolRef.START_PROC_NAME);
|
||||
Procedure startProc = getProgramScope().getLocalProcedure(SymbolRef.START_PROC_NAME);
|
||||
if(startProc != null) {
|
||||
// find all constructor-calls in __init() pointing to unused constructors
|
||||
List<ProcedureRef> unusedConstructors = new ArrayList<>();
|
||||
@ -35,7 +35,7 @@ public class PassNEliminateUnusedConstructors extends Pass2SsaOptimization {
|
||||
for(Statement statement : block.getStatements()) {
|
||||
if(statement instanceof StatementCalling) {
|
||||
final ProcedureRef procedureRef = ((StatementCalling) statement).getProcedure();
|
||||
final Procedure procedure = getScope().getProcedure(procedureRef);
|
||||
final Procedure procedure = getProgramScope().getProcedure(procedureRef);
|
||||
if(procedure.isConstructor()) {
|
||||
// This is a constructor call!
|
||||
if(!allConstructors.contains(procedureRef)) {
|
||||
|
@ -41,7 +41,7 @@ public class PassNEliminateUnusedVars extends Pass2SsaOptimization {
|
||||
if(statement instanceof StatementAssignment) {
|
||||
LValue lValue = ((StatementAssignment) statement).getlValue();
|
||||
if(lValue instanceof VariableRef) {
|
||||
Variable variable = getScope().getVariable((VariableRef) lValue);
|
||||
Variable variable = getProgramScope().getVariable((VariableRef) lValue);
|
||||
if(eliminate(variable, referenceInfos, statement)) {
|
||||
if(pass2 || getLog().isVerbosePass1CreateSsa()) {
|
||||
getLog().append("Eliminating unused variable " + lValue.toString(getProgram()) + " and assignment " + statement.toString(getProgram(), false));
|
||||
@ -56,7 +56,7 @@ public class PassNEliminateUnusedVars extends Pass2SsaOptimization {
|
||||
} else if(statement instanceof StatementCall) {
|
||||
LValue lValue = ((StatementCall) statement).getlValue();
|
||||
if(lValue instanceof VariableRef) {
|
||||
Variable variable = getScope().getVariable((VariableRef) lValue);
|
||||
Variable variable = getProgramScope().getVariable((VariableRef) lValue);
|
||||
if(eliminate(variable, referenceInfos, statement)) {
|
||||
if(pass2 || getLog().isVerbosePass1CreateSsa()) {
|
||||
getLog().append("Eliminating unused variable - keeping the call " + lValue.toString(getProgram()));
|
||||
@ -71,7 +71,7 @@ public class PassNEliminateUnusedVars extends Pass2SsaOptimization {
|
||||
} else if(statement instanceof StatementCallFinalize) {
|
||||
LValue lValue = ((StatementCallFinalize) statement).getlValue();
|
||||
if(lValue instanceof VariableRef) {
|
||||
Variable variable = getScope().getVariable((VariableRef) lValue);
|
||||
Variable variable = getProgramScope().getVariable((VariableRef) lValue);
|
||||
if(eliminate(variable, referenceInfos, statement)) {
|
||||
if(pass2 || getLog().isVerbosePass1CreateSsa()) {
|
||||
getLog().append("Eliminating unused variable - keeping the call " + lValue.toString(getProgram()));
|
||||
@ -86,7 +86,7 @@ public class PassNEliminateUnusedVars extends Pass2SsaOptimization {
|
||||
} else if(statement instanceof StatementCallPointer) {
|
||||
LValue lValue = ((StatementCallPointer) statement).getlValue();
|
||||
if(lValue instanceof VariableRef) {
|
||||
Variable variable = getScope().getVariable((VariableRef) lValue);
|
||||
Variable variable = getProgramScope().getVariable((VariableRef) lValue);
|
||||
if(eliminate(variable, referenceInfos, statement)) {
|
||||
if(pass2 || getLog().isVerbosePass1CreateSsa()) {
|
||||
getLog().append("Eliminating unused variable - keeping the call " + lValue.toString(getProgram()));
|
||||
@ -104,7 +104,7 @@ public class PassNEliminateUnusedVars extends Pass2SsaOptimization {
|
||||
while(phiVarIt.hasNext()) {
|
||||
StatementPhiBlock.PhiVariable phiVariable = phiVarIt.next();
|
||||
VariableRef variableRef = phiVariable.getVariable();
|
||||
Variable variable = getScope().getVariable(variableRef);
|
||||
Variable variable = getProgramScope().getVariable(variableRef);
|
||||
if(eliminate(variable, referenceInfos, statement)) {
|
||||
if(pass2 || getLog().isVerbosePass1CreateSsa()) {
|
||||
getLog().append("Eliminating unused variable - keeping the phi block " + variableRef.toString(getProgram()));
|
||||
@ -120,14 +120,14 @@ public class PassNEliminateUnusedVars extends Pass2SsaOptimization {
|
||||
}
|
||||
}
|
||||
|
||||
for(Variable variable : getScope().getAllVariables(true)) {
|
||||
for(Variable variable : getProgramScope().getAllVariables(true)) {
|
||||
if(eliminate(variable, referenceInfos, null) && !variable.isKindPhiMaster()) {
|
||||
getLog().append("Eliminating unused variable with no statement " + variable.getRef().toString(getProgram()));
|
||||
variable.getScope().remove(variable);
|
||||
}
|
||||
}
|
||||
|
||||
Collection<Variable> allConstants = getScope().getAllConstants(true);
|
||||
Collection<Variable> allConstants = getProgramScope().getAllConstants(true);
|
||||
for(Variable constant : allConstants) {
|
||||
if(eliminate(constant, referenceInfos, null)) {
|
||||
if(pass2 || getLog().isVerbosePass1CreateSsa()) {
|
||||
|
@ -34,22 +34,22 @@ public class PassNFinalizeNumberTypeConversions extends Pass2SsaOptimization {
|
||||
if(programValue.get() instanceof ConstantInteger) {
|
||||
ConstantInteger constantInteger = (ConstantInteger) programValue.get();
|
||||
if(SymbolType.UNUMBER.equals(constantInteger.getType())) {
|
||||
SymbolType integerType = SymbolTypeConversion.getSmallestUnsignedFixedIntegerType(constantInteger, getScope());
|
||||
SymbolType integerType = SymbolTypeConversion.getSmallestUnsignedFixedIntegerType(constantInteger, getProgramScope());
|
||||
programValue.set(new ConstantInteger(constantInteger.getValue(), integerType));
|
||||
getLog().append("Finalized unsigned number type (" + integerType + ") " + programValue.get().toString(getProgram()));
|
||||
modified.set(true);
|
||||
} else if(SymbolType.SNUMBER.equals(constantInteger.getType())) {
|
||||
SymbolType integerType = SymbolTypeConversion.getSmallestSignedFixedIntegerType(constantInteger, getScope());
|
||||
SymbolType integerType = SymbolTypeConversion.getSmallestSignedFixedIntegerType(constantInteger, getProgramScope());
|
||||
programValue.set(new ConstantInteger(constantInteger.getValue(), integerType));
|
||||
getLog().append("Finalized signed number type (" + integerType + ") " + programValue.get().toString(getProgram()));
|
||||
modified.set(true);
|
||||
} else if(finalizeAllNumbers && SymbolType.NUMBER.equals(constantInteger.getType()) && constantInteger.getValue() >= 0) {
|
||||
SymbolType integerType = SymbolTypeConversion.getSmallestUnsignedFixedIntegerType(constantInteger, getScope());
|
||||
SymbolType integerType = SymbolTypeConversion.getSmallestUnsignedFixedIntegerType(constantInteger, getProgramScope());
|
||||
programValue.set(new ConstantInteger(constantInteger.getValue(), integerType));
|
||||
getLog().append("Finalized unsigned number type (" + integerType + ") " + programValue.get().toString(getProgram()));
|
||||
modified.set(true);
|
||||
} else if(finalizeAllNumbers && SymbolType.NUMBER.equals(constantInteger.getType()) && constantInteger.getValue() <= 0) {
|
||||
SymbolType integerType = SymbolTypeConversion.getSmallestSignedFixedIntegerType(constantInteger, getScope());
|
||||
SymbolType integerType = SymbolTypeConversion.getSmallestSignedFixedIntegerType(constantInteger, getProgramScope());
|
||||
programValue.set(new ConstantInteger(constantInteger.getValue(), integerType));
|
||||
getLog().append("Finalized signed number type (" + integerType + ") " + programValue.get().toString(getProgram()));
|
||||
modified.set(true);
|
||||
@ -60,7 +60,7 @@ public class PassNFinalizeNumberTypeConversions extends Pass2SsaOptimization {
|
||||
if(SymbolType.UNUMBER.equals(toType)) {
|
||||
if(constantCastValue.getValue() instanceof ConstantRef) {
|
||||
ConstantRef constRef = (ConstantRef) constantCastValue.getValue();
|
||||
Variable constant = getScope().getConstant(constRef);
|
||||
Variable constant = getProgramScope().getConstant(constRef);
|
||||
if(constant.isKindIntermediate())
|
||||
constant.setType(toType);
|
||||
else
|
||||
@ -72,7 +72,7 @@ public class PassNFinalizeNumberTypeConversions extends Pass2SsaOptimization {
|
||||
} catch (ConstantNotLiteral e) {
|
||||
throw new InternalError("Cannot cast declared type!" + constantCastValue.toString());
|
||||
}
|
||||
SymbolType smallestUnsigned = SymbolTypeConversion.getSmallestUnsignedFixedIntegerType(constantLiteral, getScope());
|
||||
SymbolType smallestUnsigned = SymbolTypeConversion.getSmallestUnsignedFixedIntegerType(constantLiteral, getProgramScope());
|
||||
if(smallestUnsigned != null) {
|
||||
constantCastValue.setToType(smallestUnsigned);
|
||||
}
|
||||
@ -80,14 +80,14 @@ public class PassNFinalizeNumberTypeConversions extends Pass2SsaOptimization {
|
||||
} else if(SymbolType.SNUMBER.equals(toType)) {
|
||||
if(constantCastValue.getValue() instanceof ConstantRef) {
|
||||
ConstantRef constRef = (ConstantRef) constantCastValue.getValue();
|
||||
Variable constant = getScope().getConstant(constRef);
|
||||
Variable constant = getProgramScope().getConstant(constRef);
|
||||
if(constant.isKindIntermediate())
|
||||
constant.setType(toType);
|
||||
else
|
||||
throw new InternalError("Cannot cast declared type!" + constant.toString());
|
||||
} else {
|
||||
ConstantLiteral constantLiteral = constantCastValue.getValue().calculateLiteral(getProgram().getScope());
|
||||
SymbolType smallestSigned = SymbolTypeConversion.getSmallestSignedFixedIntegerType(constantLiteral, getScope());
|
||||
SymbolType smallestSigned = SymbolTypeConversion.getSmallestSignedFixedIntegerType(constantLiteral, getProgramScope());
|
||||
if(smallestSigned != null) {
|
||||
constantCastValue.setToType(smallestSigned);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ public class PassNFixIntermediateMemoryArea extends Pass2SsaOptimization {
|
||||
public boolean step() {
|
||||
boolean modified = false;
|
||||
final VariableBuilderConfig variableBuilderConfig = getProgram().getTargetPlatform().getVariableBuilderConfig();
|
||||
for(Variable var : getScope().getAllVars(true)) {
|
||||
for(Variable var : getProgramScope().getAllVars(true)) {
|
||||
if(var.isKindIntermediate()) {
|
||||
final VariableBuilder builder = new VariableBuilder(var.getLocalName(), var.getScope(), false, true, var.getType(), null, var.getDataSegment(), variableBuilderConfig);
|
||||
final Variable.MemoryArea memoryArea = builder.getMemoryArea();
|
||||
|
@ -28,8 +28,8 @@ public class PassNRenumberLabels extends Pass2SsaOptimization {
|
||||
@Override
|
||||
public boolean step() {
|
||||
Map<LabelRef, LabelRef> renamed = new LinkedHashMap<>();
|
||||
renumberLabels(getScope(), renamed);
|
||||
for(Scope scope : getScope().getAllScopes(true)) {
|
||||
renumberLabels(getProgramScope(), renamed);
|
||||
for(Scope scope : getProgramScope().getAllScopes(true)) {
|
||||
renumberLabels(scope, renamed);
|
||||
}
|
||||
ProgramValueIterator.execute(getGraph(), (programValue, currentStmt, stmtIt, currentBlock) -> {
|
||||
|
@ -37,11 +37,11 @@ public class PassNSizeOfSimplification extends Pass2SsaOptimization {
|
||||
if(Operators.SIZEOF.equals(assignment.getOperator())) {
|
||||
if(assignment.getrValue2() instanceof SymbolVariableRef) {
|
||||
SymbolVariableRef symbolRef = (SymbolVariableRef) assignment.getrValue2();
|
||||
Variable symbolVar = (Variable) getScope().getSymbol(symbolRef);
|
||||
Variable symbolVar = (Variable) getProgramScope().getSymbol(symbolRef);
|
||||
SymbolType symbolType = symbolVar.getType();
|
||||
if(!(symbolVar.isArray())) {
|
||||
getLog().append("Resolving sizeof() " + assignment.toString(getProgram(), false));
|
||||
ConstantRef sizeOfConstantVar = SizeOfConstants.getSizeOfConstantVar(getScope(), symbolType);
|
||||
ConstantRef sizeOfConstantVar = SizeOfConstants.getSizeOfConstantVar(getProgramScope(), symbolType);
|
||||
assignment.setrValue2(sizeOfConstantVar);
|
||||
assignment.setOperator(null);
|
||||
modified.set(true);
|
||||
@ -68,20 +68,20 @@ public class PassNSizeOfSimplification extends Pass2SsaOptimization {
|
||||
|
||||
public void resolveConstantSizeOf(AtomicBoolean modified, ProgramValue programValue, ConstantUnary unary, ConstantValue operand) {
|
||||
if(operand instanceof ConstantRef) {
|
||||
Variable constant = getScope().getConstant((ConstantRef) operand);
|
||||
Variable constant = getProgramScope().getConstant((ConstantRef) operand);
|
||||
SymbolType symbolType = constant.getType();
|
||||
if(constant.isArray() && symbolType instanceof SymbolTypePointer) {
|
||||
SymbolTypePointer arrayType = (SymbolTypePointer) symbolType;
|
||||
ConstantValue arraySize = constant.getArraySize();
|
||||
if(arraySize!=null) {
|
||||
getLog().append("Resolving array sizeof() " + unary.toString(getProgram()));
|
||||
ConstantRef sizeOfConstantVar = SizeOfConstants.getSizeOfConstantVar(getScope(), arrayType.getElementType());
|
||||
ConstantRef sizeOfConstantVar = SizeOfConstants.getSizeOfConstantVar(getProgramScope(), arrayType.getElementType());
|
||||
programValue.set(new ConstantBinary(arraySize, Operators.MULTIPLY, sizeOfConstantVar));
|
||||
modified.set(true);
|
||||
} else if(constant.getInitValue() instanceof ConstantArrayList) {
|
||||
getLog().append("Resolving array sizeof() " + unary.toString(getProgram()));
|
||||
int size = ((ConstantArrayList) constant.getInitValue()).getElements().size();
|
||||
ConstantRef sizeOfConstantVar = SizeOfConstants.getSizeOfConstantVar(getScope(), arrayType.getElementType());
|
||||
ConstantRef sizeOfConstantVar = SizeOfConstants.getSizeOfConstantVar(getProgramScope(), arrayType.getElementType());
|
||||
programValue.set(new ConstantBinary(new ConstantInteger((long) size), Operators.MULTIPLY, sizeOfConstantVar));
|
||||
modified.set(true);
|
||||
} else {
|
||||
@ -96,7 +96,7 @@ public class PassNSizeOfSimplification extends Pass2SsaOptimization {
|
||||
ConstantString constString = (ConstantString) stringLiteral;
|
||||
int length = constString.getStringLength();
|
||||
getLog().append("Resolving string sizeof() " + unary.toString(getProgram()));
|
||||
ConstantRef sizeOfChar = SizeOfConstants.getSizeOfConstantVar(getScope(), SymbolType.BYTE);
|
||||
ConstantRef sizeOfChar = SizeOfConstants.getSizeOfConstantVar(getProgramScope(), SymbolType.BYTE);
|
||||
programValue.set(new ConstantBinary(new ConstantInteger((long) length), Operators.MULTIPLY, sizeOfChar));
|
||||
modified.set(true);
|
||||
} else {
|
||||
@ -105,14 +105,14 @@ public class PassNSizeOfSimplification extends Pass2SsaOptimization {
|
||||
}
|
||||
} else if(symbolType instanceof SymbolTypePointer ){
|
||||
getLog().append("Resolving sizeof() " + unary.toString(getProgram()));
|
||||
ConstantRef sizeOfConstantVar = SizeOfConstants.getSizeOfConstantVar(getScope(), symbolType);
|
||||
ConstantRef sizeOfConstantVar = SizeOfConstants.getSizeOfConstantVar(getProgramScope(), symbolType);
|
||||
programValue.set(sizeOfConstantVar);
|
||||
modified.set(true);
|
||||
} else {
|
||||
getLog().append("Resolving sizeof() " + unary.toString(getProgram()));
|
||||
ConstantLiteral literal = operand.calculateLiteral(getProgram().getScope());
|
||||
SymbolType constType = literal.getType(getProgram().getScope());
|
||||
ConstantRef sizeOfConstantVar = SizeOfConstants.getSizeOfConstantVar(getScope(), constType);
|
||||
ConstantRef sizeOfConstantVar = SizeOfConstants.getSizeOfConstantVar(getProgramScope(), constType);
|
||||
programValue.set(sizeOfConstantVar);
|
||||
modified.set(true);
|
||||
}
|
||||
@ -120,7 +120,7 @@ public class PassNSizeOfSimplification extends Pass2SsaOptimization {
|
||||
getLog().append("Resolving sizeof() " + unary.toString(getProgram()));
|
||||
ConstantLiteral literal = operand.calculateLiteral(getProgram().getScope());
|
||||
SymbolType constType = literal.getType(getProgram().getScope());
|
||||
ConstantRef sizeOfConstantVar = SizeOfConstants.getSizeOfConstantVar(getScope(), constType);
|
||||
ConstantRef sizeOfConstantVar = SizeOfConstants.getSizeOfConstantVar(getProgramScope(), constType);
|
||||
programValue.set(sizeOfConstantVar);
|
||||
modified.set(true);
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ public class PassNStructUnwoundPlaceholderRemoval extends Pass2SsaOptimization {
|
||||
if(statement instanceof StatementAssignment) {
|
||||
StatementAssignment assignment = (StatementAssignment) statement;
|
||||
if(assignment.getrValue2() instanceof StructUnwoundPlaceholder && assignment.getlValue() instanceof VariableRef)
|
||||
if(getScope().getVariable((SymbolVariableRef) assignment.getlValue()).isStructClassic()) {
|
||||
if(getProgramScope().getVariable((SymbolVariableRef) assignment.getlValue()).isStructClassic()) {
|
||||
getLog().append("Removing C-classic struct-unwound assignment "+assignment.toString(getProgram(), false));
|
||||
stmtIt.remove();
|
||||
}
|
||||
|
@ -29,12 +29,12 @@ public class PassNTypeIdSimplification extends Pass2SsaOptimization {
|
||||
ProgramExpressionUnary unary = (ProgramExpressionUnary) programExpression;
|
||||
if(Operators.TYPEID.equals(unary.getOperator())) {
|
||||
RValue rValue = unary.getOperand();
|
||||
SymbolType symbolType = SymbolTypeInference.inferType(getScope(), rValue);
|
||||
SymbolType symbolType = SymbolTypeInference.inferType(getProgramScope(), rValue);
|
||||
if(SymbolType.VAR.equals(symbolType) || SymbolType.NUMBER.equals(symbolType)) {
|
||||
|
||||
} else {
|
||||
getLog().append("Resolving typeid() " + currentStmt.toString(getProgram(), false));
|
||||
ConstantRef typeIDConstantVar = OperatorTypeId.getTypeIdConstantVar(getScope(), symbolType);
|
||||
ConstantRef typeIDConstantVar = OperatorTypeId.getTypeIdConstantVar(getProgramScope(), symbolType);
|
||||
unary.set(typeIDConstantVar);
|
||||
modified.set(true);
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ public class Unroller {
|
||||
prepare();
|
||||
if(program.getLog().isVerboseLoopUnroll()) {
|
||||
program.getLog().append("CONTROL FLOW GRAPH (PREPARED FOR LOOP HEAD UNROLL)");
|
||||
program.getLog().append(program.getGraph().toString(program));
|
||||
program.getLog().append(program.prettyControlFlowGraph());
|
||||
}
|
||||
// 1. Create new versions of all symbols assigned inside the loop
|
||||
this.varsOriginalToCopied = copyDefinedVars(unrollBlocks, program);
|
||||
@ -84,7 +84,7 @@ public class Unroller {
|
||||
reVersionAllUsages(origVarRef, newPhis, varVersions);
|
||||
if(program.getLog().isVerboseLoopUnroll()) {
|
||||
program.getLog().append("Created new versions for " + origVarRef );
|
||||
//program.getLog().append(program.getGraph().toString(program));
|
||||
//program.getLog().append(program.prettyControlFlowGraph());
|
||||
}
|
||||
// Recursively fill out & add PHI-functions until they have propagated everywhere needed
|
||||
completePhiFunctions(newPhis, varVersions);
|
||||
@ -213,7 +213,7 @@ public class Unroller {
|
||||
}
|
||||
}
|
||||
//program.getLog().append("Completing PHI-functions...");
|
||||
//program.getLog().append(program.getGraph().toString(program));
|
||||
//program.getLog().append(program.prettyControlFlowGraph());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ public class TestPrograms {
|
||||
String baseFileName = FileNameUtils.removeExtension(fileName);
|
||||
success &= helper.testOutput(baseFileName, ".asm", program.getAsm().toString(new AsmProgram.AsmPrintState(false, true, false, false), program));
|
||||
success &= helper.testOutput(baseFileName, ".sym", program.getScope().toStringVars(program, false));
|
||||
success &= helper.testOutput(baseFileName, ".cfg", program.getGraph().toString(program));
|
||||
success &= helper.testOutput(baseFileName, ".cfg", program.prettyControlFlowGraph());
|
||||
success &= helper.testOutput(baseFileName, ".log", program.getLog().toString());
|
||||
if(!success) {
|
||||
// System.out.println("\nCOMPILE LOG");
|
||||
|
Loading…
x
Reference in New Issue
Block a user