Improve bytecode generation.
This commit is contained in:
@@ -14,13 +14,8 @@ public class BasicBlock {
|
||||
BasicBlock[] prev; // previous basic blocks (0-n 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) {
|
||||
this.pc0 = this.pc1 = pc0;
|
||||
this.ninputs = new short[p.maxstacksize];
|
||||
this.inputs = new VarInfo[p.maxstacksize][];
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
@@ -28,18 +23,7 @@ public class BasicBlock {
|
||||
sb.append( (pc0+1)+"-"+(pc1+1)
|
||||
+(prev!=null? " prv: "+str(prev,1): "")
|
||||
+(next!=null? " nxt: "+str(next,0): "")
|
||||
+"\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]);
|
||||
}
|
||||
}
|
||||
+"\n" );
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -121,7 +105,6 @@ public class BasicBlock {
|
||||
int sbx,j;
|
||||
int[] code = p.code;
|
||||
int n = code.length;
|
||||
boolean[] branchdests = new boolean[n];
|
||||
for ( int i=0; i<n; i++ ) {
|
||||
int ins = code[i];
|
||||
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) {
|
||||
Vector list = new Vector();
|
||||
Hashtable seen = new Hashtable();
|
||||
|
||||
@@ -198,7 +198,7 @@ public class JavaBuilder {
|
||||
// create the fields
|
||||
for ( int i=0; i<p.nups; 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);
|
||||
cg.addField(fg.getField());
|
||||
}
|
||||
@@ -610,7 +610,7 @@ public class JavaBuilder {
|
||||
|
||||
public void closureInitUpvalueFromUpvalue(String protoname, int newup, int 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 destname = upvalueName(newup);
|
||||
append(InstructionConstants.THIS);
|
||||
@@ -620,7 +620,7 @@ public class JavaBuilder {
|
||||
|
||||
public void closureInitUpvalueFromLocal(String protoname, int newup, int pc, int srcslot) {
|
||||
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);
|
||||
int index = findSlotIndex( srcslot, isrw );
|
||||
append(new ALOAD(index));
|
||||
|
||||
@@ -22,7 +22,7 @@ public class ProtoInfo {
|
||||
public final Prototype prototype; // the prototype that this info is about
|
||||
public final ProtoInfo[] subprotos; // one per enclosed prototype, or null
|
||||
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[][] vars; // Each variable
|
||||
public final UpvalInfo[] upvals; // from outer scope
|
||||
@@ -49,7 +49,6 @@ public class ProtoInfo {
|
||||
for ( int slot=0; slot<p.maxstacksize; slot++ ) {
|
||||
VarInfo v = VarInfo.PARAM(slot);
|
||||
params[slot] = v;
|
||||
this.blocklist[0].mergeSlotInput(slot, v);
|
||||
}
|
||||
|
||||
// find variables
|
||||
@@ -74,17 +73,13 @@ public class ProtoInfo {
|
||||
// basic blocks
|
||||
for ( int i=0; i<blocklist.length; i++ ) {
|
||||
sb.append( " block "+blocklist[i].toString() );
|
||||
sb.append( "\n" );
|
||||
appendOpenUps( sb, -1 );
|
||||
|
||||
// instructions
|
||||
for ( int pc=blocklist[i].pc0; pc<=blocklist[i].pc1; pc++ ) {
|
||||
|
||||
// open upvalue storage
|
||||
for ( int j=0; j<prototype.maxstacksize; j++ ) {
|
||||
if ( vars[j][pc].pc == pc && vars[j][pc].allocupvalue ) {
|
||||
sb.append( " open: "+vars[j][pc].upvalue+"\n" );
|
||||
}
|
||||
}
|
||||
appendOpenUps( sb, pc );
|
||||
|
||||
// opcode
|
||||
sb.append( " " );
|
||||
@@ -117,6 +112,15 @@ public class ProtoInfo {
|
||||
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() {
|
||||
|
||||
// create storage for variables.
|
||||
@@ -385,10 +389,6 @@ public class ProtoInfo {
|
||||
private void substituteVariable(int slot, VarInfo vold, VarInfo vnew) {
|
||||
for ( int i=0, n=prototype.code.length; i<n; i++ )
|
||||
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) {
|
||||
@@ -429,7 +429,11 @@ public class ProtoInfo {
|
||||
openups[slot] = new UpvalInfo[prototype.code.length];
|
||||
if ( openups[slot][pc] != null )
|
||||
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) {
|
||||
|
||||
@@ -69,9 +69,9 @@ public class UpvalInfo {
|
||||
|
||||
// look for loops
|
||||
if ( v.upvalue == this ) {
|
||||
for ( int i=0, n=b.ninputs[slot]; i<n; i++ ) {
|
||||
v = b.inputs[slot][i];
|
||||
if ( v.upvalue != this )
|
||||
for ( int i=0, n=b.prev!=null? b.prev.length: 0; i<n; i++ ) {
|
||||
v = pi.vars[slot][b.prev[i].pc1];
|
||||
if ( v != null && v.upvalue != this )
|
||||
includeVars(v);
|
||||
}
|
||||
return;
|
||||
@@ -106,11 +106,17 @@ public class UpvalInfo {
|
||||
BasicBlock b = pi.blocks[v.pc];
|
||||
if ( v.pc > b.pc0 )
|
||||
return pi.vars[slot][v.pc-1].upvalue != this;
|
||||
if ( b.ninputs[slot] <= 0 )
|
||||
return true;
|
||||
for ( int k=0, n=b.ninputs[slot]; k<n; k++ )
|
||||
if ( b.inputs[slot][k].upvalue != this )
|
||||
if ( b.prev == null ) {
|
||||
v = pi.params[slot];
|
||||
if ( v != null && v.upvalue != this )
|
||||
return true;
|
||||
} else {
|
||||
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 false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user