/* * This file is part of JOP, the Java Optimized Processor * see <http://www.jopdesign.com/> * * Copyright (C) 2011, Stefan Hepp (stefan@stefant.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.jopdesign.jcopter.optimizer; import com.jopdesign.common.MethodInfo; import com.jopdesign.jcopter.JCopter; import org.apache.bcel.generic.GOTO; import org.apache.bcel.generic.IfInstruction; import org.apache.bcel.generic.InstructionHandle; import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionTargeter; import org.apache.bcel.generic.TargetLostException; import org.apache.bcel.util.InstructionFinder; import org.apache.bcel.util.InstructionFinder.CodeConstraint; import org.apache.log4j.Logger; import java.util.Iterator; /** * @author Stefan Hepp (stefan@stefant.org) */ public class PeepholeOptimizer extends AbstractOptimizer { private static final Logger logger = Logger.getLogger(JCopter.LOG_OPTIMIZER+".PeepholeOptimizer"); private long matchBoolExpressions; public PeepholeOptimizer(JCopter jcopter) { super(jcopter); } @Override public void initialize() { matchBoolExpressions = 0; } @Override public void optimizeMethod(MethodInfo method) { InstructionList il = method.getCode().getInstructionList(); // BCEL Example optimization optimizeBoolExpressions(il); } @Override public void printStatistics() { logger.info("Boolean Expressions optimized: "+matchBoolExpressions); } /** * Optimize some boolean expressions. * <p> * This code is taken directly from the BCEL manual, chapter 3.3.8. * </p> * * @param il the instruction list to optimize. */ private void optimizeBoolExpressions(InstructionList il) { InstructionFinder f = new InstructionFinder(il); String pat = "IfInstruction ICONST_0 GOTO ICONST_1 NOP(IFEQ|IFNE)"; CodeConstraint constraint = new CodeConstraint() { @Override public boolean checkCode(InstructionHandle[] match) { IfInstruction if1 = (IfInstruction)match[0].getInstruction(); GOTO g = (GOTO)match[2].getInstruction(); return (if1.getTarget() == match[3]) && (g.getTarget() == match[4]); } }; for(Iterator e = f.search(pat, constraint); e.hasNext(); ) { InstructionHandle[] match = (InstructionHandle[])e.next(); IfInstruction if1 = (IfInstruction)match[0].getInstruction(); IfInstruction if2 = (IfInstruction)match[5].getInstruction(); if1.setTarget(if2.getTarget()); // Update target try { il.delete(match[1], match[5]); } catch(TargetLostException ex) { for (InstructionHandle target : ex.getTargets()) { for (InstructionTargeter t : target.getTargeters()) { t.updateTarget(target, match[0]); } } } matchBoolExpressions++; } } }