mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-01 00:51:12 +00:00
Added versions to struct-unwinding.
This commit is contained in:
parent
ad6eadad0b
commit
3725bf6821
@ -223,6 +223,7 @@ public class Compiler {
|
||||
|
||||
program.setGraph(new Pass1ProcedureCallsReturnValue(program).generate());
|
||||
new PassNUnwindLValueLists(program).execute();
|
||||
new Pass1UnwindStructVersions(program).execute();
|
||||
|
||||
getLog().append("\nCONTROL FLOW GRAPH SSA");
|
||||
getLog().append(program.getGraph().toString(program));
|
||||
|
@ -6,7 +6,6 @@ import dk.camelot64.kickc.model.statements.StatementInfos;
|
||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
import dk.camelot64.kickc.model.values.LabelRef;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
import dk.camelot64.kickc.passes.Pass1UnwindStructValues;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
@ -75,7 +74,7 @@ public class Program {
|
||||
/** Cached phi transitions into each block. */
|
||||
private Map<LabelRef, PhiTransitions> phiTransitions;
|
||||
/** Struct values unwound to individual variables. */
|
||||
private Pass1UnwindStructValues.StructUnwinding structUnwinding;
|
||||
private StructUnwinding structUnwinding;
|
||||
|
||||
public Program() {
|
||||
this.scope = new ProgramScope();
|
||||
@ -86,11 +85,11 @@ public class Program {
|
||||
this.reservedZps = new ArrayList<>();
|
||||
}
|
||||
|
||||
public Pass1UnwindStructValues.StructUnwinding getStructUnwinding() {
|
||||
public StructUnwinding getStructUnwinding() {
|
||||
return structUnwinding;
|
||||
}
|
||||
|
||||
public void setStructUnwinding(Pass1UnwindStructValues.StructUnwinding structUnwinding) {
|
||||
public void setStructUnwinding(StructUnwinding structUnwinding) {
|
||||
this.structUnwinding = structUnwinding;
|
||||
}
|
||||
|
||||
|
113
src/main/java/dk/camelot64/kickc/model/StructUnwinding.java
Normal file
113
src/main/java/dk/camelot64/kickc/model/StructUnwinding.java
Normal file
@ -0,0 +1,113 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
|
||||
import dk.camelot64.kickc.model.values.LValue;
|
||||
import dk.camelot64.kickc.model.values.SymbolRef;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Keeps track of all structs that have been unwound into member variables.
|
||||
*/
|
||||
public class StructUnwinding {
|
||||
|
||||
/** Maps struct variables to unwinding of each member. */
|
||||
Map<VariableRef, VariableUnwinding> structVariables = new LinkedHashMap<>();
|
||||
|
||||
/**
|
||||
* Get information about how a struct variable was unwound into member variables
|
||||
*
|
||||
* @param ref The variable to look for
|
||||
* @return Information about the unwinding. Null if not unwound
|
||||
*/
|
||||
public VariableUnwinding getVariableUnwinding(VariableRef ref) {
|
||||
return structVariables.get(ref);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add information about how a struct variable was unwound into member variables
|
||||
*
|
||||
* @param ref The variable to add information for
|
||||
* @return The new information about the unwinding.
|
||||
*/
|
||||
public VariableUnwinding createVariableUnwinding(VariableRef ref) {
|
||||
VariableUnwinding existing = structVariables.put(ref, new VariableUnwinding());
|
||||
if(existing != null) {
|
||||
throw new InternalError("ERROR! Struct unwinding was already created once! " + ref.toString());
|
||||
}
|
||||
return structVariables.get(ref);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the struct variable that the passed symbol was unwound from.
|
||||
*
|
||||
* @param symbolRef The symbol to look for
|
||||
* @return The struct variable containing it. null if the passed symbol is not an unwound variable.
|
||||
*/
|
||||
public VariableRef getContainingStructVariable(SymbolRef symbolRef) {
|
||||
for(VariableRef structVarRef : structVariables.keySet()) {
|
||||
VariableUnwinding variableUnwinding = getVariableUnwinding(structVarRef);
|
||||
for(String memberName : variableUnwinding.getMemberNames()) {
|
||||
LValue memberUnwinding = variableUnwinding.getMemberUnwinding(memberName);
|
||||
if(memberUnwinding instanceof VariableRef && memberUnwinding.equals(symbolRef)) {
|
||||
return structVarRef;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/** Information about how a single struct variable was unwound. */
|
||||
public static class VariableUnwinding implements StructMemberUnwinding {
|
||||
|
||||
/** Maps member names to the unwound variables. */
|
||||
Map<String, VariableRef> memberUnwinding = new LinkedHashMap<>();
|
||||
|
||||
/** Set how a member variable was unwound to a specific (new) variable. */
|
||||
public void setMemberUnwinding(String memberName, VariableRef memberVariableUnwound) {
|
||||
this.memberUnwinding.put(memberName, memberVariableUnwound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the names of the members of the struct
|
||||
*
|
||||
* @return the names
|
||||
*/
|
||||
public List<String> getMemberNames() {
|
||||
return new ArrayList<>(memberUnwinding.keySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the (new) variable that a specific member was unwound to
|
||||
*
|
||||
* @param memberName The member name
|
||||
* @return The new variable
|
||||
*/
|
||||
public LValue getMemberUnwinding(String memberName) {
|
||||
return this.memberUnwinding.get(memberName);
|
||||
}
|
||||
}
|
||||
|
||||
/** Information about how members of an struct Lvalue is unwound. */
|
||||
public interface StructMemberUnwinding {
|
||||
|
||||
/**
|
||||
* Get the names of the members of the struct
|
||||
*
|
||||
* @return the names
|
||||
*/
|
||||
List<String> getMemberNames();
|
||||
|
||||
/**
|
||||
* Get the LValue that a specific member was unwound to
|
||||
*
|
||||
* @param memberName The member name
|
||||
* @return The unwinding of the member
|
||||
*/
|
||||
LValue getMemberUnwinding(String memberName);
|
||||
}
|
||||
}
|
@ -68,7 +68,7 @@ public class Pass1ProcedureCallParameters extends ControlFlowGraphCopyVisitor {
|
||||
|
||||
// Special handing of struct value returns
|
||||
if(procReturnVar.getType() instanceof SymbolTypeStruct) {
|
||||
Pass1UnwindStructValues.StructUnwinding.VariableUnwinding returnVarUnwinding = program.getStructUnwinding().getVariableUnwinding((VariableRef) procReturnVarRef);
|
||||
StructUnwinding.VariableUnwinding returnVarUnwinding = program.getStructUnwinding().getVariableUnwinding((VariableRef) procReturnVarRef);
|
||||
if(returnVarUnwinding!=null) {
|
||||
ArrayList<RValue> unwoundReturnVars = new ArrayList<>();
|
||||
for(String memberName : returnVarUnwinding.getMemberNames()) {
|
||||
|
@ -269,7 +269,7 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
private boolean unwindAssignment(StatementAssignment assignment, SymbolTypeStruct structType, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock, StructUnwinding structUnwinding) {
|
||||
boolean modified = false;
|
||||
|
||||
StructMemberUnwinding memberUnwinding = getStructMemberUnwinding(assignment.getlValue(), structType, structUnwinding, assignment, stmtIt, currentBlock);
|
||||
StructUnwinding.StructMemberUnwinding memberUnwinding = getStructMemberUnwinding(assignment.getlValue(), structType, structUnwinding, assignment, stmtIt, currentBlock);
|
||||
if(memberUnwinding == null) {
|
||||
throw new CompileError("Cannot unwind struct assignment " + assignment.toString(getProgram(), false), assignment);
|
||||
}
|
||||
@ -322,7 +322,7 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
SymbolType sourceType = SymbolTypeInference.inferType(getScope(), assignment.getrValue2());
|
||||
if(sourceType.equals(structType)) {
|
||||
// Copying a struct - unwind to assigning each member!
|
||||
StructMemberUnwinding sourceMemberUnwinding = getStructMemberUnwinding((LValue) assignment.getrValue2(), structType, structUnwinding, assignment, stmtIt, currentBlock);
|
||||
StructUnwinding.StructMemberUnwinding sourceMemberUnwinding = getStructMemberUnwinding((LValue) assignment.getrValue2(), structType, structUnwinding, assignment, stmtIt, currentBlock);
|
||||
if(sourceMemberUnwinding != null) {
|
||||
List<RValue> membersUnwound = new ArrayList<>();
|
||||
stmtIt.previous();
|
||||
@ -351,7 +351,7 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
return modified;
|
||||
}
|
||||
|
||||
private StructMemberUnwinding getStructMemberUnwinding(LValue lValue, SymbolTypeStruct lValueType, StructUnwinding structUnwinding, Statement currentStmt, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock) {
|
||||
private StructUnwinding.StructMemberUnwinding getStructMemberUnwinding(LValue lValue, SymbolTypeStruct lValueType, StructUnwinding structUnwinding, Statement currentStmt, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock) {
|
||||
if(lValue instanceof VariableRef) {
|
||||
return structUnwinding.getVariableUnwinding((VariableRef) lValue);
|
||||
} else if(lValue instanceof PointerDereferenceSimple) {
|
||||
@ -364,120 +364,15 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
}
|
||||
|
||||
|
||||
/** Information about how members of an struct Lvalue is unwound. */
|
||||
interface StructMemberUnwinding {
|
||||
|
||||
/**
|
||||
* Get the names of the members of the struct
|
||||
*
|
||||
* @return the names
|
||||
*/
|
||||
List<String> getMemberNames();
|
||||
|
||||
/**
|
||||
* Get the LValue that a specific member was unwound to
|
||||
*
|
||||
* @param memberName The member name
|
||||
* @return The unwinding of the member
|
||||
*/
|
||||
LValue getMemberUnwinding(String memberName);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Keeps track of all structs that have been unwound into member variables.
|
||||
*/
|
||||
public static class StructUnwinding {
|
||||
|
||||
/** Maps struct variables to unwinding of each member. */
|
||||
Map<VariableRef, VariableUnwinding> structVariables = new LinkedHashMap<>();
|
||||
|
||||
/**
|
||||
* Get information about how a struct variable was unwound into member variables
|
||||
*
|
||||
* @param ref The variable to look for
|
||||
* @return Information about the unwinding. Null if not unwound
|
||||
*/
|
||||
VariableUnwinding getVariableUnwinding(VariableRef ref) {
|
||||
return structVariables.get(ref);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add information about how a struct variable was unwound into member variables
|
||||
*
|
||||
* @param ref The variable to add information for
|
||||
* @return The new information about the unwinding.
|
||||
*/
|
||||
VariableUnwinding createVariableUnwinding(VariableRef ref) {
|
||||
VariableUnwinding existing = structVariables.put(ref, new VariableUnwinding());
|
||||
if(existing != null) {
|
||||
throw new InternalError("ERROR! Struct unwinding was already created once! " + ref.toString());
|
||||
}
|
||||
return structVariables.get(ref);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the struct variable that the passed symbol was unwound from.
|
||||
*
|
||||
* @param symbolRef The symbol to look for
|
||||
* @return The struct variable containing it. null if the passed symbol is not an unwound variable.
|
||||
*/
|
||||
public VariableRef getContainingStructVariable(SymbolRef symbolRef) {
|
||||
for(VariableRef structVarRef : structVariables.keySet()) {
|
||||
VariableUnwinding variableUnwinding = getVariableUnwinding(structVarRef);
|
||||
for(String memberName : variableUnwinding.getMemberNames()) {
|
||||
LValue memberUnwinding = variableUnwinding.getMemberUnwinding(memberName);
|
||||
if(memberUnwinding instanceof VariableRef && memberUnwinding.equals(symbolRef)) {
|
||||
return structVarRef;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/** Information about how a single struct variable was unwound. */
|
||||
static class VariableUnwinding implements StructMemberUnwinding {
|
||||
|
||||
/** Maps member names to the unwound variables. */
|
||||
Map<String, VariableRef> memberUnwinding = new LinkedHashMap<>();
|
||||
|
||||
/** Set how a member variable was unwound to a specific (new) variable. */
|
||||
void setMemberUnwinding(String memberName, VariableRef memberVariableUnwound) {
|
||||
this.memberUnwinding.put(memberName, memberVariableUnwound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the names of the members of the struct
|
||||
*
|
||||
* @return the names
|
||||
*/
|
||||
public List<String> getMemberNames() {
|
||||
return new ArrayList<>(memberUnwinding.keySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the (new) variable that a specific member was unwound to
|
||||
*
|
||||
* @param memberName The member name
|
||||
* @return The new variable
|
||||
*/
|
||||
public LValue getMemberUnwinding(String memberName) {
|
||||
return this.memberUnwinding.get(memberName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Unwinding for a simple pointer deref to a struct. */
|
||||
private class StructMemberUnwindingPointerDerefSimple implements StructMemberUnwinding {
|
||||
private class StructMemberUnwindingPointerDerefSimple implements StructUnwinding.StructMemberUnwinding {
|
||||
private final StructDefinition structDefinition;
|
||||
private final ControlFlowBlock currentBlock;
|
||||
private final ListIterator<Statement> stmtIt;
|
||||
private final PointerDereferenceSimple pointerDeref;
|
||||
private final Statement currentStmt;
|
||||
|
||||
public StructMemberUnwindingPointerDerefSimple(PointerDereferenceSimple pointerDeref, StructDefinition structDefinition, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock, Statement currentStmt) {
|
||||
StructMemberUnwindingPointerDerefSimple(PointerDereferenceSimple pointerDeref, StructDefinition structDefinition, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock, Statement currentStmt) {
|
||||
this.structDefinition = structDefinition;
|
||||
this.currentBlock = currentBlock;
|
||||
this.stmtIt = stmtIt;
|
||||
@ -511,14 +406,14 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
}
|
||||
|
||||
/** Unwinding for a indexed pointer deref to a struct. */
|
||||
private class StructMemberUnwindingPointerDerefIndexed implements StructMemberUnwinding {
|
||||
private class StructMemberUnwindingPointerDerefIndexed implements StructUnwinding.StructMemberUnwinding {
|
||||
private final StructDefinition structDefinition;
|
||||
private final ControlFlowBlock currentBlock;
|
||||
private final ListIterator<Statement> stmtIt;
|
||||
private final PointerDereferenceIndexed pointerDeref;
|
||||
private final Statement currentStmt;
|
||||
|
||||
public StructMemberUnwindingPointerDerefIndexed(PointerDereferenceIndexed pointerDeref, StructDefinition structDefinition, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock, Statement currentStmt) {
|
||||
StructMemberUnwindingPointerDerefIndexed(PointerDereferenceIndexed pointerDeref, StructDefinition structDefinition, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock, Statement currentStmt) {
|
||||
this.structDefinition = structDefinition;
|
||||
this.currentBlock = currentBlock;
|
||||
this.stmtIt = stmtIt;
|
||||
|
@ -0,0 +1,60 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.ControlFlowBlock;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.StructUnwinding;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.symbols.StructDefinition;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeStruct;
|
||||
import dk.camelot64.kickc.model.values.RValue;
|
||||
import dk.camelot64.kickc.model.values.StructUnwoundPlaceholder;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/** Find the versioned unwound structs - and update the StructUnwinding data structure */
|
||||
public class Pass1UnwindStructVersions extends Pass1Base {
|
||||
|
||||
public Pass1UnwindStructVersions(Program program) {
|
||||
super(program);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean step() {
|
||||
boolean modified = false;
|
||||
StructUnwinding structUnwinding = getProgram().getStructUnwinding();
|
||||
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
|
||||
for(Statement statement : block.getStatements()) {
|
||||
if(statement instanceof StatementAssignment) {
|
||||
StatementAssignment assignment = (StatementAssignment) statement;
|
||||
if(assignment.getOperator() == null && assignment.getlValue() instanceof VariableRef && assignment.getrValue2() instanceof StructUnwoundPlaceholder) {
|
||||
VariableRef structVarRef = (VariableRef) assignment.getlValue();
|
||||
if(structUnwinding.getVariableUnwinding(structVarRef) == null) {
|
||||
StructUnwinding.VariableUnwinding versionedUnwinding = structUnwinding.createVariableUnwinding(structVarRef);
|
||||
StructUnwoundPlaceholder placeholder = (StructUnwoundPlaceholder) assignment.getrValue2();
|
||||
SymbolTypeStruct typeStruct = placeholder.getTypeStruct();
|
||||
StructDefinition structDefinition = typeStruct.getStructDefinition(getProgram().getScope());
|
||||
Collection<Variable> members = structDefinition.getAllVariables(false);
|
||||
Iterator<Variable> memberDefIt = members.iterator();
|
||||
List<RValue> unwoundMembers = placeholder.getUnwoundMembers();
|
||||
Iterator<RValue> memberUnwoundIt = unwoundMembers.iterator();
|
||||
while(memberDefIt.hasNext()) {
|
||||
Variable memberVar = memberDefIt.next();
|
||||
RValue memberVal = memberUnwoundIt.next();
|
||||
versionedUnwinding.setMemberUnwinding(memberVar.getLocalName(), (VariableRef) memberVal);
|
||||
}
|
||||
getLog().append("Adding versioned struct unwinding for "+assignment.getlValue().toString(getProgram()));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
}
|
@ -1,9 +1,6 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.CompileError;
|
||||
import dk.camelot64.kickc.model.ConstantNotLiteral;
|
||||
import dk.camelot64.kickc.model.ControlFlowBlock;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
|
||||
import dk.camelot64.kickc.model.operators.OperatorBinary;
|
||||
import dk.camelot64.kickc.model.operators.OperatorUnary;
|
||||
@ -330,7 +327,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
|
||||
}
|
||||
|
||||
// If the symbol is part of an unwound struct - look at the struct itself
|
||||
Pass1UnwindStructValues.StructUnwinding structUnwinding = program.getStructUnwinding();
|
||||
StructUnwinding structUnwinding = program.getStructUnwinding();
|
||||
VariableRef structVarRef = structUnwinding.getContainingStructVariable(symbolRef);
|
||||
if(structVarRef != null) {
|
||||
return isAddressOfUsed(structVarRef, program);
|
||||
|
@ -2,6 +2,7 @@ package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.ControlFlowBlock;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.StructUnwinding;
|
||||
import dk.camelot64.kickc.model.VariableReferenceInfos;
|
||||
import dk.camelot64.kickc.model.statements.*;
|
||||
import dk.camelot64.kickc.model.symbols.ConstantVar;
|
||||
@ -50,15 +51,11 @@ public class PassNEliminateUnusedVars extends Pass2SsaOptimization {
|
||||
eliminate = true;
|
||||
} else if(variable.isDeclaredVolatile() && variable.getType() instanceof SymbolTypeStruct) {
|
||||
// If an unwound volatile struct - eliminate it
|
||||
if(variable.getRef().isVersion()) {
|
||||
String fullNameUnversioned = variable.getRef().getFullNameUnversioned();
|
||||
VariableRef unversionedRef = new VariableRef(fullNameUnversioned);
|
||||
Pass1UnwindStructValues.StructUnwinding.VariableUnwinding variableUnwinding = getProgram().getStructUnwinding().getVariableUnwinding(unversionedRef);
|
||||
StructUnwinding.VariableUnwinding variableUnwinding = getProgram().getStructUnwinding().getVariableUnwinding(variable.getRef());
|
||||
if(variableUnwinding != null) {
|
||||
eliminate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(eliminate) {
|
||||
if(!pass2 && isReturnValue(variable)) {
|
||||
// Do not eliminate return variables in pass 1
|
||||
|
@ -189,6 +189,8 @@ Culled Empty Block (label) @15
|
||||
Culled Empty Block (label) setupRasterIrq::@4
|
||||
Unwinding list assignment { (byte) main::$9_x, (byte) main::$9_y, (word) main::$9_dist } ← { (byte) getCharToProcess::return_x, (byte) getCharToProcess::return_y, (word) getCharToProcess::return_dist }
|
||||
Unwinding list assignment { (byte) getCharToProcess::return_x#0, (byte) getCharToProcess::return_y#0, (word) getCharToProcess::return_dist#0 } ← { (byte) getCharToProcess::return_x#2, (byte) getCharToProcess::return_y#2, (word) getCharToProcess::return_dist#2 }
|
||||
Adding versioned struct unwinding for (struct ProcessingChar) getCharToProcess::return#0
|
||||
Adding versioned struct unwinding for (struct ProcessingChar) getCharToProcess::return#1
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
|
@ -31,6 +31,8 @@ Culled Empty Block (label) @1
|
||||
Culled Empty Block (label) point::@1
|
||||
Unwinding list assignment { (byte) main::$0_x, (byte) main::$0_y } ← { (byte) point::return_x, (byte) point::return_y }
|
||||
Unwinding list assignment { (byte) point::return_x#0, (byte) point::return_y#0 } ← { (byte) point::return_x#2, (byte) point::return_y#2 }
|
||||
Adding versioned struct unwinding for (struct Point) point::return#0
|
||||
Adding versioned struct unwinding for (struct Point) point::return#1
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
|
@ -6,6 +6,7 @@ Adding struct value list initializer (byte) main::p_y ← (number) 3
|
||||
Rewriting struct pointer member access *((struct Point*) main::q).x
|
||||
Rewriting struct pointer member access *((struct Point*) main::q).y
|
||||
Adding pointer type conversion cast (byte*) main::SCREEN in (byte*) main::SCREEN ← (number) $400
|
||||
Adding versioned struct unwinding for (struct Point) main::p#0
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
|
@ -9,6 +9,7 @@ Rewriting struct pointer member access *((struct Point*) set::ptr).x
|
||||
Rewriting struct pointer member access *((struct Point*) set::ptr).y
|
||||
Adding pointer type conversion cast (byte*) main::SCREEN in (byte*) main::SCREEN ← (number) $400
|
||||
Culled Empty Block (label) @1
|
||||
Adding versioned struct unwinding for (struct Point) main::p#0
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
|
Loading…
Reference in New Issue
Block a user