Move all logic regarding establishing type of variable into Block.java

This commit is contained in:
igor%mir2.org 2004-05-09 21:06:20 +00:00
Родитель 98b0af3853
Коммит 5a48e9dc3a
2 изменённых файлов: 76 добавлений и 80 удалений

Просмотреть файл

@ -88,6 +88,19 @@ class Block
static void runFlowAnalyzes(OptFunctionNode fn, Node[] statementNodes) static void runFlowAnalyzes(OptFunctionNode fn, Node[] statementNodes)
{ {
int paramCount = fn.fnode.getParamCount();
int varCount = fn.fnode.getParamAndVarCount();
int[] varTypes = new int[varCount];
// If the variable is a parameter, it could have any type.
for (int i = 0; i != paramCount; ++i) {
varTypes[i] = Optimizer.AnyType;
}
// If the variable is from a "var" statement, its typeEvent will be set
// when we see the setVar node.
for (int i = paramCount; i != varCount; ++i) {
varTypes[i] = Optimizer.NoType;
}
Block[] theBlocks = buildBlocks(statementNodes); Block[] theBlocks = buildBlocks(statementNodes);
if (DEBUG) { if (DEBUG) {
@ -96,19 +109,23 @@ class Block
System.out.println(toString(theBlocks, statementNodes)); System.out.println(toString(theBlocks, statementNodes));
} }
reachingDefDataFlow(fn, statementNodes, theBlocks); reachingDefDataFlow(fn, statementNodes, theBlocks, varTypes);
typeFlow(fn, statementNodes, theBlocks); typeFlow(fn, statementNodes, theBlocks, varTypes);
if (DEBUG) { if (DEBUG) {
for (int i = 0; i < theBlocks.length; i++) { for (int i = 0; i < theBlocks.length; i++) {
System.out.println("For block " + theBlocks[i].itsBlockID); System.out.println("For block " + theBlocks[i].itsBlockID);
theBlocks[i].printLiveOnEntrySet(fn); theBlocks[i].printLiveOnEntrySet(fn);
} }
int N = fn.getVarCount(); System.out.println("Variable Table, size = " + varCount);
System.out.println("Variable Table, size = " + N); for (int i = 0; i != varCount; i++) {
for (int i = 0; i != N; i++) { System.out.println("["+i+"] type: "+varTypes[i]);
OptLocalVariable lVar = fn.getVar(i); }
System.out.println(lVar.toString()); }
for (int i = paramCount; i != varCount; i++) {
if (varTypes[i] == Optimizer.NumberType) {
fn.getVar(i).setIsNumber();
} }
} }
@ -248,7 +265,7 @@ class Block
return sw.toString(); return sw.toString();
} }
private static void reachingDefDataFlow(OptFunctionNode fn, Node[] statementNodes, Block theBlocks[]) private static void reachingDefDataFlow(OptFunctionNode fn, Node[] statementNodes, Block theBlocks[], int[] varTypes)
{ {
/* /*
initialize the liveOnEntry and liveOnExit sets, then discover the variables initialize the liveOnEntry and liveOnExit sets, then discover the variables
@ -300,10 +317,10 @@ class Block
'undefined'-ness of that variable. 'undefined'-ness of that variable.
*/ */
theBlocks[0].markAnyTypeVariables(fn); theBlocks[0].markAnyTypeVariables(varTypes);
} }
private static void typeFlow(OptFunctionNode fn, Node[] statementNodes, Block theBlocks[]) private static void typeFlow(OptFunctionNode fn, Node[] statementNodes, Block theBlocks[], int[] varTypes)
{ {
boolean visit[] = new boolean[theBlocks.length]; boolean visit[] = new boolean[theBlocks.length];
boolean doneOnce[] = new boolean[theBlocks.length]; boolean doneOnce[] = new boolean[theBlocks.length];
@ -314,7 +331,7 @@ class Block
if (visit[vIndex] || !doneOnce[vIndex]) { if (visit[vIndex] || !doneOnce[vIndex]) {
doneOnce[vIndex] = true; doneOnce[vIndex] = true;
visit[vIndex] = false; visit[vIndex] = false;
if (theBlocks[vIndex].doTypeFlow(statementNodes)) { if (theBlocks[vIndex].doTypeFlow(statementNodes, varTypes)) {
Block succ[] = theBlocks[vIndex].itsSuccessors; Block succ[] = theBlocks[vIndex].itsSuccessors;
if (succ != null) { if (succ != null) {
for (int i = 0; i < succ.length; i++) { for (int i = 0; i < succ.length; i++) {
@ -336,23 +353,25 @@ class Block
else else
vIndex++; vIndex++;
} }
for (int i = 0; i < fn.getVarCount(); i++) {
OptLocalVariable lVar = fn.getVar(i);
if (!lVar.isParameter()) {
int theType = lVar.getTypeUnion();
if (theType == Optimizer.NumberType) {
lVar.setIsNumber();
}
}
}
} }
private void markAnyTypeVariables(OptFunctionNode fn) private static int getVarIndex(Node n)
{ {
for (int i = 0; i < fn.getVarCount(); i++) return OptLocalVariable.get(n).getIndex();
if (itsLiveOnEntrySet.test(i)) }
fn.getVar(i).assignType(Optimizer.AnyType);
private static boolean assignType(int[] varTypes, int index, int type)
{
return type != (varTypes[index] |= type);
}
private void markAnyTypeVariables(int[] varTypes)
{
for (int i = 0; i != varTypes.length; i++) {
if (itsLiveOnEntrySet.test(i)) {
assignType(varTypes, i, Optimizer.AnyType);
}
}
} }
@ -372,10 +391,10 @@ class Block
{ {
Node child = n.getFirstChild(); Node child = n.getFirstChild();
if (child.getType() == Token.GETVAR) { if (child.getType() == Token.GETVAR) {
int theVarIndex = OptLocalVariable.get(child).getIndex(); int varIndex = getVarIndex(child);
if (!itsNotDefSet.test(theVarIndex)) if (!itsNotDefSet.test(varIndex))
itsUseBeforeDefSet.set(theVarIndex); itsUseBeforeDefSet.set(varIndex);
itsNotDefSet.set(theVarIndex); itsNotDefSet.set(varIndex);
} }
} }
break; break;
@ -384,16 +403,14 @@ class Block
Node lhs = n.getFirstChild(); Node lhs = n.getFirstChild();
Node rhs = lhs.getNext(); Node rhs = lhs.getNext();
lookForVariableAccess(rhs); lookForVariableAccess(rhs);
OptLocalVariable theVar = OptLocalVariable.get(n); itsNotDefSet.set(getVarIndex(n));
int theVarIndex = theVar.getIndex();
itsNotDefSet.set(theVarIndex);
} }
break; break;
case Token.GETVAR : case Token.GETVAR :
{ {
int theVarIndex = OptLocalVariable.get(n).getIndex(); int varIndex = getVarIndex(n);
if (!itsNotDefSet.test(theVarIndex)) if (!itsNotDefSet.test(varIndex))
itsUseBeforeDefSet.set(theVarIndex); itsUseBeforeDefSet.set(varIndex);
} }
break; break;
default : default :
@ -447,7 +464,7 @@ class Block
Literals, Literals,
Arithmetic operations - always return a Number Arithmetic operations - always return a Number
*/ */
private static int findExpressionType(Node n) private static int findExpressionType(Node n, int[] varTypes)
{ {
switch (n.getType()) { switch (n.getType()) {
case Token.NUMBER : case Token.NUMBER :
@ -461,7 +478,7 @@ class Block
return Optimizer.AnyType; return Optimizer.AnyType;
case Token.GETVAR : case Token.GETVAR :
return OptLocalVariable.get(n).getTypeUnion(); return varTypes[getVarIndex(n)];
case Token.INC : case Token.INC :
case Token.DEC : case Token.DEC :
@ -480,8 +497,8 @@ class Block
// if the lhs & rhs are known to be numbers, we can be sure that's // if the lhs & rhs are known to be numbers, we can be sure that's
// the result, otherwise it could be a string. // the result, otherwise it could be a string.
Node child = n.getFirstChild(); Node child = n.getFirstChild();
int lType = findExpressionType(child); int lType = findExpressionType(child, varTypes);
int rType = findExpressionType(child.getNext()); int rType = findExpressionType(child.getNext(), varTypes);
return lType | rType; // we're not distinguishng strings yet return lType | rType; // we're not distinguishng strings yet
} }
default : { default : {
@ -491,7 +508,7 @@ class Block
else { else {
int result = Optimizer.NoType; int result = Optimizer.NoType;
while (child != null) { while (child != null) {
result |= findExpressionType(child); result |= findExpressionType(child, varTypes);
child = child.getNext(); child = child.getNext();
} }
return result; return result;
@ -500,66 +517,60 @@ class Block
} }
} }
private static boolean findDefPoints(Node n) private static boolean findDefPoints(Node n, int[] varTypes)
{ {
boolean result = false; boolean result = false;
Node child = n.getFirstChild();
switch (n.getType()) { switch (n.getType()) {
default : { default : {
Node child = n.getFirstChild();
while (child != null) { while (child != null) {
result |= findDefPoints(child); result |= findDefPoints(child, varTypes);
child = child.getNext(); child = child.getNext();
} }
} }
break; break;
case Token.DEC : case Token.DEC :
case Token.INC : { case Token.INC : {
Node firstChild = n.getFirstChild(); if (child.getType() == Token.GETVAR) {
if (firstChild.getType() == Token.GETVAR) {
// theVar is a Number now // theVar is a Number now
OptLocalVariable theVar = OptLocalVariable.get(firstChild); int i = getVarIndex(child);
result |= theVar.assignType(Optimizer.NumberType); result |= assignType(varTypes, i, Optimizer.NumberType);
} }
} }
break; break;
case Token.SETPROP : case Token.SETPROP :
case Token.SETPROP_OP : { case Token.SETPROP_OP : {
Node baseChild = n.getFirstChild(); if (child.getType() == Token.GETVAR) {
Node nameChild = baseChild.getNext(); int i = getVarIndex(child);
Node rhs = nameChild.getNext(); assignType(varTypes, i, Optimizer.AnyType);
if (baseChild != null) { }
if (baseChild.getType() == Token.GETVAR) { while (child != null) {
OptLocalVariable theVar = OptLocalVariable.get(baseChild); result |= findDefPoints(child, varTypes);
theVar.assignType(Optimizer.AnyType); child = child.getNext();
}
result |= findDefPoints(baseChild);
} }
if (nameChild != null) result |= findDefPoints(nameChild);
if (rhs != null) result |= findDefPoints(rhs);
} }
break; break;
case Token.SETVAR : { case Token.SETVAR : {
Node firstChild = n.getFirstChild(); Node rValue = child.getNext();
OptLocalVariable theVar = OptLocalVariable.get(n); int theType = findExpressionType(rValue, varTypes);
Node rValue = firstChild.getNext(); int i = getVarIndex(n);
int theType = findExpressionType(rValue); result |= assignType(varTypes, i, theType);
result |= theVar.assignType(theType);
} }
break; break;
} }
return result; return result;
} }
private boolean doTypeFlow(Node[] statementNodes) private boolean doTypeFlow(Node[] statementNodes, int[] varTypes)
{ {
boolean changed = false; boolean changed = false;
for (int i = itsStartNodeIndex; i <= itsEndNodeIndex; i++) { for (int i = itsStartNodeIndex; i <= itsEndNodeIndex; i++) {
Node n = statementNodes[i]; Node n = statementNodes[i];
if (n != null) if (n != null)
changed |= findDefPoints(n); changed |= findDefPoints(n, varTypes);
} }
return changed; return changed;

Просмотреть файл

@ -46,10 +46,6 @@ final class OptLocalVariable implements JavaVariable
{ {
itsName = name; itsName = name;
itsIsParameter = isParameter; itsIsParameter = isParameter;
// If the variable is a parameter, it could have any type.
// If it is from a "var" statement, its typeEvent will be set
// when we see the setVar node.
itsTypeUnion = isParameter ? Optimizer.AnyType : Optimizer.NoType;
} }
static OptLocalVariable get(Node n) static OptLocalVariable get(Node n)
@ -112,15 +108,6 @@ final class OptLocalVariable implements JavaVariable
boolean isParameter() { return itsIsParameter; } boolean isParameter() { return itsIsParameter; }
boolean assignType(int aType) {
itsTypeUnion |= aType;
return itsTypeUnion != aType;
}
int getTypeUnion() {
return itsTypeUnion;
}
private String itsName; private String itsName;
private boolean itsIsParameter; private boolean itsIsParameter;
private int itsIndex = -1; private int itsIndex = -1;
@ -129,7 +116,5 @@ final class OptLocalVariable implements JavaVariable
private boolean itsIsNumber; private boolean itsIsNumber;
private int itsTypeUnion; // the union of all assigned types
private int initPC; private int initPC;
} }