mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-02-20 00:29:10 +00:00
Implemented PhiMemCoalesce.
This commit is contained in:
parent
16d4ab93f0
commit
13c84a1741
@ -101,22 +101,29 @@ public class Compiler {
|
||||
Pass3BlockSequencePlanner pass3BlockSequencePlanner = new Pass3BlockSequencePlanner(program, log);
|
||||
pass3BlockSequencePlanner.plan();
|
||||
|
||||
//Pass3PhiLifting pass3PhiLifting = new Pass3PhiLifting(program, log);
|
||||
//pass3PhiLifting.perform();
|
||||
//pass3BlockSequencePlanner.plan();
|
||||
|
||||
//log.append("CONTROL FLOW GRAPH - PHI LIFTED");
|
||||
//log.append(program.getGraph().toString(program.getScope()));
|
||||
//pass2AssertSSA(program, log);
|
||||
Pass3PhiLifting pass3PhiLifting = new Pass3PhiLifting(program, log);
|
||||
pass3PhiLifting.perform();
|
||||
pass3BlockSequencePlanner.plan();
|
||||
log.append("CONTROL FLOW GRAPH - PHI LIFTED");
|
||||
log.append(program.getGraph().toString(program.getScope()));
|
||||
pass2AssertSSA(program, log);
|
||||
|
||||
Pass3IdentifyAliveRanges pass3IdentifyAliveRanges = new Pass3IdentifyAliveRanges(program, log);
|
||||
pass3IdentifyAliveRanges.findLiveRanges();
|
||||
|
||||
|
||||
log.append("CONTROL FLOW GRAPH - LIVE RANGES");
|
||||
log.append(program.getGraph().toString(program.getScope()));
|
||||
pass2AssertSSA(program, log);
|
||||
|
||||
Pass3PhiMemCoalesce pass3PhiMemCoalesce = new Pass3PhiMemCoalesce(program, log);
|
||||
pass3PhiMemCoalesce.optimize();
|
||||
Pass2CullEmptyBlocks cullEmptyBlocks = new Pass2CullEmptyBlocks(program, log);
|
||||
cullEmptyBlocks.optimize();
|
||||
pass3BlockSequencePlanner.plan();
|
||||
pass3IdentifyAliveRanges.findLiveRanges();
|
||||
log.append("CONTROL FLOW GRAPH - PHI MEM COALESCED");
|
||||
log.append(program.getGraph().toString(program.getScope()));
|
||||
pass2AssertSSA(program, log);
|
||||
|
||||
}
|
||||
|
||||
public void pass2OptimizeSSA(Program program, CompileLog log) {
|
||||
|
@ -109,6 +109,37 @@ public class LiveRange {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if this live range overlaps another live range
|
||||
* @param other The other live range
|
||||
* @return true if there is an overlap
|
||||
*/
|
||||
public boolean overlaps(LiveRange other) {
|
||||
if(this.getMaxIndex()==-1 || other.getMaxIndex()==-1) {
|
||||
return false;
|
||||
}
|
||||
int maxIdx = getMaxIndex();
|
||||
for(int i=0;i<=maxIdx; i++) {
|
||||
if(contains(i) && other.contains(i)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds another live range to this one - extending this live range to include the other one.
|
||||
* @param other The live range to add
|
||||
*/
|
||||
public void add(LiveRange other) {
|
||||
int otherMaxIndex = other.getMaxIndex();
|
||||
for(int i=0;i<=otherMaxIndex; i++) {
|
||||
if(other.contains(i)) {
|
||||
add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the live range contains a statement
|
||||
* @param statement The statement to examine
|
||||
@ -136,5 +167,16 @@ public class LiveRange {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximal index contained in the live range
|
||||
* @return The max index. -1 if the range is empty.
|
||||
*/
|
||||
int getMaxIndex() {
|
||||
if(intervals.isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
return intervals.get(intervals.size()-1).lastStatementIdx;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -44,4 +44,13 @@ public class VariableLiveRanges {
|
||||
return aliveVars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the alive range of a variable
|
||||
* @param variable The variable reference
|
||||
* @return The alive range for the variable
|
||||
*/
|
||||
public LiveRange getLiveRange(VariableRef variable) {
|
||||
return liveRanges.get(variable);
|
||||
}
|
||||
|
||||
}
|
||||
|
239
src/dk/camelot64/kickc/passes/Pass3PhiMemCoalesce.java
Normal file
239
src/dk/camelot64/kickc/passes/Pass3PhiMemCoalesce.java
Normal file
@ -0,0 +1,239 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.CompileLog;
|
||||
import dk.camelot64.kickc.icl.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Eliminate virtual variables introduced by PhiLifting if they do not have overlapping live ranges with other phi equivalent variables.
|
||||
* (This pass requires variable alive ranges).
|
||||
* <p>
|
||||
* See http://compilers.cs.ucla.edu/fernando/projects/soc/reports/short_tech.pdf
|
||||
*/
|
||||
public class Pass3PhiMemCoalesce extends Pass2SsaOptimization {
|
||||
|
||||
public Pass3PhiMemCoalesce(Program program, CompileLog log) {
|
||||
super(program, log);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean optimize() {
|
||||
PhiEquivalenceClassInitializer phiEquivalenceClassInitializer = new PhiEquivalenceClassInitializer();
|
||||
phiEquivalenceClassInitializer.visitGraph(getGraph());
|
||||
ProgramPhiEquivalenceClasses phiEquivalenceClasses = phiEquivalenceClassInitializer.getPhiEquivalenceClasses();
|
||||
log.append("Created " +phiEquivalenceClasses.size()+ " initial phi equivalence classes");
|
||||
PhiMemCoalescer phiMemCoalescer = new PhiMemCoalescer(phiEquivalenceClasses);
|
||||
phiMemCoalescer.visitGraph(getGraph());
|
||||
removeAssignments(phiMemCoalescer.getRemove());
|
||||
replaceVariables(phiMemCoalescer.getReplace());
|
||||
deleteVariables(phiMemCoalescer.getRemove());
|
||||
log.append("Coalesced down to " +phiEquivalenceClasses.size()+ " phi equivalence classes");
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Coalesces phi equivalence classes when they do not overlap based on assignments to variables in phi statements. */
|
||||
private class PhiMemCoalescer extends ControlFlowGraphBaseVisitor<Void> {
|
||||
|
||||
private ProgramPhiEquivalenceClasses phiEquivalenceClasses;
|
||||
private List<VariableRef> remove;
|
||||
private Map<VariableRef, VariableRef> replace;
|
||||
|
||||
public PhiMemCoalescer(ProgramPhiEquivalenceClasses phiEquivalenceClasses) {
|
||||
this.phiEquivalenceClasses = phiEquivalenceClasses;
|
||||
this.remove = new ArrayList<>();
|
||||
this.replace = new HashMap<>();
|
||||
}
|
||||
|
||||
public List<VariableRef> getRemove() {
|
||||
return remove;
|
||||
}
|
||||
|
||||
public Map<VariableRef, VariableRef> getReplace() {
|
||||
return replace;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitAssignment(StatementAssignment assignment) {
|
||||
if (assignment.getlValue() instanceof VariableRef) {
|
||||
PhiEquivalenceClass lValEquivalenceClass =
|
||||
phiEquivalenceClasses.getPhiEquivalenceClass((VariableRef) assignment.getlValue());
|
||||
if (lValEquivalenceClass != null && assignment.getOperator() == null && assignment.getrValue1() == null && assignment.getrValue2() instanceof VariableRef) {
|
||||
// Found copy assignment to a variable in an equivalence class - attempt to coalesce
|
||||
VariableRef assignVar = (VariableRef) assignment.getrValue2();
|
||||
PhiEquivalenceClass assignVarEquivalenceClass = phiEquivalenceClasses.getOrCreateEquivalenceClass(assignVar);
|
||||
if(lValEquivalenceClass.equals(assignVarEquivalenceClass)) {
|
||||
remove.add((VariableRef) assignment.getlValue());
|
||||
replace.put((VariableRef) assignment.getlValue(), assignVar);
|
||||
log.append("Coalesced (already) "+assignment);
|
||||
} else if (!lValEquivalenceClass.getLiveRange().overlaps(assignVarEquivalenceClass.getLiveRange())) {
|
||||
lValEquivalenceClass.addAll(assignVarEquivalenceClass);
|
||||
phiEquivalenceClasses.remove(assignVarEquivalenceClass);
|
||||
remove.add((VariableRef) assignment.getlValue());
|
||||
replace.put((VariableRef) assignment.getlValue(), assignVar);
|
||||
log.append("Coalesced "+assignment);
|
||||
} else {
|
||||
log.append("Not coalescing "+assignment);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/** Creates initial phi equivalence classes from program phi statements.*/
|
||||
private class PhiEquivalenceClassInitializer extends ControlFlowGraphBaseVisitor<Void> {
|
||||
|
||||
private ProgramPhiEquivalenceClasses phiEquivalenceClasses;
|
||||
|
||||
public PhiEquivalenceClassInitializer() {
|
||||
this.phiEquivalenceClasses = new ProgramPhiEquivalenceClasses();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitPhiBlock(StatementPhiBlock phi) {
|
||||
for (StatementPhiBlock.PhiVariable phiVariable : phi.getPhiVariables()) {
|
||||
VariableRef variable = phiVariable.getVariable();
|
||||
PhiEquivalenceClass equivalenceClass = phiEquivalenceClasses.getOrCreateEquivalenceClass(variable);
|
||||
for (StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
|
||||
if(!(phiRValue.getrValue() instanceof Constant)) {
|
||||
VariableRef phiRVar = (VariableRef) phiRValue.getrValue();
|
||||
equivalenceClass.addVariable(phiRVar);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ProgramPhiEquivalenceClasses getPhiEquivalenceClasses() {
|
||||
return phiEquivalenceClasses;
|
||||
}
|
||||
}
|
||||
|
||||
/** The entire set of phi equivalence classes in the pgogram. */
|
||||
public class ProgramPhiEquivalenceClasses {
|
||||
|
||||
List<PhiEquivalenceClass> equivalenceClasses;
|
||||
|
||||
public ProgramPhiEquivalenceClasses() {
|
||||
this.equivalenceClasses = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the phi equivalence class for a specific variable.
|
||||
* If the equivalence class does not exist it is created.
|
||||
*
|
||||
* @param variable The variable
|
||||
* @return The existing or new phi equivalence class
|
||||
*/
|
||||
public PhiEquivalenceClass getOrCreateEquivalenceClass(VariableRef variable) {
|
||||
PhiEquivalenceClass equivalenceClass1 = getPhiEquivalenceClass(variable);
|
||||
if (equivalenceClass1 != null) return equivalenceClass1;
|
||||
// Not found - create it
|
||||
PhiEquivalenceClass equivalenceClass = new PhiEquivalenceClass();
|
||||
equivalenceClasses.add(equivalenceClass);
|
||||
equivalenceClass.addVariable(variable);
|
||||
return equivalenceClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the phi equivalence class for a specific variable.
|
||||
*
|
||||
* @param variable The variable
|
||||
* @return The existing phi equivalence class. null if no equivalence class contains the variable.
|
||||
*/
|
||||
private PhiEquivalenceClass getPhiEquivalenceClass(VariableRef variable) {
|
||||
for (PhiEquivalenceClass equivalenceClass : equivalenceClasses) {
|
||||
if(equivalenceClass.contains(variable)) {
|
||||
return equivalenceClass;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public int size() {
|
||||
return equivalenceClasses.size();
|
||||
}
|
||||
|
||||
public void remove(PhiEquivalenceClass equivalenceClass) {
|
||||
equivalenceClasses.remove(equivalenceClass);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A phi equivalence class contains all varialbes connected in by phi statements.
|
||||
* In the phi statement <code>va = phi(vb, vc)</code> all 3 variables are in the same equivalence class.
|
||||
* The equivalence class is the closure over all phi statements in the program.
|
||||
* The set of equivalence classes is a disjoint partition of all variables uses in phi statements
|
||||
* (ie. those variables crossing non-trivial block transitions).
|
||||
* <p>
|
||||
* See http://compilers.cs.ucla.edu/fernando/projects/soc/reports/short_tech.pdf
|
||||
**/
|
||||
public class PhiEquivalenceClass {
|
||||
|
||||
/** The variables of the equivalence class. */
|
||||
List<VariableRef> variables;
|
||||
|
||||
/** The combined live range of the variables. */
|
||||
LiveRange classLiveRange;
|
||||
|
||||
public PhiEquivalenceClass() {
|
||||
this.variables = new ArrayList<>();
|
||||
this.classLiveRange = new LiveRange();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a variable to the equivalence class
|
||||
* @param variable The variable to add
|
||||
*/
|
||||
public void addVariable(VariableRef variable) {
|
||||
VariableLiveRanges liveRanges = getSymbols().getLiveRanges();
|
||||
LiveRange varLiveRange = liveRanges.getLiveRange(variable);
|
||||
if(classLiveRange.overlaps(varLiveRange)) {
|
||||
throw new RuntimeException("Compilation error! Variable live range overlaps phi equivalence class live range. "+variable);
|
||||
}
|
||||
classLiveRange.add(varLiveRange);
|
||||
variables.add(variable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the phi equivalence class contains a variable
|
||||
* @param variable The variable to look for
|
||||
* @return true if the equivalence class contains the variable
|
||||
*/
|
||||
public boolean contains(VariableRef variable) {
|
||||
return variables.contains(variable);
|
||||
}
|
||||
|
||||
public LiveRange getLiveRange() {
|
||||
return classLiveRange;
|
||||
}
|
||||
|
||||
public void addAll(PhiEquivalenceClass other) {
|
||||
variables.addAll(other.variables);
|
||||
classLiveRange.add(other.classLiveRange);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
PhiEquivalenceClass that = (PhiEquivalenceClass) o;
|
||||
|
||||
return variables.equals(that.variables);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return variables.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -844,6 +844,52 @@ Multiple usages for variable. Not optimizing sub-constant (byte*) cursor#1
|
||||
Multiple usages for variable. Not optimizing sub-constant (byte) y#2
|
||||
Multiple usages for variable. Not optimizing sub-constant (byte*) cursor#1
|
||||
Block Sequence Planned @BEGIN @1 @3 @END @2
|
||||
Added new block during phi lifting @7(between @3 and @1)
|
||||
Added new block during phi lifting @8(between @1 and @3)
|
||||
Block Sequence Planned @BEGIN @1 @8 @3 @END @7 @2
|
||||
CONTROL FLOW GRAPH - PHI LIFTED
|
||||
@BEGIN: from
|
||||
to:@1
|
||||
@1: from @7 @BEGIN
|
||||
(byte) y#2 ← phi( @7/(byte~) y#5 @BEGIN/(byte) 0 )
|
||||
(byte) e#3 ← phi( @7/(byte~) e#6 @BEGIN/(byte) 12 )
|
||||
(byte) x#2 ← phi( @7/(byte~) x#5 @BEGIN/(byte) 0 )
|
||||
(byte*) cursor#3 ← phi( @7/(byte*~) cursor#6 @BEGIN/(word) 1024 )
|
||||
*((byte*) cursor#3) ← (byte) 81
|
||||
(byte) x#1 ← (byte) x#2 + (byte) 1
|
||||
(byte*) cursor#1 ← (byte*) cursor#3 + (byte) 1
|
||||
(byte) e#1 ← (byte) e#3 + (byte) 24
|
||||
if((byte) 39<(byte) e#1) goto @2
|
||||
to:@8
|
||||
@8: from @1
|
||||
(byte*~) cursor#7 ← (byte*) cursor#1
|
||||
(byte~) e#7 ← (byte) e#1
|
||||
(byte~) y#6 ← (byte) y#2
|
||||
to:@3
|
||||
@3: from @2 @8
|
||||
(byte) y#4 ← phi( @8/(byte~) y#6 @2/(byte~) y#7 )
|
||||
(byte) e#5 ← phi( @8/(byte~) e#7 @2/(byte~) e#8 )
|
||||
(byte*) cursor#5 ← phi( @8/(byte*~) cursor#7 @2/(byte*~) cursor#8 )
|
||||
if((byte) x#1<(byte) 40) goto @7
|
||||
to:@END
|
||||
@END: from @3
|
||||
@7: from @3
|
||||
(byte*~) cursor#6 ← (byte*) cursor#5
|
||||
(byte~) x#5 ← (byte) x#1
|
||||
(byte~) e#6 ← (byte) e#5
|
||||
(byte~) y#5 ← (byte) y#4
|
||||
to:@1
|
||||
@2: from @1
|
||||
(byte) y#1 ← (byte) y#2 + (byte) 1
|
||||
(byte*) cursor#2 ← (byte*) cursor#1 + (byte) 40
|
||||
(byte) e#2 ← (byte) e#1 - (byte) 39
|
||||
(byte*~) cursor#8 ← (byte*) cursor#2
|
||||
(byte~) e#8 ← (byte) e#2
|
||||
(byte~) y#7 ← (byte) y#1
|
||||
to:@3
|
||||
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
@ -851,6 +897,68 @@ Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
CONTROL FLOW GRAPH - LIVE RANGES
|
||||
@BEGIN: from
|
||||
to:@1
|
||||
@1: from @7 @BEGIN
|
||||
[0] (byte) y#2 ← phi( @7/(byte~) y#5 @BEGIN/(byte) 0 ) [ cursor#3 x#2 e#3 y#2 ]
|
||||
[0] (byte) e#3 ← phi( @7/(byte~) e#6 @BEGIN/(byte) 12 ) [ cursor#3 x#2 e#3 y#2 ]
|
||||
[0] (byte) x#2 ← phi( @7/(byte~) x#5 @BEGIN/(byte) 0 ) [ cursor#3 x#2 e#3 y#2 ]
|
||||
[0] (byte*) cursor#3 ← phi( @7/(byte*~) cursor#6 @BEGIN/(word) 1024 ) [ cursor#3 x#2 e#3 y#2 ]
|
||||
[1] *((byte*) cursor#3) ← (byte) 81 [ cursor#3 x#2 e#3 y#2 ]
|
||||
[2] (byte) x#1 ← (byte) x#2 + (byte) 1 [ cursor#3 e#3 y#2 x#1 ]
|
||||
[3] (byte*) cursor#1 ← (byte*) cursor#3 + (byte) 1 [ e#3 cursor#1 y#2 x#1 ]
|
||||
[4] (byte) e#1 ← (byte) e#3 + (byte) 24 [ e#1 cursor#1 y#2 x#1 ]
|
||||
[5] if((byte) 39<(byte) e#1) goto @2 [ e#1 cursor#1 y#2 x#1 ]
|
||||
to:@8
|
||||
@8: from @1
|
||||
[6] (byte*~) cursor#7 ← (byte*) cursor#1 [ e#1 y#2 cursor#7 x#1 ]
|
||||
[7] (byte~) e#7 ← (byte) e#1 [ y#2 cursor#7 e#7 x#1 ]
|
||||
[8] (byte~) y#6 ← (byte) y#2 [ cursor#7 e#7 y#6 x#1 ]
|
||||
to:@3
|
||||
@3: from @2 @8
|
||||
[9] (byte) y#4 ← phi( @8/(byte~) y#6 @2/(byte~) y#7 ) [ x#1 cursor#5 e#5 y#4 ]
|
||||
[9] (byte) e#5 ← phi( @8/(byte~) e#7 @2/(byte~) e#8 ) [ x#1 cursor#5 e#5 y#4 ]
|
||||
[9] (byte*) cursor#5 ← phi( @8/(byte*~) cursor#7 @2/(byte*~) cursor#8 ) [ x#1 cursor#5 e#5 y#4 ]
|
||||
[10] if((byte) x#1<(byte) 40) goto @7 [ x#1 cursor#5 e#5 y#4 ]
|
||||
to:@END
|
||||
@END: from @3
|
||||
@7: from @3
|
||||
[11] (byte*~) cursor#6 ← (byte*) cursor#5 [ cursor#6 x#1 e#5 y#4 ]
|
||||
[12] (byte~) x#5 ← (byte) x#1 [ cursor#6 x#5 e#5 y#4 ]
|
||||
[13] (byte~) e#6 ← (byte) e#5 [ cursor#6 x#5 e#6 y#4 ]
|
||||
[14] (byte~) y#5 ← (byte) y#4 [ cursor#6 x#5 e#6 y#5 ]
|
||||
to:@1
|
||||
@2: from @1
|
||||
[15] (byte) y#1 ← (byte) y#2 + (byte) 1 [ e#1 cursor#1 x#1 y#1 ]
|
||||
[16] (byte*) cursor#2 ← (byte*) cursor#1 + (byte) 40 [ e#1 x#1 cursor#2 y#1 ]
|
||||
[17] (byte) e#2 ← (byte) e#1 - (byte) 39 [ x#1 cursor#2 e#2 y#1 ]
|
||||
[18] (byte*~) cursor#8 ← (byte*) cursor#2 [ cursor#8 x#1 e#2 y#1 ]
|
||||
[19] (byte~) e#8 ← (byte) e#2 [ cursor#8 e#8 x#1 y#1 ]
|
||||
[20] (byte~) y#7 ← (byte) y#1 [ cursor#8 e#8 y#7 x#1 ]
|
||||
to:@3
|
||||
|
||||
Created 7 initial phi equivalence classes
|
||||
Coalesced [6] cursor#7 ← cursor#1
|
||||
Coalesced [7] e#7 ← e#1
|
||||
Coalesced [8] y#6 ← y#2
|
||||
Coalesced [11] cursor#6 ← cursor#5
|
||||
Coalesced [12] x#5 ← x#1
|
||||
Coalesced [13] e#6 ← e#5
|
||||
Coalesced (already) [14] y#5 ← y#4
|
||||
Coalesced [18] cursor#8 ← cursor#2
|
||||
Coalesced [19] e#8 ← e#2
|
||||
Coalesced [20] y#7 ← y#1
|
||||
Coalesced down to 4 phi equivalence classes
|
||||
Culled Empty Block (label) @8
|
||||
Culled Empty Block (label) @7
|
||||
Block Sequence Planned @BEGIN @1 @3 @END @2
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
CONTROL FLOW GRAPH - PHI MEM COALESCED
|
||||
@BEGIN: from
|
||||
to:@1
|
||||
@1: from @3 @BEGIN
|
||||
|
@ -3310,6 +3310,149 @@ Multiple usages for variable. Not optimizing sub-constant (byte) flip::i#2
|
||||
Multiple usages for variable. Not optimizing sub-constant (byte) flip::i#2
|
||||
Multiple usages for variable. Not optimizing sub-constant (byte) plot::i#2
|
||||
Block Sequence Planned @BEGIN @END main main::@3 main::@4 main::@6 main::@7 main::@10 main::@11 main::@return plot plot::@1 plot::@2 plot::@3 plot::@return flip flip::@1 flip::@2 flip::@4 flip::@3 flip::@return prepare prepare::@1 prepare::@return
|
||||
Added new block during phi lifting main::@12(between main::@6 and main::@3)
|
||||
Added new block during phi lifting plot::@5(between plot::@3 and plot::@1)
|
||||
Added new block during phi lifting plot::@6(between plot::@2 and plot::@2)
|
||||
Added new block during phi lifting flip::@7(between flip::@4 and flip::@1)
|
||||
Added new block during phi lifting flip::@8(between flip::@2 and flip::@2)
|
||||
Added new block during phi lifting flip::@9(between flip::@3 and flip::@3)
|
||||
Added new block during phi lifting prepare::@3(between prepare::@1 and prepare::@1)
|
||||
Block Sequence Planned @BEGIN @END main main::@3 main::@4 main::@6 main::@7 main::@10 main::@11 main::@return main::@12 plot plot::@1 plot::@2 plot::@3 plot::@return plot::@5 plot::@6 flip flip::@1 flip::@2 flip::@4 flip::@3 flip::@return flip::@9 flip::@7 flip::@8 prepare prepare::@1 prepare::@return prepare::@3
|
||||
CONTROL FLOW GRAPH - PHI LIFTED
|
||||
@BEGIN: from
|
||||
call main param-assignment
|
||||
to:@END
|
||||
@END: from @BEGIN
|
||||
main: from @BEGIN
|
||||
call prepare param-assignment
|
||||
to:main::@3
|
||||
main::@3: from main main::@11 main::@12 main::@3
|
||||
(byte) main::c#2 ← phi( main/(byte) 25 main::@12/(byte~) main::c#6 main::@11/(byte) 25 )
|
||||
(byte~) main::$1 ← * (word) 53266
|
||||
if((byte~) main::$1!=(byte) 254) goto main::@3
|
||||
to:main::@4
|
||||
main::@4: from main::@3 main::@4
|
||||
(byte~) main::$3 ← * (word) 53266
|
||||
if((byte~) main::$3!=(byte) 255) goto main::@4
|
||||
to:main::@6
|
||||
main::@6: from main::@4
|
||||
(byte) main::c#1 ← -- (byte) main::c#2
|
||||
if((byte) main::c#1!=(byte) 0) goto main::@12
|
||||
to:main::@7
|
||||
main::@7: from main::@6
|
||||
call flip param-assignment
|
||||
to:main::@10
|
||||
main::@10: from main::@7
|
||||
call plot param-assignment
|
||||
to:main::@11
|
||||
main::@11: from main::@10
|
||||
if(true) goto main::@3
|
||||
to:main::@return
|
||||
main::@return: from main::@11
|
||||
return
|
||||
to:@RETURN
|
||||
main::@12: from main::@6
|
||||
(byte~) main::c#6 ← (byte) main::c#1
|
||||
to:main::@3
|
||||
plot: from main::@10
|
||||
to:plot::@1
|
||||
plot::@1: from plot plot::@5
|
||||
(byte) plot::y#2 ← phi( plot/(byte) 16 plot::@5/(byte~) plot::y#5 )
|
||||
(byte*) plot::line#2 ← phi( plot/(word) 1236 plot::@5/(byte*~) plot::line#5 )
|
||||
(byte) plot::i#3 ← phi( plot/(byte) 0 plot::@5/(byte~) plot::i#5 )
|
||||
(byte~) plot::i#6 ← (byte) plot::i#3
|
||||
to:plot::@2
|
||||
plot::@2: from plot::@1 plot::@6
|
||||
(byte) plot::x#2 ← phi( plot::@1/(byte) 0 plot::@6/(byte~) plot::x#3 )
|
||||
(byte) plot::i#2 ← phi( plot::@1/(byte~) plot::i#6 plot::@6/(byte~) plot::i#7 )
|
||||
(byte~) plot::$3 ← (word) 4096 *idx (byte) plot::i#2
|
||||
*((byte*) plot::line#2 + (byte) plot::x#2) ← (byte~) plot::$3
|
||||
(byte) plot::i#1 ← ++ (byte) plot::i#2
|
||||
(byte) plot::x#1 ← ++ (byte) plot::x#2
|
||||
if((byte) plot::x#1<(byte) 16) goto plot::@6
|
||||
to:plot::@3
|
||||
plot::@3: from plot::@2
|
||||
(byte*) plot::line#1 ← (byte*) plot::line#2 + (byte) 40
|
||||
(byte) plot::y#1 ← -- (byte) plot::y#2
|
||||
if((byte) plot::y#1!=(byte) 0) goto plot::@5
|
||||
to:plot::@return
|
||||
plot::@return: from plot::@3
|
||||
return
|
||||
to:@RETURN
|
||||
plot::@5: from plot::@3
|
||||
(byte~) plot::i#5 ← (byte) plot::i#1
|
||||
(byte*~) plot::line#5 ← (byte*) plot::line#1
|
||||
(byte~) plot::y#5 ← (byte) plot::y#1
|
||||
to:plot::@1
|
||||
plot::@6: from plot::@2
|
||||
(byte~) plot::i#7 ← (byte) plot::i#1
|
||||
(byte~) plot::x#3 ← (byte) plot::x#1
|
||||
to:plot::@2
|
||||
flip: from main::@7
|
||||
to:flip::@1
|
||||
flip::@1: from flip flip::@7
|
||||
(byte) flip::r#2 ← phi( flip/(byte) 16 flip::@7/(byte~) flip::r#5 )
|
||||
(byte) flip::dstIdx#5 ← phi( flip/(byte) 15 flip::@7/(byte~) flip::dstIdx#6 )
|
||||
(byte) flip::srcIdx#3 ← phi( flip/(byte) 0 flip::@7/(byte~) flip::srcIdx#5 )
|
||||
(byte~) flip::srcIdx#6 ← (byte) flip::srcIdx#3
|
||||
(byte~) flip::dstIdx#7 ← (byte) flip::dstIdx#5
|
||||
to:flip::@2
|
||||
flip::@2: from flip::@1 flip::@8
|
||||
(byte) flip::c#2 ← phi( flip::@1/(byte) 16 flip::@8/(byte~) flip::c#3 )
|
||||
(byte) flip::dstIdx#3 ← phi( flip::@1/(byte~) flip::dstIdx#7 flip::@8/(byte~) flip::dstIdx#8 )
|
||||
(byte) flip::srcIdx#2 ← phi( flip::@1/(byte~) flip::srcIdx#6 flip::@8/(byte~) flip::srcIdx#7 )
|
||||
(byte~) flip::$0 ← (word) 4096 *idx (byte) flip::srcIdx#2
|
||||
*((word) 4352 + (byte) flip::dstIdx#3) ← (byte~) flip::$0
|
||||
(byte) flip::srcIdx#1 ← ++ (byte) flip::srcIdx#2
|
||||
(byte) flip::dstIdx#1 ← (byte) flip::dstIdx#3 + (byte) 16
|
||||
(byte) flip::c#1 ← -- (byte) flip::c#2
|
||||
if((byte) flip::c#1!=(byte) 0) goto flip::@8
|
||||
to:flip::@4
|
||||
flip::@4: from flip::@2
|
||||
(byte) flip::dstIdx#2 ← -- (byte) flip::dstIdx#1
|
||||
(byte) flip::r#1 ← -- (byte) flip::r#2
|
||||
if((byte) flip::r#1!=(byte) 0) goto flip::@7
|
||||
to:flip::@3
|
||||
flip::@3: from flip::@4 flip::@9
|
||||
(byte) flip::i#2 ← phi( flip::@9/(byte~) flip::i#3 flip::@4/(byte) 0 )
|
||||
(byte~) flip::$4 ← (word) 4352 *idx (byte) flip::i#2
|
||||
*((word) 4096 + (byte) flip::i#2) ← (byte~) flip::$4
|
||||
(byte) flip::i#1 ← ++ (byte) flip::i#2
|
||||
if((byte) flip::i#1!=(byte) 0) goto flip::@9
|
||||
to:flip::@return
|
||||
flip::@return: from flip::@3
|
||||
return
|
||||
to:@RETURN
|
||||
flip::@9: from flip::@3
|
||||
(byte~) flip::i#3 ← (byte) flip::i#1
|
||||
to:flip::@3
|
||||
flip::@7: from flip::@4
|
||||
(byte~) flip::srcIdx#5 ← (byte) flip::srcIdx#1
|
||||
(byte~) flip::dstIdx#6 ← (byte) flip::dstIdx#2
|
||||
(byte~) flip::r#5 ← (byte) flip::r#1
|
||||
to:flip::@1
|
||||
flip::@8: from flip::@2
|
||||
(byte~) flip::srcIdx#7 ← (byte) flip::srcIdx#1
|
||||
(byte~) flip::dstIdx#8 ← (byte) flip::dstIdx#1
|
||||
(byte~) flip::c#3 ← (byte) flip::c#1
|
||||
to:flip::@2
|
||||
prepare: from main
|
||||
to:prepare::@1
|
||||
prepare::@1: from prepare prepare::@3
|
||||
(byte) prepare::i#2 ← phi( prepare/(byte) 0 prepare::@3/(byte~) prepare::i#3 )
|
||||
*((word) 4096 + (byte) prepare::i#2) ← (byte) prepare::i#2
|
||||
(byte) prepare::i#1 ← ++ (byte) prepare::i#2
|
||||
if((byte) prepare::i#1!=(byte) 0) goto prepare::@3
|
||||
to:prepare::@return
|
||||
prepare::@return: from prepare::@1
|
||||
return
|
||||
to:@RETURN
|
||||
prepare::@3: from prepare::@1
|
||||
(byte~) prepare::i#3 ← (byte) prepare::i#1
|
||||
to:prepare::@1
|
||||
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
@ -3324,6 +3467,175 @@ CONTROL FLOW GRAPH - LIVE RANGES
|
||||
[0] call main param-assignment [ ]
|
||||
to:@END
|
||||
@END: from @BEGIN
|
||||
main: from @BEGIN
|
||||
[1] call prepare param-assignment [ ]
|
||||
to:main::@3
|
||||
main::@3: from main main::@11 main::@12 main::@3
|
||||
[2] (byte) main::c#2 ← phi( main/(byte) 25 main::@12/(byte~) main::c#6 main::@11/(byte) 25 ) [ 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 ]
|
||||
to:main::@4
|
||||
main::@4: from main::@3 main::@4
|
||||
[5] (byte~) main::$3 ← * (word) 53266 [ main::$3 main::c#2 ]
|
||||
[6] if((byte~) main::$3!=(byte) 255) goto main::@4 [ main::c#2 ]
|
||||
to:main::@6
|
||||
main::@6: from main::@4
|
||||
[7] (byte) main::c#1 ← -- (byte) main::c#2 [ main::c#1 ]
|
||||
[8] if((byte) main::c#1!=(byte) 0) goto main::@12 [ main::c#1 ]
|
||||
to:main::@7
|
||||
main::@7: from main::@6
|
||||
[9] call flip param-assignment [ ]
|
||||
to:main::@10
|
||||
main::@10: from main::@7
|
||||
[10] call plot param-assignment [ ]
|
||||
to:main::@11
|
||||
main::@11: from main::@10
|
||||
[11] if(true) goto main::@3 [ ]
|
||||
to:main::@return
|
||||
main::@return: from main::@11
|
||||
[12] return [ ]
|
||||
to:@RETURN
|
||||
main::@12: from main::@6
|
||||
[13] (byte~) main::c#6 ← (byte) main::c#1 [ main::c#6 ]
|
||||
to:main::@3
|
||||
plot: from main::@10
|
||||
to:plot::@1
|
||||
plot::@1: from plot plot::@5
|
||||
[14] (byte) plot::y#2 ← phi( plot/(byte) 16 plot::@5/(byte~) plot::y#5 ) [ plot::i#3 plot::line#2 plot::y#2 ]
|
||||
[14] (byte*) plot::line#2 ← phi( plot/(word) 1236 plot::@5/(byte*~) plot::line#5 ) [ plot::i#3 plot::line#2 plot::y#2 ]
|
||||
[14] (byte) plot::i#3 ← phi( plot/(byte) 0 plot::@5/(byte~) plot::i#5 ) [ plot::i#3 plot::line#2 plot::y#2 ]
|
||||
[15] (byte~) plot::i#6 ← (byte) plot::i#3 [ plot::i#6 plot::line#2 plot::y#2 ]
|
||||
to:plot::@2
|
||||
plot::@2: from plot::@1 plot::@6
|
||||
[16] (byte) plot::x#2 ← phi( plot::@1/(byte) 0 plot::@6/(byte~) plot::x#3 ) [ plot::i#2 plot::line#2 plot::x#2 plot::y#2 ]
|
||||
[16] (byte) plot::i#2 ← phi( plot::@1/(byte~) plot::i#6 plot::@6/(byte~) plot::i#7 ) [ plot::i#2 plot::line#2 plot::x#2 plot::y#2 ]
|
||||
[17] (byte~) plot::$3 ← (word) 4096 *idx (byte) plot::i#2 [ plot::i#2 plot::line#2 plot::x#2 plot::$3 plot::y#2 ]
|
||||
[18] *((byte*) plot::line#2 + (byte) plot::x#2) ← (byte~) plot::$3 [ plot::i#2 plot::line#2 plot::x#2 plot::y#2 ]
|
||||
[19] (byte) plot::i#1 ← ++ (byte) plot::i#2 [ plot::line#2 plot::x#2 plot::y#2 plot::i#1 ]
|
||||
[20] (byte) plot::x#1 ← ++ (byte) plot::x#2 [ plot::line#2 plot::x#1 plot::y#2 plot::i#1 ]
|
||||
[21] if((byte) plot::x#1<(byte) 16) goto plot::@6 [ plot::line#2 plot::x#1 plot::y#2 plot::i#1 ]
|
||||
to:plot::@3
|
||||
plot::@3: from plot::@2
|
||||
[22] (byte*) plot::line#1 ← (byte*) plot::line#2 + (byte) 40 [ plot::y#2 plot::i#1 plot::line#1 ]
|
||||
[23] (byte) plot::y#1 ← -- (byte) plot::y#2 [ plot::y#1 plot::i#1 plot::line#1 ]
|
||||
[24] if((byte) plot::y#1!=(byte) 0) goto plot::@5 [ plot::y#1 plot::i#1 plot::line#1 ]
|
||||
to:plot::@return
|
||||
plot::@return: from plot::@3
|
||||
[25] return [ ]
|
||||
to:@RETURN
|
||||
plot::@5: from plot::@3
|
||||
[26] (byte~) plot::i#5 ← (byte) plot::i#1 [ plot::i#5 plot::y#1 plot::line#1 ]
|
||||
[27] (byte*~) plot::line#5 ← (byte*) plot::line#1 [ plot::i#5 plot::line#5 plot::y#1 ]
|
||||
[28] (byte~) plot::y#5 ← (byte) plot::y#1 [ plot::i#5 plot::line#5 plot::y#5 ]
|
||||
to:plot::@1
|
||||
plot::@6: from plot::@2
|
||||
[29] (byte~) plot::i#7 ← (byte) plot::i#1 [ plot::i#7 plot::line#2 plot::x#1 plot::y#2 ]
|
||||
[30] (byte~) plot::x#3 ← (byte) plot::x#1 [ plot::i#7 plot::x#3 plot::line#2 plot::y#2 ]
|
||||
to:plot::@2
|
||||
flip: from main::@7
|
||||
to:flip::@1
|
||||
flip::@1: from flip flip::@7
|
||||
[31] (byte) flip::r#2 ← phi( flip/(byte) 16 flip::@7/(byte~) flip::r#5 ) [ flip::srcIdx#3 flip::dstIdx#5 flip::r#2 ]
|
||||
[31] (byte) flip::dstIdx#5 ← phi( flip/(byte) 15 flip::@7/(byte~) flip::dstIdx#6 ) [ flip::srcIdx#3 flip::dstIdx#5 flip::r#2 ]
|
||||
[31] (byte) flip::srcIdx#3 ← phi( flip/(byte) 0 flip::@7/(byte~) flip::srcIdx#5 ) [ flip::srcIdx#3 flip::dstIdx#5 flip::r#2 ]
|
||||
[32] (byte~) flip::srcIdx#6 ← (byte) flip::srcIdx#3 [ flip::dstIdx#5 flip::srcIdx#6 flip::r#2 ]
|
||||
[33] (byte~) flip::dstIdx#7 ← (byte) flip::dstIdx#5 [ flip::srcIdx#6 flip::dstIdx#7 flip::r#2 ]
|
||||
to:flip::@2
|
||||
flip::@2: from flip::@1 flip::@8
|
||||
[34] (byte) flip::c#2 ← phi( flip::@1/(byte) 16 flip::@8/(byte~) flip::c#3 ) [ flip::srcIdx#2 flip::dstIdx#3 flip::c#2 flip::r#2 ]
|
||||
[34] (byte) flip::dstIdx#3 ← phi( flip::@1/(byte~) flip::dstIdx#7 flip::@8/(byte~) flip::dstIdx#8 ) [ flip::srcIdx#2 flip::dstIdx#3 flip::c#2 flip::r#2 ]
|
||||
[34] (byte) flip::srcIdx#2 ← phi( flip::@1/(byte~) flip::srcIdx#6 flip::@8/(byte~) flip::srcIdx#7 ) [ flip::srcIdx#2 flip::dstIdx#3 flip::c#2 flip::r#2 ]
|
||||
[35] (byte~) flip::$0 ← (word) 4096 *idx (byte) flip::srcIdx#2 [ flip::srcIdx#2 flip::dstIdx#3 flip::$0 flip::c#2 flip::r#2 ]
|
||||
[36] *((word) 4352 + (byte) flip::dstIdx#3) ← (byte~) flip::$0 [ flip::srcIdx#2 flip::dstIdx#3 flip::c#2 flip::r#2 ]
|
||||
[37] (byte) flip::srcIdx#1 ← ++ (byte) flip::srcIdx#2 [ flip::dstIdx#3 flip::c#2 flip::r#2 flip::srcIdx#1 ]
|
||||
[38] (byte) flip::dstIdx#1 ← (byte) flip::dstIdx#3 + (byte) 16 [ flip::c#2 flip::dstIdx#1 flip::r#2 flip::srcIdx#1 ]
|
||||
[39] (byte) flip::c#1 ← -- (byte) flip::c#2 [ flip::c#1 flip::dstIdx#1 flip::r#2 flip::srcIdx#1 ]
|
||||
[40] if((byte) flip::c#1!=(byte) 0) goto flip::@8 [ flip::c#1 flip::dstIdx#1 flip::r#2 flip::srcIdx#1 ]
|
||||
to:flip::@4
|
||||
flip::@4: from flip::@2
|
||||
[41] (byte) flip::dstIdx#2 ← -- (byte) flip::dstIdx#1 [ flip::r#2 flip::srcIdx#1 flip::dstIdx#2 ]
|
||||
[42] (byte) flip::r#1 ← -- (byte) flip::r#2 [ flip::r#1 flip::srcIdx#1 flip::dstIdx#2 ]
|
||||
[43] if((byte) flip::r#1!=(byte) 0) goto flip::@7 [ flip::r#1 flip::srcIdx#1 flip::dstIdx#2 ]
|
||||
to:flip::@3
|
||||
flip::@3: from flip::@4 flip::@9
|
||||
[44] (byte) flip::i#2 ← phi( flip::@9/(byte~) flip::i#3 flip::@4/(byte) 0 ) [ flip::i#2 ]
|
||||
[45] (byte~) flip::$4 ← (word) 4352 *idx (byte) flip::i#2 [ flip::i#2 flip::$4 ]
|
||||
[46] *((word) 4096 + (byte) flip::i#2) ← (byte~) flip::$4 [ flip::i#2 ]
|
||||
[47] (byte) flip::i#1 ← ++ (byte) flip::i#2 [ flip::i#1 ]
|
||||
[48] if((byte) flip::i#1!=(byte) 0) goto flip::@9 [ flip::i#1 ]
|
||||
to:flip::@return
|
||||
flip::@return: from flip::@3
|
||||
[49] return [ ]
|
||||
to:@RETURN
|
||||
flip::@9: from flip::@3
|
||||
[50] (byte~) flip::i#3 ← (byte) flip::i#1 [ flip::i#3 ]
|
||||
to:flip::@3
|
||||
flip::@7: from flip::@4
|
||||
[51] (byte~) flip::srcIdx#5 ← (byte) flip::srcIdx#1 [ flip::srcIdx#5 flip::r#1 flip::dstIdx#2 ]
|
||||
[52] (byte~) flip::dstIdx#6 ← (byte) flip::dstIdx#2 [ flip::srcIdx#5 flip::dstIdx#6 flip::r#1 ]
|
||||
[53] (byte~) flip::r#5 ← (byte) flip::r#1 [ flip::srcIdx#5 flip::dstIdx#6 flip::r#5 ]
|
||||
to:flip::@1
|
||||
flip::@8: from flip::@2
|
||||
[54] (byte~) flip::srcIdx#7 ← (byte) flip::srcIdx#1 [ flip::srcIdx#7 flip::c#1 flip::dstIdx#1 flip::r#2 ]
|
||||
[55] (byte~) flip::dstIdx#8 ← (byte) flip::dstIdx#1 [ flip::srcIdx#7 flip::dstIdx#8 flip::c#1 flip::r#2 ]
|
||||
[56] (byte~) flip::c#3 ← (byte) flip::c#1 [ flip::srcIdx#7 flip::dstIdx#8 flip::c#3 flip::r#2 ]
|
||||
to:flip::@2
|
||||
prepare: from main
|
||||
to:prepare::@1
|
||||
prepare::@1: from prepare prepare::@3
|
||||
[57] (byte) prepare::i#2 ← phi( prepare/(byte) 0 prepare::@3/(byte~) prepare::i#3 ) [ prepare::i#2 ]
|
||||
[58] *((word) 4096 + (byte) prepare::i#2) ← (byte) prepare::i#2 [ prepare::i#2 ]
|
||||
[59] (byte) prepare::i#1 ← ++ (byte) prepare::i#2 [ prepare::i#1 ]
|
||||
[60] if((byte) prepare::i#1!=(byte) 0) goto prepare::@3 [ prepare::i#1 ]
|
||||
to:prepare::@return
|
||||
prepare::@return: from prepare::@1
|
||||
[61] return [ ]
|
||||
to:@RETURN
|
||||
prepare::@3: from prepare::@1
|
||||
[62] (byte~) prepare::i#3 ← (byte) prepare::i#1 [ prepare::i#3 ]
|
||||
to:prepare::@1
|
||||
|
||||
Created 14 initial phi equivalence classes
|
||||
Coalesced [13] main::c#6 ← main::c#1
|
||||
Coalesced [15] plot::i#6 ← plot::i#3
|
||||
Coalesced [26] plot::i#5 ← plot::i#1
|
||||
Coalesced [27] plot::line#5 ← plot::line#1
|
||||
Coalesced [28] plot::y#5 ← plot::y#1
|
||||
Coalesced (already) [29] plot::i#7 ← plot::i#1
|
||||
Coalesced [30] plot::x#3 ← plot::x#1
|
||||
Coalesced [32] flip::srcIdx#6 ← flip::srcIdx#3
|
||||
Coalesced [33] flip::dstIdx#7 ← flip::dstIdx#5
|
||||
Coalesced [50] flip::i#3 ← flip::i#1
|
||||
Coalesced [51] flip::srcIdx#5 ← flip::srcIdx#1
|
||||
Coalesced [52] flip::dstIdx#6 ← flip::dstIdx#2
|
||||
Coalesced [53] flip::r#5 ← flip::r#1
|
||||
Coalesced (already) [54] flip::srcIdx#7 ← flip::srcIdx#1
|
||||
Coalesced [55] flip::dstIdx#8 ← flip::dstIdx#1
|
||||
Coalesced [56] flip::c#3 ← flip::c#1
|
||||
Coalesced [62] prepare::i#3 ← prepare::i#1
|
||||
Coalesced down to 11 phi equivalence classes
|
||||
Culled Empty Block (label) main::@12
|
||||
Culled Empty Block (label) plot::@5
|
||||
Culled Empty Block (label) plot::@6
|
||||
Culled Empty Block (label) flip::@9
|
||||
Culled Empty Block (label) flip::@7
|
||||
Culled Empty Block (label) flip::@8
|
||||
Culled Empty Block (label) prepare::@3
|
||||
Block Sequence Planned @BEGIN @END main main::@3 main::@4 main::@6 main::@7 main::@10 main::@11 main::@return plot plot::@1 plot::@2 plot::@3 plot::@return flip flip::@1 flip::@2 flip::@4 flip::@3 flip::@return prepare prepare::@1 prepare::@return
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
CONTROL FLOW GRAPH - PHI MEM COALESCED
|
||||
@BEGIN: from
|
||||
[0] call main param-assignment [ ]
|
||||
to:@END
|
||||
@END: from @BEGIN
|
||||
main: from @BEGIN
|
||||
[1] call prepare param-assignment [ ]
|
||||
to:main::@3
|
||||
|
@ -252,10 +252,78 @@ CONTROL FLOW GRAPH
|
||||
@END: from @3
|
||||
|
||||
Block Sequence Planned @BEGIN @1 @3 @END @2
|
||||
Added new block during phi lifting @7(between @3 and @1)
|
||||
Added new block during phi lifting @8(between @1 and @3)
|
||||
Block Sequence Planned @BEGIN @1 @8 @3 @END @7 @2
|
||||
CONTROL FLOW GRAPH - PHI LIFTED
|
||||
@BEGIN: from
|
||||
to:@1
|
||||
@1: from @7 @BEGIN
|
||||
(byte) s#2 ← phi( @7/(byte~) s#5 @BEGIN/(byte) 0 )
|
||||
(byte) i#2 ← phi( @7/(byte~) i#5 @BEGIN/(byte) 10 )
|
||||
if((byte) i#2>(byte) 5) goto @2
|
||||
to:@8
|
||||
@8: from @1
|
||||
(byte~) s#6 ← (byte) s#2
|
||||
to:@3
|
||||
@3: from @2 @8
|
||||
(byte) s#4 ← phi( @8/(byte~) s#6 @2/(byte~) s#7 )
|
||||
(byte) i#1 ← -- (byte) i#2
|
||||
if((byte) i#1>(byte) 0) goto @7
|
||||
to:@END
|
||||
@END: from @3
|
||||
@7: from @3
|
||||
(byte~) i#5 ← (byte) i#1
|
||||
(byte~) s#5 ← (byte) s#4
|
||||
to:@1
|
||||
@2: from @1
|
||||
(byte) s#1 ← (byte) s#2 + (byte) i#2
|
||||
(byte~) s#7 ← (byte) s#1
|
||||
to:@3
|
||||
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
CONTROL FLOW GRAPH - LIVE RANGES
|
||||
@BEGIN: from
|
||||
to:@1
|
||||
@1: from @7 @BEGIN
|
||||
[0] (byte) s#2 ← phi( @7/(byte~) s#5 @BEGIN/(byte) 0 ) [ i#2 s#2 ]
|
||||
[0] (byte) i#2 ← phi( @7/(byte~) i#5 @BEGIN/(byte) 10 ) [ i#2 s#2 ]
|
||||
[1] if((byte) i#2>(byte) 5) goto @2 [ i#2 s#2 ]
|
||||
to:@8
|
||||
@8: from @1
|
||||
[2] (byte~) s#6 ← (byte) s#2 [ i#2 s#6 ]
|
||||
to:@3
|
||||
@3: from @2 @8
|
||||
[3] (byte) s#4 ← phi( @8/(byte~) s#6 @2/(byte~) s#7 ) [ i#2 s#4 ]
|
||||
[4] (byte) i#1 ← -- (byte) i#2 [ i#1 s#4 ]
|
||||
[5] if((byte) i#1>(byte) 0) goto @7 [ i#1 s#4 ]
|
||||
to:@END
|
||||
@END: from @3
|
||||
@7: from @3
|
||||
[6] (byte~) i#5 ← (byte) i#1 [ i#5 s#4 ]
|
||||
[7] (byte~) s#5 ← (byte) s#4 [ i#5 s#5 ]
|
||||
to:@1
|
||||
@2: from @1
|
||||
[8] (byte) s#1 ← (byte) s#2 + (byte) i#2 [ i#2 s#1 ]
|
||||
[9] (byte~) s#7 ← (byte) s#1 [ i#2 s#7 ]
|
||||
to:@3
|
||||
|
||||
Created 3 initial phi equivalence classes
|
||||
Coalesced [2] s#6 ← s#2
|
||||
Coalesced [6] i#5 ← i#1
|
||||
Coalesced (already) [7] s#5 ← s#4
|
||||
Coalesced [9] s#7 ← s#1
|
||||
Coalesced down to 2 phi equivalence classes
|
||||
Culled Empty Block (label) @8
|
||||
Culled Empty Block (label) @7
|
||||
Block Sequence Planned @BEGIN @1 @3 @END @2
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
CONTROL FLOW GRAPH - PHI MEM COALESCED
|
||||
@BEGIN: from
|
||||
to:@1
|
||||
@1: from @3 @BEGIN
|
||||
|
@ -207,9 +207,50 @@ Multiple usages for variable. Not optimizing sub-constant (byte) i#2
|
||||
Multiple usages for variable. Not optimizing sub-constant (byte) i#2
|
||||
Multiple usages for variable. Not optimizing sub-constant (byte) i#2
|
||||
Block Sequence Planned @BEGIN @1 @END
|
||||
Added new block during phi lifting @3(between @1 and @1)
|
||||
Block Sequence Planned @BEGIN @1 @END @3
|
||||
CONTROL FLOW GRAPH - PHI LIFTED
|
||||
@BEGIN: from
|
||||
to:@1
|
||||
@1: from @3 @BEGIN
|
||||
(byte) i#2 ← phi( @3/(byte~) i#3 @BEGIN/(byte) 5 )
|
||||
(byte~) $0 ← (byte) 2 + (byte) i#2
|
||||
(byte~) $1 ← (byte~) $0 + (byte) 2
|
||||
*((word) 4352 + (byte) i#2) ← (byte~) $1
|
||||
(byte) i#1 ← (byte) i#2 + (byte) 1
|
||||
if((byte) i#1<(byte) 10) goto @3
|
||||
to:@END
|
||||
@END: from @1
|
||||
@3: from @1
|
||||
(byte~) i#3 ← (byte) i#1
|
||||
to:@1
|
||||
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
CONTROL FLOW GRAPH - LIVE RANGES
|
||||
@BEGIN: from
|
||||
to:@1
|
||||
@1: from @3 @BEGIN
|
||||
[0] (byte) i#2 ← phi( @3/(byte~) i#3 @BEGIN/(byte) 5 ) [ i#2 ]
|
||||
[1] (byte~) $0 ← (byte) 2 + (byte) i#2 [ i#2 $0 ]
|
||||
[2] (byte~) $1 ← (byte~) $0 + (byte) 2 [ i#2 $1 ]
|
||||
[3] *((word) 4352 + (byte) i#2) ← (byte~) $1 [ i#2 ]
|
||||
[4] (byte) i#1 ← (byte) i#2 + (byte) 1 [ i#1 ]
|
||||
[5] if((byte) i#1<(byte) 10) goto @3 [ i#1 ]
|
||||
to:@END
|
||||
@END: from @1
|
||||
@3: from @1
|
||||
[6] (byte~) i#3 ← (byte) i#1 [ i#3 ]
|
||||
to:@1
|
||||
|
||||
Created 1 initial phi equivalence classes
|
||||
Coalesced [6] i#3 ← i#1
|
||||
Coalesced down to 1 phi equivalence classes
|
||||
Culled Empty Block (label) @3
|
||||
Block Sequence Planned @BEGIN @1 @END
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
CONTROL FLOW GRAPH - PHI MEM COALESCED
|
||||
@BEGIN: from
|
||||
to:@1
|
||||
@1: from @1 @BEGIN
|
||||
|
@ -241,6 +241,24 @@ sum::@return: from sum
|
||||
@END: from @2
|
||||
|
||||
Block Sequence Planned @BEGIN @2 @END sum sum::@return
|
||||
Block Sequence Planned @BEGIN @2 @END sum sum::@return
|
||||
CONTROL FLOW GRAPH - PHI LIFTED
|
||||
@BEGIN: from
|
||||
call sum param-assignment
|
||||
to:@2
|
||||
@2: from @BEGIN
|
||||
call sum param-assignment
|
||||
to:@END
|
||||
@END: from @2
|
||||
sum: from @2 @BEGIN
|
||||
(byte) sum::b#2 ← phi( @2/(byte) 13 @BEGIN/(byte) 2 )
|
||||
(byte) sum::a#2 ← phi( @2/(byte) 9 @BEGIN/(byte) 1 )
|
||||
(byte) s1#0 ← (byte) sum::a#2 + (byte) sum::b#2
|
||||
to:sum::@return
|
||||
sum::@return: from sum
|
||||
return (byte) s1#0
|
||||
to:@RETURN
|
||||
|
||||
Propagating live ranges...
|
||||
CONTROL FLOW GRAPH - LIVE RANGES
|
||||
@BEGIN: from
|
||||
@ -259,6 +277,27 @@ sum::@return: from sum
|
||||
[4] return (byte) s1#0 [ ]
|
||||
to:@RETURN
|
||||
|
||||
Created 2 initial phi equivalence classes
|
||||
Coalesced down to 2 phi equivalence classes
|
||||
Block Sequence Planned @BEGIN @2 @END sum sum::@return
|
||||
Propagating live ranges...
|
||||
CONTROL FLOW GRAPH - PHI MEM COALESCED
|
||||
@BEGIN: from
|
||||
[0] call sum param-assignment [ ]
|
||||
to:@2
|
||||
@2: from @BEGIN
|
||||
[1] call sum param-assignment [ ]
|
||||
to:@END
|
||||
@END: from @2
|
||||
sum: from @2 @BEGIN
|
||||
[2] (byte) sum::b#2 ← phi( @2/(byte) 13 @BEGIN/(byte) 2 ) [ sum::a#2 sum::b#2 ]
|
||||
[2] (byte) sum::a#2 ← phi( @2/(byte) 9 @BEGIN/(byte) 1 ) [ sum::a#2 sum::b#2 ]
|
||||
[3] (byte) s1#0 ← (byte) sum::a#2 + (byte) sum::b#2 [ s1#0 ]
|
||||
to:sum::@return
|
||||
sum::@return: from sum
|
||||
[4] return (byte) s1#0 [ ]
|
||||
to:@RETURN
|
||||
|
||||
INITIAL ASM
|
||||
BBEGIN:
|
||||
sum_from_BBEGIN:
|
||||
|
Loading…
x
Reference in New Issue
Block a user