/* * 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.AppInfo; import com.jopdesign.common.ClassInfo; import com.jopdesign.common.MethodInfo; import com.jopdesign.common.graphutils.ClassVisitor; import com.jopdesign.jcopter.JCopter; import com.jopdesign.jcopter.JCopterConfig; import java.util.Collection; import java.util.TreeMap; /** * This is the root class for simple intraprocedural optimizations, which provides some basic checks * if classes and methods should be optimized and iterates over all non-abstract methods. * * @author Stefan Hepp (stefan@stefant.org) */ public abstract class AbstractOptimizer implements ClassVisitor { private final JCopter jcopter; private final boolean iterateSorted; private final AppInfo appInfo; public AbstractOptimizer(JCopter jcopter) { this(jcopter, false); } public AbstractOptimizer(JCopter jcopter, boolean iterateSorted) { this.jcopter = jcopter; this.iterateSorted = iterateSorted; this.appInfo = AppInfo.getSingleton(); } public JCopter getJCopter() { return jcopter; } public JCopterConfig getJConfig() { return jcopter.getJConfig(); } public void optimize() { initialize(); if (appInfo.hasCallGraph()) { Collection<MethodInfo> methods = appInfo.getCallGraph().getMethodInfos(); if (iterateSorted) { // little hack to make the DFA cache hack more deterministic TreeMap<String, MethodInfo> temp = new TreeMap<String, MethodInfo>(); for (MethodInfo method : methods) { temp.put(method.getFQMethodName(), method); } methods = temp.values(); } for (MethodInfo method : methods) { if (appInfo.isHwObject(method.getClassInfo())) { // Do not optimize Hardware Objects, leave them alone! continue; } if (method.hasCode()) { optimizeMethod(method); } } } else { if (iterateSorted) { TreeMap<String, ClassInfo> temp = new TreeMap<String, ClassInfo>(); for (ClassInfo cls : appInfo.getClassInfos()) { temp.put(cls.getClassName(), cls); } for (ClassInfo cls: temp.values()) { visitClass(cls); } } else { appInfo.iterate(this); } } printStatistics(); } @Override public final boolean visitClass(ClassInfo classInfo) { if (appInfo.isHwObject(classInfo)) { // Do not optimize Hardware Objects, leave them alone! return false; } Collection<MethodInfo> methods = classInfo.getMethods(); if (iterateSorted) { // little hack to make the DFA cache hack more deterministic TreeMap<String, MethodInfo> temp = new TreeMap<String, MethodInfo>(); for (MethodInfo method : methods) { temp.put(method.getMethodSignature(), method); } methods = temp.values(); } for (MethodInfo method : methods) { if (method.hasCode()) { optimizeMethod(method); } } return true; } @Override public final void finishClass(ClassInfo classInfo) { } public abstract void initialize(); public abstract void optimizeMethod(MethodInfo method); public abstract void printStatistics(); }