mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-01-12 11:31:11 +00:00
Implemented phi transition reuse when transitions are identical
This commit is contained in:
parent
23d9af8420
commit
83edd3e21b
@ -68,6 +68,7 @@ public class Pass4CodeGeneration {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Add label declarations for all scope variables assigned to ZP registers
|
* Add label declarations for all scope variables assigned to ZP registers
|
||||||
|
*
|
||||||
* @param asm The ASM program
|
* @param asm The ASM program
|
||||||
* @param scope The scope
|
* @param scope The scope
|
||||||
*/
|
*/
|
||||||
@ -170,7 +171,6 @@ public class Pass4CodeGeneration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains previous assignment added to the ALU register between calls to generateStatementAsm
|
* Contains previous assignment added to the ALU register between calls to generateStatementAsm
|
||||||
*/
|
*/
|
||||||
@ -195,10 +195,110 @@ public class Pass4CodeGeneration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate all block entry points (phi transitions) which have not already been generated.
|
||||||
|
*
|
||||||
|
* @param asm The ASM program to generate into
|
||||||
|
* @param toBlock The block to generate remaining entry points for.
|
||||||
|
*/
|
||||||
|
private void genBlockEntryPoints(AsmProgram asm, ControlFlowBlock toBlock) {
|
||||||
|
PhiTransitions transitions = getTransitions(toBlock);
|
||||||
|
for (ControlFlowBlock fromBlock : transitions.getFromBlocks()) {
|
||||||
|
PhiTransitions.PhiTransition transition = transitions.getTransition(fromBlock);
|
||||||
|
if (!transition.isGenerated() && toBlock.getLabel().equals(fromBlock.getConditionalSuccessor())) {
|
||||||
|
genBlockPhiTransition(asm, fromBlock, toBlock, toBlock.getScope());
|
||||||
|
asm.addInstruction("JMP", AsmAddressingMode.ABS, toBlock.getLabel().getLocalName().replace('@', 'b').replace(':', '_'), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void genBlockEntryPoints(AsmProgram asm, ControlFlowBlock block) {
|
/**
|
||||||
if (block.hasPhiBlock()) {
|
* Generate a phi block transition. The transition performs all necessary assignment operations when moving from one block to another.
|
||||||
List<ControlFlowBlock> predecessors = new ArrayList<>(getGraph().getPredecessors(block));
|
* The transition can be inserted either at the start of the to-block (used for conditional jumps)
|
||||||
|
* or at the end of the from-block ( used at default block transitions and before JMP/JSR)
|
||||||
|
*
|
||||||
|
* @param asm The ASP program to generate the transition into.
|
||||||
|
* @param fromBlock The from-block
|
||||||
|
* @param toBlock The to-block
|
||||||
|
* @param scope The scope where the ASM code is being inserted. Used to ensure that labels inserted in the code reference the right variables.
|
||||||
|
* If the transition code is inserted in the to-block, this is the scope of the to-block.
|
||||||
|
* If the transition code is inserted in the from-block this is the scope of the from-block.
|
||||||
|
*/
|
||||||
|
private void genBlockPhiTransition(AsmProgram asm, ControlFlowBlock fromBlock, ControlFlowBlock toBlock, ScopeRef scope) {
|
||||||
|
PhiTransitions transitions = getTransitions(toBlock);
|
||||||
|
PhiTransitions.PhiTransition transition = transitions.getTransition(fromBlock);
|
||||||
|
if (!transition.isGenerated()) {
|
||||||
|
|
||||||
|
Statement toFirstStatement = toBlock.getStatements().get(0);
|
||||||
|
String segmentSrc = "[" + toFirstStatement.getIndex() + "] phi from ";
|
||||||
|
for (ControlFlowBlock fBlock : transition.getFromBlocks()) {
|
||||||
|
segmentSrc += fBlock.getLabel().getFullName() + " ";
|
||||||
|
}
|
||||||
|
segmentSrc += "to " + toBlock.getLabel().getFullName();
|
||||||
|
asm.startSegment(toFirstStatement.getIndex(), segmentSrc);
|
||||||
|
|
||||||
|
for (ControlFlowBlock fBlock : transition.getFromBlocks()) {
|
||||||
|
asm.addLabel((toBlock.getLabel().getLocalName() + "_from_" + fBlock.getLabel().getLocalName()).replace('@', 'b').replace(':', '_'));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<PhiTransitions.PhiTransition.PhiAssignment> assignments = transition.getAssignments();
|
||||||
|
for (PhiTransitions.PhiTransition.PhiAssignment assignment : assignments) {
|
||||||
|
genAsmMove(asm, assignment.getVariable(), assignment.getrValue(), assignment.getPhiBlock(), scope);
|
||||||
|
}
|
||||||
|
transition.setGenerated(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps track of the phi transitions into blocks during code generation.
|
||||||
|
* Used to ensure that duplicate transitions are only code generated once.
|
||||||
|
* Maps to-blocks to the transition information for the block
|
||||||
|
*/
|
||||||
|
private Map<ControlFlowBlock, PhiTransitions> blockTransitions = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get phi transitions for a specific to-block.
|
||||||
|
*
|
||||||
|
* @param toBlock The block
|
||||||
|
* @return The transitions into the block
|
||||||
|
*/
|
||||||
|
private PhiTransitions getTransitions(ControlFlowBlock toBlock) {
|
||||||
|
PhiTransitions transitions = this.blockTransitions.get(toBlock);
|
||||||
|
if (transitions == null) {
|
||||||
|
transitions = new PhiTransitions(toBlock);
|
||||||
|
this.blockTransitions.put(toBlock, transitions);
|
||||||
|
}
|
||||||
|
return transitions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps track of the phi transitions into a single block during code generation.
|
||||||
|
* Used to ensure that duplicate transitions are only code generated once.
|
||||||
|
*/
|
||||||
|
public class PhiTransitions {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Label of the to-block.
|
||||||
|
*/
|
||||||
|
private ControlFlowBlock toBlock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The phi-block of the to-block.
|
||||||
|
*/
|
||||||
|
private StatementPhiBlock phiBlock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps from-block to the transition from the from-block to the to-block.
|
||||||
|
*/
|
||||||
|
private Map<ControlFlowBlock, PhiTransition> transitions;
|
||||||
|
|
||||||
|
public PhiTransitions(ControlFlowBlock toBlock) {
|
||||||
|
this.toBlock = toBlock;
|
||||||
|
this.transitions = new LinkedHashMap<>();
|
||||||
|
if (toBlock.hasPhiBlock()) {
|
||||||
|
this.phiBlock = toBlock.getPhiBlock();
|
||||||
|
List<ControlFlowBlock> predecessors = new ArrayList<>(getGraph().getPredecessors(toBlock));
|
||||||
Collections.sort(predecessors, new Comparator<ControlFlowBlock>() {
|
Collections.sort(predecessors, new Comparator<ControlFlowBlock>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(ControlFlowBlock o1, ControlFlowBlock o2) {
|
public int compare(ControlFlowBlock o1, ControlFlowBlock o2) {
|
||||||
@ -206,34 +306,46 @@ public class Pass4CodeGeneration {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
for (ControlFlowBlock predecessor : predecessors) {
|
for (ControlFlowBlock predecessor : predecessors) {
|
||||||
if (block.getLabel().equals(predecessor.getConditionalSuccessor())) {
|
PhiTransition transition = findTransition(predecessor);
|
||||||
genBlockPhiTransition(asm, predecessor, block, block.getScope());
|
transitions.put(predecessor, transition);
|
||||||
asm.addInstruction("JMP", AsmAddressingMode.ABS, block.getLabel().getLocalName().replace('@', 'b').replace(':', '_'), false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Keeps track of the phi transitions into blocks during code generation.
|
|
||||||
* Used to ensure that duplicate transitions are only code generated once.
|
|
||||||
* Maps to-block label to the transition information*/
|
|
||||||
private Map<LabelRef, PhiTransitions> transitions;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keeps track of the phi transitions into a single block during code generation.
|
* Find the transition from a specific fromBlock.
|
||||||
* Used to ensure that duplicate transitions are only code generated once.
|
* If another transition already has the same assignments it is reused. If not a new transition is created.
|
||||||
|
* @param fromBlock
|
||||||
|
* @return
|
||||||
*/
|
*/
|
||||||
public static class PhiTransitions {
|
private PhiTransition findTransition(ControlFlowBlock fromBlock) {
|
||||||
|
PhiTransition transition = new PhiTransition(fromBlock);
|
||||||
|
for (PhiTransition candidate : transitions.values()) {
|
||||||
|
if(candidate.equalAssignments(transition)) {
|
||||||
|
candidate.addFromBlock(fromBlock);
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return transition;
|
||||||
|
}
|
||||||
|
|
||||||
/** Label of the to-block. */
|
public Collection<ControlFlowBlock> getFromBlocks() {
|
||||||
private ControlFlowBlock toBlock;
|
return transitions.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
/** The phi-block of the to-block. */
|
/**
|
||||||
private StatementPhiBlock phiBlock;
|
* Get the transition into the to-block from a specific from-block
|
||||||
|
*
|
||||||
public PhiTransition getTransition(LabelRef fromBlock) {
|
* @param fromBlock The from-block
|
||||||
return null;
|
* @return The transition from the from-block into the to-block
|
||||||
|
*/
|
||||||
|
public PhiTransition getTransition(ControlFlowBlock fromBlock) {
|
||||||
|
PhiTransition transition = transitions.get(fromBlock);
|
||||||
|
if (transition == null) {
|
||||||
|
transition = findTransition(fromBlock);
|
||||||
|
transitions.put(fromBlock, transition);
|
||||||
|
}
|
||||||
|
return transition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -246,10 +358,41 @@ public class Pass4CodeGeneration {
|
|||||||
|
|
||||||
private List<ControlFlowBlock> fromBlocks;
|
private List<ControlFlowBlock> fromBlocks;
|
||||||
|
|
||||||
|
private List<PhiAssignment> assignments;
|
||||||
|
|
||||||
private boolean generated;
|
private boolean generated;
|
||||||
|
|
||||||
|
public PhiTransition(ControlFlowBlock fromBlock) {
|
||||||
|
this.fromBlocks = new ArrayList<>();
|
||||||
|
this.fromBlocks.add(fromBlock);
|
||||||
|
this.generated = false;
|
||||||
|
initAssignments(fromBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initAssignments(ControlFlowBlock fromBlock) {
|
||||||
|
this.assignments = new ArrayList<>();
|
||||||
|
if (phiBlock != null) {
|
||||||
|
List<StatementPhiBlock.PhiVariable> phiVariables = new ArrayList<>(phiBlock.getPhiVariables());
|
||||||
|
Collections.reverse(phiVariables);
|
||||||
|
for (StatementPhiBlock.PhiVariable phiVariable : phiVariables) {
|
||||||
|
List<StatementPhiBlock.PhiRValue> phiRValues = new ArrayList<>(phiVariable.getValues());
|
||||||
|
Collections.sort(phiRValues, new Comparator<StatementPhiBlock.PhiRValue>() {
|
||||||
|
@Override
|
||||||
|
public int compare(StatementPhiBlock.PhiRValue o1, StatementPhiBlock.PhiRValue o2) {
|
||||||
|
return o1.getPredecessor().getFullName().compareTo(o2.getPredecessor().getFullName());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
for (StatementPhiBlock.PhiRValue phiRValue : phiRValues) {
|
||||||
|
if (phiRValue.getPredecessor().equals(fromBlock.getLabel())) {
|
||||||
|
this.assignments.add(new PhiAssignment(phiVariable, phiRValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public List<PhiAssignment> getAssignments() {
|
public List<PhiAssignment> getAssignments() {
|
||||||
return null;
|
return assignments;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isGenerated() {
|
public boolean isGenerated() {
|
||||||
@ -260,6 +403,37 @@ public class Pass4CodeGeneration {
|
|||||||
this.generated = generated;
|
this.generated = generated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addFromBlock(ControlFlowBlock fromBlock) {
|
||||||
|
fromBlocks.add(fromBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if another transition has the exact same assignments as this block
|
||||||
|
* @param other The other transition to examine
|
||||||
|
* @return true if the assignments are identical
|
||||||
|
*/
|
||||||
|
public boolean equalAssignments(PhiTransition other) {
|
||||||
|
List<PhiAssignment> otherAssignments = other.getAssignments();
|
||||||
|
if(assignments.size()!=otherAssignments.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < assignments.size(); i++) {
|
||||||
|
PhiAssignment assignment = assignments.get(i);
|
||||||
|
PhiAssignment otherAssignment = otherAssignments.get(i);
|
||||||
|
if(!assignment.getVariable().equals(otherAssignment.getVariable())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!assignment.getrValue().equals(otherAssignment.getrValue())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ControlFlowBlock> getFromBlocks() {
|
||||||
|
return fromBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assignment of a single value during a phi transition
|
* Assignment of a single value during a phi transition
|
||||||
*/
|
*/
|
||||||
@ -269,52 +443,30 @@ public class Pass4CodeGeneration {
|
|||||||
|
|
||||||
private StatementPhiBlock.PhiRValue phiRValue;
|
private StatementPhiBlock.PhiRValue phiRValue;
|
||||||
|
|
||||||
|
public PhiAssignment(StatementPhiBlock.PhiVariable phiVariable, StatementPhiBlock.PhiRValue phiRValue) {
|
||||||
|
this.phiVariable = phiVariable;
|
||||||
|
this.phiRValue = phiRValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LValue getVariable() {
|
||||||
|
return phiVariable.getVariable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public RValue getrValue() {
|
||||||
|
return phiRValue.getrValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Statement getPhiBlock() {
|
||||||
|
return phiBlock;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a phi block transition. The transition performs all necessary assignment operations when moving from one block to another.
|
|
||||||
* The transition can be inserted either at the start of the to-block (used for conditional jumps)
|
|
||||||
* or at the end of the from-block ( used at default block transitions and before JMP/JSR)
|
|
||||||
* @param asm The ASP program to generate the transition into.
|
|
||||||
* @param fromBlock The from-block
|
|
||||||
* @param toBlock The to-block
|
|
||||||
* @param scope The scope where the ASM code is being inserted. Used to ensure that labels inserted in the code reference the right variables.
|
|
||||||
* If the transition code is inserted in the to-block, this is the scope of the to-block.
|
|
||||||
* If the transition code is inserted in the from-block this is the scope of the from-block.
|
|
||||||
*/
|
|
||||||
private void genBlockPhiTransition(AsmProgram asm, ControlFlowBlock fromBlock, ControlFlowBlock toBlock, ScopeRef scope) {
|
|
||||||
Statement toFirstStatement = toBlock.getStatements().get(0);
|
|
||||||
asm.startSegment(toFirstStatement.getIndex(), "[" + toFirstStatement.getIndex() + "]" + " phi from " + fromBlock.getLabel().getFullName() + " to " + toBlock.getLabel().getFullName());
|
|
||||||
asm.addLabel((toBlock.getLabel().getLocalName() + "_from_" + fromBlock.getLabel().getLocalName()).replace('@', 'b').replace(':', '_'));
|
|
||||||
if (toBlock.hasPhiBlock()) {
|
|
||||||
StatementPhiBlock phiBlock = toBlock.getPhiBlock();
|
|
||||||
List<StatementPhiBlock.PhiVariable> phiVariables = new ArrayList<>(phiBlock.getPhiVariables());
|
|
||||||
Collections.reverse(phiVariables);
|
|
||||||
for (StatementPhiBlock.PhiVariable phiVariable : phiVariables) {
|
|
||||||
List<StatementPhiBlock.PhiRValue> phiRValues = phiVariable.getValues();
|
|
||||||
Collections.sort(phiRValues, new Comparator<StatementPhiBlock.PhiRValue>() {
|
|
||||||
@Override
|
|
||||||
public int compare(StatementPhiBlock.PhiRValue o1, StatementPhiBlock.PhiRValue o2) {
|
|
||||||
return o1.getPredecessor().getFullName().compareTo(o2.getPredecessor().getFullName());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
for (StatementPhiBlock.PhiRValue phiRValue : phiRValues) {
|
|
||||||
if (phiRValue.getPredecessor().equals(fromBlock.getLabel())) {
|
|
||||||
genAsmMove(asm, phiVariable.getVariable(), phiRValue.getrValue(), phiBlock, scope);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Registers.Register getRegister(RValue rValue) {
|
private Registers.Register getRegister(RValue rValue) {
|
||||||
if (rValue instanceof VariableRef) {
|
if (rValue instanceof VariableRef) {
|
||||||
VariableRef rValueRef = (VariableRef) rValue;
|
VariableRef rValueRef = (VariableRef) rValue;
|
||||||
@ -326,6 +478,7 @@ public class Pass4CodeGeneration {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate ASM assigning a value (rValue) to a variable (lValue).
|
* Generate ASM assigning a value (rValue) to a variable (lValue).
|
||||||
|
*
|
||||||
* @param asm The ASM program to generate into
|
* @param asm The ASM program to generate into
|
||||||
* @param lValue The lValue that should be assigned the value
|
* @param lValue The lValue that should be assigned the value
|
||||||
* @param rValue The rValue to assign to the lValue.
|
* @param rValue The rValue to assign to the lValue.
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
jsr main
|
jsr main
|
||||||
main: {
|
main: {
|
||||||
jsr prepare
|
jsr prepare
|
||||||
ldx #$19
|
|
||||||
jmp b3
|
|
||||||
b3_from_b11:
|
b3_from_b11:
|
||||||
ldx #$19
|
ldx #$19
|
||||||
b3:
|
b3:
|
||||||
|
@ -6,7 +6,7 @@ main: scope:[main] from @begin
|
|||||||
[1] call prepare param-assignment [ ]
|
[1] call prepare param-assignment [ ]
|
||||||
to:main::@3
|
to:main::@3
|
||||||
main::@3: scope:[main] from main main::@11 main::@3 main::@6
|
main::@3: scope:[main] from main main::@11 main::@3 main::@6
|
||||||
[2] (byte) main::c#2 ← phi( main/(byte) 25 main::@11/(byte) 25 main::@6/(byte) main::c#1 ) [ main::c#2 ]
|
[2] (byte) main::c#2 ← phi( main/(byte) 25 main::@6/(byte) main::c#1 main::@11/(byte) 25 ) [ main::c#2 ]
|
||||||
[3] (byte~) main::$1 ← * (word) 53266 [ main::$1 main::c#2 ]
|
[3] (byte~) main::$1 ← * (word) 53266 [ main::$1 main::c#2 ]
|
||||||
[4] if((byte~) main::$1!=(byte) 254) goto main::@3 [ main::c#2 ]
|
[4] if((byte~) main::$1!=(byte) 254) goto main::@3 [ main::c#2 ]
|
||||||
to:main::@4
|
to:main::@4
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -13,7 +13,7 @@ main::@1: scope:[main] from main main::@1
|
|||||||
[4] if((byte) main::i#1!=(byte) 0) goto main::@1 [ main::i#1 ]
|
[4] if((byte) main::i#1!=(byte) 0) goto main::@1 [ main::i#1 ]
|
||||||
to:main::@2
|
to:main::@2
|
||||||
main::@2: scope:[main] from main::@1 main::@2
|
main::@2: scope:[main] from main::@1 main::@2
|
||||||
[5] (byte) main::j#2 ← phi( main::@1/(byte) 100 main::@2/(byte) main::j#1 ) [ main::j#2 ]
|
[5] (byte) main::j#2 ← phi( main::@2/(byte) main::j#1 main::@1/(byte) 100 ) [ main::j#2 ]
|
||||||
[6] *((word) 1280 + (byte) main::j#2) ← (byte) main::j#2 [ main::j#2 ]
|
[6] *((word) 1280 + (byte) main::j#2) ← (byte) main::j#2 [ main::j#2 ]
|
||||||
[7] (byte) main::j#1 ← -- (byte) main::j#2 [ main::j#1 ]
|
[7] (byte) main::j#1 ← -- (byte) main::j#2 [ main::j#1 ]
|
||||||
[8] if((byte) main::j#1!=(byte) 255) goto main::@2 [ main::j#1 ]
|
[8] if((byte) main::j#1!=(byte) 255) goto main::@2 [ main::j#1 ]
|
||||||
|
@ -138,7 +138,7 @@ findcol::@9: scope:[findcol] from findcol::@1
|
|||||||
[68] if((byte) findcol::y#0!=(byte) findcol::yp#0) goto findcol::@2 [ render::x#2 render::y#2 render::colline#2 findcol::i#12 findcol::x#0 findcol::xp#0 findcol::y#0 findcol::yp#0 findcol::mindiff#10 findcol::mincol#11 numpoints#1 ]
|
[68] if((byte) findcol::y#0!=(byte) findcol::yp#0) goto findcol::@2 [ render::x#2 render::y#2 render::colline#2 findcol::i#12 findcol::x#0 findcol::xp#0 findcol::y#0 findcol::yp#0 findcol::mindiff#10 findcol::mincol#11 numpoints#1 ]
|
||||||
to:findcol::@return
|
to:findcol::@return
|
||||||
findcol::@return: scope:[findcol] from findcol::@8 findcol::@9
|
findcol::@return: scope:[findcol] from findcol::@8 findcol::@9
|
||||||
[69] (byte) findcol::return#0 ← phi( findcol::@8/(byte) findcol::mincol#2 findcol::@9/(byte) 0 ) [ render::x#2 render::y#2 findcol::return#0 render::colline#2 ]
|
[69] (byte) findcol::return#0 ← phi( findcol::@9/(byte) 0 findcol::@8/(byte) findcol::mincol#2 ) [ render::x#2 render::y#2 findcol::return#0 render::colline#2 ]
|
||||||
[70] return [ render::x#2 render::y#2 findcol::return#0 render::colline#2 ]
|
[70] return [ render::x#2 render::y#2 findcol::return#0 render::colline#2 ]
|
||||||
to:@return
|
to:@return
|
||||||
findcol::@2: scope:[findcol] from findcol::@1 findcol::@9
|
findcol::@2: scope:[findcol] from findcol::@1 findcol::@9
|
||||||
|
Loading…
x
Reference in New Issue
Block a user