summaryrefslogtreecommitdiff
path: root/vaporize/RegisterAlloc.java
blob: 4b956d03499113166e581c9f6679177a327c259d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package vaporize;

import java.util.*;
import misc.*;

public class RegisterAlloc {

    private LIRDict intervals;
    private String[] all_registers;
    private Stack<String> free_registers;
    private TreeSet<LIRVar> active;
    
    public RegisterAlloc(LIRDict intervals, String[] all_registers) {
	this.intervals = intervals;
	this.all_registers = all_registers;
	this.free_registers = new Stack<String>();
	this.free_registers.addAll(Arrays.asList(this.all_registers));
	this.active = new TreeSet<LIRVar>((v1, v2) -> {
		int ret;
		if (v1.getLastUse() > v2.getLastUse())
		    ret = 1;
		else if (v1.getLastUse() < v2.getLastUse())
		    ret = -1;
		else if (v1.equals(v2))
		    ret = 0;
		else
		    ret = 1;
		return ret;
	});

	MinimalLogger.info(String.format("Starting allocation with registers %s",
					 this.free_registers.toString()));

	String register;
	for (LIRVar interval : this.intervals.getIntervals()) {
	    this.expireOldIntervals(interval);
	    if (this.active.size() >= this.all_registers.length)
		this.spillAtInterval(interval);
	    else {
		register = this.free_registers.pop();
		interval.assignRegister(register);
		this.active.add(interval);
		MinimalLogger.info(String.format("Assigning register %s to %s.",
						 register,
						 interval.toString()));

	    }
	}
    }

    private void expireOldIntervals(LIRVar interval) {
	for (LIRVar active : new TreeSet<LIRVar>(this.active)) {
	    if (active.getLastUse() >= interval.getFirstDef())
		return;
	    MinimalLogger.info("Register " + active.getAssignedRegister() + " expired!");
	    this.active.remove(active);
	    this.free_registers.push(active.getAssignedRegister());
	}
    }

    private void spillAtInterval(LIRVar interval) {
	MinimalLogger.severe(String.format("Ran out of free registers, but a spill for %s was not performed!",
					   interval.toString()));
	this.intervals.addSpilledNum();
	// LIRVar spill = this.active.get(this.active.length()-1);
	// if (spill.getLastUse() > interval.getLastUse()) {
	//     ;
	// }
    }
    
}