/* Soot - a J*va Optimization Framework * Copyright (C) 2005 Nomair A. Naeem * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ package soot.dava.toolkits.base.AST.transformations; import soot.dava.toolkits.base.AST.analysis.*; import soot.dava.internal.javaRep.*; import soot.dava.internal.AST.*; import soot.*; import soot.jimple.*; /* TO MAKE CODE EFFECIENT BLOCK THE ANALYSIS TO GOING INTO STATEMENTS this is done by overriding the caseASTStatementSequenceNode */ public class BooleanConditionSimplification extends DepthFirstAdapter{ public BooleanConditionSimplification(boolean verbose){ super(verbose); } public void caseASTStatementSequenceNode(ASTStatementSequenceNode node){ } public BooleanConditionSimplification(){ } /* The method checks whether a particular ASTBinaryCondition is a comparison of a local with a boolean If so the ASTBinaryCondition is replaced by a ASTUnaryCondition */ public void outASTIfNode(ASTIfNode node){ ASTCondition condition = node.get_Condition(); if(condition instanceof ASTBinaryCondition){ ConditionExpr condExpr = ((ASTBinaryCondition)condition).getConditionExpr(); Value unary = checkBooleanUse(condExpr); if(unary != null){ node.set_Condition(new ASTUnaryCondition(unary)); } } } public void outASTIfElseNode(ASTIfElseNode node){ ASTCondition condition = node.get_Condition(); if(condition instanceof ASTBinaryCondition){ ConditionExpr condExpr = ((ASTBinaryCondition)condition).getConditionExpr(); Value unary = checkBooleanUse(condExpr); if(unary != null){ node.set_Condition(new ASTUnaryCondition(unary)); } } } public void outASTWhileNode(ASTWhileNode node){ ASTCondition condition = node.get_Condition(); if(condition instanceof ASTBinaryCondition){ ConditionExpr condExpr = ((ASTBinaryCondition)condition).getConditionExpr(); Value unary = checkBooleanUse(condExpr); if(unary != null){ node.set_Condition(new ASTUnaryCondition(unary)); } } } public void outASTDoWhileNode(ASTDoWhileNode node){ ASTCondition condition = node.get_Condition(); if(condition instanceof ASTBinaryCondition){ ConditionExpr condExpr = ((ASTBinaryCondition)condition).getConditionExpr(); Value unary = checkBooleanUse(condExpr); if(unary != null){ node.set_Condition(new ASTUnaryCondition(unary)); } } } private Value checkBooleanUse(ConditionExpr condition){ //check whether the condition qualifies as a boolean use if(condition instanceof NeExpr || condition instanceof EqExpr){ Value op1 = condition.getOp1(); Value op2 = condition.getOp2(); if(op1 instanceof DIntConstant){ Type op1Type = ((DIntConstant)op1).type; if( op1Type instanceof BooleanType){ return decideCondition(op2,((DIntConstant)op1).toString(),condition); } } else if(op2 instanceof DIntConstant){ Type op2Type = ((DIntConstant)op2).type; if( op2Type instanceof BooleanType){ return decideCondition(op1,((DIntConstant)op2).toString(),condition); } } else return null;//meaning no Value used as boolean found } return null; //meaning no local used as boolean found } /* Used to decide what the condition should be if we are converting from ConditionExpr to Value A != false/0 --> A A != true/1 --> !A A == false/0 --> !A A == true/1 --> A */ private Value decideCondition(Value A, String truthString, ConditionExpr condition){ int truthValue =0; boolean notEqual=false; //find out whether we are dealing with a false or true if(truthString.compareTo("false")==0) truthValue=0; else if(truthString.compareTo("true")==0) truthValue=1; else throw new RuntimeException(); //find out whether the comparison operator is != or == if(condition instanceof NeExpr ){ notEqual=true; } else if( condition instanceof EqExpr){ notEqual=false; } else throw new RuntimeException(); //decide and return if( notEqual && truthValue==0){ //A != false -->A return A; } else if(notEqual && truthValue==1){//A != true --> !A if(A instanceof DNotExpr){//A is actually !B return ((DNotExpr)A).getOp(); } else return (new DNotExpr(A)); } else if(!notEqual && truthValue==0){//A == false --> !A if(A instanceof DNotExpr){//A is actually !B return ((DNotExpr)A).getOp(); } else return new DNotExpr(A); } else if(!notEqual && truthValue==1){//A == true --> A return A; } else throw new RuntimeException(); } }