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

#815 more procedure compilation

This commit is contained in:
jespergravgaard 2023-04-06 22:46:28 +02:00
parent adb9688acb
commit 185bd439e4
88 changed files with 378 additions and 481 deletions

View File

@ -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());
}

View File

@ -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)) {

View File

@ -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)

View File

@ -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;
}
}

View File

@ -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)

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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());

View File

@ -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);
}

View File

@ -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());
}

View File

@ -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()));
}

View File

@ -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);
}

View File

@ -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())) {

View File

@ -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) {

View File

@ -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());
}

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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());
}

View File

@ -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();
}
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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());

View File

@ -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());
}
}

View File

@ -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);

View File

@ -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();

View File

@ -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());
}
}

View File

@ -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;

View File

@ -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();

View File

@ -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));
}
}

View File

@ -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) {

View File

@ -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());
}

View File

@ -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);

View File

@ -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());

View File

@ -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()));

View File

@ -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);

View File

@ -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) {

View File

@ -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);
}

View File

@ -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++) {

View File

@ -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()) {

View File

@ -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) {

View File

@ -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);

View File

@ -18,10 +18,6 @@ public class Pass2Base {
return program.getLog();
}
public ControlFlowGraph getGraph() {
return program.getGraph();
}
public ProgramScope getSymbols() {
return program.getScope();
}

View File

@ -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
}

View File

@ -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);

View File

@ -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());
}

View File

@ -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);

View File

@ -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;

View File

@ -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))

View File

@ -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());

View File

@ -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();

View File

@ -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<>();

View File

@ -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)

View File

@ -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) {

View File

@ -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++;

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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());

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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) {

View File

@ -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);

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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());

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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()));

View File

@ -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());

View File

@ -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;

View File

@ -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)) {

View File

@ -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()) {

View File

@ -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);
}

View File

@ -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();

View File

@ -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) -> {

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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());
}
}

View File

@ -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");