/* * 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 middlewares; import API.Utils; import common.Instruction; 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 BlockBaseOcorrences { protected LinkedHashMap> ocorrences = new LinkedHashMap<>(); protected LinkedHashMap> intervals = new LinkedHashMap<>(); protected Integer Position = 0; protected Integer leader = 0; protected Integer LastPosition = 0; protected Interval interval; protected Pattern addresspattern; protected String name; public BlockBaseOcorrences(String name, Integer leader) { this.name = name; this.leader = leader; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getLeader() { return leader; } public void setLeader(Integer leader) { this.leader = leader; } public LinkedHashMap> All() { return ocorrences; } protected boolean Alive(String alias) { if (intervals.containsKey(alias)) { return Position <= intervals.get(alias).peekLast().End; } return false; } public boolean Inside(String var, int i) throws Exception { return Get(var, i) != null; } public LinkedList Get(String var) { if (!intervals.containsKey(var)) { return null; } return intervals.get(var); } 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, Position)); } protected void CloseAllIntervals() { LastPosition = Position - 1; // System.out.println("//////// CloseAllIntervals(" + leader + "):" + LastPosition); // Para cada variavel for (Map.Entry> x : intervals.entrySet()) { // Pega o ultimo intervalo interval = x.getValue().peekLast(); // System.out.println("Check interval(" // + interval.Alive(Position) // + "): " // + x.getKey() // + " > " // + Position // + " > " // + interval); if (interval.Alive(LastPosition)) { // System.out.println("Interval:" + x.getKey() + ":open:" + ocorrences.get(x.getKey()).peekLast()); interval.Close(); } } } public void Register(Instruction x, String attr) throws Exception { String alias = x.Get(attr); ArrayList aliases; if (!BasicBlockMiddleware.IsAddress(alias)) { return; } aliases = new ArrayList<>(); alias = ToAliase(x, attr); aliases.add(alias); String index = attr + ".indice"; if (x.Has(index) && !x.isNumber(index)) { aliases.add(x.Get(index)); } for (String a : aliases) { if (!ocorrences.containsKey(a)) { ocorrences.put(a, new LinkedList<>()); } ocorrences.get(a).add(Position); if (!Alive(a)) { OpenInterval(a); } // System.out.println("Register:a, Position," + a + ":" + Position); Get(a, Position).setLastOcorrence(Position); } } public Interval Last(String addr) { LinkedList itvls = Get(addr); if (itvls != null) { return itvls.peekLast(); } return null; } public Interval Get(String var, int i) throws Exception { LinkedList intervls = Get(var); if (intervls != null) { // System.out.println("Encontrei o intervalo de " + var); for (Interval inter : intervls) { // System.out.println("Interval:" + inter + ":" + i); if (inter.Inside(i)) { return inter; } } } // else { // System.out.println("Encontrei o intervalo de " + var); // } return null; // throw new CompileException("Intervalo não definido para a variável %s na posição %d", var, i); } // 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) throws Exception { // 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); // 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: (position:" + position + ") " + 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(), pos)); 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.Get(attr); String op = x.Get("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_assign")) { alias = op + alias; } // System.out.println("Aliase:" + alias + ":" + attr + ":" + x); return alias; } @Override public String toString() { StringBuilder buffer = new StringBuilder("Block: " + name + " - Leader: " + leader + " - Size: " + Position + "\n"); buffer.append("Inst/Var "); // for (int i = 0; i <= Position; i++) { for (int i = 0; i < Position; i++) { buffer.append(Utils.Pad(i + "", " ", "-", 3)); } buffer.append("\n"); String append, var, reg; Interval inter; try { for (Map.Entry> x : ocorrences.entrySet()) { var = x.getKey(); buffer.append(Utils.Pad(var, " ", "-", 11)); // for (int i = 0; i <= Position; i++) { for (int i = 0; i < Position; 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"); } } catch (Exception ex) { // Logger.getLogger(BlockBaseOcorrences.class.getName()).log(Level.SEVERE, null, ex); } return buffer.toString(); } public int getLastPosition() { return getLeader() + Position; } public int getSize() { return Position; } } // protected void Register(Instruction x, String attr) { // String alias = x.Get(attr); // if (!BasicBlockMiddleware.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.Get(index)); // } // for (String a : aliases) { // if (!ocorrences.containsKey(a)) { // ocorrences.put(a, new LinkedList()); // } // // ocorrences.Get(a).add(Position); // if (!Alive(a)) { // OpenInterval(a); // } // } // }