Improve bytecode generation.

This commit is contained in:
James Roseborough
2010-08-10 17:46:17 +00:00
parent 28a6ad6bca
commit d27f2d6e20
4 changed files with 35 additions and 77 deletions

View File

@@ -14,13 +14,8 @@ public class BasicBlock {
BasicBlock[] prev; // previous basic blocks (0-n of these) BasicBlock[] prev; // previous basic blocks (0-n of these)
BasicBlock[] next; // next basic blocks (0, 1, or 2 of these) BasicBlock[] next; // next basic blocks (0, 1, or 2 of these)
short[] ninputs; // number of input values per slot, >0 means is phi variable
VarInfo[][] inputs; // variables for each input, -1=closed/undefined, 1,2...=revisionof that variable
public BasicBlock(Prototype p, int pc0) { public BasicBlock(Prototype p, int pc0) {
this.pc0 = this.pc1 = pc0; this.pc0 = this.pc1 = pc0;
this.ninputs = new short[p.maxstacksize];
this.inputs = new VarInfo[p.maxstacksize][];
} }
public String toString() { public String toString() {
@@ -29,17 +24,6 @@ public class BasicBlock {
+(prev!=null? " prv: "+str(prev,1): "") +(prev!=null? " prv: "+str(prev,1): "")
+(next!=null? " nxt: "+str(next,0): "") +(next!=null? " nxt: "+str(next,0): "")
+"\n" ); +"\n" );
for ( int i=0; i<ninputs.length; i++ ) {
if ( ninputs[i] < 0 )
sb.append( " x " );
else if ( ninputs[i] == 0 )
sb.append( " - " );
else {
sb.append( " "+inputs[i][0] );
for ( int j=1; j<ninputs[i]; j++ )
sb.append(","+inputs[i][j]);
}
}
return sb.toString(); return sb.toString();
} }
@@ -121,7 +105,6 @@ public class BasicBlock {
int sbx,j; int sbx,j;
int[] code = p.code; int[] code = p.code;
int n = code.length; int n = code.length;
boolean[] branchdests = new boolean[n];
for ( int i=0; i<n; i++ ) { for ( int i=0; i<n; i++ ) {
int ins = code[i]; int ins = code[i];
switch ( Lua.GET_OPCODE( ins ) ) { switch ( Lua.GET_OPCODE( ins ) ) {
@@ -162,41 +145,6 @@ public class BasicBlock {
} }
} }
public boolean mergeSlotInput(int slot, VarInfo v) {
int n = ninputs[slot];
if ( n == -1 )
return false;
if ( v == VarInfo.INVALID) {
ninputs[slot] = -1;
inputs[slot] = null;
return true;
}
if ( n == 0 ) {
ninputs[slot] = 1;
inputs[slot] = new VarInfo[] { v };
return true;
}
for ( int i=0; i<n; i++ )
if ( inputs[slot][i] == v )
return false;
if ( n+1 > inputs[slot].length ) {
VarInfo[] s = inputs[slot];
inputs[slot] = new VarInfo[(n+1)*2];
System.arraycopy(s, 0, inputs[slot], 0, n);
}
inputs[slot][n] = v;
ninputs[slot]++;
return true;
}
boolean includesVar(int slot, VarInfo v) {
int n = ninputs[slot];
for ( int i=0; i<n; i++ )
if ( inputs[slot][i] == v )
return true;
return false;
}
public static BasicBlock[] sortDepthFirst(BasicBlock[] blocks) { public static BasicBlock[] sortDepthFirst(BasicBlock[] blocks) {
Vector list = new Vector(); Vector list = new Vector();
Hashtable seen = new Hashtable(); Hashtable seen = new Hashtable();

View File

@@ -198,7 +198,7 @@ public class JavaBuilder {
// create the fields // create the fields
for ( int i=0; i<p.nups; i++ ) { for ( int i=0; i<p.nups; i++ ) {
boolean isrw = pi.isReadWriteUpvalue( pi.upvals[i] ); boolean isrw = pi.isReadWriteUpvalue( pi.upvals[i] );
Type uptype = isrw? TYPE_LOCALUPVALUE: TYPE_LUAVALUE; Type uptype = isrw? (Type) TYPE_LOCALUPVALUE: (Type) TYPE_LUAVALUE;
FieldGen fg = new FieldGen(0, uptype, upvalueName(i), cp); FieldGen fg = new FieldGen(0, uptype, upvalueName(i), cp);
cg.addField(fg.getField()); cg.addField(fg.getField());
} }
@@ -610,7 +610,7 @@ public class JavaBuilder {
public void closureInitUpvalueFromUpvalue(String protoname, int newup, int upindex) { public void closureInitUpvalueFromUpvalue(String protoname, int newup, int upindex) {
boolean isrw = pi.isReadWriteUpvalue( pi.upvals[upindex] ); boolean isrw = pi.isReadWriteUpvalue( pi.upvals[upindex] );
Type uptype = isrw? TYPE_LOCALUPVALUE: TYPE_LUAVALUE; Type uptype = isrw? (Type) TYPE_LOCALUPVALUE: (Type) TYPE_LUAVALUE;
String srcname = upvalueName(upindex); String srcname = upvalueName(upindex);
String destname = upvalueName(newup); String destname = upvalueName(newup);
append(InstructionConstants.THIS); append(InstructionConstants.THIS);
@@ -620,7 +620,7 @@ public class JavaBuilder {
public void closureInitUpvalueFromLocal(String protoname, int newup, int pc, int srcslot) { public void closureInitUpvalueFromLocal(String protoname, int newup, int pc, int srcslot) {
boolean isrw = pi.isReadWriteUpvalue( pi.vars[srcslot][pc].upvalue ); boolean isrw = pi.isReadWriteUpvalue( pi.vars[srcslot][pc].upvalue );
Type uptype = isrw? TYPE_LOCALUPVALUE: TYPE_LUAVALUE; Type uptype = isrw? (Type) TYPE_LOCALUPVALUE: (Type) TYPE_LUAVALUE;
String destname = upvalueName(newup); String destname = upvalueName(newup);
int index = findSlotIndex( srcslot, isrw ); int index = findSlotIndex( srcslot, isrw );
append(new ALOAD(index)); append(new ALOAD(index));

View File

@@ -22,7 +22,7 @@ public class ProtoInfo {
public final Prototype prototype; // the prototype that this info is about public final Prototype prototype; // the prototype that this info is about
public final ProtoInfo[] subprotos; // one per enclosed prototype, or null public final ProtoInfo[] subprotos; // one per enclosed prototype, or null
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 breadth-first order
public final VarInfo[] params; // Parameters and initial values of stack variables public final VarInfo[] params; // Parameters and initial values of stack variables
public final VarInfo[][] vars; // Each variable public final VarInfo[][] vars; // Each variable
public final UpvalInfo[] upvals; // from outer scope public final UpvalInfo[] upvals; // from outer scope
@@ -49,7 +49,6 @@ public class ProtoInfo {
for ( int slot=0; slot<p.maxstacksize; slot++ ) { for ( int slot=0; slot<p.maxstacksize; slot++ ) {
VarInfo v = VarInfo.PARAM(slot); VarInfo v = VarInfo.PARAM(slot);
params[slot] = v; params[slot] = v;
this.blocklist[0].mergeSlotInput(slot, v);
} }
// find variables // find variables
@@ -74,17 +73,13 @@ public class ProtoInfo {
// basic blocks // basic blocks
for ( int i=0; i<blocklist.length; i++ ) { for ( int i=0; i<blocklist.length; i++ ) {
sb.append( " block "+blocklist[i].toString() ); sb.append( " block "+blocklist[i].toString() );
sb.append( "\n" ); appendOpenUps( sb, -1 );
// instructions // instructions
for ( int pc=blocklist[i].pc0; pc<=blocklist[i].pc1; pc++ ) { for ( int pc=blocklist[i].pc0; pc<=blocklist[i].pc1; pc++ ) {
// open upvalue storage // open upvalue storage
for ( int j=0; j<prototype.maxstacksize; j++ ) { appendOpenUps( sb, pc );
if ( vars[j][pc].pc == pc && vars[j][pc].allocupvalue ) {
sb.append( " open: "+vars[j][pc].upvalue+"\n" );
}
}
// opcode // opcode
sb.append( " " ); sb.append( " " );
@@ -117,6 +112,15 @@ public class ProtoInfo {
return sb.toString(); return sb.toString();
} }
private void appendOpenUps(StringBuffer sb, int pc) {
for ( int j=0; j<prototype.maxstacksize; j++ ) {
VarInfo v = (pc<0? params[j]: vars[j][pc]);
if ( v.pc == pc && v.allocupvalue ) {
sb.append( " open: "+v.upvalue+"\n" );
}
}
}
private VarInfo[][] findVariables() { private VarInfo[][] findVariables() {
// create storage for variables. // create storage for variables.
@@ -385,10 +389,6 @@ public class ProtoInfo {
private void substituteVariable(int slot, VarInfo vold, VarInfo vnew) { private void substituteVariable(int slot, VarInfo vold, VarInfo vnew) {
for ( int i=0, n=prototype.code.length; i<n; i++ ) for ( int i=0, n=prototype.code.length; i<n; i++ )
replaceAll( vars[slot], vars[slot].length, vold, vnew ); replaceAll( vars[slot], vars[slot].length, vold, vnew );
for ( int i=0; i<blocklist.length; i++ ) {
BasicBlock b = blocklist[i];
replaceAll( b.inputs[slot], b.ninputs[slot], vold, vnew );
}
} }
private void replaceAll(VarInfo[] v, int n, VarInfo vold, VarInfo vnew) { private void replaceAll(VarInfo[] v, int n, VarInfo vold, VarInfo vnew) {
@@ -429,7 +429,11 @@ public class ProtoInfo {
openups[slot] = new UpvalInfo[prototype.code.length]; openups[slot] = new UpvalInfo[prototype.code.length];
if ( openups[slot][pc] != null ) if ( openups[slot][pc] != null )
return openups[slot][pc]; return openups[slot][pc];
return new UpvalInfo(this, pc, slot); UpvalInfo u = new UpvalInfo(this, pc, slot);
for ( int i=0, n=prototype.code.length; i<n; ++i )
if ( vars[slot][i] != null && vars[slot][i].upvalue == u )
openups[slot][i] = u;
return u;
} }
public boolean isUpvalueAssign(int pc, int slot) { public boolean isUpvalueAssign(int pc, int slot) {

View File

@@ -69,9 +69,9 @@ public class UpvalInfo {
// look for loops // look for loops
if ( v.upvalue == this ) { if ( v.upvalue == this ) {
for ( int i=0, n=b.ninputs[slot]; i<n; i++ ) { for ( int i=0, n=b.prev!=null? b.prev.length: 0; i<n; i++ ) {
v = b.inputs[slot][i]; v = pi.vars[slot][b.prev[i].pc1];
if ( v.upvalue != this ) if ( v != null && v.upvalue != this )
includeVars(v); includeVars(v);
} }
return; return;
@@ -106,11 +106,17 @@ public class UpvalInfo {
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;
if ( b.ninputs[slot] <= 0 ) if ( b.prev == null ) {
v = pi.params[slot];
if ( v != null && v.upvalue != this )
return true; return true;
for ( int k=0, n=b.ninputs[slot]; k<n; k++ ) } else {
if ( b.inputs[slot][k].upvalue != this ) for ( int i=0, n=b.prev.length; i<n; i++ ) {
v = pi.vars[slot][b.prev[i].pc1];
if ( v != null && v.upvalue != this )
return true; return true;
}
}
return false; return false;
} }