cleanup backend: make pre_spill_prepare_constraint independent of chordal allocator...
[libfirm] / scripts / ir_spec.py
1 from spec_util import abstract, setnodedefaults
2
3 class Op(object):
4         "Base class for firm nodes"
5 abstract(Op)
6
7 class Unop(Op):
8         "Unary nodes have exactly 1 input"
9         name     = "unop"
10         ins      = [ "op" ]
11         op_index = 0
12         pinned   = "no"
13 abstract(Unop)
14
15 class Binop(Op):
16         "Binary nodes have exactly 2 inputs"
17         name     = "binop"
18         ins      = [ "left", "right" ]
19         op_index = 0
20         pinned   = "no"
21 abstract(Binop)
22
23 class Abs(Unop):
24         flags = []
25
26 class Add(Binop):
27         flags = ["commutative"]
28
29 class Alloc(Op):
30         ins   = [ "mem", "size" ]
31         outs  = [ "M", "X_regular", "X_except", "res" ]
32         flags = [ "fragile", "uses_memory" ]
33         attrs = [
34                 dict(
35                         name = "type",
36                         type = "ir_type*"
37                 ),
38                 dict(
39                         name = "where",
40                         type = "ir_where_alloc"
41                 )
42         ]
43         pinned      = "yes"
44         attr_struct = "alloc_attr"
45         d_post = '''
46         firm_alloc_frag_arr(res, op_Alloc, &res->attr.alloc.exc.frag_arr);
47         '''
48
49 class Anchor(Op):
50         mode        = "mode_ANY"
51         arity       = "variable"
52         flags       = [ "dump_noblock" ]
53         pinned      = "yes"
54         knownBlock  = True
55         singleton   = True
56
57 class And(Binop):
58         flags    = [ "commutative" ]
59
60 class ASM(Op):
61         mode          = "mode_T"
62         arity         = "variable"
63         flags         = [ "keep", "uses_memory" ]
64         attr_struct   = "asm_attr"
65         pinned        = "memory"
66         pinned_init   = "op_pin_state_pinned"
67         attrs = [
68                 dict(
69                         name = "input_constraints",
70                         type = "ir_asm_constraint*",
71                 ),
72                 dict(
73                         name = "n_output_constraints",
74                         type = "int",
75                 ),
76                 dict(
77                         name = "output_constraints",
78                         type = "ir_asm_constraint*",
79                 ),
80                 dict(
81                         name = "n_clobbers",
82                         type = "int",
83                 ),
84                 dict(
85                         name = "clobbers",
86                         type = "ident**",
87                 ),
88                 dict(
89                         name = "text",
90                         type = "ident*",
91                 ),
92         ]
93         java_noconstr = True
94
95 class Bad(Op):
96         mode        = "mode_Bad"
97         flags       = [ "cfopcode", "fragile", "start_block", "dump_noblock" ]
98         pinned      = "yes"
99         knownBlock  = True
100         singleton   = True
101         attr_struct = "irg_attr"
102         init = '''
103         res->attr.irg.irg = irg;
104         '''
105
106 class Block(Op):
107         mode        = "mode_BB"
108         knownBlock  = True
109         block       = "NULL"
110         pinned      = "yes"
111         optimize    = False
112         arity       = "variable"
113         flags       = [ "labeled" ]
114         attr_struct = "block_attr"
115         java_noconstr = True
116
117         init = '''
118         /* macroblock header */
119         res->in[0] = res;
120
121         res->attr.block.is_dead     = 0;
122         res->attr.block.is_mb_head  = 1;
123         res->attr.block.irg.irg     = irg;
124         res->attr.block.backedge    = new_backedge_arr(irg->obst, arity);
125         res->attr.block.in_cg       = NULL;
126         res->attr.block.cg_backedge = NULL;
127         res->attr.block.extblk      = NULL;
128         res->attr.block.mb_depth    = 0;
129         res->attr.block.entity      = NULL;
130
131         set_Block_matured(res, 1);
132         set_Block_block_visited(res, 0);
133         '''
134
135         d_pre = '''
136         int i;
137         int has_unknown = 0;
138         '''
139
140         d_post = '''
141         /* Create and initialize array for Phi-node construction. */
142         if (get_irg_phase_state(current_ir_graph) == phase_building) {
143                 res->attr.block.graph_arr = NEW_ARR_D(ir_node *, current_ir_graph->obst,
144                                                       current_ir_graph->n_loc);
145                 memset(res->attr.block.graph_arr, 0, sizeof(ir_node *)*current_ir_graph->n_loc);
146         }
147
148         for (i = arity - 1; i >= 0; i--)
149                 if (is_Unknown(in[i])) {
150                         has_unknown = 1;
151                         break;
152                 }
153
154         if (!has_unknown) res = optimize_node(res);
155
156         current_ir_graph->current_block = res;
157
158         IRN_VRFY_IRG(res, current_ir_graph);
159         '''
160
161         java_add   = '''
162         public void addPred(Node node) {
163                 binding_cons.add_immBlock_pred(ptr, node.ptr);
164         }
165
166         public void mature() {
167                 binding_cons.mature_immBlock(ptr);
168         }
169
170         @Override
171         public Block getBlock() {
172                 return null;
173         }
174
175         public boolean blockVisited() {
176                 return 0 != binding.Block_block_visited(ptr);
177         }
178
179         public void markBlockVisited() {
180                 binding.mark_Block_block_visited(ptr);
181         }
182
183         public boolean isBad() {
184                 return binding.is_Bad(ptr) != 0;
185         }
186         '''
187
188 class Borrow(Binop):
189         flags = []
190
191 class Bound(Op):
192         ins    = [ "mem", "index", "lower", "upper" ]
193         outs   = [ "M", "X_regular", "X_except", "res" ]
194         flags  = [ "fragile", "highlevel" ]
195         pinned = "exception"
196         pinned_init = "op_pin_state_pinned"
197         attr_struct = "bound_attr"
198         d_post = '''
199         firm_alloc_frag_arr(res, op_Bound, &res->attr.bound.exc.frag_arr);
200         '''
201
202 class Break(Op):
203         mode   = "mode_X"
204         flags  = [ "cfopcode" ]
205         pinned = "yes"
206
207 class Builtin(Op):
208         ins      = [ "mem" ]
209         arity    = "variable"
210         outs     = [ "M_regular", "X_regular", "X_except", "T_result", "M_except", "P_value_res_base" ]
211         flags    = [ "uses_memory" ]
212         attrs    = [
213                 dict(
214                         type = "ir_builtin_kind",
215                         name = "kind"
216                 ),
217                 dict(
218                         type = "ir_type*",
219                         name = "type"
220                 )
221         ]
222         pinned      = "memory"
223         pinned_init = "op_pin_state_pinned"
224         attr_struct = "builtin_attr"
225         init   = '''
226         assert((get_unknown_type() == type) || is_Method_type(type));
227         '''
228
229 class Call(Op):
230         ins      = [ "mem", "ptr" ]
231         arity    = "variable"
232         outs     = [ "M_regular", "X_regular", "X_except", "T_result", "M_except", "P_value_res_base" ]
233         flags    = [ "fragile", "uses_memory" ]
234         attrs    = [
235                 dict(
236                         type = "ir_type*",
237                         name = "type"
238                 )
239         ]
240         attr_struct = "call_attr"
241         pinned      = "memory"
242         pinned_init = "op_pin_state_pinned"
243         init = '''
244         assert((get_unknown_type() == type) || is_Method_type(type));
245         '''
246         d_post = '''
247         firm_alloc_frag_arr(res, op_Call, &res->attr.call.exc.frag_arr);
248         '''
249
250 class CallBegin(Op):
251         ins   = [ "ptr" ]
252         outs  = [ "" ] # TODO
253         flags         = [ "cfopcode", "ip_cfopcode" ]
254         pinned        = "yes"
255         # TODO: attribute with call...
256         attr_struct   = "callbegin_attr"
257         attrs         = [
258                 dict(
259                         type = "ir_node*",
260                         name = "call"
261                 )
262         ]
263         java_noconstr = True
264
265 class Carry(Binop):
266         flags = [ "commutative" ]
267
268 class Cast(Op):
269         ins      = [ "op" ]
270         mode     = "get_irn_mode(irn_op)"
271         flags    = [ "highlevel" ]
272         pinned   = "no"
273         attrs    = [
274                 dict(
275                         type = "ir_type*",
276                         name = "type"
277                 )
278         ]
279         attr_struct = "cast_attr"
280         init     = "assert(is_atomic_type(type));"
281
282 class Cmp(Binop):
283         outs  = [ "False", "Eq", "Lt", "Le", "Gt", "Ge", "Lg", "Leg", "Uo", "Ue", "Ul", "Ule", "Ug", "Uge", "Ne", "True" ]
284         flags = []
285
286 class Cond(Op):
287         ins      = [ "selector" ]
288         outs     = [ "false", "true" ]
289         flags    = [ "cfopcode", "forking" ]
290         pinned   = "yes"
291         attrs    = [
292                 dict(
293                         name = "kind",
294                         type = "cond_kind",
295                         init = "dense"
296                 ),
297                 dict(
298                         name = "default_proj",
299                         type = "long",
300                         init = "0"
301                 ),
302                 dict(
303                         name = "jmp_pred",
304                         type = "cond_jmp_predicate",
305                         init = "COND_JMP_PRED_NONE"
306                 )
307         ]
308         attr_struct = "cond_attr"
309
310 class Confirm(Op):
311         ins      = [ "value", "bound" ]
312         mode     = "get_irn_mode(irn_value)"
313         flags    = [ "highlevel" ]
314         pinned   = "yes"
315         attrs    = [
316                 dict(
317                         name = "cmp",
318                         type = "pn_Cmp"
319                 ),
320         ]
321         attr_struct = "confirm_attr"
322
323 class Const(Op):
324         mode       = ""
325         flags      = [ "constlike", "start_block" ]
326         knownBlock = True
327         pinned     = "no"
328         attrs_name = "con"
329         attrs      = [
330                 dict(
331                         type = "tarval*",
332                         name = "tarval",
333                 )
334         ]
335         attr_struct = "const_attr"
336
337 class Conv(Unop):
338         flags = []
339         attrs = [
340                 dict(
341                         name = "strict",
342                         type = "int",
343                         init = "0",
344                         special = dict(
345                                 prefix = "strict",
346                                 init = "1"
347                         )
348                 )
349         ]
350         attr_struct = "conv_attr"
351
352 class CopyB(Op):
353         ins   = [ "mem", "dst", "src" ]
354         outs  = [ "M", "X_regular", "X_except" ]
355         flags = [ "fragile", "highlevel", "uses_memory" ]
356         attrs = [
357                 dict(
358                         name = "type",
359                         type = "ir_type*"
360                 )
361         ]
362         attr_struct = "copyb_attr"
363         pinned      = "memory"
364         pinned_init = "op_pin_state_pinned"
365         d_post = '''
366         firm_alloc_frag_arr(res, op_CopyB, &res->attr.copyb.exc.frag_arr);
367         '''
368
369 class Div(Op):
370         ins   = [ "mem", "left", "right" ]
371         outs  = [ "M", "X_regular", "X_except", "res" ]
372         flags = [ "fragile", "uses_memory" ]
373         attrs_name = "divmod"
374         attrs = [
375                 dict(
376                         type = "ir_mode*",
377                         name = "resmode"
378                 ),
379                 dict(
380                         name = "no_remainder",
381                         type = "int",
382                         init = "0",
383                         special = dict(
384                                 suffix = "RL",
385                                 init = "1"
386                         )
387                 )
388         ]
389         attr_struct = "divmod_attr"
390         pinned      = "exception"
391         op_index    = 1
392         arity_override = "oparity_binary"
393         d_post = '''
394         firm_alloc_frag_arr(res, op_Div, &res->attr.except.frag_arr);
395         '''
396
397 class DivMod(Op):
398         ins   = [ "mem", "left", "right" ]
399         outs  = [ "M", "X_regular", "X_except", "res_div", "res_mod" ]
400         flags = [ "fragile", "uses_memory" ]
401         attrs_name = "divmod"
402         attrs = [
403                 dict(
404                         type = "ir_mode*",
405                         name = "resmode"
406                 ),
407         ]
408         attr_struct = "divmod_attr"
409         pinned      = "exception"
410         op_index    = 1
411         arity_override = "oparity_binary"
412         d_post = '''
413         firm_alloc_frag_arr(res, op_DivMod, &res->attr.except.frag_arr);
414         '''
415
416 class Dummy(Op):
417         ins   = []
418         flags = [ "cfopcode", "fragile", "start_block", "constlike",
419                   "dump_noblock" ]
420         knownBlock = True
421         pinned     = "yes"
422         block      = "get_irg_start_block(irg)"
423
424 class End(Op):
425         mode       = "mode_X"
426         pinned     = "yes"
427         arity      = "dynamic"
428         flags      = [ "cfopcode" ]
429         singleton  = True
430
431 class EndExcept(Op):
432         mode      = "mode_X"
433         pinned    = "yes"
434         arity     = "dynamic"
435         flags     = [ "cfopcode", "ip_cfopcode" ]
436         singleton = True
437
438 class EndReg(Op):
439         mode      = "mode_X"
440         pinned    = "yes"
441         arity     = "dynamic"
442         flags     = [ "cfopcode", "ip_cfopcode" ]
443         singleton = True
444
445 class Eor(Binop):
446         flags    = [ "commutative" ]
447
448 class Filter(Op):
449         ins   = [ "pred" ]
450         flags = []
451         attrs = [
452                 dict(
453                         name = "proj",
454                         type = "long"
455                 )
456         ]
457         pinned      = "yes"
458         attr_struct = "filter_attr"
459         java_noconstr = True
460
461 class Free(Op):
462         ins    = [ "mem", "ptr", "size" ]
463         mode   = "mode_M"
464         flags  = [ "uses_memory" ]
465         pinned = "yes"
466         attrs  = [
467                 dict(
468                         name = "type",
469                         type = "ir_type*"
470                 ),
471                 dict(
472                         name = "where",
473                         type = "ir_where_alloc"
474                 )
475         ]
476         attr_struct = "free_attr"
477
478 class Id(Op):
479         ins    = [ "pred" ]
480         pinned = "no"
481         flags  = []
482
483 class IJmp(Op):
484         mode     = "mode_X"
485         pinned   = "yes"
486         ins      = [ "target" ]
487         flags    = [ "cfopcode", "forking", "keep" ]
488
489 class InstOf(Op):
490         ins   = [ "store", "obj" ]
491         outs  = [ "M", "X_regular", "X_except", "res", "M_except" ]
492         flags = [ "highlevel" ]
493         attrs = [
494                 dict(
495                         name = "type",
496                         type = "ir_type*"
497                 )
498         ]
499         attr_struct = "io_attr"
500         pinned      = "memory"
501         pinned_init = "op_pin_state_floats"
502
503 class Jmp(Op):
504         mode     = "mode_X"
505         pinned   = "yes"
506         ins      = []
507         flags    = [ "cfopcode" ]
508
509 class Load(Op):
510         ins      = [ "mem", "ptr" ]
511         outs     = [ "M", "X_regular", "X_except", "res" ]
512         flags    = [ "fragile", "uses_memory" ]
513         pinned   = "exception"
514         pinned_init = "flags & cons_floats ? op_pin_state_floats : op_pin_state_pinned"
515         attrs    = [
516                 dict(
517                         type = "ir_mode*",
518                         name = "mode",
519                         java_name = "load_mode"
520                 ),
521         ]
522         attr_struct = "load_attr"
523         constructor_args = [
524                 dict(
525                         type = "ir_cons_flags",
526                         name = "flags",
527                 ),
528         ]
529         d_post = '''
530         firm_alloc_frag_arr(res, op_Load, &res->attr.load.exc.frag_arr);
531         '''
532
533 class Minus(Unop):
534         flags = []
535
536 class Mod(Op):
537         ins   = [ "mem", "left", "right" ]
538         outs  = [ "M", "X_regular", "X_except", "res" ]
539         flags = [ "fragile", "uses_memory" ]
540         attrs_name = "divmod"
541         attrs = [
542                 dict(
543                         type = "ir_mode*",
544                         name = "resmode"
545                 ),
546         ]
547         attr_struct = "divmod_attr"
548         pinned      = "exception"
549         op_index    = 1
550         arity_override = "oparity_binary"
551         d_post = '''
552         firm_alloc_frag_arr(res, op_Mod, &res->attr.except.frag_arr);
553         '''
554
555 class Mul(Binop):
556         flags = [ "commutative" ]
557
558 class Mulh(Binop):
559         flags = [ "commutative" ]
560
561 class Mux(Op):
562         ins    = [ "sel", "false", "true" ]
563         flags  = []
564         pinned = "no"
565
566 class NoMem(Op):
567         mode       = "mode_M"
568         flags      = [ "dump_noblock", "dump_noinput" ]
569         pinned     = "yes"
570         knownBlock = True
571         singleton  = True
572
573 class Not(Unop):
574         flags = []
575
576 class Or(Binop):
577         flags = [ "commutative" ]
578
579 class Phi(Op):
580         pinned      = "yes"
581         arity       = "variable"
582         flags       = []
583         attr_struct = "phi_attr"
584         custom_is   = True
585         java_noconstr = True
586         init = '''
587         /* Memory Phis in endless loops must be kept alive.
588            As we can't distinguish these easily we keep all of them alive. */
589         if (is_Phi(res) && mode == mode_M)
590                 add_End_keepalive(get_irg_end(irg), res);
591         '''
592
593 class Pin(Op):
594         ins      = [ "op" ]
595         mode     = "get_irn_mode(irn_op)"
596         flags    = [ "highlevel" ]
597         pinned   = "yes"
598
599 class Proj(Op):
600         ins      = [ "pred" ]
601         flags    = []
602         pinned   = "no"
603         attrs    = [
604                 dict(
605                         type = "long",
606                         name = "proj",
607                         initname = ""
608                 )
609         ]
610         attr_struct = "long"
611         custom_is   = True
612
613 class Quot(Op):
614         ins   = [ "mem", "left", "right" ]
615         outs  = [ "M", "X_regular", "X_except", "res" ]
616         flags = [ "fragile", "uses_memory" ]
617         attrs_name = "divmod"
618         attrs = [
619                 dict(
620                         type = "ir_mode*",
621                         name = "resmode"
622                 ),
623         ]
624         attr_struct = "divmod_attr"
625         pinned      = "exception"
626         op_index    = 1
627         arity_override = "oparity_binary"
628         d_post = '''
629         firm_alloc_frag_arr(res, op_Quot, &res->attr.except.frag_arr);
630         '''
631
632 class Raise(Op):
633         ins    = [ "mem", "exo_ptr" ]
634         outs   = [ "M", "X" ]
635         flags  = [ "highlevel", "cfopcode" ]
636         pinned = "yes"
637
638 class Return(Op):
639         ins      = [ "mem" ]
640         arity    = "variable"
641         mode     = "mode_X"
642         flags    = [ "cfopcode" ]
643         pinned   = "yes"
644
645 class Rotl(Binop):
646         flags    = []
647
648 class Sel(Op):
649         ins    = [ "mem", "ptr" ]
650         arity  = "variable"
651         flags  = []
652         mode   = "is_Method_type(get_entity_type(entity)) ? mode_P_code : mode_P_data"
653         pinned = "no"
654         attrs  = [
655                 dict(
656                         type = "ir_entity*",
657                         name = "entity"
658                 )
659         ]
660         attr_struct = "sel_attr"
661
662 class Shl(Binop):
663         flags = []
664
665 class Shr(Binop):
666         flags = []
667
668 class Shrs(Binop):
669         flags = []
670
671 class Start(Op):
672         mode       = "mode_T"
673         pinned     = "yes"
674         flags      = [ "cfopcode" ]
675         singleton  = True
676
677 class Store(Op):
678         ins      = [ "mem", "ptr", "value" ]
679         outs     = [ "M", "X_regular", "X_except" ]
680         flags    = [ "fragile", "uses_memory" ]
681         pinned   = "exception"
682         attr_struct = "store_attr"
683         pinned_init = "flags & cons_floats ? op_pin_state_floats : op_pin_state_pinned"
684         constructor_args = [
685                 dict(
686                         type = "ir_cons_flags",
687                         name = "flags",
688                 ),
689         ]
690         d_post = '''
691         firm_alloc_frag_arr(res, op_Store, &res->attr.store.exc.frag_arr);
692         '''
693
694 class Sub(Binop):
695         flags = []
696
697 class SymConst(Op):
698         mode       = "mode_P"
699         flags      = [ "constlike", "start_block" ]
700         knownBlock = True
701         pinned     = "no"
702         attrs      = [
703                 dict(
704                         type = "ir_entity*",
705                         name = "entity"
706                 )
707         ]
708         attr_struct = "symconst_attr"
709         java_noconstr = True
710
711 class Sync(Op):
712         mode     = "mode_M"
713         flags    = []
714         pinned   = "no"
715         optimize = False
716         arity    = "dynamic"
717
718 class Tuple(Op):
719         arity  = "variable"
720         mode   = "mode_T"
721         pinned = "no"
722         flags  = [ "labeled" ]
723         java_noconstr = True
724
725 class Unknown(Op):
726         knownBlock = True
727         pinned     = "yes"
728         block      = "get_irg_start_block(irg)"
729         flags      = [ "cfopcode", "fragile", "start_block", "constlike",
730                        "dump_noblock" ]
731
732 # Prepare node list
733
734 def getOpList(namespace):
735         nodes = []
736         for t in namespace.values():
737                 if type(t) != type:
738                         continue
739
740                 if issubclass(t, Op):
741                         setnodedefaults(t)
742                         nodes.append(t)
743         return nodes
744
745 nodes = getOpList(globals())
746 nodes = sorted(nodes, lambda x,y: cmp(x.name, y.name))