diff --git a/src/main/java/dk/camelot64/kickc/model/values/ConstantSymbolPointer.java b/src/main/java/dk/camelot64/kickc/model/values/ConstantSymbolPointer.java index c5731959a..fb5ce7b8b 100644 --- a/src/main/java/dk/camelot64/kickc/model/values/ConstantSymbolPointer.java +++ b/src/main/java/dk/camelot64/kickc/model/values/ConstantSymbolPointer.java @@ -9,6 +9,7 @@ import dk.camelot64.kickc.model.symbols.Variable; import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolTypePointer; +import java.util.Collection; import java.util.Objects; /** A pointer to a symbol (variable or procedure) */ @@ -42,6 +43,18 @@ public class ConstantSymbolPointer implements ConstantValue { if(symbol instanceof Variable) { Variable variable = (Variable) symbol; if(variable.isVariable()) { + + // Hacky solution to get a version that has an allocation + if(variable.isKindPhiMaster()) { + Collection versions = variable.getScope().getVersions(variable); + for(Variable version : versions) { + if(variable.isVariable()) + variable = version; + break; + } + } + + Registers.Register allocation = variable.getAllocation(); if(allocation != null && Registers.RegisterType.ZP_MEM.equals(allocation.getType())) { int zp = ((Registers.RegisterZpMem) allocation).getZp(); diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1AddressOfVolatile.java b/src/main/java/dk/camelot64/kickc/passes/Pass1AddressOfVolatile.java index 27f10a717..f3545c326 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1AddressOfVolatile.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1AddressOfVolatile.java @@ -1,17 +1,16 @@ package dk.camelot64.kickc.passes; -import dk.camelot64.kickc.model.ControlFlowBlock; import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.iterator.ProgramExpressionIterator; +import dk.camelot64.kickc.model.iterator.ProgramExpressionUnary; +import dk.camelot64.kickc.model.iterator.ProgramValueIterator; import dk.camelot64.kickc.model.operators.Operators; -import dk.camelot64.kickc.model.statements.Statement; -import dk.camelot64.kickc.model.statements.StatementAssignment; import dk.camelot64.kickc.model.symbols.Symbol; import dk.camelot64.kickc.model.symbols.Variable; -import dk.camelot64.kickc.model.values.RValue; -import dk.camelot64.kickc.model.values.SymbolVariableRef; +import dk.camelot64.kickc.model.values.*; /** - * Add infered volatile to all variables, where address-of is used + * Add inferred volatile to all variables, where address-of is used */ public class Pass1AddressOfVolatile extends Pass2SsaOptimization { @@ -21,23 +20,30 @@ public class Pass1AddressOfVolatile extends Pass2SsaOptimization { @Override public boolean step() { - for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) { - for(Statement statement : block.getStatements()) { - if(statement instanceof StatementAssignment) { - StatementAssignment assignment = (StatementAssignment) statement; - if(Operators.ADDRESS_OF.equals(assignment.getOperator()) ) { - RValue rValue = assignment.getrValue2(); - if(rValue instanceof SymbolVariableRef) { - Symbol toSymbol = getScope().getSymbol((SymbolVariableRef) rValue); - if(toSymbol instanceof Variable) { - ((Variable) toSymbol).setInferredVolatile(true); - getLog().append("Setting inferred volatile on symbol affected by address-of "+statement.toString(getProgram(), false)); - } - } + ProgramExpressionIterator.execute(getProgram(), (programExpression, currentStmt, stmtIt, currentBlock) -> { + if(Operators.ADDRESS_OF.equals(programExpression.getOperator())) { + RValue rValue = ((ProgramExpressionUnary) programExpression).getOperand(); + if(rValue instanceof SymbolVariableRef) { + Symbol toSymbol = getScope().getSymbol((SymbolVariableRef) rValue); + if(toSymbol instanceof Variable) { + ((Variable) toSymbol).setInferredVolatile(true); + getLog().append("Setting inferred volatile on symbol affected by address-of " + currentStmt.toString(getProgram(), false)); } } } - } + }); + ProgramValueIterator.execute(getProgram(), (programValue, currentStmt, stmtIt, currentBlock) -> { + if(programValue.get() instanceof ConstantSymbolPointer) { + Value value = ((ConstantSymbolPointer) programValue.get()).getToSymbol(); + if(value instanceof SymbolVariableRef) { + Symbol toSymbol = getScope().getSymbol((SymbolVariableRef) value); + if(toSymbol instanceof Variable) { + ((Variable) toSymbol).setInferredVolatile(true); + getLog().append("Setting inferred volatile on symbol affected by address-of " + currentStmt.toString(getProgram(), false)); + } + } + } + }); return false; } diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index 1125c6ec5..07c204288 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -2710,8 +2710,7 @@ public class TestPrograms { @Test public void testAddressOf1() throws IOException, URISyntaxException { - compileAndCompare("address-of-1", log().verboseCreateSsa()); - fail("Address-of-not detected!"); + compileAndCompare("address-of-1"); } @Test