1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
2 ** All rights reserved.
4 ** Authors: Martin Trapp, Christian Schaefer
6 ** ircons.c: basic and more detailed irnode constructors
7 ** store, block and parameter administration ,
8 ** Adapted to extended FIRM nodes (exceptions...) and commented
9 ** by Goetz Lindenmaier
15 /* memset belongs to string.h */
19 /*********************************************** */
20 /** privat interfaces, for professional use only */
24 new_r_Block (ir_graph *irg, int arity, ir_node **in)
28 res = new_ir_node (current_ir_graph, NULL, op_Block, mode_R, -1, NULL);
35 new_r_Start (ir_graph *irg, ir_node *block)
39 res = new_ir_node (irg, block, op_Start, mode_T, 0, NULL);
47 new_r_End (ir_graph *irg, ir_node *block)
51 res = new_ir_node (irg, block, op_End, mode_X, -1, NULL);
59 /* Creates a Phi node with 0 predecessors */
61 new_r_Phi0 (ir_graph *irg, ir_node *block, ir_mode *mode)
65 res = new_ir_node (irg, block, op_Phi, mode, 0, NULL);
67 /* GL I'm not sure whether we should optimize this guy. *
68 res = optimize (res); ??? */
73 /* Creates a Phi node with all predecessors. Calling this constructor
74 is only allowed if the corresponding block is mature. */
76 new_r_Phi (ir_graph *irg, ir_node *block, int arity, ir_node **in, ir_mode *mode)
80 assert( get_Block_matured(block) );
81 assert( get_irn_arity(block) == arity );
83 res = new_ir_node (irg, block, op_Phi, mode, arity, in);
90 /* This is a stack used for allocating and deallocating nodes in
91 new_r_Phi_in. The original implementation used the obstack
92 to model this stack, now it is explicit. This reduces side effects.
94 #if USE_EXPICIT_PHI_IN_STACK
99 res = (Phi_in_stack *) malloc ( sizeof (Phi_in_stack));
101 res->stack = NEW_ARR_F (ir_node *, 1);
108 void free_to_Phi_in_stack(ir_node *phi) {
109 assert(get_irn_opcode(phi) == iro_Phi);
111 if (ARR_LEN(current_ir_graph->Phi_in_stack->stack) ==
112 current_ir_graph->Phi_in_stack->pos)
113 ARR_APP1 (ir_node *, current_ir_graph->Phi_in_stack->stack, phi);
115 current_ir_graph->Phi_in_stack->stack[current_ir_graph->Phi_in_stack->pos] = phi;
117 (current_ir_graph->Phi_in_stack->pos)++;
121 alloc_or_pop_from_Phi_in_stack(ir_graph *irg, ir_node *block, ir_mode *mode,
122 int arity, ir_node **in) {
124 ir_node **stack = current_ir_graph->Phi_in_stack->stack;
125 int pos = current_ir_graph->Phi_in_stack->pos;
129 /* We need to allocate a new node */
130 res = new_ir_node (irg, block, op_Phi, mode, arity, in);
132 /* reuse the old node and initialize it again. */
135 assert (res->kind == k_ir_node);
136 assert (res->op == op_Phi);
141 /* ???!!! How to free the old in array?? */
142 res->in = NEW_ARR_D (ir_node *, irg->obst, (arity+1));
144 memcpy (&res->in[1], in, sizeof (ir_node *) * arity);
146 (current_ir_graph->Phi_in_stack->pos)--;
154 /* Creates a Phi node with a given, fixed array **in of predecessors.
155 If the Phi node is unnecessary, as the same value reaches the block
156 through all control flow paths, it is eliminated and the value
157 returned directly. This constructor is only intended for use in
158 the automatic Phi node generation triggered by get_value or mature.
159 The implementation is quite tricky and depends on the fact, that
160 the nodes are allocated on a stack:
161 The in array contains predecessors and NULLs. The NULLs appear,
162 if get_r_value_internal, that computed the predecessors, reached
163 the same block on two paths. In this case the same value reaches
164 this block on both paths, there is no definition in between. We need
165 not allocate a Phi where these path's merge, but we have to communicate
166 this fact to the caller. This happens by returning a pointer to the
167 node the caller _will_ allocate. (Yes, we predict the address. We can
168 do so because the nodes are allocated on the obstack.) The caller then
169 finds a pointer to itself and, when this routine is called again,
173 new_r_Phi_in (ir_graph *irg, ir_node *block, ir_mode *mode,
174 ir_node **in, int ins)
177 ir_node *res, *known;
179 /* allocate a new node on the obstack.
180 This can return a node to which some of the pointers in the in-array
182 Attention: the constructor copies the in array, i.e., the later changes
183 to the array in this routine do not affect the constructed node! If
184 the in array contains NULLs, there will be missing predecessors in the
186 Is this a possible internal state of the Phi node generation? */
187 #if USE_EXPICIT_PHI_IN_STACK
188 res = known = alloc_or_pop_from_Phi_in_stack(irg, block, mode, ins, in);
190 res = known = new_ir_node (irg, block, op_Phi, mode, ins, in);
192 /* The in-array can contain NULLs. These were returned by get_r_value_internal
193 if it reached the same block/definition on a second path.
194 The NULLs are replaced by the node itself to simplify the test in the
196 for (i=0; i < ins; ++i)
197 if (in[i] == NULL) in[i] = res;
199 /* This loop checks whether the Phi has more than one predecessor.
200 If so, it is a real Phi node and we break the loop. Else the
201 Phi node merges the same definition on several paths and therefore
203 for (i=0; i < ins; ++i)
205 if (in[i]==res || in[i]==known) continue;
213 /* i==ins: there is at most one predecessor, we don't need a phi node. */
215 #if USE_EXPICIT_PHI_IN_STACK
216 free_to_Phi_in_stack(res);
218 obstack_free (current_ir_graph->obst, res);
222 res = optimize (res);
226 /* return the pointer to the Phi node. This node might be deallocated! */
231 new_r_Const (ir_graph *irg, ir_node *block, ir_mode *mode, tarval *con)
234 res = new_ir_node (irg, block, op_Const, mode, 0, NULL);
236 res = optimize (res);
240 res = local_optimize_newby (res);
247 new_r_Id (ir_graph *irg, ir_node *block, ir_node *val, ir_mode *mode)
249 ir_node *in[1] = {val};
251 res = new_ir_node (irg, block, op_Id, mode, 1, in);
252 res = optimize (res);
258 new_r_Proj (ir_graph *irg, ir_node *block, ir_node *arg, ir_mode *mode, long proj)
260 ir_node *in[1] = {arg};
262 res = new_ir_node (irg, block, op_Proj, mode, 1, in);
263 res->attr.proj = proj;
264 res = optimize (res);
271 new_r_Conv (ir_graph *irg, ir_node *block, ir_node *op, ir_mode *mode)
273 ir_node *in[1] = {op};
275 res = new_ir_node (irg, block, op_Conv, mode, 1, in);
276 res = optimize (res);
283 new_r_Tuple (ir_graph *irg, ir_node *block, int arity, ir_node **in)
287 res = new_ir_node (irg, block, op_Tuple, mode_T, arity, in);
288 res = optimize (res);
294 new_r_Add (ir_graph *irg, ir_node *block,
295 ir_node *op1, ir_node *op2, ir_mode *mode)
297 ir_node *in[2] = {op1, op2};
299 res = new_ir_node (irg, block, op_Add, mode, 2, in);
300 res = optimize (res);
306 new_r_Sub (ir_graph *irg, ir_node *block,
307 ir_node *op1, ir_node *op2, ir_mode *mode)
309 ir_node *in[2] = {op1, op2};
311 res = new_ir_node (irg, block, op_Sub, mode, 2, in);
312 res = optimize (res);
318 new_r_Minus (ir_graph *irg, ir_node *block,
319 ir_node *op, ir_mode *mode)
321 ir_node *in[1] = {op};
323 res = new_ir_node (irg, block, op_Minus, mode, 1, in);
324 res = optimize (res);
330 new_r_Mul (ir_graph *irg, ir_node *block,
331 ir_node *op1, ir_node *op2, ir_mode *mode)
333 ir_node *in[2] = {op1, op2};
335 res = new_ir_node (irg, block, op_Mul, mode, 2, in);
336 res = optimize (res);
342 new_r_Quot (ir_graph *irg, ir_node *block,
343 ir_node *memop, ir_node *op1, ir_node *op2)
345 ir_node *in[3] = {memop, op1, op2};
347 res = new_ir_node (irg, block, op_Quot, mode_T, 2, in);
348 res = optimize (res);
354 new_r_DivMod (ir_graph *irg, ir_node *block,
355 ir_node *memop, ir_node *op1, ir_node *op2)
357 ir_node *in[3] = {memop, op1, op2};
359 res = new_ir_node (irg, block, op_DivMod, mode_T, 2, in);
360 res = optimize (res);
366 new_r_Div (ir_graph *irg, ir_node *block,
367 ir_node *memop, ir_node *op1, ir_node *op2)
369 ir_node *in[3] = {memop, op1, op2};
371 res = new_ir_node (irg, block, op_Div, mode_T, 2, in);
372 res = optimize (res);
378 new_r_Mod (ir_graph *irg, ir_node *block,
379 ir_node *memop, ir_node *op1, ir_node *op2)
381 ir_node *in[3] = {memop, op1, op2};
383 res = new_ir_node (irg, block, op_Mod, mode_T, 2, in);
384 res = optimize (res);
390 new_r_And (ir_graph *irg, ir_node *block,
391 ir_node *op1, ir_node *op2, ir_mode *mode)
393 ir_node *in[2] = {op1, op2};
395 res = new_ir_node (irg, block, op_And, mode, 2, in);
396 res = optimize (res);
402 new_r_Or (ir_graph *irg, ir_node *block,
403 ir_node *op1, ir_node *op2, ir_mode *mode)
405 ir_node *in[2] = {op1, op2};
407 res = new_ir_node (irg, block, op_Or, mode, 2, in);
408 res = optimize (res);
414 new_r_Eor (ir_graph *irg, ir_node *block,
415 ir_node *op1, ir_node *op2, ir_mode *mode)
417 ir_node *in[2] = {op1, op2};
419 res = new_ir_node (irg, block, op_Eor, mode, 2, in);
420 res = optimize (res);
426 new_r_Not (ir_graph *irg, ir_node *block,
427 ir_node *op, ir_mode *mode)
429 ir_node *in[1] = {op};
431 res = new_ir_node (irg, block, op_Not, mode, 1, in);
432 res = optimize (res);
438 new_r_Shl (ir_graph *irg, ir_node *block,
439 ir_node *op, ir_node *k, ir_mode *mode)
441 ir_node *in[2] = {op, k};
443 res = new_ir_node (irg, block, op_Shl, mode, 2, in);
444 res = optimize (res);
450 new_r_Shr (ir_graph *irg, ir_node *block,
451 ir_node *op, ir_node *k, ir_mode *mode)
453 ir_node *in[2] = {op, k};
455 res = new_ir_node (irg, block, op_Shr, mode, 2, in);
456 res = optimize (res);
462 new_r_Shrs (ir_graph *irg, ir_node *block,
463 ir_node *op, ir_node *k, ir_mode *mode)
465 ir_node *in[2] = {op, k};
467 res = new_ir_node (irg, block, op_Shrs, mode, 2, in);
468 res = optimize (res);
474 new_r_Rot (ir_graph *irg, ir_node *block,
475 ir_node *op, ir_node *k, ir_mode *mode)
477 ir_node *in[2] = {op, k};
479 res = new_ir_node (irg, block, op_Rot, mode, 2, in);
480 res = optimize (res);
486 new_r_Abs (ir_graph *irg, ir_node *block,
487 ir_node *op, ir_mode *mode)
489 ir_node *in[1] = {op};
491 res = new_ir_node (irg, block, op_Abs, mode, 1, in);
492 res = optimize (res);
498 new_r_Cmp (ir_graph *irg, ir_node *block,
499 ir_node *op1, ir_node *op2)
501 ir_node *in[2] = {op1, op2};
503 res = new_ir_node (irg, block, op_Cmp, mode_T, 2, in);
504 res = optimize (res);
510 new_r_Jmp (ir_graph *irg, ir_node *block)
514 res = new_ir_node (irg, block, op_Jmp, mode_X, 0, in);
515 res = optimize (res);
521 new_r_Cond (ir_graph *irg, ir_node *block, ir_node *c)
523 ir_node *in[1] = {c};
525 res = new_ir_node (irg, block, op_Cond, mode_T, 1, in);
526 res = optimize (res);
532 new_r_Call (ir_graph *irg, ir_node *block, ir_node *store,
533 ir_node *callee, int arity, ir_node **in, type_method *type)
540 NEW_ARR_A (ir_node *, r_in, r_arity);
543 memcpy (&r_in[2], in, sizeof (ir_node *) * arity);
545 res = new_ir_node (irg, block, op_Call, mode_T, r_arity, r_in);
547 set_Call_type(res, type);
548 res = optimize (res);
554 new_r_Return (ir_graph *irg, ir_node *block,
555 ir_node *store, int arity, ir_node **in)
563 NEW_ARR_A (ir_node *, r_in, r_arity);
567 memcpy (&r_in[1], in, sizeof (ir_node *) * arity);
569 res = new_ir_node (irg, block, op_Return, mode_X, r_arity, r_in);
571 res = optimize (res);
578 new_r_Raise (ir_graph *irg, ir_node *block, ir_node *store, ir_node *obj)
580 ir_node *in[2] = {store, obj};
582 res = new_ir_node (irg, block, op_Raise, mode_X, 2, in);
584 res = optimize (res);
590 new_r_Load (ir_graph *irg, ir_node *block,
591 ir_node *store, ir_node *adr)
593 ir_node *in[2] = {store, adr};
595 res = new_ir_node (irg, block, op_Load, mode_T, 2, in);
597 res = optimize (res);
603 new_r_Store (ir_graph *irg, ir_node *block,
604 ir_node *store, ir_node *adr, ir_node *val)
606 ir_node *in[3] = {store, adr, val};
608 res = new_ir_node (irg, block, op_Store, mode_T, 3, in);
610 res = optimize (res);
616 new_r_Alloc (ir_graph *irg, ir_node *block, ir_node *store,
617 ir_node *size, type *alloc_type, where_alloc where)
619 ir_node *in[2] = {store, size};
621 res = new_ir_node (irg, block, op_Alloc, mode_T, 2, in);
623 res->attr.a.where = where;
624 res->attr.a.type = alloc_type;
626 res = optimize (res);
632 new_r_Free (ir_graph *irg, ir_node *block, ir_node *store,
633 ir_node *ptr, ir_node *size, type *free_type)
635 ir_node *in[3] = {store, ptr, size};
637 res = new_ir_node (irg, block, op_Free, mode_T, 3, in);
639 res->attr.f = free_type;
641 res = optimize (res);
647 new_r_Sel (ir_graph *irg, ir_node *block, ir_node *store, ir_node *objptr,
648 int arity, ir_node **in, entity *ent)
655 NEW_ARR_A (ir_node *, r_in, r_arity);
658 memcpy (&r_in[2], in, sizeof (ir_node *) * arity);
659 res = new_ir_node (irg, block, op_Sel, mode_p, r_arity, r_in);
661 res->attr.s.ltyp = static_linkage;
662 res->attr.s.ent = ent;
664 res = optimize (res);
670 new_r_SymConst (ir_graph *irg, ir_node *block, type_or_id *value,
671 symconst_kind symkind)
675 res = new_ir_node (irg, block, op_SymConst, mode_I, 0, in);
677 res->attr.i.num = symkind;
678 if (symkind == linkage_ptr_info) {
679 res->attr.i.tori.ptrinfo = (ident *)value;
681 assert ( ( (symkind == type_tag)
682 || (symkind == size))
683 && (is_type(value)));
684 res->attr.i.tori.typ = (type *)value;
686 res = optimize (res);
692 new_r_Sync (ir_graph *irg, ir_node *block, int arity, ir_node **in)
696 res = new_ir_node (irg, block, op_Sync, mode_M, arity, in);
698 res = optimize (res);
705 new_r_Bad (ir_node *block)
707 return current_ir_graph->bad;
710 /***********************/
711 /** public interfaces */
712 /** construction tools */
719 res = new_ir_node (current_ir_graph, current_ir_graph->current_block,
720 op_Start, mode_T, 0, NULL);
722 res = optimize (res);
733 res = new_ir_node (current_ir_graph, current_ir_graph->current_block,
734 op_End, mode_X, -1, NULL);
736 res = optimize (res);
747 res = new_ir_node (current_ir_graph, NULL, op_Block, mode_R, -1, NULL);
748 current_ir_graph->current_block = res;
749 res->attr.block.matured = 0;
750 set_Block_block_visit(res, 0);
752 /* forget this optimization. use this only if mature !!!!
753 res = optimize (res); */
756 /** create a new dynamic array, which stores all parameters in irnodes */
757 /** using the same obstack as the whole irgraph */
758 res->attr.block.graph_arr = NEW_ARR_D (ir_node *, current_ir_graph->obst,
759 current_ir_graph->params);
761 /** initialize the parameter array */
762 memset(res->attr.block.graph_arr, 0, sizeof(ir_node *)*current_ir_graph->params);
769 new_Phi (int arity, ir_node **in, ir_mode *mode)
771 return new_r_Phi (current_ir_graph, current_ir_graph->current_block,
776 new_Const (ir_mode *mode, tarval *con)
778 return new_r_Const (current_ir_graph, current_ir_graph->start_block,
783 new_Id (ir_node *val, ir_mode *mode)
785 return new_r_Id (current_ir_graph, current_ir_graph->current_block,
790 new_Proj (ir_node *arg, ir_mode *mode, long proj)
792 return new_r_Proj (current_ir_graph, current_ir_graph->current_block,
797 new_Conv (ir_node *op, ir_mode *mode)
799 return new_r_Conv (current_ir_graph, current_ir_graph->current_block,
804 new_Tuple (int arity, ir_node **in)
806 return new_r_Tuple (current_ir_graph, current_ir_graph->current_block,
811 new_Add (ir_node *op1, ir_node *op2, ir_mode *mode)
813 return new_r_Add (current_ir_graph, current_ir_graph->current_block,
818 new_Sub (ir_node *op1, ir_node *op2, ir_mode *mode)
820 return new_r_Sub (current_ir_graph, current_ir_graph->current_block,
826 new_Minus (ir_node *op, ir_mode *mode)
828 return new_r_Minus (current_ir_graph, current_ir_graph->current_block,
833 new_Mul (ir_node *op1, ir_node *op2, ir_mode *mode)
835 return new_r_Mul (current_ir_graph, current_ir_graph->current_block,
840 new_Quot (ir_node *memop, ir_node *op1, ir_node *op2)
842 return new_r_Quot (current_ir_graph, current_ir_graph->current_block,
847 new_DivMod (ir_node *memop, ir_node *op1, ir_node *op2)
849 return new_r_DivMod (current_ir_graph, current_ir_graph->current_block,
854 new_Div (ir_node *memop, ir_node *op1, ir_node *op2)
856 return new_r_Div (current_ir_graph, current_ir_graph->current_block,
861 new_Mod (ir_node *memop, ir_node *op1, ir_node *op2)
863 return new_r_Mod (current_ir_graph, current_ir_graph->current_block,
868 new_And (ir_node *op1, ir_node *op2, ir_mode *mode)
870 return new_r_And (current_ir_graph, current_ir_graph->current_block,
875 new_Or (ir_node *op1, ir_node *op2, ir_mode *mode)
877 return new_r_Or (current_ir_graph, current_ir_graph->current_block,
882 new_Eor (ir_node *op1, ir_node *op2, ir_mode *mode)
884 return new_r_Eor (current_ir_graph, current_ir_graph->current_block,
889 new_Not (ir_node *op, ir_mode *mode)
891 return new_r_Not (current_ir_graph, current_ir_graph->current_block,
896 new_Shl (ir_node *op, ir_node *k, ir_mode *mode)
898 return new_r_Shl (current_ir_graph, current_ir_graph->current_block,
903 new_Shr (ir_node *op, ir_node *k, ir_mode *mode)
905 return new_r_Shr (current_ir_graph, current_ir_graph->current_block,
910 new_Shrs (ir_node *op, ir_node *k, ir_mode *mode)
912 return new_r_Shrs (current_ir_graph, current_ir_graph->current_block,
917 new_Rotate (ir_node *op, ir_node *k, ir_mode *mode)
919 return new_r_Rot (current_ir_graph, current_ir_graph->current_block,
924 new_Abs (ir_node *op, ir_mode *mode)
926 return new_r_Abs (current_ir_graph, current_ir_graph->current_block,
931 new_Cmp (ir_node *op1, ir_node *op2)
933 return new_r_Cmp (current_ir_graph, current_ir_graph->current_block,
940 return new_r_Jmp (current_ir_graph, current_ir_graph->current_block);
944 new_Cond (ir_node *c)
946 return new_r_Cond (current_ir_graph, current_ir_graph->current_block, c);
950 new_Call (ir_node *store, ir_node *callee, int arity, ir_node **in,
953 return new_r_Call (current_ir_graph, current_ir_graph->current_block,
954 store, callee, arity, in, type);
957 /* make M parameter in call explicit:
958 new_Return (ir_node* store, int arity, ir_node **in) */
960 new_Return (ir_node* store, int arity, ir_node **in)
962 return new_r_Return (current_ir_graph, current_ir_graph->current_block,
967 new_Raise (ir_node *store, ir_node *obj)
969 return new_r_Raise (current_ir_graph, current_ir_graph->current_block,
974 new_Load (ir_node *store, ir_node *addr)
976 return new_r_Load (current_ir_graph, current_ir_graph->current_block,
981 new_Store (ir_node *store, ir_node *addr, ir_node *val)
983 return new_r_Store (current_ir_graph, current_ir_graph->current_block,
988 new_Alloc (ir_node *store, ir_node *size, type *alloc_type,
991 return new_r_Alloc (current_ir_graph, current_ir_graph->current_block,
992 store, size, alloc_type, where);
996 new_Free (ir_node *store, ir_node *ptr, ir_node *size, type *free_type)
998 return new_r_Free (current_ir_graph, current_ir_graph->current_block,
999 store, ptr, size, free_type);
1003 new_simpleSel (ir_node *store, ir_node *objptr, entity *ent)
1004 /* GL: objptr was called frame before. Frame was a bad choice for the name
1005 as the operand could as well be a pointer to a dynamic object. */
1007 return new_r_Sel (current_ir_graph, current_ir_graph->current_block,
1008 store, objptr, 0, NULL, ent);
1012 new_Sel (ir_node *store, ir_node *objptr, int n_index, ir_node **index, entity *sel)
1014 return new_r_Sel (current_ir_graph, current_ir_graph->current_block,
1015 store, objptr, n_index, index, sel);
1019 new_SymConst (type_or_id *value, symconst_kind kind)
1021 return new_r_SymConst (current_ir_graph, current_ir_graph->current_block,
1026 new_Sync (int arity, ir_node** in)
1028 return new_r_Sync (current_ir_graph, current_ir_graph->current_block,
1036 return current_ir_graph->bad;
1040 /************************/
1041 /* ir block constructor */
1043 /* GL: what's this good for? */
1045 typedef struct ir_block {
1048 /* -1 = error, 0 = OK */
1065 /* call once for each run of the library */