diff options
author | Mike Pall <mike> | 2009-12-08 19:46:35 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2009-12-08 19:46:35 +0100 |
commit | 55b16959717084884fd4a0cbae6d19e3786c20c7 (patch) | |
tree | c8a07a43c13679751ed25a9d06796e9e7b2134a6 /src/lj_target.h | |
download | luajit-2.0.0-beta1.tar.gz luajit-2.0.0-beta1.tar.bz2 luajit-2.0.0-beta1.zip |
RELEASE LuaJIT-2.0.0-beta1v2.0.0-beta1
Diffstat (limited to 'src/lj_target.h')
-rw-r--r-- | src/lj_target.h | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/src/lj_target.h b/src/lj_target.h new file mode 100644 index 00000000..0b464d3f --- /dev/null +++ b/src/lj_target.h | |||
@@ -0,0 +1,132 @@ | |||
1 | /* | ||
2 | ** Definitions for target CPU. | ||
3 | ** Copyright (C) 2005-2009 Mike Pall. See Copyright Notice in luajit.h | ||
4 | */ | ||
5 | |||
6 | #ifndef _LJ_TARGET_H | ||
7 | #define _LJ_TARGET_H | ||
8 | |||
9 | #include "lj_def.h" | ||
10 | #include "lj_arch.h" | ||
11 | |||
12 | /* -- Registers and spill slots ------------------------------------------- */ | ||
13 | |||
14 | /* Register type (uint8_t in ir->r). */ | ||
15 | typedef uint32_t Reg; | ||
16 | |||
17 | /* The hi-bit is NOT set for an allocated register. This means the value | ||
18 | ** can be directly used without masking. The hi-bit is set for a register | ||
19 | ** allocation hint or for RID_INIT. | ||
20 | */ | ||
21 | #define RID_NONE 0x80 | ||
22 | #define RID_MASK 0x7f | ||
23 | #define RID_INIT (RID_NONE|RID_MASK) | ||
24 | |||
25 | #define ra_noreg(r) ((r) & RID_NONE) | ||
26 | #define ra_hasreg(r) (!((r) & RID_NONE)) | ||
27 | |||
28 | /* The ra_hashint() macro assumes a previous test for ra_noreg(). */ | ||
29 | #define ra_hashint(r) ((r) != RID_INIT) | ||
30 | #define ra_gethint(r) ((Reg)((r) & RID_MASK)) | ||
31 | #define ra_sethint(rr, r) rr = (uint8_t)((r)|RID_NONE) | ||
32 | #define ra_samehint(r1, r2) (ra_gethint((r1)^(r2)) == 0) | ||
33 | |||
34 | /* Spill slot 0 means no spill slot has been allocated. */ | ||
35 | #define SPS_NONE 0 | ||
36 | |||
37 | #define ra_hasspill(s) ((s) != SPS_NONE) | ||
38 | |||
39 | /* Combined register and spill slot (uint16_t in ir->prev). */ | ||
40 | typedef uint32_t RegSP; | ||
41 | |||
42 | #define REGSP(r, s) ((r) + ((s) << 8)) | ||
43 | #define REGSP_HINT(r) ((r)|RID_NONE) | ||
44 | #define REGSP_INIT REGSP(RID_INIT, 0) | ||
45 | |||
46 | #define regsp_reg(rs) ((rs) & 255) | ||
47 | #define regsp_spill(rs) ((rs) >> 8) | ||
48 | #define regsp_used(rs) \ | ||
49 | (((rs) & ~REGSP(RID_MASK, 0)) != REGSP(RID_NONE, 0)) | ||
50 | |||
51 | /* -- Register sets ------------------------------------------------------- */ | ||
52 | |||
53 | /* Bitset for registers. 32 registers suffice right now. | ||
54 | ** Note that one set holds bits for both GPRs and FPRs. | ||
55 | */ | ||
56 | typedef uint32_t RegSet; | ||
57 | |||
58 | #define RID2RSET(r) (((RegSet)1) << (r)) | ||
59 | #define RSET_EMPTY 0 | ||
60 | #define RSET_RANGE(lo, hi) ((RID2RSET((hi)-(lo))-1) << (lo)) | ||
61 | |||
62 | #define rset_test(rs, r) (((rs) >> (r)) & 1) | ||
63 | #define rset_set(rs, r) (rs |= RID2RSET(r)) | ||
64 | #define rset_clear(rs, r) (rs &= ~RID2RSET(r)) | ||
65 | #define rset_exclude(rs, r) (rs & ~RID2RSET(r)) | ||
66 | #define rset_picktop(rs) ((Reg)lj_fls(rs)) | ||
67 | #define rset_pickbot(rs) ((Reg)lj_ffs(rs)) | ||
68 | |||
69 | /* -- Register allocation cost -------------------------------------------- */ | ||
70 | |||
71 | /* The register allocation heuristic keeps track of the cost for allocating | ||
72 | ** a specific register: | ||
73 | ** | ||
74 | ** A free register (obviously) has a cost of 0 and a 1-bit in the free mask. | ||
75 | ** | ||
76 | ** An already allocated register has the (non-zero) IR reference in the lowest | ||
77 | ** bits and the result of a blended cost-model in the higher bits. | ||
78 | ** | ||
79 | ** The allocator first checks the free mask for a hit. Otherwise an (unrolled) | ||
80 | ** linear search for the minimum cost is used. The search doesn't need to | ||
81 | ** keep track of the position of the minimum, which makes it very fast. | ||
82 | ** The lowest bits of the minimum cost show the desired IR reference whose | ||
83 | ** register is the one to evict. | ||
84 | ** | ||
85 | ** Without the cost-model this degenerates to the standard heuristics for | ||
86 | ** (reverse) linear-scan register allocation. Since code generation is done | ||
87 | ** in reverse, a live interval extends from the last use to the first def. | ||
88 | ** For an SSA IR the IR reference is the first (and only) def and thus | ||
89 | ** trivially marks the end of the interval. The LSRA heuristics says to pick | ||
90 | ** the register whose live interval has the furthest extent, i.e. the lowest | ||
91 | ** IR reference in our case. | ||
92 | ** | ||
93 | ** A cost-model should take into account other factors, like spill-cost and | ||
94 | ** restore- or rematerialization-cost, which depend on the kind of instruction. | ||
95 | ** E.g. constants have zero spill costs, variant instructions have higher | ||
96 | ** costs than invariants and PHIs should preferably never be spilled. | ||
97 | ** | ||
98 | ** Here's a first cut at simple, but effective blended cost-model for R-LSRA: | ||
99 | ** - Due to careful design of the IR, constants already have lower IR | ||
100 | ** references than invariants and invariants have lower IR references | ||
101 | ** than variants. | ||
102 | ** - The cost in the upper 16 bits is the sum of the IR reference and a | ||
103 | ** weighted score. The score currently only takes into account whether | ||
104 | ** the IRT_ISPHI bit is set in the instruction type. | ||
105 | ** - The PHI weight is the minimum distance (in IR instructions) a PHI | ||
106 | ** reference has to be further apart from a non-PHI reference to be spilled. | ||
107 | ** - It should be a power of two (for speed) and must be between 2 and 32768. | ||
108 | ** Good values for the PHI weight seem to be between 40 and 150. | ||
109 | ** - Further study is required. | ||
110 | */ | ||
111 | #define REGCOST_PHI_WEIGHT 64 | ||
112 | |||
113 | /* Cost for allocating a specific register. */ | ||
114 | typedef uint32_t RegCost; | ||
115 | |||
116 | /* Note: assumes 16 bit IRRef1. */ | ||
117 | #define REGCOST(cost, ref) ((RegCost)(ref) + ((RegCost)(cost) << 16)) | ||
118 | #define regcost_ref(rc) ((IRRef1)(rc)) | ||
119 | |||
120 | #define REGCOST_T(t) \ | ||
121 | ((RegCost)((t)&IRT_ISPHI) * (((RegCost)(REGCOST_PHI_WEIGHT)<<16)/IRT_ISPHI)) | ||
122 | #define REGCOST_REF_T(ref, t) (REGCOST((ref), (ref)) + REGCOST_T((t))) | ||
123 | |||
124 | /* -- Target-specific definitions ----------------------------------------- */ | ||
125 | |||
126 | #if LJ_TARGET_X86ORX64 | ||
127 | #include "lj_target_x86.h" | ||
128 | #else | ||
129 | #error "Missing include for target CPU" | ||
130 | #endif | ||
131 | |||
132 | #endif | ||