/* * 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. */ package IntermediaryCode; import API.Instruction; import API.Utils; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.Map; import java.util.regex.Pattern; /** * * @author EUGENIO CARVALHO */ public class BlockOcorrences { protected LinkedHashMap> ocorrences = new LinkedHashMap<>(); protected LinkedHashMap> intervals = new LinkedHashMap<>(); protected int Position = 0; protected int LastPosition = 0; protected Interval interval; protected Pattern addresspattern; protected String name; public BlockOcorrences(String name) { this.name = name; } protected void CloseAllIntervals() { // System.out.println("CloseAllIntervals:"); for (Map.Entry> x : intervals.entrySet()) { interval = x.getValue().peekLast(); // System.out.println("Check interval:" + x.getKey() + Position + ":" + interval); if (interval.Alive(Position)) { // System.out.println("Interval:" + x.getKey() + ":open:" + ocorrences.G(x.getKey()).peekLast()); interval.Close(ocorrences.get(x.getKey()).peekLast()); } } } protected void Register(Instruction x, String attr) { String alias = x.G(attr); if (!OcorrenceFinderProcessor.IsAddress(alias)) { return; } alias = ToAliase(x, attr); // System.out.println("Register x:" + x); ArrayList aliases = new ArrayList<>(); aliases.add(alias); String index = attr + ".indice"; if (x.Has(index) && !x.isNumber(index)) { aliases.add(x.G(index)); } for (String a : aliases) { if (!ocorrences.containsKey(a)) { ocorrences.put(a, new LinkedList()); } ocorrences.get(a).add(Position); if (!Alive(a)) { OpenInterval(a); } } } protected boolean Alive(String alias) { if (intervals.containsKey(alias)) { return Position <= intervals.get(alias).peekLast().End; } return false; } protected void OpenInterval(String alias) { if (!intervals.containsKey(alias)) { intervals.put(alias, new LinkedList()); } // System.out.println("Open interval:(" + alias + "):" + Position + ":" + LastPosition); intervals.get(alias).add(new Interval(Position, LastPosition)); } @Override public String toString() { StringBuilder buffer = new StringBuilder("Block: " + name + "\n"); buffer.append("Inst/Var "); for (int i = 0; i <= LastPosition; i++) { buffer.append(Utils.Pad(i + "", " ", "-", 3)); } buffer.append("\n"); String append, var, reg; Interval inter; for (Map.Entry> x : ocorrences.entrySet()) { var = x.getKey(); buffer.append(Utils.Pad(var, " ", "-", 11)); for (int i = 0; i <= LastPosition; i++) { // System.out.println("OCOR:" +); reg = ""; append = "---"; if (x.getValue().contains(i)) { // append = Get(var, i).getRegister() + "##"; // Ocorrencia da variavel append = "###"; // Ocorrencia da variavel } else if (Inside(var, i)) { append = "+++"; // dentro do intervalo } inter = Get(x.getKey(), i); if (inter != null) { reg = inter.getRegister(); } buffer.append(reg + append.substring(0, append.length() - reg.length())); } buffer.append("\n"); } return buffer.toString(); } public boolean Inside(String var, int i) { return Get(var, i) != null; } public LinkedList Get(String var) { if (!intervals.containsKey(var)) { return null; } return intervals.get(var); } public Interval Last(String addr) { LinkedList itvls = Get(addr); if (itvls != null) { return itvls.peekLast(); } return null; } public Interval Get(String var, int i) { LinkedList intervls = Get(var); if (intervls != null) { for (Interval inter : intervls) { if (inter.Inside(i)) { return inter; } } } return null; } // Busca por um intervalo expirado ou que esteja disponivel para ser subdividido // Retorna a primeira parte intervalo que foi dividido public Interval Spill(int position) { // System.out.println("Spill:[" + position + "]{"); HashMap is = new HashMap<>(); Interval inter = null; String var = ""; for (Map.Entry> I : intervals.entrySet()) { var = I.getKey(); inter = Get(var, position); System.out.println("Interval:" + inter); // Tem intervalo nessa posicao agora deve verificar se ela não ocorre nessa instrucao; if (inter != null && !ocorrences.get(var).contains(position)) { is.put(var, inter); } } inter = null; // System.out.println("Spill disp:" + is.size()); // is Contem todos os intervalos que podem ser divididos; // o intervalo escolhido é o que possui a ocorrencia mais longe int pos = 0, pos1, interpos; for (Map.Entry x : is.entrySet()) { pos1 = FirstAfter(ocorrences.get(x.getKey()), position); if (pos1 > pos) { pos = pos1; var = x.getKey(); inter = x.getValue(); } } // System.out.println("Spill inter:" + var + "|" + inter); // Se encontrou um intervalo para ser dividido executa a divisao if (inter != null) { LinkedList lintervals = intervals.get(var); interpos = lintervals.indexOf(inter); lintervals.add(interpos + 1, new Interval(pos, inter.getEnd())); inter.Close(position); } // System.out.println("End spill}"); return inter; } protected Integer FirstAfter(LinkedList get, int position) { for (Integer integer : get) { if (integer > position) { return integer; } } return 0; } protected static Pattern operators = Pattern.compile("(\\&|\\*)"); public String ToAliase(Instruction x, String attr) { String alias = x.G(attr); String op = x.G("op"); // System.out.println("ToAliase:" + x); boolean isdst = attr.equals("dst"); if (isdst && x.Has("dst.pointer")) { // System.out.println("Has Pointer:"); alias = "*" + alias; } else if (!isdst && operators.matcher(op).matches() && x.eq("type", "pointer_assignment")) { alias = op + alias; } // System.out.println("Aliase:" + alias + ":" + attr + ":" + x); return alias; } }