1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-11-23 23:32:55 +00:00

Eliminated VariableUnversioned.

This commit is contained in:
jespergravgaard 2019-09-28 08:44:04 +02:00
parent 51d3d8e7d5
commit 5d0fe66906
12 changed files with 123 additions and 114 deletions

View File

@ -80,12 +80,12 @@ public class AsmFragmentTemplate {
// Generate a dummy instance to find clobber & cycles // Generate a dummy instance to find clobber & cycles
ProgramScope scope = new ProgramScope(); ProgramScope scope = new ProgramScope();
LinkedHashMap<String, Value> bindings = new LinkedHashMap<>(); LinkedHashMap<String, Value> bindings = new LinkedHashMap<>();
Variable v1 = new Variable("$tmp1", scope, SymbolType.BYTE, null, false, true); Variable v1 = new Variable("$tmp1", scope, SymbolType.BYTE, null, true, false, false);
Variable v2 = new Variable("$tmp2", scope, SymbolType.BYTE, null, false, true); Variable v2 = new Variable("$tmp2", scope, SymbolType.BYTE, null, true, false, false);
Variable v3 = new Variable("$tmp3", scope, SymbolType.BYTE, null, false, true); Variable v3 = new Variable("$tmp3", scope, SymbolType.BYTE, null, true, false, false);
Variable v4 = new Variable("$tmp4", scope, SymbolType.BYTE, null, false, true); Variable v4 = new Variable("$tmp4", scope, SymbolType.BYTE, null, true, false, false);
Variable v5 = new Variable("$tmp5", scope, SymbolType.BYTE, null, false, true); Variable v5 = new Variable("$tmp5", scope, SymbolType.BYTE, null, true, false, false);
Variable v6 = new Variable("$tmp6", scope, SymbolType.BYTE, null, false, true); Variable v6 = new Variable("$tmp6", scope, SymbolType.BYTE, null, true, false, false);
v1.setAllocation(new Registers.RegisterZpByte(2)); v1.setAllocation(new Registers.RegisterZpByte(2));
v2.setAllocation(new Registers.RegisterZpByte(4)); v2.setAllocation(new Registers.RegisterZpByte(4));
v3.setAllocation(new Registers.RegisterZpByte(6)); v3.setAllocation(new Registers.RegisterZpByte(6));

View File

@ -99,26 +99,26 @@ public abstract class Scope implements Symbol, Serializable {
symbols.remove(symbol.getLocalName()); symbols.remove(symbol.getLocalName());
} }
public VariableUnversioned addVariable(String name, SymbolType type, String dataSegment) { public Variable addVariablePhiMaster(String name, SymbolType type, String dataSegment) {
return add(new VariableUnversioned(name, this, type, dataSegment)); return add(new Variable(name, this, type, dataSegment, false, false, true));
} }
public Variable addVariableIntermediate() { public Variable addVariableIntermediate() {
String name = allocateIntermediateVariableName(); String name = allocateIntermediateVariableName();
return add(new Variable(name, this, SymbolType.VAR, getSegmentData(), true, false)); return add(new Variable(name, this, SymbolType.VAR, getSegmentData(), true, false, false));
} }
/** /**
* Get all versions of an unversioned variable * Get all versions of a PHI-master variable
* *
* @param unversioned The unversioned variable * @param unversioned The unversioned PHI-master variable
* @return All versions of the variable * @return All versions of the variable
*/ */
public Collection<Variable> getVersions(VariableUnversioned unversioned) { public Collection<Variable> getVersions(Variable unversioned) {
LinkedHashSet<Variable> versions = new LinkedHashSet<>(); LinkedHashSet<Variable> versions = new LinkedHashSet<>();
for(Symbol symbol : symbols.values()) { for(Symbol symbol : symbols.values()) {
if(symbol instanceof Variable) { if(symbol instanceof Variable) {
if(((Variable) symbol).isVersioned()) { if(((Variable) symbol).isPhiVersion()) {
if(((Variable) symbol).getVersionOf().equals(unversioned)) { if(((Variable) symbol).getVersionOf().equals(unversioned)) {
versions.add((Variable) symbol); versions.add((Variable) symbol);
} }

View File

@ -1,47 +1,70 @@
package dk.camelot64.kickc.model.symbols; package dk.camelot64.kickc.model.symbols;
import dk.camelot64.kickc.model.InternalError;
import dk.camelot64.kickc.model.Registers; import dk.camelot64.kickc.model.Registers;
import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.values.VariableRef; import dk.camelot64.kickc.model.values.VariableRef;
import java.util.Objects; import java.util.Objects;
/** A Variable (or a Constant) */ /** A Variable in the program.
*
* There are several types of variables
*
* - Intermediate: A variable added by the compiler to hold some intermediate value. Intermediate variables are names $1, $2, ...
* - PHI-variable: A variable with storage strategy PHI is turned into versions. The variable itself is never used directly in the program.
* - PHI-versions: A variable with storage strategy PHI is turned into versions. Versions of the PHI-variable name are named name#1, name#2, name#3
* - Memory: A variable with storage strategy memory is used directly in the program.
* */
public class Variable extends SymbolVariable { public class Variable extends SymbolVariable {
/** true if the variable is intermediate. */ /** true if the variable is intermediate. */
private boolean isIntermediate; private boolean isIntermediate;
/* true if the variable is a PHI version. (the variable has storage strategy PHI)*/ /* true if the variable is a PHI master variable that is turned into versions. (the variable has storage strategy PHI)*/
private boolean isVersion; private boolean isPhiMaster;
/** The number of the next version (only used for PHI masters)*/
private Integer nextVersionNumber;
/* true if the variable is a PHI version. (the "master" variable has storage strategy PHI)*/
private boolean isPhiVersion;
/** If the variable is assigned to a specific "register", this contains the register. If null the variable has no allocation (yet). Constants are never assigned to registers. */ /** If the variable is assigned to a specific "register", this contains the register. If null the variable has no allocation (yet). Constants are never assigned to registers. */
private Registers.Register allocation; private Registers.Register allocation;
public Variable(String name, Scope scope, SymbolType type, String dataSegment, boolean isIntermediate, boolean isVersion) { public Variable(String name, Scope scope, SymbolType type, String dataSegment, boolean isIntermediate, boolean isPhiVersion, boolean isPhiMaster) {
super(name, scope, type, dataSegment); super(name, scope, type, dataSegment);
this.isIntermediate = isIntermediate; this.isIntermediate = isIntermediate;
this.isVersion = isVersion; this.isPhiVersion = isPhiVersion;
this.isPhiMaster = isPhiMaster;
if(isPhiMaster)
this.nextVersionNumber = 0;
} }
public Variable(VariableUnversioned versionOf, int version) { /**
super(versionOf.getName()+"#"+version, versionOf.getScope(), versionOf.getType(), versionOf.getDataSegment()); * Create a version of a PHI master variable
this.setDeclaredAlignment(versionOf.getDeclaredAlignment()); * @param phiMaster The PHI master variable.
this.setDeclaredAsRegister(versionOf.isDeclaredAsRegister()); * @param version The version number
this.setDeclaredAsMemory(versionOf.isDeclaredAsMemory()); */
this.setDeclaredRegister(versionOf.getDeclaredRegister()); public Variable(Variable phiMaster, int version) {
this.setDeclaredMemoryAddress(versionOf.getDeclaredMemoryAddress()); super(phiMaster.getName()+"#"+version, phiMaster.getScope(), phiMaster.getType(), phiMaster.getDataSegment());
this.setStorageStrategy(versionOf.getStorageStrategy()); this.setDeclaredAlignment(phiMaster.getDeclaredAlignment());
this.setDeclaredVolatile(versionOf.isDeclaredVolatile()); this.setDeclaredAsRegister(phiMaster.isDeclaredAsRegister());
this.setDeclaredExport(versionOf.isDeclaredExport()); this.setDeclaredAsMemory(phiMaster.isDeclaredAsMemory());
this.setInferedVolatile(versionOf.isInferedVolatile()); this.setDeclaredRegister(phiMaster.getDeclaredRegister());
this.setInferredType(versionOf.isInferredType()); this.setDeclaredMemoryAddress(phiMaster.getDeclaredMemoryAddress());
this.setComments(versionOf.getComments()); this.setStorageStrategy(phiMaster.getStorageStrategy());
this.setDeclaredVolatile(phiMaster.isDeclaredVolatile());
this.setDeclaredExport(phiMaster.isDeclaredExport());
this.setInferedVolatile(phiMaster.isInferedVolatile());
this.setInferredType(phiMaster.isInferredType());
this.setComments(phiMaster.getComments());
this.isPhiMaster = false;
this.isPhiVersion = true;
this.isIntermediate = false; this.isIntermediate = false;
this.isVersion = true;
} }
public Registers.Register getAllocation() { public Registers.Register getAllocation() {
return allocation; return allocation;
} }
@ -50,23 +73,39 @@ public class Variable extends SymbolVariable {
this.allocation = allocation; this.allocation = allocation;
} }
public boolean isVersioned() { public boolean isPhiMaster() {
return isVersion; return isPhiMaster;
}
public boolean isPhiVersion() {
return isPhiVersion;
} }
public boolean isIntermediate() { public boolean isIntermediate() {
return isIntermediate; return isIntermediate;
} }
/**
* Creates a new PHI-version from a PHI-master
* @return The new version of the PHI master
*/
public Variable createVersion() {
if(!isPhiMaster)
throw new InternalError("Cannot version non-PHI variable");
Variable version = new Variable(this, nextVersionNumber++);
getScope().add(version);
return version;
}
/** /**
* If the variable is a version of a variable returns the original variable. * If the variable is a version of a variable returns the original variable.
* @return The original variable. Null if this is not a version. * @return The original variable. Null if this is not a version.
*/ */
public VariableUnversioned getVersionOf() { public Variable getVersionOf() {
if(isVersioned()) { if(isPhiVersion()) {
String name = getName(); String name = getName();
String versionOfName = name.substring(0, name.indexOf("#")); String versionOfName = name.substring(0, name.indexOf("#"));
return (VariableUnversioned) getScope().getVariable(versionOfName); return getScope().getVariable(versionOfName);
} else { } else {
return null; return null;
} }
@ -83,12 +122,12 @@ public class Variable extends SymbolVariable {
if(!super.equals(o)) return false; if(!super.equals(o)) return false;
Variable variable = (Variable) o; Variable variable = (Variable) o;
return isIntermediate == variable.isIntermediate && return isIntermediate == variable.isIntermediate &&
isVersion == variable.isVersion && isPhiVersion == variable.isPhiVersion &&
Objects.equals(allocation, variable.allocation); Objects.equals(allocation, variable.allocation);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(super.hashCode(), isIntermediate, isVersion, allocation); return Objects.hash(super.hashCode(), isIntermediate, isPhiVersion, allocation);
} }
} }

View File

@ -1,30 +0,0 @@
package dk.camelot64.kickc.model.symbols;
import dk.camelot64.kickc.model.types.SymbolType;
/**
* A Symbol (variable, jump label, etc.)
*/
public class VariableUnversioned extends Variable {
/** The number of the next version */
private Integer nextVersionNumber;
public VariableUnversioned( String name, Scope scope, SymbolType type, String dataSegment) {
super(name, scope, type, dataSegment, false, false);
this.nextVersionNumber = 0;
}
/**
* Get the version number of the next version. (if anyone versions the symbol).
*/
int getNextVersionNumber() {
return nextVersionNumber++;
}
public Variable createVersion() {
Variable version = new Variable(this, this.getNextVersionNumber());
getScope().add(version);
return version;
}
}

View File

@ -199,9 +199,9 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
procedure.setComments(ensureUnusedComments(getCommentsSymbol(ctx))); procedure.setComments(ensureUnusedComments(getCommentsSymbol(ctx)));
scopeStack.push(procedure); scopeStack.push(procedure);
Label procExit = procedure.addLabel(SymbolRef.PROCEXIT_BLOCK_NAME); Label procExit = procedure.addLabel(SymbolRef.PROCEXIT_BLOCK_NAME);
VariableUnversioned returnVar = null; Variable returnVar = null;
if(!SymbolType.VOID.equals(type)) { if(!SymbolType.VOID.equals(type)) {
returnVar = procedure.addVariable("return", type, procedure.getSegmentData()); returnVar = procedure.addVariablePhiMaster("return", type, procedure.getSegmentData());
} }
List<Variable> parameterList = new ArrayList<>(); List<Variable> parameterList = new ArrayList<>();
if(ctx.parameterListDecl() != null) { if(ctx.parameterListDecl() != null) {
@ -260,7 +260,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
this.visitDeclTypes(ctx.declTypes()); this.visitDeclTypes(ctx.declTypes());
SymbolType type = declVarType; SymbolType type = declVarType;
List<Directive> directives = declVarDirectives; List<Directive> directives = declVarDirectives;
VariableUnversioned param = new VariableUnversioned(ctx.NAME().getText(), getCurrentScope(), type, currentDataSegment); Variable param = new Variable(ctx.NAME().getText(), getCurrentScope(), type, currentDataSegment, false, false, true);
// Set initial storage strategy // Set initial storage strategy
param.setStorageStrategy(SymbolVariable.StorageStrategy.PHI_REGISTER); param.setStorageStrategy(SymbolVariable.StorageStrategy.PHI_REGISTER);
// Add directives // Add directives
@ -554,7 +554,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
@Override @Override
public Object visitDeclVariableInitExpr(KickCParser.DeclVariableInitExprContext ctx) { public Object visitDeclVariableInitExpr(KickCParser.DeclVariableInitExprContext ctx) {
String varName = ctx.NAME().getText(); String varName = ctx.NAME().getText();
VariableUnversioned lValue = visitDeclVariableInit(varName, ctx); Variable lValue = visitDeclVariableInit(varName, ctx);
SymbolType type = declVarType; SymbolType type = declVarType;
List<Comment> comments = declVarComments; List<Comment> comments = declVarComments;
KickCParser.ExprContext initializer = ctx.expr(); KickCParser.ExprContext initializer = ctx.expr();
@ -579,7 +579,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
@Override @Override
public Object visitDeclVariableInitKasm(KickCParser.DeclVariableInitKasmContext ctx) { public Object visitDeclVariableInitKasm(KickCParser.DeclVariableInitKasmContext ctx) {
String varName = ctx.NAME().getText(); String varName = ctx.NAME().getText();
VariableUnversioned lValue = visitDeclVariableInit(varName, ctx); Variable lValue = visitDeclVariableInit(varName, ctx);
SymbolType type = this.declVarType; SymbolType type = this.declVarType;
List<Comment> comments = this.declVarComments; List<Comment> comments = this.declVarComments;
if(!(type instanceof SymbolTypeArray)) { if(!(type instanceof SymbolTypeArray)) {
@ -608,14 +608,14 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
return null; return null;
} }
private VariableUnversioned visitDeclVariableInit(String varName, KickCParser.DeclVariableInitContext ctx) { private Variable visitDeclVariableInit(String varName, KickCParser.DeclVariableInitContext ctx) {
List<Directive> directives = declVarDirectives; List<Directive> directives = declVarDirectives;
SymbolType type = declVarType; SymbolType type = declVarType;
List<Comment> comments = declVarComments; List<Comment> comments = declVarComments;
VariableUnversioned lValue; Variable lValue;
try { try {
lValue = getCurrentScope().addVariable(varName, type, currentDataSegment); lValue = getCurrentScope().addVariablePhiMaster(varName, type, currentDataSegment);
} catch(CompileError e) { } catch(CompileError e) {
throw new CompileError(e.getMessage(), new StatementSource(ctx)); throw new CompileError(e.getMessage(), new StatementSource(ctx));
} }
@ -1202,7 +1202,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
Variable lValue; Variable lValue;
if(varType != null) { if(varType != null) {
try { try {
lValue = getCurrentScope().addVariable(varName, varType, currentDataSegment); lValue = getCurrentScope().addVariablePhiMaster(varName, varType, currentDataSegment);
} catch(CompileError e) { } catch(CompileError e) {
throw new CompileError(e.getMessage(), statementSource); throw new CompileError(e.getMessage(), statementSource);
} }
@ -1627,7 +1627,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
scopeStack.push(typedefScope); scopeStack.push(typedefScope);
SymbolType type = (SymbolType) this.visit(ctx.typeDecl()); SymbolType type = (SymbolType) this.visit(ctx.typeDecl());
String typedefName = ctx.NAME().getText(); String typedefName = ctx.NAME().getText();
typedefScope.addVariable(typedefName, type, currentDataSegment); typedefScope.addVariablePhiMaster(typedefName, type, currentDataSegment);
scopeStack.pop(); scopeStack.pop();
return null; return null;
} }

View File

@ -76,9 +76,9 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
private void versionAssignment(VariableRef lValueRef, ProgramValue programLValue, StatementSource source) { private void versionAssignment(VariableRef lValueRef, ProgramValue programLValue, StatementSource source) {
Collection<VariableRef> earlyIdentifiedConstants = getProgram().getEarlyIdentifiedConstants(); Collection<VariableRef> earlyIdentifiedConstants = getProgram().getEarlyIdentifiedConstants();
Variable assignedVar = getScope().getVariable(lValueRef); Variable assignedVar = getScope().getVariable(lValueRef);
if(assignedVar instanceof VariableUnversioned) { if(assignedVar.isPhiMaster()) {
// Assignment to a non-versioned non-intermediary variable // Assignment to a non-versioned non-intermediary variable
VariableUnversioned assignedSymbol = (VariableUnversioned) assignedVar; Variable assignedSymbol = assignedVar;
Variable version; Variable version;
if(assignedSymbol.isDeclaredConstant() || earlyIdentifiedConstants.contains(assignedSymbol.getRef())) { if(assignedSymbol.isDeclaredConstant() || earlyIdentifiedConstants.contains(assignedSymbol.getRef())) {
Collection<Variable> versions = assignedVar.getScope().getVersions(assignedSymbol); Collection<Variable> versions = assignedVar.getScope().getVersions(assignedSymbol);
@ -100,9 +100,9 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
private void versionAllUses() { private void versionAllUses() {
for(ControlFlowBlock block : getGraph().getAllBlocks()) { for(ControlFlowBlock block : getGraph().getAllBlocks()) {
// Newest version of variables in the block. // Newest version of variables in the block.
Map<VariableUnversioned, Variable> blockVersions = new LinkedHashMap<>(); Map<Variable, Variable> blockVersions = new LinkedHashMap<>();
// New phi functions introduced in the block to create versions of variables. // New phi functions introduced in the block to create versions of variables.
Map<VariableUnversioned, Variable> blockNewPhis = new LinkedHashMap<>(); Map<Variable, Variable> blockNewPhis = new LinkedHashMap<>();
ProgramValueIterator.execute(block, (programValue, currentStmt, stmtIt, currentBlock) -> { ProgramValueIterator.execute(block, (programValue, currentStmt, stmtIt, currentBlock) -> {
if(programValue instanceof ProgramValue.ProgramValueParamValue) { if(programValue instanceof ProgramValue.ProgramValueParamValue) {
// Call parameter values should not be versioned // Call parameter values should not be versioned
@ -146,16 +146,16 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
} }
}); });
// Add new Phi functions to block // Add new Phi functions to block
for(VariableUnversioned symbol : blockNewPhis.keySet()) { for(Variable symbol : blockNewPhis.keySet()) {
block.getPhiBlock().addPhiVariable(blockNewPhis.get(symbol).getRef()); block.getPhiBlock().addPhiVariable(blockNewPhis.get(symbol).getRef());
} }
} }
} }
private void updateBlockVersions(VariableRef lValue, Map<VariableUnversioned, Variable> blockVersions) { private void updateBlockVersions(VariableRef lValue, Map<Variable, Variable> blockVersions) {
VariableRef lValueRef = lValue; VariableRef lValueRef = lValue;
Variable variable = Pass1GenerateSingleStaticAssignmentForm.this.getScope().getVariable(lValueRef); Variable variable = Pass1GenerateSingleStaticAssignmentForm.this.getScope().getVariable(lValueRef);
if(variable.isVersioned()) { if(variable.isPhiVersion()) {
blockVersions.put(variable.getVersionOf(), variable); blockVersions.put(variable.getVersionOf(), variable);
} }
} }
@ -171,15 +171,15 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
*/ */
private Variable findOrCreateVersion( private Variable findOrCreateVersion(
Value rValue, Value rValue,
Map<VariableUnversioned, Variable> blockVersions, Map<Variable, Variable> blockVersions,
Map<VariableUnversioned, Variable> blockNewPhis) { Map<Variable, Variable> blockNewPhis) {
Collection<VariableRef> earlyIdentifiedConstants = getProgram().getEarlyIdentifiedConstants(); Collection<VariableRef> earlyIdentifiedConstants = getProgram().getEarlyIdentifiedConstants();
Variable version = null; Variable version = null;
if(rValue instanceof VariableRef) { if(rValue instanceof VariableRef) {
Variable rValueVar = getScope().getVariable((VariableRef) rValue); Variable rValueVar = getScope().getVariable((VariableRef) rValue);
if(rValueVar instanceof VariableUnversioned) { if(rValueVar.isPhiMaster()) {
// rValue needs versioning - look for version in statements // rValue needs versioning - look for version in statements
VariableUnversioned rSymbol = (VariableUnversioned) rValueVar; Variable rSymbol = rValueVar;
if(rSymbol.isDeclaredConstant() || earlyIdentifiedConstants.contains(rSymbol.getRef())) { if(rSymbol.isDeclaredConstant() || earlyIdentifiedConstants.contains(rSymbol.getRef())) {
// A constant - find the single created version // A constant - find the single created version
Scope scope = rSymbol.getScope(); Scope scope = rSymbol.getScope();
@ -213,8 +213,8 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
* false if new phis were added, meaning another iteration is needed. * false if new phis were added, meaning another iteration is needed.
*/ */
private boolean completePhiFunctions() { private boolean completePhiFunctions() {
Map<LabelRef, Map<VariableUnversioned, Variable>> newPhis = new LinkedHashMap<>(); Map<LabelRef, Map<Variable, Variable>> newPhis = new LinkedHashMap<>();
Map<LabelRef, Map<VariableUnversioned, Variable>> symbolMap = buildSymbolMap(); Map<LabelRef, Map<Variable, Variable>> symbolMap = buildSymbolMap();
for(ControlFlowBlock block : getGraph().getAllBlocks()) { for(ControlFlowBlock block : getGraph().getAllBlocks()) {
for(Statement statement : block.getStatements()) { for(Statement statement : block.getStatements()) {
@ -224,18 +224,18 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
if(phiVariable.isEmpty()) { if(phiVariable.isEmpty()) {
VariableRef phiLValVarRef = phiVariable.getVariable(); VariableRef phiLValVarRef = phiVariable.getVariable();
Variable versioned = getScope().getVariable(phiLValVarRef); Variable versioned = getScope().getVariable(phiLValVarRef);
VariableUnversioned unversioned = versioned.getVersionOf(); Variable unversioned = versioned.getVersionOf();
List<ControlFlowBlock> predecessors = getPhiPredecessors(block, getProgram()); List<ControlFlowBlock> predecessors = getPhiPredecessors(block, getProgram());
for(ControlFlowBlock predecessor : predecessors) { for(ControlFlowBlock predecessor : predecessors) {
LabelRef predecessorLabel = predecessor.getLabel(); LabelRef predecessorLabel = predecessor.getLabel();
Map<VariableUnversioned, Variable> predecessorMap = symbolMap.get(predecessorLabel); Map<Variable, Variable> predecessorMap = symbolMap.get(predecessorLabel);
Variable previousSymbol = null; Variable previousSymbol = null;
if(predecessorMap != null) { if(predecessorMap != null) {
previousSymbol = predecessorMap.get(unversioned); previousSymbol = predecessorMap.get(unversioned);
} }
if(previousSymbol == null) { if(previousSymbol == null) {
// No previous symbol found in predecessor block. Look in new phi functions. // No previous symbol found in predecessor block. Look in new phi functions.
Map<VariableUnversioned, Variable> predecessorNewPhis = newPhis.get(predecessorLabel); Map<Variable, Variable> predecessorNewPhis = newPhis.get(predecessorLabel);
if(predecessorNewPhis == null) { if(predecessorNewPhis == null) {
predecessorNewPhis = new LinkedHashMap<>(); predecessorNewPhis = new LinkedHashMap<>();
newPhis.put(predecessorLabel, predecessorNewPhis); newPhis.put(predecessorLabel, predecessorNewPhis);
@ -256,9 +256,9 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
} }
// Ads new phi functions to blocks // Ads new phi functions to blocks
for(ControlFlowBlock block : getGraph().getAllBlocks()) { for(ControlFlowBlock block : getGraph().getAllBlocks()) {
Map<VariableUnversioned, Variable> blockNewPhis = newPhis.get(block.getLabel()); Map<Variable, Variable> blockNewPhis = newPhis.get(block.getLabel());
if(blockNewPhis != null) { if(blockNewPhis != null) {
for(VariableUnversioned symbol : blockNewPhis.keySet()) { for(Variable symbol : blockNewPhis.keySet()) {
StatementPhiBlock phiBlock = block.getPhiBlock(); StatementPhiBlock phiBlock = block.getPhiBlock();
phiBlock.addPhiVariable(blockNewPhis.get(symbol).getRef()); phiBlock.addPhiVariable(blockNewPhis.get(symbol).getRef());
} }
@ -297,8 +297,8 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
* Builds a map of all which versions each symbol has in each block. * Builds a map of all which versions each symbol has in each block.
* Maps Control Flow Block Label -> ( Unversioned Symbol -> Versioned Symbol) for all relevant symbols. * Maps Control Flow Block Label -> ( Unversioned Symbol -> Versioned Symbol) for all relevant symbols.
*/ */
private Map<LabelRef, Map<VariableUnversioned, Variable>> buildSymbolMap() { private Map<LabelRef, Map<Variable, Variable>> buildSymbolMap() {
Map<LabelRef, Map<VariableUnversioned, Variable>> symbolMap = new LinkedHashMap<>(); Map<LabelRef, Map<Variable, Variable>> symbolMap = new LinkedHashMap<>();
for(ControlFlowBlock block : getGraph().getAllBlocks()) { for(ControlFlowBlock block : getGraph().getAllBlocks()) {
for(Statement statement : block.getStatements()) { for(Statement statement : block.getStatements()) {
if(statement instanceof StatementLValue) { if(statement instanceof StatementLValue) {
@ -315,14 +315,14 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
return symbolMap; return symbolMap;
} }
private void addSymbolToMap(LValue lValue, ControlFlowBlock block, Map<LabelRef, Map<VariableUnversioned, Variable>> symbolMap) { private void addSymbolToMap(LValue lValue, ControlFlowBlock block, Map<LabelRef, Map<Variable, Variable>> symbolMap) {
if(lValue instanceof VariableRef) { if(lValue instanceof VariableRef) {
Variable lValueVar = getScope().getVariable((VariableRef) lValue); Variable lValueVar = getScope().getVariable((VariableRef) lValue);
if(lValueVar.isVersioned()) { if(lValueVar.isPhiVersion()) {
Variable versioned = lValueVar; Variable versioned = lValueVar;
LabelRef label = block.getLabel(); LabelRef label = block.getLabel();
VariableUnversioned unversioned = versioned.getVersionOf(); Variable unversioned = versioned.getVersionOf();
Map<VariableUnversioned, Variable> blockMap = symbolMap.get(label); Map<Variable, Variable> blockMap = symbolMap.get(label);
if(blockMap == null) { if(blockMap == null) {
blockMap = new LinkedHashMap<>(); blockMap = new LinkedHashMap<>();
symbolMap.put(label, blockMap); symbolMap.put(label, blockMap);

View File

@ -300,7 +300,7 @@ public class Pass1ProcedureInline extends Pass1Base {
if(procSymbol instanceof Variable) { if(procSymbol instanceof Variable) {
Variable procVar = (Variable) procSymbol; Variable procVar = (Variable) procSymbol;
String inlineVarName = getInlineSymbolName(procedure, procSymbol, serial); String inlineVarName = getInlineSymbolName(procedure, procSymbol, serial);
VariableUnversioned inlineVar = callScope.addVariable(inlineVarName, procSymbol.getType(), procVar.getDataSegment()); Variable inlineVar = callScope.addVariablePhiMaster(inlineVarName, procSymbol.getType(), procVar.getDataSegment());
inlineVar.setInferredType(procVar.isInferredType()); inlineVar.setInferredType(procVar.isInferredType());
inlineVar.setDeclaredAlignment(procVar.getDeclaredAlignment()); inlineVar.setDeclaredAlignment(procVar.getDeclaredAlignment());
inlineVar.setDeclaredConstant(procVar.isDeclaredConstant()); inlineVar.setDeclaredConstant(procVar.isDeclaredConstant());

View File

@ -67,10 +67,10 @@ public class Pass1UnwindBlockScopes extends Pass1Base {
Label unwound = procedure.addLabel(name); Label unwound = procedure.addLabel(name);
unwoundSymbols.put(symbol.getRef(), unwound.getRef()); unwoundSymbols.put(symbol.getRef(), unwound.getRef());
} }
} else if(symbol instanceof VariableUnversioned) { } else if(symbol instanceof Variable && ((Variable) symbol).isPhiMaster()) {
String name = findLocalName(procedure, symbol); String name = findLocalName(procedure, symbol);
VariableUnversioned var = (VariableUnversioned) symbol; Variable var = (Variable) symbol;
VariableUnversioned unwound = procedure.addVariable(name, symbol.getType(), var.getDataSegment()); Variable unwound = procedure.addVariablePhiMaster(name, symbol.getType(), var.getDataSegment());
unwound.setDeclaredAlignment(var.getDeclaredAlignment()); unwound.setDeclaredAlignment(var.getDeclaredAlignment());
unwound.setDeclaredConstant(var.isDeclaredConstant()); unwound.setDeclaredConstant(var.isDeclaredConstant());
unwound.setDeclaredVolatile(var.isDeclaredVolatile()); unwound.setDeclaredVolatile(var.isDeclaredVolatile());

View File

@ -212,9 +212,9 @@ public class Pass1UnwindStructValues extends Pass1Base {
for(Variable member : structDefinition.getAllVariables(false)) { for(Variable member : structDefinition.getAllVariables(false)) {
Variable memberVariable; Variable memberVariable;
if(variable.getRef().isIntermediate()) { if(variable.getRef().isIntermediate()) {
memberVariable = scope.add(new Variable(variable.getLocalName() + "_" + member.getLocalName(), scope, member.getType(), variable.getDataSegment(), true, false)); memberVariable = scope.add(new Variable(variable.getLocalName() + "_" + member.getLocalName(), scope, member.getType(), variable.getDataSegment(), true, false, false));
} else { } else {
memberVariable = scope.addVariable(variable.getLocalName() + "_" + member.getLocalName(), member.getType(), variable.getDataSegment()); memberVariable = scope.addVariablePhiMaster(variable.getLocalName() + "_" + member.getLocalName(), member.getType(), variable.getDataSegment());
} }
memberVariable.setDeclaredVolatile(variable.isDeclaredVolatile()); memberVariable.setDeclaredVolatile(variable.isDeclaredVolatile());
memberVariable.setInferedVolatile(variable.isInferedVolatile()); memberVariable.setInferedVolatile(variable.isInferedVolatile());

View File

@ -43,7 +43,7 @@ public class Pass2AssertSymbols extends Pass2SsaAssertion {
Collection<Symbol> tableSymbols = getScope().getAllSymbols(true); Collection<Symbol> tableSymbols = getScope().getAllSymbols(true);
for(Symbol tableSymbol : tableSymbols) { for(Symbol tableSymbol : tableSymbols) {
if(tableSymbol instanceof VariableUnversioned) continue; if(tableSymbol instanceof Variable && ((Variable) tableSymbol).isPhiMaster()) continue;
if(tableSymbol instanceof ConstantVar) continue; if(tableSymbol instanceof ConstantVar) continue;
if(tableSymbol instanceof StructDefinition) continue; if(tableSymbol instanceof StructDefinition) continue;
if(tableSymbol instanceof EnumDefinition) continue; if(tableSymbol instanceof EnumDefinition) continue;

View File

@ -263,7 +263,7 @@ public class Pass4CodeGeneration {
signature.append(" ").append(procedure.getLocalName()).append("("); signature.append(" ").append(procedure.getLocalName()).append("(");
int i = 0; int i = 0;
for(Variable parameter : procedure.getParameters()) { for(Variable parameter : procedure.getParameters()) {
List<Variable> versions = new ArrayList<>(procedure.getVersions((VariableUnversioned) parameter)); List<Variable> versions = new ArrayList<>(procedure.getVersions(parameter));
if(versions.size() > 0) { if(versions.size() > 0) {
Variable param = versions.get(0); Variable param = versions.get(0);
Registers.Register allocation = param.getAllocation(); Registers.Register allocation = param.getAllocation();

View File

@ -33,10 +33,10 @@ public class Pass4LiveRangeEquivalenceClassesFinalize extends Pass2Base {
// Add all versions of volatile variables to the same equivalence class // Add all versions of volatile variables to the same equivalence class
for(Variable variable : getSymbols().getAllVariables(true)) { for(Variable variable : getSymbols().getAllVariables(true)) {
if(variable.isVersioned() && variable.isVolatile()) { if(variable.isPhiVersion() && variable.isVolatile()) {
// Found a volatile non-versioned variable // Found a volatile non-versioned variable
for(Variable otherVariable : variable.getScope().getAllVariables(false)) { for(Variable otherVariable : variable.getScope().getAllVariables(false)) {
if(otherVariable.isVersioned()) { if(otherVariable.isPhiVersion()) {
if((otherVariable).getVersionOf().equals((variable).getVersionOf())) { if((otherVariable).getVersionOf().equals((variable).getVersionOf())) {
// They share the same main variable // They share the same main variable
LiveRangeEquivalenceClass varEC = liveRangeEquivalenceClassSet.getOrCreateEquivalenceClass(variable.getRef()); LiveRangeEquivalenceClass varEC = liveRangeEquivalenceClassSet.getOrCreateEquivalenceClass(variable.getRef());