Improve bytecode generation.
This commit is contained in:
@@ -18,6 +18,7 @@ public class ProtoInfo {
|
||||
public final BasicBlock[] blocks; // basic block analysis of code branching
|
||||
public final BasicBlock[] blocklist; // blocks in breadhth-first order
|
||||
public final VarInfo[][] vars; // Each variable
|
||||
public final VarInfo[] params; // Parameters and initial values of stack variables
|
||||
public final UpvalInfo[] upvals; // from outer scope
|
||||
public final UpvalInfo[][] openups; // per slot, upvalues allocated by this prototype
|
||||
|
||||
@@ -35,6 +36,15 @@ public class ProtoInfo {
|
||||
// find basic blocks
|
||||
this.blocks = BasicBlock.findBasicBlocks(p);
|
||||
this.blocklist = BasicBlock.sortDepthFirst(blocks);
|
||||
|
||||
|
||||
// params are inputs to first block
|
||||
this.params = new VarInfo[p.maxstacksize];
|
||||
for ( int slot=0; slot<p.maxstacksize; slot++ ) {
|
||||
VarInfo v = VarInfo.PARAM(slot);
|
||||
params[slot] = v;
|
||||
this.blocklist[0].mergeSlotInput(slot, v);
|
||||
}
|
||||
|
||||
// find variables and block inputs
|
||||
this.vars = findVariables();
|
||||
@@ -295,23 +305,20 @@ public class ProtoInfo {
|
||||
}
|
||||
|
||||
public boolean isUpvalueAssign(int pc, int slot) {
|
||||
if ( pc < 0 ) pc = 0;
|
||||
VarInfo v = vars[slot][pc];
|
||||
VarInfo v = pc<0? params[slot]: vars[slot][pc];
|
||||
// return v.upvalue != null && v.upvalue.rw;
|
||||
return v != null && v.upvalue != null;
|
||||
}
|
||||
|
||||
public boolean isUpvalueCreate(int pc, int slot) {
|
||||
if ( pc < 0 ) pc = 0;
|
||||
VarInfo v = vars[slot][pc];
|
||||
VarInfo v = pc<0? params[slot]: vars[slot][pc];
|
||||
// return v.upvalue != null && v.upvalue.rw && v.allocupvalue && pc == v.pc;
|
||||
return v != null && v.upvalue != null && v.allocupvalue && pc == v.pc;
|
||||
}
|
||||
|
||||
public boolean isUpvalueRefer(int pc, int slot) {
|
||||
// TODO: when it is a CALL
|
||||
if ( pc < 0 ) pc = 0;
|
||||
VarInfo v = vars[slot][pc];
|
||||
VarInfo v = pc<0? params[slot]: vars[slot][pc];
|
||||
// return v.upvalue != null && v.upvalue.rw;
|
||||
return v != null && v.upvalue != null;
|
||||
}
|
||||
|
||||
@@ -63,13 +63,12 @@ public class UpvalInfo {
|
||||
// invalid values terminate search
|
||||
if ( v == VarInfo.INVALID )
|
||||
return;
|
||||
// nil values also terminate (TODO: mark as unintialized upvalue)
|
||||
if ( v.pc == -1 )
|
||||
return;
|
||||
|
||||
// basic block for nil values is initial block
|
||||
BasicBlock b = pi.blocks[v.pc<0? 0: v.pc];
|
||||
|
||||
BasicBlock b = pi.blocks[v.pc];
|
||||
// look for loops
|
||||
if ( v.upvalue == this ) {
|
||||
// loop detected, include previous values
|
||||
for ( int i=0, n=b.ninputs[slot]; i<n; i++ ) {
|
||||
v = b.inputs[slot][i];
|
||||
if ( v.upvalue != this )
|
||||
@@ -77,7 +76,7 @@ public class UpvalInfo {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// check for assignment to 2 upvalues at once
|
||||
if ( v.upvalue != null )
|
||||
throw new IllegalArgumentException("upvalue collision detected between "+v.upvalue+" and "+this);
|
||||
@@ -86,6 +85,10 @@ public class UpvalInfo {
|
||||
v.upvalue = this;
|
||||
this.includeVar(v);
|
||||
|
||||
// nil values also terminate
|
||||
if ( v.pc == -1 )
|
||||
return;
|
||||
|
||||
// find next variable within the basic block
|
||||
for ( int i=v.pc; i<=b.pc1; i++ ) {
|
||||
if ( pi.vars[slot][i] != v ) {
|
||||
@@ -102,6 +105,8 @@ public class UpvalInfo {
|
||||
}
|
||||
|
||||
private boolean testIsAllocUpvalue(VarInfo v) {
|
||||
if ( v.pc < 0 )
|
||||
return true;
|
||||
BasicBlock b = pi.blocks[v.pc];
|
||||
if ( v.pc > b.pc0 )
|
||||
return pi.vars[slot][v.pc-1].upvalue != this;
|
||||
|
||||
@@ -7,14 +7,26 @@ public class VarInfo {
|
||||
|
||||
public static VarInfo INVALID = new VarInfo(-1,-1);
|
||||
|
||||
public static VarInfo NIL(int slot) {
|
||||
return new VarInfo(slot,-1);
|
||||
public static VarInfo PARAM(int slot) {
|
||||
return new VarInfo(slot,-1) {
|
||||
public String toString() {
|
||||
return slot+".p";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static VarInfo NIL(final int slot) {
|
||||
return new VarInfo(slot,-1) {
|
||||
public String toString() {
|
||||
return "nil";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static VarInfo PHI(int slot, int pc) {
|
||||
return new VarInfo(slot,pc) {
|
||||
public String toString() {
|
||||
return super.toString()+"p";
|
||||
return super.toString()+"{}";
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -23,7 +35,7 @@ public class VarInfo {
|
||||
public final int pc; // where assigned, or -1 if for block inputs
|
||||
|
||||
public UpvalInfo upvalue; // not null if this var is an upvalue
|
||||
public boolean allocupvalue; // true if this variable allocations r/w upvalue storage
|
||||
public boolean allocupvalue; // true if this variable allocates r/w upvalue storage
|
||||
|
||||
public VarInfo(int slot, int pc) {
|
||||
this.slot = slot;
|
||||
@@ -32,7 +44,6 @@ public class VarInfo {
|
||||
|
||||
public String toString() {
|
||||
return slot<0? "x.x":
|
||||
pc<0? "nil":
|
||||
(slot+"."+pc);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user