 Welcome to part 3 of the lecture on global register allocation. So, in part 1 we looked at the issues in global register allocation and we also discussed the definition of what is global register location and the problem itself. We also saw register allocation for loops which is based on the principle of usage counts that was in part 2 and a very fast linear scan register location was also discussed. Now, we today we are going to discuss graph coloring algorithm based algorithm due to chat in. So, this is probably the most complicated and most efficient register location scheme that is possible for programs. The formulation of the problem is based on graph coloring and the graph underlying the problem is what is known as the interference graph. So, when we say a interference graph we also need to mention which are the nodes and which are the edges in the interference graph nodes in the graph or either the live ranges of variables or entities called webs. So, we know what live ranges are these are the points at which the a particular variable is live. So, from the definition you know to the last use of that particular definition. So, that is called as a live range. So, nodes in the graph represent live ranges of variables webs or extensions of these and will not deal with them in this lecture. An edge connects two live ranges that interfere or conflict with one another. So, basically if there are two variables and both of them are active in the program at the same time it is very clear that we cannot assign the same register to both these variables. So, the same concept can be extended to the live ranges. So, if there are two live ranges which are active at the same time they are said to interfere or conflict with one another. So, we add an edge in the interference graph between two nodes which are conflicting. And as I mentioned in the last part we require both the adjacency matrix and the adjacency list to represent the graph. The basic idea is to assign colors to the nodes such that no two nodes connected by an edge or you know assign the same color. So, you know if we assign the same color it implies that we are assigning the same register that is the reason why interfering nodes cannot be assigned the same color. The number of colors available is the number of registers in the machine and k coloring of the interference graph can be mapped on to a graph you know a register location problem with k registers. So, I showed you this example in the last part also this is a two colorable graph that means the program corresponding to this graph actually uses only two registers and the allocation of the registers is in this fashion. The variable corresponding to this will be given a register corresponding to this violet rather light pink color. This is also given the same register this live range, but these two live ranges are given a different register this is a three colorable program or the interference graph corresponding to the program and it is similar in you know spirit. So, these two are given the same register these two live ranges are given the same register and this is given a different register. So, what is the idea behind Chaitin's algorithm? Basically the idea behind Chaitin's algorithm is one of you know a graph reduction. So, by graph reduction we mean picking up the arbitrary nodes of the graph which have which have degree less than k you know and then we remove the nodes. So, typically we pick an arbitrary node of degree less than k and first put it on the stack. So, that is what this says. So, why degree less than k and why not equal to or greater that would be the question. We will see the reason for this very soon, but basically the idea is if we remove any arbitrary node of degree less than k and then color the graph of with the remaining nodes and edges then we can show that it is possible to color the original graph with this node and the corresponding edges included. So, when we remove the vertex we have to remove all the edges connected to that vertex as well and this process may decrease the edges of some other nodes and cause more nodes to have degree less than k. So, this is a repetitive process we go on doing it and we reach a point where there are no more nodes in the graph. So, that is one possibility that if we reach that stage then you know we can simply color the nodes appropriately. We will see how with an example and the other possibility is at some point all the vertices have degree greater than or equal to k. So, in this case we cannot continue the reduction process further and we have to resort to what is known as spilling. So, spilling implies that the live range or the variable corresponding to that particular node will not be assigned a register, but it will be actually placed in memory location all the time. So, it is not going to get a register at all. So, if a vertex actually gets spilled then you know we are going to remove the vertex from the graph as if it was a reduction process and then continue further. So, let us look at this simple example to begin with the stack is empty we have this small interference graph and let us assume that there are three registers. That means, for the reduction process we must look at those nodes which have degree you know two or less. So, node one has degree two this node has degree three. So, that is not eligible for the reduction the same is true for three as well four also has degree three and five also has degree three. So, we are actually you know restricted to node number one. So, when we remove node number one the two edges corresponding to this node number one attached to it are also removed and node number one is going to be placed on stack. So, one is placed on stack. So, the dotted edges imply that they have been removed. Now, node number two and node number three have just two edges each because the third one is gone. So, we can pick either node two or node three and continue with the reduction operation. So, let us choose node number two remove node two and the two edges you know attached to it. So, that leaves us with the graph of three nodes three four and five each of the nodes in this small graph actually have just degree two. So, any one of them can be chosen for the reduction process for the next step in the reduction process. So, we choose four we remove four and the two edges related to it four is put on the stack. So, we have three and five. So, we remove three put it on stack remove the edge you know related to it we have just node number five. So, five can also be removed and placed on the stack now the graph is empty. So, this is a completely you know reduce it could be reduced completely. So, the graph can be colored with three registers the process of coloring the graph starts in the order of nodes placed you know in the reverse order of the nodes that have been placed on the graph. That means we start coloring with five then go to three four two and one let us see how it proceeds. So, we pick node number five and that is restored to the graph. So, and we assign a color to it there are three colors that we have. So, node number five is given a particular color say green right. So, that is allocating it a register now restore node number three and the edge with it. So, we have three it cannot be given the same color as five. So, we have we pick another color from the free colors here and then assign the color to three then number four is reintroduced into the graph along with it adjust. So, it is connected to both three and five. So, we need a third color for four which is available assign that to node number four. Now, two is introduced two is connected to four and five. So, we must give a color which is different from that of four and five and that can be brown. Now, we introduce one again one is connected to both two and three. So, you cannot actually give the color of either two or three we can give one of the free colors. So, usually we try to you know assign a color which is more frequently used. So, that is four. So, we assign one to it and that completes our example. So, let us look at the steps in Chaitin's algorithm in more detail. The first step is to identify the units for allocation. So, in doing this there is a process of renaming the variables which have to be undertaken. So, it is possible that the same definition you know same variable has more than one live range attached to it. In other words it is possible that I define a variable then have a couple of uses for that variable define the variable once again have a few more uses use define the variable a third time have some more uses this can go on any number of times. Each of these definition use ranges qualify to be a live range on its own. So, we make these three live ranges as three different you know variables in the program. So, that the program now does not reassign a variable you know unless it is absolutely necessary. So, I will show you when it becomes absolutely necessary with an example. So, once the renaming of the variables you know is completed we have each live range having a unique name and a live range is now entitled to get a register. So, let us look at the example. So, in the small example we have a equal to an assignment a equal to another assignment equal to a usage of a a equal to one more assignment equal to a usage of a and here is equal to a usage of a. The renaming process makes both these definitions as s 1 equal to and s 1 equal to that is because the value which is reaching this a can be either from this branch or from this branch. So, even though these two are two different definitions we actually place them in the same live range and. So, this this and this together come into the same live range and therefore, they have the same variable s 1. Whereas, the second definition of a here rather the third definition of a is not related to any of these and it can be assigned a unique name s 2 and obviously, the two users will also be marked as s 2. So, there is there are two live ranges here this is one live range and this is another live range. So, this has the name s 1 and this has the name s 2. So, once the live ranges have been renamed we build the interference graph. So, we are going to look at the steps needed to build the interference graph very soon after building the interference graph there is what is known as coalescing of the copy instructions or this is also called as removing the unnecessary move or copy instructions. So, I will go give you examples of this as well after that we color the graph that is the reduction process is applied there by we select the registers. Suppose, we get stuck during the coloring of the graph and the graph cannot be reduced further we need to you know spill some of the variables as I mentioned. So, we spill we compute spill cause then choose a particular node to spill then remove that node simplify the graph add the spill code to the original program and now we again do all these steps once more you know not here, but this particular step from building the interference graph onwards until the graph becomes completely colorable. So, let us now look at these steps in more detail. So, this is the iterative process rename build coalesce is in a loop and then simplify is the reduction process if it is complete then we select registers otherwise we compute the spill cost insert the spill code and go back to renaming building etcetera etcetera. If renaming is not necessary we could directly go to build. So, let us take a simple example for the renaming. So, we have x equal to 2 and we have x equal to z star 2 we have y equal to 4 and then we have w z and u being assigned. So, let us just rename them. So, this x gets s 1 and this x gets a different name called s 6. So, the others of course, could have been retained as it is, but just to make sure that the intermediate code is uniform we have assigned new names to all of them otherwise it was not really essential only this first x and the last x needed different names. Now, what about the live ranges? So, if you look at the definition of s 1 till you know the last use of s 1 is the live range of s 1. So, from instruction 1 to instruction 5 we have the live range of s 1. So, similarly for s 2 it says it is from 2 to 5 2 and then s 2 last use is 5 l v of 3 is 3 4. So, it is just that you know instead of just one instruction we have just said the instruction 3 and the next one and 4 it is 4 to 6 here s 1 is used and 5 also you know there is no usage of s 1 s 4 here sorry there is usage of s 4 here and then there is usage of s 4 here as well. So, 4 to 6 right. So, then we have s 5 5 and 6. So, again instead of marking just one instruction we have marked 5 to 6 and the usage of s 6 will be from this point onwards we do not know about that. So, this is the way we calculate the live ranges and once the live ranges are calculated we you know compute the interference graph. So, the nodes of the interference graph the you know symbolic registers unique symbolic registers that we have shown in the previous example. So, and the edges between these show the interferences. So, I will come to R 1 R 2 and R 3 shortly. So, let us focus on s 1 it says it interferes with the s 3 s 2 and s 4 let us verify it with our example here. So, whenever we say interfere you know we just check whether there is an overlap of the live ranges. So, for example, here this s 1 interferes with 2 because 1 to 5 and 2 to 5 they have overlapping ranges and then s 3 again you know it is 3 to 4. So, that also overlaps with this right. So, s 1 interferes with s 3 it interferes with s 2 and it interferes with s 4 also. So, finally, we have s 4 which is going from 4 to 6. So, that also interferes with s 1 right. So, s 2 s 3 and s 4 see that 5 to 6 does not interfere with this and 6 onwards also does not interfere with s 1. So, this is the way we actually look at the interference similarly, s 5 interferes with s 4 s 4 interferes with s 2 and of course, s 1 and so on and so forth. Now, so coming to the of course, the colors would not have been assigned right in the beginning. So, that is important coming to these 3 you know nodes which are marked as R 1, R 2 and R 3 R 1, R 2 and R 3 correspond to the 3 physical registers which are present in the machine. Whenever there is a constraint that one of the registers cannot be used or interferes for a with a particular live range, then we introduce these physical registers and then add an edge between that particular live range and the register. So, in this case the constraint is that s 4 cannot be given the register number R 1. So, we have added an edge between s 4 and R 1. If there were no restrictions of this kind and any variable could have could be given any register, then adding these 3 registers to the interference graph is not really necessary, but in the absence of that we need to add this as well. Continuing this example after the register location or the coloring is performed. So, coloring actually has been done very simply with 1, 2 and 3 colors. So, for example, you know we could start with this push it on to the stack, then start with this you know then go on to this push this also on to the stack. We have 3 registers, then you know this edge will also go, we take out this and the 2 edges, then we are left with these rest of it. We could take out either this or this and then you know the other one finally, we take out this and of course, we have already assigned the colors to R 1, R 2 and R 3 because they are physical registers. So, the reverse process will assign the colors as I explained in the previous example. Having done that we could assign the registers corresponding to those colors and rewrite the code in the form of using a registers. So, now R 1 equal to 2 and R 1 equal to R 1 star R 2 indicates that the assignment you know for the same variable is taking place in the same register. This is just a coincidence, it is possible that you know R 1 was assigned some other live range you know once it becomes not useful. Let us take one more example. So, here this is a basic block, these are all basic blocks b 1, b 2, b 3, b 4, b 5, b 6. So, in this basic block we have a definition of x and a definition of another variable y. Here we have a usage of x and then followed by a usage of y, here we have a usage of x and then a definition of x, this has a usage of x, here is a definition of y, a definition of x and usage of y. So, if you look at the live ranges, so the live ranges here are called w 1, w 2, w 3 and w 4. So, if you look at w 1 it says def x in v 2, def x in v 3, use x in v 4 and use x in v 5 alright. So, this, this, this and this, these four together form one live range because these are interrelated you know we cannot assign a different variable to these two definitions. Whereas, this x now can be assigned a different live range because it does not interfere with any of these. The second one is here def x and use x, then the third one is here def y and use y and the fourth one is again def y and use y, none of them interfere with each other. So, they are made into different live ranges you know. So, once we have these different live ranges they are associated with different variables w 1, w 2, w 3 and w 4. The interference is also noted w 1 interferes with both w 3 and w 4. So, if you look at that red which is w 1 it is very clearly interfering with def y, use y that is nothing but w 3 and then you know it is also interfering with the last one which is w 4. So, here so this is the way we actually compute the interference graph. So, here is a description of what I just now explained. So, create a node for each live variable and for each physical register in the interference graph, if two distinct live variables interfere that is a variable associated with one live variable is live at the definition point of another add an edge between the two LVs. So, this is what I just now mentioned. If a particular variable cannot reside in the register, then add an edge between all LVs associated with that variable and the register. So, this is the I know extra that we do for physical registers, then the next step is called as copy subsumption or coalescing copy coalescing. So, what happens is that the copy instructions which are present in the program for example, of the kind B equal to E this is a copy. So, whatever is in E is copied to B. So, both of them carry the same value there is no other computation. In the presence of such instructions sometimes it is possible to merge the nodes corresponding to the live range of B and the live range of E. So, if we are able to do this merging then it is called as a copy subsumption operation. If the live ranges of B and E do not overlap that means, the there is no edge between the live range of B and the live range of E in the interference graph. Then obviously, B and E can be given the same register. So, if they do not overlap we can give them the same register. So, this is implied by the lack of any edges between B and E in the interference graph I am going to show you an example very soon. The copy instruction can then be removed from the final program and we merge B and E into one node that contains the edges of both the. So, B equal to E is a copy instruction this is the original interference graph and since there is no edge between B and E that means the live ranges of B and E do not overlap. So, we could merge B and E into a single node. So, that becomes the node B E all the edges which are connected to B and E will now go to will connect to the node B E. For example, D C and A connect to node B. So, D C and A connect to node B E as well. Now, node F connects to E along with A and D. So, A and D are already connected to B. So, they are connected. So, F also now connects to the node B E. So, why should we do this? So, before understanding why this helps a few more examples will help to clarify the situation. So, there is a live range for this old B then there is a copy operation and then the there is a different live range of the new B. So, here this is the live range of E in this case the live range of E is actually overlapping the live range of you know new B right. So, this is see this and therefore, after we copy it is not possible to assign the same register to both the live range of E and the live range of new B. That means, we cannot actually get rid of this copy instruction copy subsumption in this case is not possible. What about this case? The live range of old B and the live range of E overlap, but the L R of E and L R of new B do not overlap. Therefore, whatever is the value of E here can be safely assumed to be the value of B since there is no other modification to the variable E. So, copy subsumption is possible here because they do not interfere and in this case we can remove the copy instruction. So, in this case copy subsumption you know is required to be applied repeatedly here is X here is E and here is old B or rather B. So, B equal to E. So, we can do away with this copy operation because B and E do not have any overlap after this there is another copy operation A equal to B since the live ranges of A and B do not overlap. We can do away with this copy operation as well and assign the same register to both A and B. So, in effect A B and E are all given the same register, but of course, X gets a different register. So, this shows that copy subsumption perhaps should be applied more than once in order to get the best benefit. So, the coalescing operation coalesces all possible copy instructions the way I just now discussed and then it builds the rebuilds the graph which may offer further opportunities for coalescing. We do coalescing only you know one instruction at a time and then rebuild the graph. Build coalesce phase is repeated till no further coalescing is possible basically coalescing reduces the size of the graph and possibly reduces the spilling operation. Now, we move on to the step of reduction and we also provide a justification why reduction is correct. Suppose the number of registers available is capital R. If a graph G contains a node n with fewer than R neighbors then statement is that removing n and its adjust from G will not affect its R colorability. So, let us understand why basically if G prime which is nothing but G minus n can be colored with R colors then so can G. Let us see why basically now we know from G we have removed a node and its adjust now that is our G prime. So, we color G prime and definitely the assumption is it can be colored with R colors after this is over we look at the node n. So, now there are R minus 1 neighbors for n. So, they would have been given in the worst case R minus 1 colors. So, the R-th color is still remaining we can assign it to n and thereby complete the coloring. So, the important point is that reduction operation does not affect the colorability of the graph. So, after reduction if we are able to color the graph then we could have done it before coloring before the reduction operation as well this is the justification for the reduction operation. So, if a node n in the interference graph has degree less than R remove node and all its adjust from the graph and place n on a coloring stack. So, this is the reduction operation when no more at such adjust are removal we need to spill. So, what does spilling mean spilling a variable x let us look at the fine print now it implies loading x into a register at every use of x. So, the reason is we say x will not get a when we spill a node it does not get a register. So, it goes into it is always resident in memory. So, whenever we use a variable x we will have to load it into a register at every use of x. So, we cannot do any operations without loading a value into a register that is why we want to move x into a register at the usage point and then perform the operation on it using it. At the definition point storing x from a register to memory is necessary because finally the value of x must reside in the memory location corresponding to x. So, I will show you the effect of spilling very soon effect I know the spill code that needs to be introduced will be shown very soon, but now let us understand how to choose a node that is to be spilled. So, that is done based on what is known as the spilling cost. So, the node to be spilled is decided based on the spill cost for the live range represented by the node. So, how do we compute the spill cost? So, here is the live range v its cost is sum of all the you know factor c star 10 to the power d over all the load or store operations in a live range v. So, this is the you know only cost that needs why are we considering only the load or store operations in a live range. The point is if we spill a node, then you know at every use we need to load and at every definition we need to store. So, these are basically the use and def operations inside the code. What is the cost of each of these load or store operations? It is c into 10 to the power d, c is the cost of the operation it could be an addition or you know it could be a multiplication or division etcetera etcetera. So, multiplied by 10 to the power d. So, d is the loop nesting depth why should be multiplied by 10 to the power d? Let us understand this by looking at loop nesting of 0 that is the instructions are not nested at all in any loop. So, this d would become 0 10 to the power 0 is 1. So, that means we are looking at only the cost of that particular operation that is a load you know for that particular operation. Suppose the instruction is present inside a loop, then obviously the loop is going to be executed a large number of times. So, the number of times the use or def you know needs to be loaded or stored will also increase depending on the number of times the load or the loop operates. The experimentation has shown that you know the exact number of times the loop iterates is not really necessary. You know we could simply assign a number such as 5 or 10 or 50 or 100, 10 is just a number it could be 50 or 100 as well it approximates the number of iterations of any loop. So, even if you place 100 here and evaluate the you know this cost function it is not going to actually make a difference as far as the register location is concerned. The cost will be obviously different, we only want to differentiate the number of times the cost of a variable which is used inside a loop as compared to the cost of a variable which is used outside the loop. And this d is necessary to take care of the number of times the you know the loop nesting has been done. So, if there is a doubly nested loop obviously then you know we need to have 10 into 10. So, this becomes 10 to the power 2 if it is a triply nested loop then they will be 3 because the loop would be executing 10 into 10 into 10, 1000 number of times. So, this is the way we actually compute the cost of spilling a loop. Now, after we compute the cost for each one of the variables we compute another quantity called the cost v per degree v. So, divided by degree v and then take the minimum of these and that is the node which is to be spilled. So, this cost v per degree v kind of distributes the cost to the various edges of that particular node v that is why that is what the division operation really indicates degree v is the number of neighbors. So, we distribute it to the number of neighbors for that particular live range or node v. So, once we do this the obviously the node that has a minimum cost per degree is the node that is to be spilled because any of a spilling operation which is very expensive should be avoided the minimum cost spilling operation is the one which is to be encouraged. So, here is a graph which can be colored with 3 colors without any spills. So, that is easy to see and as I mentioned in the early part of this register location lecture the graph coloring algorithm actually graph coloring is an NP complete problem in general and we have used a heuristic which is by way of spilling the node when the graph coloring cannot proceed and because it is a heuristic it has its shortcomings. One problem is there are graphs such as this which can be 3 colored, but our heuristic shows that it cannot be colored using 3 colors. So, here is such a graph obviously by doing a manual coloring of the graph we have been able to color it, but if we apply the algorithm then you know it is very clear with 3 colors none of the nodes have degree less than 3. So, we cannot actually start the reduction process at all we have to spill a node before the coloring process reduction process begins. So, whereas by coloring like this we are able to color it without any spills. So, this is a shortcoming of the limitation of the coloring heuristic. So, what exactly do we mean by spilling a node? So, to spill a node we remove it from the graph and represent the effect of spilling you know as follows. We reload the spilled object at each use that means we introduce a load instruction for every use and we store it at in memory at each definition point that means we introduce a store instruction at after the immediately after the definition is over. So, remember we have a load instruction just before usage and we have a store instruction immediately after a definition. So, it so happens that this creates very small live ranges for the load and store points and again these you know we cannot perform any operation without registers. So, this load and store also require registers they require they have small live ranges of their own which will also have to be given registers and this is the reason why after the spill decisions are made we insert the spill code, rebuild the interference graph and repeat the attempt to color. So, this make sure that even the small live ranges get the registers appropriately when the simplification yields an empty graph then it is time to select the colors that is nothing but the registers. So, I want to show you the effect of spilling here. So, this is our original example you know with w 1, w 2, w 3, w 4 as the 4 live ranges. So, let us assume that the variable x is spilled in the live range w 1 that means just before just after this definition of x we must have a store instruction just before the use of x we must have a load. Here also we must have a load just before the use and just after this def we must have a store. So, def store load use load use and again def and store. So, these are the small live ranges that I actually mentioned you know this could be like x equal to something say x equal to 5 that is the definition right and then we have a store instruction. So, we need a small you know we need a register for doing this computation and then of course the register will be freed after the store instruction. But nevertheless this is a small live range which requires a register for its operation to be completed the same is true for this as well right and even this I need a register to load the value of x and then use it here. So, this load and use requires a small is a small live range which requires a register this is another small live range which requires one more register. So, by spilling the variable x in this live range we have actually introduced many more live ranges, but hopefully the original interferences are gone and the graph is easier to color in this case of course the number of interferences is approximately the same. So, it does not help, but this is an example to show the effect of spilling. So, the graph now will have 8 of these nodes rather w 1, w 2 you know 7 nodes and the interferences between these nodes are also slightly different. So, for example, w 4 and w 6 they have an interference. So, we have w 4 here right. So, this def and use that is one of these and then w 6 is the small live range they interfere w 5 and w 2 also interferes. So, this is w 2 and this def and use is w 5 they also interfere and there is no interference among the other live ranges at all. Then what do you mean by coloring the graph or selecting the registers for the graph or for the program. So, we have a repeat until loop. So, all the nodes have been placed on the stack. So, we pop the stack get a live range colors used v this is a set is equal to colors used by the neighbors of v. So, neighbors of v have been assign some colors then you know that is the set we are looking at initially none of the colors have been used. So, this would be empty colors free is all colors minus colors used to begin with all colors will be become colors free as well. Now, choose any color from colors free and assign it to node v. So, once we have done this right the you know we go back check whether the stack is empty then the next operation you know next live range is obtained from the stack and the same process is repeated. So, convert the color assigned to a symbolic register to the corresponding real registers name in the code and rewrite the code with the physical registers. So, this is the coloring or selection of registers. So, let us look at a complete example starting with a program you know and then going through the various steps of building the graph coloring it and so on. So, this program has many variables the I is a programmer defined variable whereas, the others are all temporaries, but still for coloring operation all the variables are equal. So, we do not differentiate between programmer defined variables and temporaries. So, T 1 has a live range from 1 to 10. So, here is the first definition of T 1 and the last use of T 1. So, that is 10 I has the range from 2 to 11. So, there is a definition of I here and there is a last use of I here of course, this definition is also I. So, 2 and both these I's are given the same live actually assign the same live range T 2 is between 3 and 4. So, T 2 is defined here and the last use is here T 3 is 6 to 7. So, T 3 is defined here and used here T 4 is between 7 and 9. So, T 4 is defined here and used here last time T 5 is between 8 and 9. So, T 5 is defined in 8 and last use is in 9 T 6 is between 9 and 10. So, T 6 is defined in 9 and then you know star T 6 is a use actually T 6 is used it is a pointer. So, star T 6 is the address where T 1 is placed. So, this is a usage. So, this is these are the various live ranges. So, it is easy to see the interference right. So, T 1 and obviously, I they interfere and T 1 also interferes with T 5. So, whenever there is overlap with the range. So, T 2 interferes then T 3 interferes T 4 interferes T 5 interferes and T 6 also interferes. So, T 1 is connected to all of them. So, it is connected to all of them whereas, T 3 is connected to only T 1 and I. So, T 1 has 6 to T 3 has 6 to 7 as its live range. So, obviously, I and T 1 are the only two which interfere with it. Similarly, T 2 is connected to only T 1 and I T 6 is connected to only T 1 and I and so on and so forth. So, let us look at T 4 it is connected to let us look at it T 4 is 7 to 9. So, we have T 1 and I as obvious candidates. So, T 1 and I, but it is also connected to T 5 which is between 8 and 9. So, this is 7 and 9 this is 8 and 9. So, they overlap. So, this is our interference graph for which we need to assign colors. So, we start you know let us assume that there are three colors three registers. So, we can you know look at T 6, T 2 and T 3 these have degree 2 which is less than 3 all those have three or more. So, we could simply take T 6, T 2 and T 3 and place them on a stack. So, once we do that and we remove the nodes along with their edges the graph that is left is this graph. Unfortunately, all the nodes in this graph have degree 3 you know this has 3, this has 3, this has 3 and this also has 3. So, the reduction process cannot proceed spilling will be necessary. Let us compute the cost of spilling for each of the nodes in this particular graph. So, if you look at node T 1 then you know in the live range for T 1 we have one operation which is outside the loop. So, that is cost 1 and there are three operations associated with T 1 inside the loop. So, there is a T 1 here right there is a T 1 here and there is another T 1 here. So, these three operations are inside the loop. So, the it is multiplied by 10 you know based on our spilling heuristic. So, sorry here here multiplied by 10. So, the cost total cost is 31. Similarly, for I we have one operation outside. So, that is the this instruction number 2 and then we have 1 you know then 2 right then 3 and 4 4 operations inside the loop. So, that is multiplied by 10. So, 40 plus 1 is 41 then the third one is T 4. T 4 has 2 operations inside the loop. So, T 4 is here and T 4 is here 2 operations. So, that cost is 20. Similarly, T 5 also has 2 operations inside the loops. So, that cost is also 20. Now, the degree of each of these vertices is 3. So, divide and you know round off. So, 31 by rather truncate. So, this is 10. So, this is 14 and then this is 7 and this is also 7 right. So, we are really rounding off in these cases. So, this also less than 0.5 then take the floor otherwise take the ceiling value. Out of these these are the two with least value. So, any one of them can be chosen for the spilling operation. So, let us choose T 5 for the spilling then we remove that you know we get actually this small graph which can be easily colored using 3 colors. So, now the coloring stack has T 6, T 2, T 3, T 4, T 1, I. So, all the nodes are placed here. We can color them in the reverse order. Note that T 5 is not present here it is spilled. So, it will be permanently in memory and it will be let us assume that our temporary register can be provided to this particular node or variable during the code generation process. So, the global register allocator need not provide any registers for this particular variable T 5. So, otherwise the coloring part is quite straight forward. So, we get the coloring as shown in this picture. So, after this the let us look at the you know of course, then we rewrite the program with registers T 5 is retained as it is this will be given a register at the time of code generation machine code generation. These are still not machine operations, but we have assigned physical registers. Drawbacks of the algorithm constructing and modifying the interference graph is very expensive because the graphs can become very large. For example, the combined interference graphs of procedures and functions in G C C in mid 90s the older version of G C C approximately has 4.6 million edges. So, these are extremely large. So, graph coloring takes a large amount of time. So, some modifications are possible for example, we do not have to do copy subsumption if the degree of a node becomes more than the number of registers. And we can do optimistic coloring that is when a node needs to be spilled we do not you know we push it on to the coloring stack instead of spilling it right away. So, and then try to give it a color when we pop the node. So, let us look at an example. So, here say node 1 is chosen for spilling we just put it on to the stack and remove the corresponding node in the edges. The rest of the graph now becomes colorable with 3 colors because it is possible to do it you know spill 2 and then I sorry reduce 2 reduce 5 and so on and so forth. So, let us say we finish the coloring for this part of the graph. Now, when we come here we find that you know there is a color free which can be assigned to node 1. So, this is again a heuristic which is called optimistic coloring and it may not work in all cases. Suppose we had assigned 2 different colors to these nodes then you know in the coloring process then this would not have had it is color free. So, this completes our discussion on register location. Thank you.