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