Improve bytecode generation.

This commit is contained in:
James Roseborough
2010-08-09 18:16:32 +00:00
parent df86eca3c3
commit abdf9bca6f
3 changed files with 40 additions and 17 deletions

View File

@@ -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;
} }

View File

@@ -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;

View File

@@ -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);
} }
} }