00001 package edu.ksu.cis.bandera.jjjc.optimizer;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 import java.io.*;
00036 import java.math.*;
00037 import java.util.*;
00038
00039 import edu.ksu.cis.bandera.jjjc.node.*;
00040 import edu.ksu.cis.bandera.jjjc.lexer.*;
00041 import edu.ksu.cis.bandera.jjjc.parser.*;
00042 import edu.ksu.cis.bandera.jjjc.analysis.*;
00043 import edu.ksu.cis.bandera.jjjc.unicodepreprocessor.*;
00044
00045 import ca.mcgill.sable.laleh.java.astfix.*;
00046 import ca.mcgill.sable.soot.jimple.*;
00047
00048 public final class TrivialExpression extends DepthFirstAdapter {
00049 private static TrivialExpression te = new TrivialExpression();
00050 private static boolean number = false;
00051
00052
00053
00054 private TrivialExpression() {
00055 }
00056
00057
00058
00059
00060 public void caseABinaryExp(ABinaryExp node) {
00061 PBinaryOperator op = node.getBinaryOperator();
00062 node.getFirst().apply(this);
00063 node.getSecond().apply(this);
00064
00065 PExp trueValue = new ALiteralExp(new ABooleanLiteralLiteral(new ATrueBooleanLiteral(new TTrue())));
00066 PExp falseValue = new ALiteralExp(new ABooleanLiteralLiteral(new AFalseBooleanLiteral(new TFalse())));
00067 PExp first = getExp(node.getFirst());
00068 PExp second = getExp(node.getSecond());
00069
00070 if (op instanceof AOrBinaryOperator) {
00071 String firstExp = first.toString().trim();
00072 String secondExp = second.toString().trim();
00073 if ("true".equals(firstExp) || "true".equals(secondExp)) {
00074 node.replaceBy(trueValue);
00075 } else if ("false".equals(firstExp)) {
00076 node.replaceBy(node.getSecond());
00077 } else if ("false".equals(secondExp)) {
00078 node.replaceBy(node.getFirst());
00079 }
00080 } else if (op instanceof AAndBinaryOperator) {
00081 String firstExp = first.toString().trim();
00082 String secondExp = second.toString().trim();
00083 if ("false".equals(firstExp) || "false".equals(secondExp)) {
00084 node.replaceBy(falseValue);
00085 } else if ("true".equals(firstExp)) {
00086 node.replaceBy(node.getSecond());
00087 } else if ("true".equals(secondExp)) {
00088 node.replaceBy(node.getFirst());
00089 }
00090 } else if (((op instanceof AGtBinaryOperator) || (op instanceof ALtBinaryOperator)
00091 || (op instanceof ALteqBinaryOperator) || (op instanceof AGteqBinaryOperator)
00092 || (op instanceof AGteqBinaryOperator)) && (first instanceof ALiteralExp)
00093 && (second instanceof ALiteralExp)) {
00094 try {
00095 if (((Boolean) doNumber(op.toString().trim(), ((ALiteralExp) first).getLiteral(),
00096 ((ALiteralExp) second).getLiteral())).booleanValue()) {
00097 node.replaceBy(trueValue);
00098 } else {
00099 node.replaceBy(falseValue);
00100 }
00101 } catch (Exception e) {}
00102 } else if (((op instanceof AEqBinaryOperator) || (op instanceof ANeqBinaryOperator))
00103 && (first instanceof ALiteralExp) && (second instanceof ALiteralExp)) {
00104 try {
00105 if (((Boolean) doNumber(op.toString().trim(), ((ALiteralExp) first).getLiteral(),
00106 ((ALiteralExp) second).getLiteral())).booleanValue()) {
00107 node.replaceBy(trueValue);
00108 } else {
00109 node.replaceBy(falseValue);
00110 }
00111 } catch (Exception e) {
00112 if (first.toString().trim().equals(second.toString().trim())) {
00113 node.replaceBy(trueValue);
00114 } else {
00115 node.replaceBy(falseValue);
00116 }
00117 }
00118 } else if (op instanceof APlusBinaryOperator || op instanceof AMinusBinaryOperator || op instanceof AModBinaryOperator || op instanceof ADivBinaryOperator || op instanceof AStarBinaryOperator || op instanceof ABitXorBinaryOperator || op instanceof ABitAndBinaryOperator || op instanceof AShiftLeftBinaryOperator || op instanceof ASignedShiftRightBinaryOperator || op instanceof AUnsignedShiftRightBinaryOperator || op instanceof ABitOrBinaryOperator) {
00119 if (number)
00120 try {
00121 Object o = doNumber(op.toString().trim(), ((ALiteralExp) first).getLiteral(),
00122 ((ALiteralExp) second).getLiteral());
00123
00124 if (o instanceof Double) {
00125 String str = "" + ((Double) o).doubleValue();
00126 node.replaceBy(new ALiteralExp(new AFloatingPointLiteralLiteral(new TFloatingPointLiteral(str))));
00127 } else if (o instanceof Long) {
00128 String str = "" + ((Long) o).longValue() + "L";
00129 node.replaceBy(new ALiteralExp(new AIntegerLiteralLiteral(new ADecimalIntegerLiteral(new TDecimalIntegerLiteral(str)))));
00130 }
00131 } catch (Exception e) {}
00132 }
00133 }
00134
00135
00136
00137
00138
00139
00140
00141 private Object doNumber(String op, double first, double second) throws Exception {
00142 if ("==".equals(op)) {
00143 return new Boolean(first == second);
00144 } else if ("!=".equals(op)) {
00145 return new Boolean(first != second);
00146 } else if (">=".equals(op)) {
00147 return new Boolean(first >= second);
00148 } else if ("<=".equals(op)) {
00149 return new Boolean(first <= second);
00150 } else if (">".equals(op)) {
00151 return new Boolean(first > second);
00152 } else if ("<".equals(op)) {
00153 return new Boolean(first < second);
00154 } else if ("+".equals(op)) {
00155 return new Double(first + second);
00156 } else if ("-".equals(op)) {
00157 return new Double(first - second);
00158 } else if ("%".equals(op)) {
00159 return new Double(first % second);
00160 } else if ("/".equals(op)) {
00161 return new Double(first / second);
00162 } else if ("*".equals(op)) {
00163 return new Double(first * second);
00164 } else {
00165 throw new Exception();
00166 }
00167 }
00168
00169
00170
00171
00172
00173
00174
00175 private Object doNumber(String op, double first, long second) throws Exception {
00176 return doNumber(op, first, (double) second);
00177 }
00178
00179
00180
00181
00182
00183
00184
00185 private Object doNumber(String op, long first, double second) throws Exception {
00186 return doNumber(op, (double) first, second);
00187 }
00188
00189
00190
00191
00192
00193
00194
00195 private Object doNumber(String op, long first, long second) throws Exception {
00196 if ("==".equals(op)) {
00197 return new Boolean(first == second);
00198 } else if ("!=".equals(op)) {
00199 return new Boolean(first != second);
00200 } else if (">=".equals(op)) {
00201 return new Boolean(first >= second);
00202 } else if ("<=".equals(op)) {
00203 return new Boolean(first <= second);
00204 } else if (">".equals(op)) {
00205 return new Boolean(first > second);
00206 } else if ("<".equals(op)) {
00207 return new Boolean(first < second);
00208 } else if ("+".equals(op)) {
00209 return new Long(first + second);
00210 } else if ("-".equals(op)) {
00211 return new Long(first - second);
00212 } else if ("%".equals(op)) {
00213 return new Long(first % second);
00214 } else if ("/".equals(op)) {
00215 return new Long(first / second);
00216 } else if ("*".equals(op)) {
00217 return new Long(first * second);
00218 } else if ("^".equals(op)) {
00219 return new Long(first ^ second);
00220 } else if ("&".equals(op)) {
00221 return new Long(first & second);
00222 } else if ("<<".equals(op)) {
00223 return new Long(first << second);
00224 } else if (">>".equals(op)) {
00225 return new Long(first >> second);
00226 } else {
00227 return new Long(first >>> second);
00228 }
00229 }
00230
00231
00232
00233
00234
00235
00236
00237 private Object doNumber(String op, PLiteral first, PLiteral second) throws Exception {
00238 Node node1, node2;
00239
00240 if (first instanceof AIntegerLiteralLiteral) {
00241 node1 = ((AIntegerLiteralLiteral) first).getIntegerLiteral();
00242 } else {
00243 node1 = ((AFloatingPointLiteralLiteral) first).getFloatingPointLiteral();
00244 }
00245
00246 if (second instanceof AIntegerLiteralLiteral) {
00247 node2 = ((AIntegerLiteralLiteral) second).getIntegerLiteral();
00248 } else {
00249 node2 = ((AFloatingPointLiteralLiteral) second).getFloatingPointLiteral();
00250 }
00251
00252 Number number1 = getNumber(node1);
00253 Number number2 = getNumber(node2);
00254
00255 long longValue1 = 0, longValue2 = 0;
00256 double doubleValue1 = 0.0, doubleValue2 = 0.0;
00257 boolean isDouble1, isDouble2;
00258
00259 if (number1 instanceof Double) {
00260 isDouble1 = true;
00261 doubleValue1 = number1.doubleValue();
00262 } else {
00263 isDouble1 = false;
00264 longValue1 = number1.longValue();
00265 }
00266
00267 if (number2 instanceof Double) {
00268 isDouble2 = true;
00269 doubleValue2 = number2.doubleValue();
00270 } else {
00271 isDouble2 = false;
00272 longValue2 = number2.longValue();
00273 }
00274
00275 if (isDouble1) {
00276 if (isDouble2)
00277 return doNumber(op, doubleValue1, doubleValue2);
00278 else
00279 return doNumber(op, doubleValue1, longValue2);
00280 } else {
00281 if (isDouble2)
00282 return doNumber(op, longValue1, doubleValue2);
00283 else
00284 return doNumber(op, longValue1, longValue2);
00285 }
00286 }
00287
00288
00289
00290
00291
00292 private PExp getExp(PExp exp) {
00293 PExp result = exp;
00294
00295 while (result instanceof AParExp)
00296 result = ((AParExp) result).getExp();
00297
00298 return result;
00299 }
00300
00301
00302
00303
00304
00305 private Number getNumber(Node literal) throws Exception {
00306 Number result;
00307
00308 if (literal instanceof ADecimalIntegerLiteral) {
00309 String lit = literal.toString().trim();
00310 if (lit.endsWith("L") || lit.endsWith("l")) {
00311 result = Long.valueOf(lit.substring(0, lit.length() - 1));
00312 } else {
00313 result = Integer.valueOf(lit);
00314 }
00315 } else if (literal instanceof AOctalIntegerLiteral) {
00316 String lit = literal.toString().substring(1).trim();
00317 if (lit.endsWith("L") || lit.endsWith("l")) {
00318 result = new Long((new BigInteger(lit.substring(0, lit.length() - 1), 8)).longValue());
00319 } else {
00320 result = new Integer(Long.valueOf(lit, 8).intValue());
00321 }
00322 } else if (literal instanceof AHexIntegerLiteral) {
00323 String lit = literal.toString().substring(2).trim();
00324 if (lit.endsWith("L") || lit.endsWith("l")) {
00325 result = new Long((new BigInteger(lit.substring(0, lit.length() - 1), 16)).longValue());
00326 } else {
00327 result = new Integer(Long.valueOf(lit, 16).intValue());
00328 }
00329 } else if (literal instanceof TFloatingPointLiteral) {
00330 String lit = literal.toString().trim();
00331 if (lit.endsWith("F") || lit.endsWith("f")) {
00332 result = Float.valueOf(lit);
00333 } else {
00334 result = Double.valueOf(lit);
00335 }
00336 } else throw new Exception();
00337
00338 return result;
00339 }
00340
00341
00342
00343
00344 public static void optimize(Node node) {
00345 number = false;
00346 node.apply(te);
00347 }
00348
00349
00350
00351
00352
00353 public static void optimize(Node node, boolean doNumberOperation) {
00354 number = doNumberOperation;
00355 node.apply(te);
00356 }
00357 }