package middlewares; import API.MiddlewareInterface; import common.Block; import common.Code; import common.Instruction; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedList; /** * * @author Eugenio */ public class CodeOtimizadorMiddleware implements MiddlewareInterface { protected Code code; protected HashMap ConstantePropagation = new HashMap<>(); // protected ArrayList filtros = new ArrayList(); protected boolean enable = true; public CodeOtimizadorMiddleware(boolean enabled) { enable = enabled; } // // public void otimizar() throws Exception { // for (Filtros f : filtros) { // f.filtrar(code); // } // } @Override public void Exec(Code c, LinkedHashMap cp) throws Exception { if (!enable) { return; } int index = 0; String dst; Block block = c.Block(); Instruction last = null; LinkedList instructions = block.Instructions(); ArrayList remove = new ArrayList<>(); Iterator interator = block.Instructions().iterator(); // System.out.println("Exec Oti. in block " + block.getName()); while (interator.hasNext()) { Instruction inst = interator.next(); // System.out.println("Otimizando 3 enderecos:" + inst); // System.out.println("CodeOtimizadorMiddleware:" + inst.Get("type")); switch (inst.Get("cat")) { /*Se for uma expressão aritimetica*/ case "exp": switch (inst.Get("op")) { /*Se for uma multiplicacao ou divisao por 1 */ case "*": case "/": if (inst.eq("p1value", "true") && inst.eq("p1", "1")) { inst.Set("format", "copy") .Set("type", "copy") .Set("p1", inst.Get("p2")) .Set("p1value", "false") .R("p2,p2value,op,cat"); } else if (inst.eq("p2value", "true") && inst.eq("p2", "1")) { inst.Set("format", "copy") .Set("type", "copy") .R("p2,p2value,op,cat"); } case "+": } } // System.out.println("CodeOtimizadorProcessor2:" + inst.Get("type")); switch (inst.Get("type")) { case "copy": // System.out.println("Copy:" + inst); if (last != null && last.eq("dst", inst.Get("p1"))) { last.copy("dst", inst); remove.add(inst); } else if (inst.eq("p1value", "true")) { } // if (!inst.eq("copy", "true")) { // if (!inst.isNumber("p1") && ReplaceVarAndRemoveInstruction(instructions, inst, index, block)) { // System.out.println("Remove instruction:" + inst); // remove.add(inst); // } // } else { // System.out.println("COPIA TRUE:" + inst); // } // Se o destino da copia não for indexado então pode executar // o replace da ocorrencia e remover a instrucao de copia // if (!inst.eq("dst.indexed", "true") && inst.eq("p1value", "false")) { // if (!inst.eq("dst.indexed", "true")) { //// System.out.println("Otimizacao - replace " + inst.Get("p1") + " -> " + inst.Get("dst")); // if (inst.eq("p1value", "true")) { // block.ReplaceVar(inst.Get("dst"), inst.Get("p1")); // // } else { // block.ReplaceVar(inst.Get("p1"), inst.Get("dst")); // } // block.CurrentAddress--; // instructions.remove(); // } case "branch": // if (Utils.re) { // inst.Set("type", "jump"); // } break; } // if (inst.Has("dst")) { // dst = inst.Get("dst"); // if (!ConstantePropagation.containsKey(dst)) { // ConstantePropagation.put(dst, new Ocorrences()); // } // ConstantePropagation.get(dst).Add(inst); // } last = inst; index++; } // Instruction inst; // // Process constant propagation // for (Map.Entry entry : ConstantePropagation.entrySet()) { // LinkedList deps = entry.getValue().getDeps(); // // if (deps.size() > 2) { // inst = deps.pollFirst(); // // Marca a instrucao pra remover // remove.add(inst); // inst.Get("p1"); // for (Instruction dep : deps) { // dep.Set("",); // } // } // } if (!remove.isEmpty()) { for (Instruction instruction : remove) { instructions.remove(instruction); } } c.PosicaoLabel = block.BaseAddress; // block.Update(); } private boolean ReplaceVarAndRemoveInstruction(LinkedList instructions, Instruction inst, int index, Block block) { Instruction instruction; if (inst.eq("p1value", "true")) { return false; } int limit = instructions.size(); String p1 = inst.Get("p1"), dst = inst.Get("dst"), attrIndex = ""; // System.out.println("ReplaceVar[" + index + "]:" + ":" + p1 + ":" + dst + "::" + inst + "{"); index++; String[] attrs = {"dst", "p1", "p2"}; while (index < limit) { instruction = instructions.get(index); // System.out.println("instruction:" + instruction); for (String attr : attrs) { if (instruction.contem(attr, dst)) { instruction.Replace(attr, dst, p1); attrIndex = attr + ".index"; if (instruction.Has(attrIndex)) { instruction.Set(attrIndex, p1); } } } index++; } block.Context().Replace(dst, p1); // System.out.println("ReplaceVarAndRemoveInstruction:" + dst + ":" +); // // System.out.println("\t\t" + inst); // System.out.println("}"); return true; } private static class Ocorrences { protected LinkedList deps = new LinkedList<>(); public Ocorrences() { } private void Add(Instruction inst) { deps.add(inst); } public LinkedList getDeps() { return deps; } public void setDeps(LinkedList deps) { this.deps = deps; } } }