package middlewares; /* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ import API.MiddlewareInterface; import API.Utils; 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; import java.util.Objects; import java.util.regex.Pattern; /** * * @author EUGENIO CARVALHO */ public class BasicBlockMiddleware implements MiddlewareInterface { protected static Integer nextLeader; protected static BlockBaseGroup group; protected static HashMap groups = new HashMap<>(); protected static LinkedHashMap leaders; //OK protected static Block block; protected static ArrayList leadersList; public static Pattern addresspattern = Pattern.compile("\\_[VSTGC].*", Pattern.CASE_INSENSITIVE); protected Integer instructionPosition; protected Integer lastLeader; protected LinkedList instructions; protected Instruction instruction; protected String[] ignore = "label,alloc".split(","), nextIsJump = "jump,label".split(","); public BasicBlockMiddleware() { } protected void SetLeader(Integer position, Integer fix) { // Se existe um leader anterior, atualiza a ultima instrução do bloco basico if (lastLeader >= 0) { leaders.put(lastLeader, (fix == 0 ? (instructionPosition - 1) : instructionPosition)); } // Marca o proximo leader // Se a proxima instrução não foir um jump ou label if (instructions.get(position + 1).in("type", nextIsJump)) { return; } // Seta o novo leader lastLeader = instructionPosition + fix; leaders.put(lastLeader, 0); } @Override public void Exec(Code c, LinkedHashMap cp) throws Exception { String name = c.Block().getName(); BlockBaseGroup g = new BlockBaseGroup(name); block = c.Block(); group = g; groups.put(name, g); instructionPosition = 0; lastLeader = -1; leaders = new LinkedHashMap<>(); //Step 1. Identify the leaders in the code. Leaders are instructions which come under any of the following 3 categories : //The first instruction is a leader. //The target of a conditional or an unconditional goto/jump instruction is a leader. //The instruction that immediately follows a conditional or an unconditional goto/jump instruction is a leader. instructions = block.Instructions(); // Remove da quantidade o label inicial e final Integer limit = instructions.size() - 1; for (int i = 0; i < limit; i++) { instruction = instructions.get(i); // Correcao quando for um salto switch (instruction.Get("type")) { // Ignora a instrução de alocacao de memoria case "alloc": continue; case "label": SetLeader(i, 0); break; // Cria um novo bloco basico case "jump": case "call": case "branch": SetLeader(i, 1); } // Se a instrução não faz parte do grupo de instrucoes // de controle incrementa a posicao do contador if (!instruction.in("type", ignore)) { instructionPosition++; } } leaders.put(lastLeader, instructionPosition); VerifyOcorrences(); System.out.println(group); } protected void RegBasicBlock() { // System.out.println("leaders:" + leaders); // System.out.println("RegBasicBlock:(" + nextLeader + ")(" + ((leaders.Get(nextLeader) - nextLeader) + 1) + ")"); group.RegisterBlock(nextLeader, (leaders.get(nextLeader) - nextLeader)); if (!leadersList.isEmpty()) { nextLeader = leadersList.remove(0); } } public static boolean IsAddress(String alias) { return !Utils.Empty(alias) && addresspattern.matcher(alias).matches(); } public BlockBaseGroup getBasicBlockGroup(String id) { return groups.get(id); } public HashMap getGroups() { return groups; } public static Pattern getAddresspattern() { return addresspattern; } public static void setAddresspattern(Pattern addresspattern) { BasicBlockMiddleware.addresspattern = addresspattern; } protected void VerifyOcorrences() throws Exception { // reseta a posicao da instrução instructionPosition = 0; leadersList = new ArrayList<>(); leaders.entrySet().forEach((entry) -> { leadersList.add(entry.getKey()); }); System.out.println("leadersList:" + leadersList); nextLeader = leadersList.remove(0); // Registra primeiro bloco basico RegBasicBlock(); // Atribui o segundo leder como // block.LastPosition = nextLeader - 1; // System.out.println("$$$$$$$$$$$$$$$$$$$$$$$ Quantidade de instrucoes:" + instructions.size()); // Integer global = 0; for (Iterator it = instructions.iterator(); it.hasNext();) { instruction = it.next(); if (!instruction.in("type", ignore)) { // Registra // System.out.println("Ins:(" + instructionPosition + ")(" + nextLeader + ")"); if (Objects.equals(instructionPosition, nextLeader)) { // System.out.println("#####################Registrei um novo bloco###############"); // block.CloseAllIntervals(); // nextLeader = leadersList.remove(0); // block.LastPosition = nextLeader - 1; RegBasicBlock(); } // Registra os acessos de leitura e escrita dos enderecos da instrucao group.ParseInstruction(instruction, "dst,p1,p2"); // System.out.println("Instruction >>>>>>>> :" + instructionPosition + " real:" + (global)); instructionPosition++; } // global++; } // Finaliza o grupo de blocos group.Close(); // // Atualiza todos os encerramentos de intervalo para a ultima ocorrencia da variavel; // block.CloseAllIntervals(); // System.out.println("block:" + groups); } } // block = new BlockBaseOcorrences(name); // ArrayList> bbs = new ArrayList<>(); // ArrayList bb = null; // basicBlockName = name; // basicBlockCount = 0; // protected ArrayList> basicBlock = new ArrayList<>(); // basicBlocks.put(name, bbs); // blocks.put(name, block);