3 * Copyright (C) 2002-2009, Parrot Foundation.
6 #ifndef PARROT_IMCC_SYMREG_H_GUARD
7 #define PARROT_IMCC_SYMREG_H_GUARD
11 #define VARTYPE_BIT(n) ((UINTVAL)1 << (n))
12 enum VARTYPE
{ /* variable type can be */
13 VTCONST
= VARTYPE_BIT(0), /* constant */
14 VTREG
= VARTYPE_BIT(1), /* register */
15 VTIDENTIFIER
= VARTYPE_BIT(2), /* identifier */
16 VTADDRESS
= VARTYPE_BIT(3), /* address */
17 VTREGKEY
= VARTYPE_BIT(4), /* parrot [key;key..]), including registers */
18 VTPASM
= VARTYPE_BIT(5), /* parrot register), colored from .emit */
19 VT_CONSTP
= VARTYPE_BIT(6), /* pointer to constant value */
20 VT_PCC_SUB
= VARTYPE_BIT(7), /* PCC subroutine call */
21 VT_FLAT
= VARTYPE_BIT(8), /* var :flat */
22 VT_OPTIONAL
= VARTYPE_BIT(9), /* var :optional */
23 /* include/parrot/packfile.h */
24 VT_ENCODED
= VARTYPE_BIT(16), /* unicode string constant */
25 VT_OPT_FLAG
= VARTYPE_BIT(17), /* var :opt_flag */
26 VT_NAMED
= VARTYPE_BIT(18), /* var :named(name) */
27 VT_UNIQUE_REG
= VARTYPE_BIT(19),
28 VT_CALL_SIG
= VARTYPE_BIT(20)
32 /* this VARTYPE needs register allocation and such */
33 #define VTREGISTER (VTREG | VTIDENTIFIER | VTREGKEY | VTPASM)
34 #define REG_NEEDS_ALLOC(r) ((r)->type & VTREGISTER)
36 enum LIFEFLAG
{ /* The status of a var inside a basic block can be */
37 LF_use
= 1 << 0, /* block uses the the var before defining it */
38 LF_def
= 1 << 1, /* block defines the variable */
39 LF_lv_in
= 1 << 2, /* variable is alive at the beginning of the block */
40 LF_lv_out
= 1 << 3, /* variable is alive at the end of the block */
41 LF_lv_inside
= 1 << 4, /* variable is alive at some moment in the block */
42 LF_lv_all
= 1 << 5 /* variable is alive throughout the block */
45 /* Liveness represents the usage of a var inside a basic block
46 This is represented by pairs of [definition, usage] in *intervals: */
47 typedef struct _Life_range
{
49 struct _Instruction
*first_ins
;
50 struct _Instruction
*last_ins
;
54 U_KEYED
= 1 << 0, /* array, hash, keyed */
55 U_NEW
= 1 << 1, /* PMC was inited */
56 U_GLOBAL
= 1 << 3, /* symbol is global (fixup) */
57 U_LEXICAL
= 1 << 4, /* symbol is lexical */
58 U_FIXUP
= 1 << 5, /* maybe not global, force fixup */
59 U_NON_VOLATILE
= 1 << 6, /* needs preserving */
60 U_SUBID_LOOKUP
= 1 << 7 /* .const 'Sub' lookup is done by subid */
63 typedef struct _SymReg
{
66 Life_range
**life_info
; /* Each block has a Life_range status */
67 struct _SymReg
*nextkey
; /* keys */
68 struct _SymReg
*reg
; /* key->register for VTREGKEYs */
69 struct pcc_sub_t
*pcc_sub
; /* PCC subroutine */
70 struct _SymReg
*used
; /* used register in invoke */
71 struct _SymReg
*next
; /* used in the symbols hash */
72 struct _Instruction
*first_ins
; /* first and last instruction */
73 struct _Instruction
*last_ins
; /* this symbol is in */
74 INTVAL type
; /* Variable type */
75 INTVAL usage
; /* s. USAGE above */
76 int set
; /* parent register set/file */
77 int want_regno
; /* wanted register number */
78 INTVAL color
; /* Color: parrot register number
79 * and const table index of VTCONST */
80 int offset
; /* used for label fixup */
81 int use_count
; /* How often this symbol is used */
82 int lhs_use_count
; /* Frequency of writing to this symbol*/
83 int pmc_type
; /* class enum */
86 typedef struct _SymHash
{
94 typedef struct ident_t Identifier
;
100 typedef struct namespace_t Namespace
;
109 /* HEADERIZER BEGIN: compilers/imcc/symreg.c */
110 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
112 PARROT_CAN_RETURN_NULL
113 PARROT_WARN_UNUSED_RESULT
114 SymReg
* _find_sym(PARROT_INTERP
,
115 ARGIN_NULLOK(const Namespace
*nspace
),
116 ARGIN(const SymHash
*hsh
),
117 ARGIN(const char *name
))
118 __attribute__nonnull__(1)
119 __attribute__nonnull__(3)
120 __attribute__nonnull__(4);
122 PARROT_CAN_RETURN_NULL
123 PARROT_WARN_UNUSED_RESULT
124 SymReg
* _get_sym(ARGIN(const SymHash
*hsh
), ARGIN(const char *name
))
125 __attribute__nonnull__(1)
126 __attribute__nonnull__(2);
128 PARROT_WARN_UNUSED_RESULT
129 PARROT_CANNOT_RETURN_NULL
130 SymReg
* _mk_address(PARROT_INTERP
,
131 ARGMOD(SymHash
*hsh
),
132 ARGIN(const char *name
),
134 __attribute__nonnull__(1)
135 __attribute__nonnull__(2)
136 __attribute__nonnull__(3)
139 PARROT_WARN_UNUSED_RESULT
140 PARROT_CANNOT_RETURN_NULL
141 SymReg
* _mk_const(PARROT_INTERP
,
142 ARGMOD(SymHash
*hsh
),
143 ARGIN(const char *name
),
145 __attribute__nonnull__(1)
146 __attribute__nonnull__(2)
147 __attribute__nonnull__(3)
150 void _store_symreg(PARROT_INTERP
, ARGMOD(SymHash
*hsh
), ARGMOD(SymReg
*r
))
151 __attribute__nonnull__(1)
152 __attribute__nonnull__(2)
153 __attribute__nonnull__(3)
157 void add_namespace(PARROT_INTERP
, ARGMOD(IMC_Unit
*unit
))
158 __attribute__nonnull__(1)
159 __attribute__nonnull__(2)
160 FUNC_MODIFIES(*unit
);
162 void add_pcc_arg(PARROT_INTERP
, ARGMOD(SymReg
*r
), ARGMOD(SymReg
*arg
))
163 __attribute__nonnull__(1)
164 __attribute__nonnull__(2)
165 __attribute__nonnull__(3)
169 void add_pcc_cc(ARGMOD(SymReg
*r
), ARGIN(SymReg
*arg
))
170 __attribute__nonnull__(1)
171 __attribute__nonnull__(2)
174 void add_pcc_multi(PARROT_INTERP
,
176 ARGIN_NULLOK(SymReg
*arg
))
177 __attribute__nonnull__(1)
178 __attribute__nonnull__(2)
181 void add_pcc_result(PARROT_INTERP
, ARGMOD(SymReg
*r
), ARGMOD(SymReg
*arg
))
182 __attribute__nonnull__(1)
183 __attribute__nonnull__(2)
184 __attribute__nonnull__(3)
188 void add_pcc_sub(ARGMOD(SymReg
*r
), ARGIN(SymReg
*arg
))
189 __attribute__nonnull__(1)
190 __attribute__nonnull__(2)
193 void clear_globals(PARROT_INTERP
)
194 __attribute__nonnull__(1);
196 void clear_locals(ARGIN_NULLOK(IMC_Unit
*unit
));
197 void clear_sym_hash(ARGMOD(SymHash
*hsh
))
198 __attribute__nonnull__(1)
201 void create_symhash(PARROT_INTERP
, ARGOUT(SymHash
*hash
))
202 __attribute__nonnull__(1)
203 __attribute__nonnull__(2)
204 FUNC_MODIFIES(*hash
);
206 void debug_dump_sym_hash(ARGIN(const SymHash
*hsh
))
207 __attribute__nonnull__(1);
210 PARROT_CANNOT_RETURN_NULL
211 SymReg
* dup_sym(PARROT_INTERP
, ARGIN(const SymReg
*r
))
212 __attribute__nonnull__(1)
213 __attribute__nonnull__(2);
215 PARROT_CAN_RETURN_NULL
216 PARROT_WARN_UNUSED_RESULT
217 SymReg
* find_sym(PARROT_INTERP
, ARGIN(const char *name
))
218 __attribute__nonnull__(1)
219 __attribute__nonnull__(2);
221 void free_sym(ARGMOD(SymReg
*r
))
222 __attribute__nonnull__(1)
225 PARROT_CAN_RETURN_NULL
226 PARROT_WARN_UNUSED_RESULT
227 SymReg
* get_sym(PARROT_INTERP
, ARGIN(const char *name
))
228 __attribute__nonnull__(1)
229 __attribute__nonnull__(2);
232 unsigned int hash_str(ARGIN(const char *str
))
233 __attribute__nonnull__(1);
236 PARROT_CANNOT_RETURN_NULL
237 SymReg
* link_keys(PARROT_INTERP
,
239 ARGMOD(SymReg
**keys
),
241 __attribute__nonnull__(1)
242 __attribute__nonnull__(3)
243 FUNC_MODIFIES(*keys
);
245 PARROT_WARN_UNUSED_RESULT
246 PARROT_CANNOT_RETURN_NULL
247 SymReg
* mk_const(PARROT_INTERP
, ARGIN(const char *name
), int t
)
248 __attribute__nonnull__(1)
249 __attribute__nonnull__(2);
251 PARROT_CANNOT_RETURN_NULL
252 PARROT_IGNORABLE_RESULT
253 SymReg
* mk_const_ident(PARROT_INTERP
,
254 ARGIN(const char *name
),
258 __attribute__nonnull__(1)
259 __attribute__nonnull__(2)
260 __attribute__nonnull__(4)
263 PARROT_CANNOT_RETURN_NULL
264 PARROT_IGNORABLE_RESULT
265 SymReg
* mk_ident(PARROT_INTERP
, ARGIN(const char *name
), int t
)
266 __attribute__nonnull__(1)
267 __attribute__nonnull__(2);
269 PARROT_CANNOT_RETURN_NULL
270 PARROT_IGNORABLE_RESULT
271 SymReg
* mk_ident_ur(PARROT_INTERP
, ARGIN(const char *name
), int t
)
272 __attribute__nonnull__(1)
273 __attribute__nonnull__(2);
275 PARROT_WARN_UNUSED_RESULT
276 PARROT_CANNOT_RETURN_NULL
277 SymReg
* mk_label_address(PARROT_INTERP
, ARGIN(const char *name
))
278 __attribute__nonnull__(1)
279 __attribute__nonnull__(2);
281 PARROT_WARN_UNUSED_RESULT
282 PARROT_CANNOT_RETURN_NULL
283 SymReg
* mk_local_label(PARROT_INTERP
, ARGIN(const char *name
))
284 __attribute__nonnull__(1)
285 __attribute__nonnull__(2);
287 PARROT_WARN_UNUSED_RESULT
288 PARROT_CANNOT_RETURN_NULL
289 SymReg
* mk_pasm_reg(PARROT_INTERP
, ARGIN(const char *name
))
290 __attribute__nonnull__(1)
291 __attribute__nonnull__(2);
293 PARROT_WARN_UNUSED_RESULT
294 PARROT_CANNOT_RETURN_NULL
295 SymReg
* mk_pcc_sub(PARROT_INTERP
, ARGIN(const char *name
), int proto
)
296 __attribute__nonnull__(1)
297 __attribute__nonnull__(2);
299 PARROT_WARN_UNUSED_RESULT
300 PARROT_CANNOT_RETURN_NULL
301 SymReg
* mk_sub_address(PARROT_INTERP
, ARGIN(const char *name
))
302 __attribute__nonnull__(1)
303 __attribute__nonnull__(2);
305 PARROT_WARN_UNUSED_RESULT
306 PARROT_CANNOT_RETURN_NULL
307 SymReg
* mk_sub_label(PARROT_INTERP
, ARGIN(const char *name
))
308 __attribute__nonnull__(1)
309 __attribute__nonnull__(2);
311 PARROT_WARN_UNUSED_RESULT
312 PARROT_CANNOT_RETURN_NULL
313 SymReg
* mk_symreg(PARROT_INTERP
, ARGIN(const char *name
), int t
)
314 __attribute__nonnull__(1)
315 __attribute__nonnull__(2);
317 PARROT_WARN_UNUSED_RESULT
318 PARROT_CANNOT_RETURN_NULL
319 SymReg
* mk_temp_reg(PARROT_INTERP
, int t
)
320 __attribute__nonnull__(1);
322 void pop_namespace(PARROT_INTERP
, ARGIN(const char *name
))
323 __attribute__nonnull__(1)
324 __attribute__nonnull__(2);
326 void push_namespace(PARROT_INTERP
, ARGIN(const char *name
))
327 __attribute__nonnull__(1)
328 __attribute__nonnull__(2);
330 void store_symreg(PARROT_INTERP
, ARGMOD(SymReg
*r
))
331 __attribute__nonnull__(1)
332 __attribute__nonnull__(2)
336 PARROT_WARN_UNUSED_RESULT
337 PARROT_CANNOT_RETURN_NULL
338 char * symreg_to_str(ARGIN(const SymReg
*s
))
339 __attribute__nonnull__(1);
341 #define ASSERT_ARGS__find_sym __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
342 PARROT_ASSERT_ARG(interp) \
343 , PARROT_ASSERT_ARG(hsh) \
344 , PARROT_ASSERT_ARG(name))
345 #define ASSERT_ARGS__get_sym __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
346 PARROT_ASSERT_ARG(hsh) \
347 , PARROT_ASSERT_ARG(name))
348 #define ASSERT_ARGS__mk_address __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
349 PARROT_ASSERT_ARG(interp) \
350 , PARROT_ASSERT_ARG(hsh) \
351 , PARROT_ASSERT_ARG(name))
352 #define ASSERT_ARGS__mk_const __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
353 PARROT_ASSERT_ARG(interp) \
354 , PARROT_ASSERT_ARG(hsh) \
355 , PARROT_ASSERT_ARG(name))
356 #define ASSERT_ARGS__store_symreg __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
357 PARROT_ASSERT_ARG(interp) \
358 , PARROT_ASSERT_ARG(hsh) \
359 , PARROT_ASSERT_ARG(r))
360 #define ASSERT_ARGS_add_namespace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
361 PARROT_ASSERT_ARG(interp) \
362 , PARROT_ASSERT_ARG(unit))
363 #define ASSERT_ARGS_add_pcc_arg __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
364 PARROT_ASSERT_ARG(interp) \
365 , PARROT_ASSERT_ARG(r) \
366 , PARROT_ASSERT_ARG(arg))
367 #define ASSERT_ARGS_add_pcc_cc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
368 PARROT_ASSERT_ARG(r) \
369 , PARROT_ASSERT_ARG(arg))
370 #define ASSERT_ARGS_add_pcc_multi __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
371 PARROT_ASSERT_ARG(interp) \
372 , PARROT_ASSERT_ARG(r))
373 #define ASSERT_ARGS_add_pcc_result __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
374 PARROT_ASSERT_ARG(interp) \
375 , PARROT_ASSERT_ARG(r) \
376 , PARROT_ASSERT_ARG(arg))
377 #define ASSERT_ARGS_add_pcc_sub __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
378 PARROT_ASSERT_ARG(r) \
379 , PARROT_ASSERT_ARG(arg))
380 #define ASSERT_ARGS_clear_globals __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
381 PARROT_ASSERT_ARG(interp))
382 #define ASSERT_ARGS_clear_locals __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
383 #define ASSERT_ARGS_clear_sym_hash __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
384 PARROT_ASSERT_ARG(hsh))
385 #define ASSERT_ARGS_create_symhash __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
386 PARROT_ASSERT_ARG(interp) \
387 , PARROT_ASSERT_ARG(hash))
388 #define ASSERT_ARGS_debug_dump_sym_hash __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
389 PARROT_ASSERT_ARG(hsh))
390 #define ASSERT_ARGS_dup_sym __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
391 PARROT_ASSERT_ARG(interp) \
392 , PARROT_ASSERT_ARG(r))
393 #define ASSERT_ARGS_find_sym __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
394 PARROT_ASSERT_ARG(interp) \
395 , PARROT_ASSERT_ARG(name))
396 #define ASSERT_ARGS_free_sym __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
397 PARROT_ASSERT_ARG(r))
398 #define ASSERT_ARGS_get_sym __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
399 PARROT_ASSERT_ARG(interp) \
400 , PARROT_ASSERT_ARG(name))
401 #define ASSERT_ARGS_hash_str __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
402 PARROT_ASSERT_ARG(str))
403 #define ASSERT_ARGS_link_keys __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
404 PARROT_ASSERT_ARG(interp) \
405 , PARROT_ASSERT_ARG(keys))
406 #define ASSERT_ARGS_mk_const __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
407 PARROT_ASSERT_ARG(interp) \
408 , PARROT_ASSERT_ARG(name))
409 #define ASSERT_ARGS_mk_const_ident __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
410 PARROT_ASSERT_ARG(interp) \
411 , PARROT_ASSERT_ARG(name) \
412 , PARROT_ASSERT_ARG(val))
413 #define ASSERT_ARGS_mk_ident __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
414 PARROT_ASSERT_ARG(interp) \
415 , PARROT_ASSERT_ARG(name))
416 #define ASSERT_ARGS_mk_ident_ur __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
417 PARROT_ASSERT_ARG(interp) \
418 , PARROT_ASSERT_ARG(name))
419 #define ASSERT_ARGS_mk_label_address __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
420 PARROT_ASSERT_ARG(interp) \
421 , PARROT_ASSERT_ARG(name))
422 #define ASSERT_ARGS_mk_local_label __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
423 PARROT_ASSERT_ARG(interp) \
424 , PARROT_ASSERT_ARG(name))
425 #define ASSERT_ARGS_mk_pasm_reg __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
426 PARROT_ASSERT_ARG(interp) \
427 , PARROT_ASSERT_ARG(name))
428 #define ASSERT_ARGS_mk_pcc_sub __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
429 PARROT_ASSERT_ARG(interp) \
430 , PARROT_ASSERT_ARG(name))
431 #define ASSERT_ARGS_mk_sub_address __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
432 PARROT_ASSERT_ARG(interp) \
433 , PARROT_ASSERT_ARG(name))
434 #define ASSERT_ARGS_mk_sub_label __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
435 PARROT_ASSERT_ARG(interp) \
436 , PARROT_ASSERT_ARG(name))
437 #define ASSERT_ARGS_mk_symreg __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
438 PARROT_ASSERT_ARG(interp) \
439 , PARROT_ASSERT_ARG(name))
440 #define ASSERT_ARGS_mk_temp_reg __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
441 PARROT_ASSERT_ARG(interp))
442 #define ASSERT_ARGS_pop_namespace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
443 PARROT_ASSERT_ARG(interp) \
444 , PARROT_ASSERT_ARG(name))
445 #define ASSERT_ARGS_push_namespace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
446 PARROT_ASSERT_ARG(interp) \
447 , PARROT_ASSERT_ARG(name))
448 #define ASSERT_ARGS_store_symreg __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
449 PARROT_ASSERT_ARG(interp) \
450 , PARROT_ASSERT_ARG(r))
451 #define ASSERT_ARGS_symreg_to_str __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
452 PARROT_ASSERT_ARG(s))
453 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
454 /* HEADERIZER END: compilers/imcc/symreg.c */
457 P_NONE
= 0x00, /* 0<<0 */
458 P_NEED_LEX
= 0x01, /* 1<<0 */
459 P_VTABLE
= SUB_COMP_FLAG_VTABLE
, /* 1<<1 0x2 */
460 P_METHOD
= SUB_COMP_FLAG_METHOD
, /* 1<<2 0x4 */
461 P_ANON
= SUB_FLAG_PF_ANON
, /* 1<<3 0x8 - private3 */
462 P_MAIN
= SUB_FLAG_PF_MAIN
, /* 1<<4 0x10 - private4 */
463 P_LOAD
= SUB_FLAG_PF_LOAD
, /* 1<<5 0x20 - private5 */
464 P_IMMEDIATE
= SUB_FLAG_PF_IMMEDIATE
, /* 1<<6 0x40 - private6 */
465 P_POSTCOMP
= SUB_FLAG_PF_POSTCOMP
, /* 1<<7 0x80 - private7 */
466 P_INIT
= SUB_COMP_FLAG_PF_INIT
, /* 1<<10 0x400 - 10 */
467 P_NSENTRY
= SUB_COMP_FLAG_NSENTRY
/* 1<<11 0x800 - 11 */
475 typedef struct pcc_sub_t
{
482 int *arg_flags
; /* :slurpy, :optional, ... */
483 int *ret_flags
; /* :slurpy, :optional, ... */
488 int flags
; /* isNCI, isTAIL_CALL */
500 #endif /* PARROT_IMCC_SYMREG_H_GUARD */
504 * c-file-style: "parrot"
506 * vim: expandtab shiftwidth=4: