blob: ca54b4564f93b2d1c32d908282df41b1b3b1f16b (
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
|
Register Allocation
===================
The current JIT implementation uses a tree matcher to generate code. We use a
simple algorithm to allocate registers in trees, and limit the number of used
temporary register to 4 when evaluating trees. So we can use 2 registers for
global register allocation.
Register Allocation for Trees
=============================
We always evaluate trees from left to right. When there are no more registers
available we need to spill values to memory. Here is the simplified algorithm.
gboolean
tree_allocate_regs (tree, exclude_reg)
{
if (!tree_allocate_regs (tree->left, -1))
return FALSE;
if (!tree_allocate_regs (tree->right, -1)) {
tree->left->spilled == TRUE;
free_used_regs (tree->left);
if (!tree_allocate_regs (tree->right, tree->left->reg))
return FALSE;
}
free_used_regs (tree->left);
free_used_regs (tree->right);
/* try to allocate a register (reg != exclude_reg) */
if ((tree->reg = next_free_reg (exclude_reg)) != -1)
return TRUE;
return FALSE;
}
The emit routing actually spills the registers:
tree_emit (tree)
{
tree_emit (tree->left);
if (tree->left->spilled)
save_reg (tree->left->reg);
tree_emit (tree->right);
if (tree->left->spilled)
restore_reg (tree->left->reg);
emit_code (tree);
}
Global Register Allocation
==========================
TODO.
|