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[] 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() {
|
||||||
@@ -28,18 +23,7 @@ public class BasicBlock {
|
|||||||
sb.append( (pc0+1)+"-"+(pc1+1)
|
sb.append( (pc0+1)+"-"+(pc1+1)
|
||||||
+(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();
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user