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