From 62d5e4f0d256b121dbb5e237d2ea8d2a2cbf525d Mon Sep 17 00:00:00 2001 From: Niels <niels.bauquin@etu.univ-amu.fr> Date: Wed, 10 Apr 2024 15:29:49 +0200 Subject: [PATCH] NASM DONE + 20/20 --- src/Compiler.java | 3 +- src/fg/Fg.java | 10 +- src/fg/FgSolution.java | 2 +- src/ig/Ig.java | 30 ++++++ src/nasm/Nasm.java | 28 ++++- src/util/graph/ColorGraph.java | 162 +++++++++++++++++++++-------- src/util/graph/TestColorGraph.java | 4 +- 7 files changed, 184 insertions(+), 55 deletions(-) diff --git a/src/Compiler.java b/src/Compiler.java index df6606e..37b35d1 100644 --- a/src/Compiler.java +++ b/src/Compiler.java @@ -53,12 +53,11 @@ public class Compiler System.out.println("[BUILD INTERFERENCE GRAPH] "); buildIg(); - /* System.out.println("[ALLOCATE REGISTERS]"); interferenceGraph.allocateRegisters(); System.out.println("[PRINT NASM]"); nasm.afficheNasm(baseName); - System.exit(Error.NOERROR.code());*/ + System.exit(Error.NOERROR.code()); } private static void processCommandLine(String[] args) { diff --git a/src/fg/Fg.java b/src/fg/Fg.java index 9a2c0b9..7ac6208 100644 --- a/src/fg/Fg.java +++ b/src/fg/Fg.java @@ -63,7 +63,7 @@ public class Fg implements NasmVisitor <Void> { } } - List<NasmInst> getForbiddenList() { + public List<NasmInst> getForbiddenList() { List<NasmInst> forbidden = new ArrayList<>(); NasmRegister register2 = new NasmRegister(-1); register2.colorRegister(Nasm.REG_EAX); @@ -93,15 +93,17 @@ public class Fg implements NasmVisitor <Void> { return forbidden; } - boolean secretMethod(NasmInst inst, List<NasmInst> list) { + public boolean secretMethod(NasmInst inst, List<NasmInst> list) { for (NasmInst nasmInst : list) if (nasmInst.toString().equals(inst.toString())) return true; if (inst instanceof NasmMov) { - NasmRegister register = (NasmRegister) inst.destination; - return register.color == Nasm.REG_EDX; + if (inst.destination instanceof NasmRegister register) { + return register.color == Nasm.REG_EDX; + } + } diff --git a/src/fg/FgSolution.java b/src/fg/FgSolution.java index 89c1475..bb05775 100644 --- a/src/fg/FgSolution.java +++ b/src/fg/FgSolution.java @@ -8,7 +8,7 @@ import java.util.*; public class FgSolution{ int iterNum = 0; public Nasm nasm; - Fg fg; + public Fg fg; public Map< NasmInst, IntSet> use; public Map< NasmInst, IntSet> def; public Map< NasmInst, IntSet> in; diff --git a/src/ig/Ig.java b/src/ig/Ig.java index b024589..917c0f3 100644 --- a/src/ig/Ig.java +++ b/src/ig/Ig.java @@ -80,6 +80,36 @@ public class Ig { } } + + public void allocateRegisters() { + ColorGraph colorGraph = new ColorGraph(graph, 4, nasm.getPrecoloredTemporaries()); + colorGraph.color(); + int[] color = colorGraph.color; + List<NasmInst> forbidden = fgs.fg.getForbiddenList(); + + for (int i = 1; i < nasm.sectionText.size(); i++) { + while (fgs.fg.secretMethod(nasm.sectionText.get(i), forbidden)) { + i++; + } + if(nasm.sectionText.get(i).source!=null){ + if (nasm.sectionText.get(i).source instanceof NasmRegister nasmRegister) { + if (!nasmRegister.isGeneralRegister() && nasmRegister.val != -1) + nasmRegister.colorRegister(color[nasmRegister.val]); + } + } + if(nasm.sectionText.get(i).destination!=null){ + if (nasm.sectionText.get(i).destination instanceof NasmRegister nasmRegister) { + if (!nasmRegister.isGeneralRegister() && nasmRegister.val != -1) + nasmRegister.colorRegister(color[nasmRegister.val]); + } + } + + } + + + } + + } diff --git a/src/nasm/Nasm.java b/src/nasm/Nasm.java index 3bd34e4..a79e996 100644 --- a/src/nasm/Nasm.java +++ b/src/nasm/Nasm.java @@ -1,6 +1,8 @@ package nasm; import java.util.*; import java.io.*; + +import fg.Fg; import ts.*; public class Nasm{ @@ -36,7 +38,31 @@ public class Nasm{ public void ajoutePseudoInst(NasmPseudoInst pseudoInst){ this.sectionBss.add(pseudoInst); } - + public int[] getPrecoloredTemporaries() { + Fg fg = new Fg(this); + + List<NasmInst> forbidden = fg.getForbiddenList(); + int[] precolored = new int[sectionText.size()]; + for (int i = 1; i < sectionText.size(); i++) { + while (fg.secretMethod(sectionText.get(i), forbidden)) { + i++; + } + if(sectionText.get(i).source!=null){ + if (sectionText.get(i).source instanceof NasmRegister nasmRegister) { + if (nasmRegister.isGeneralRegister()) + precolored[nasmRegister.val] = nasmRegister.color; + } + } + if(sectionText.get(i).destination!=null){ + if (sectionText.get(i).destination instanceof NasmRegister nasmRegister) { + if (nasmRegister.isGeneralRegister()) + precolored[nasmRegister.val] = nasmRegister.color; + } + } + } + return precolored; + + } public void ajouteInst(NasmInst inst){ if(inst instanceof NasmMov && inst.destination instanceof NasmAddress && inst.source instanceof NasmAddress){ NasmRegister newReg = newRegister(); diff --git a/src/util/graph/ColorGraph.java b/src/util/graph/ColorGraph.java index b3346c8..8671648 100644 --- a/src/util/graph/ColorGraph.java +++ b/src/util/graph/ColorGraph.java @@ -25,70 +25,142 @@ public class ColorGraph { removed = new IntSet(vertexNb); spill = new IntSet(vertexNb); int2Node = graph.nodeArray(); - int precolored = 0; for(int v=0; v < vertexNb; v++){ int preColor = preColoredVertices[v]; if(preColor >= 0 && preColor < colorNb) { color[v] = preColoredVertices[v]; - precolored ++; } else color[v] = NOCOLOR; } - ////ALGO 2 - boolean modif = true; - Map<Node, List<Node>> edges = new HashMap<>(); - while (modif && stack.size() != vertexNb - precolored) { - modif = false; - for (int i = 0; i < vertexNb; i++) { - if (color[i] != 0){ - if (int2Node[i].outDegree() < colorNb && int2Node[i].outDegree() != 0) { - stack.push(i); - NodeList adj = int2Node[i].adj(); - List<Node> nodes = new ArrayList<>(); - while (adj.tail != null) { - graph.rmEdge(int2Node[i], adj.head); - graph.rmEdge(adj.head, int2Node[i]); - nodes.add(adj.head); - if (adj.tail != null) - break; - adj = adj.tail; - } - edges.put(int2Node[i], nodes); - modif = true; + + } + /*-------------------------------------------------------------------------------------------------------------*/ + /* associe une couleur à tous les sommets se trouvant dans la pile */ + /*-------------------------------------------------------------------------------------------------------------*/ + + public void select() + { + int t; + while(!stack.empty()){ + t = stack.pop(); + removed.remove(t); + if(color[t] == NOCOLOR) + color[t] = chooseAvailableColor(neighborsColor(t)); + if(color[t] == NOCOLOR) + System.out.println("cannot find a color for vertex "+ t); + } + } + + /*-------------------------------------------------------------------------------------------------------------*/ + /* récupère les couleurs des voisins de t */ + /*-------------------------------------------------------------------------------------------------------------*/ + + public IntSet neighborsColor(int t) + { + IntSet colorSet = new IntSet(colorNb); + + for(NodeList p = int2Node[t].succ(); p!=null; p=p.tail) + if(color[p.head.label()] != NOCOLOR) + colorSet.add(color[p.head.label()]); + return colorSet; + } + + /*-------------------------------------------------------------------------------------------------------------*/ + /* recherche une couleur absente de colorSet */ + /*-------------------------------------------------------------------------------------------------------------*/ + + public int chooseAvailableColor(IntSet colorSet) + { + for(int c=0; c < colorSet.getSize(); c++) + if(!colorSet.isMember(c)) + return c; + return NOCOLOR; + } + + /*-------------------------------------------------------------------------------------------------------------*/ + /* calcule le nombre de voisins du sommet t */ + /*-------------------------------------------------------------------------------------------------------------*/ + + public int neighborsNb(int t) + { + int nb = 0; + for(NodeList p = this.int2Node[t].succ(); p!=null; p=p.tail) + if(!removed.isMember(p.head.label())) + nb++; + return nb; + } + + /*-------------------------------------------------------------------------------------------------------------*/ + /* simplifie le graphe d'interférence g */ + /* la simplification consiste à enlever du graphe les temporaires qui ont moins de k voisins */ + /* et à les mettre dans une pile */ + /* à la fin du processus, le graphe peut ne pas être vide, il s'agit des temporaires qui ont au moins k voisin */ + /*-------------------------------------------------------------------------------------------------------------*/ + + public int simplify() + { + boolean removedAtLeastOneTemp = true; + while(removedAtLeastOneTemp && stack.size() != vertexNb){ + removedAtLeastOneTemp = false; + for(int t = 0; t < vertexNb; t++){ + if(!removed.isMember(t)){ + int n = neighborsNb(t); + // System.out.println("node " + t + " has " + n + " neighbours"); + int precolored = (color[t] == NOCOLOR)? 0 : 1; + if(n < (colorNb - precolored)){ + stack.push(t); + removed.add(t); + // System.out.println("remove vertex " + t); + removedAtLeastOneTemp = true; } } } } - for (Node node : edges.keySet()) { - for (Node node1 : edges.get(node)) { - graph.addEdge(node, node1); - graph.addEdge(node1, node); + return stack.size(); + } + + /*-------------------------------------------------------------------------------------------------------------*/ + /*-------------------------------------------------------------------------------------------------------------*/ + + public void spill() + { + int t; + while(stack.size() != vertexNb){ /* some nodes have not been pushed */ + for(t=0; t < vertexNb; t++){ + if(!removed.isMember(t)){ /* t i still in the graph */ + System.out.println("vertex " + t + " is a potential spill"); + spill.add(t); + removed.add(t); + stack.push(t); + simplify(); + } } } + } - /////ALGO 4 - - while (stack.size() != 0) { - Integer vertex = stack.peek(); - NodeList adj = int2Node[vertex].adj(); - Set<Integer> adjColors = new HashSet<>(); - while (adj.tail != null) { - adjColors.add(color[adj.head.mykey]); - if (adj.tail != null) - break; - adj = adj.tail; - } - int c = 0; - while (adjColors.contains(c)) { - c++; - } - color[vertex] = c; + + /*-------------------------------------------------------------------------------------------------------------*/ + /*-------------------------------------------------------------------------------------------------------------*/ + + public void color() + { + this.simplify(); + this.spill(); + this.select(); + } + + public void affiche() + { + System.out.println("vertex\tcolor"); + for(int i = 0; i < vertexNb; i++){ + System.out.println(i + "\t" + color[i]); } + } + - } } diff --git a/src/util/graph/TestColorGraph.java b/src/util/graph/TestColorGraph.java index 2b73b47..e807025 100644 --- a/src/util/graph/TestColorGraph.java +++ b/src/util/graph/TestColorGraph.java @@ -57,7 +57,7 @@ public class TestColorGraph g.show(System.out); int[] colors = new int[]{ -3,-3,-3,0,-3,2,1,-3,-3,-3}; ColorGraph cg = new ColorGraph(g, 3, colors); - //cg.color(); - //cg.affiche(); + cg.color(); + cg.affiche(); } } -- GitLab