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
19 /* memset belongs to string.h */
22 #if USE_EXPICIT_PHI_IN_STACK
23 /* A stack needed for the automatic Phi node construction in constructor
31 /*********************************************** */
32 /** privat interfaces, for professional use only */
36 new_r_Block (ir_graph *irg, int arity, ir_node **in)
40 res = new_ir_node (current_ir_graph, NULL, op_Block, mode_R, -1, NULL);
46 new_r_Start (ir_graph *irg, ir_node *block)
50 res = new_ir_node (irg, block, op_Start, mode_T, 0, NULL);
57 new_r_End (ir_graph *irg, ir_node *block)
61 res = new_ir_node (irg, block, op_End, mode_X, -1, NULL);
67 /* Creates a Phi node with 0 predecessors */
69 new_r_Phi0 (ir_graph *irg, ir_node *block, ir_mode *mode)
73 res = new_ir_node (irg, block, op_Phi, mode, 0, NULL);
75 /* GL I'm not sure whether we should optimize this guy. *
76 res = optimize (res); ??? */
81 /* Creates a Phi node with all predecessors. Calling this constructor
82 is only allowed if the corresponding block is mature. */
84 new_r_Phi (ir_graph *irg, ir_node *block, int arity, ir_node **in, ir_mode *mode)
88 assert( get_Block_matured(block) );
89 assert( get_irn_arity(block) == arity );
91 res = new_ir_node (irg, block, op_Phi, mode, arity, in);
98 /* This is a stack used for allocating and deallocating nodes in
99 new_r_Phi_in. The original implementation used the obstack
100 to model this stack, now it is explicit. This reduces side effects.
102 #if USE_EXPICIT_PHI_IN_STACK
107 res = (Phi_in_stack *) malloc ( sizeof (Phi_in_stack));
109 res->stack = NEW_ARR_F (ir_node *, 1);
115 void free_to_Phi_in_stack(ir_node *phi) {
116 assert(get_irn_opcode(phi) == iro_Phi);
118 if (ARR_LEN(current_ir_graph->Phi_in_stack->stack) ==
119 current_ir_graph->Phi_in_stack->pos)
120 ARR_APP1 (ir_node *, current_ir_graph->Phi_in_stack->stack, phi);
122 current_ir_graph->Phi_in_stack->stack[current_ir_graph->Phi_in_stack->pos] = phi;
124 (current_ir_graph->Phi_in_stack->pos)++;
128 alloc_or_pop_from_Phi_in_stack(ir_graph *irg, ir_node *block, ir_mode *mode,
129 int arity, ir_node **in) {
131 ir_node **stack = current_ir_graph->Phi_in_stack->stack;
132 int pos = current_ir_graph->Phi_in_stack->pos;
136 /* We need to allocate a new node */
137 res = new_ir_node (irg, block, op_Phi, mode, arity, in);
139 /* reuse the old node and initialize it again. */
142 assert (res->kind == k_ir_node);
143 assert (res->op == op_Phi);
148 /* ???!!! How to free the old in array?? */
149 res->in = NEW_ARR_D (ir_node *, irg->obst, (arity+1));
151 memcpy (&res->in[1], in, sizeof (ir_node *) * arity);
153 (current_ir_graph->Phi_in_stack->pos)--;
160 /* Creates a Phi node with a given, fixed array **in of predecessors.
161 If the Phi node is unnecessary, as the same value reaches the block
162 through all control flow paths, it is eliminated and the value
163 returned directly. This constructor is only intended for use in
164 the automatic Phi node generation triggered by get_value or mature.
165 The implementation is quite tricky and depends on the fact, that
166 the nodes are allocated on a stack:
167 The in array contains predecessors and NULLs. The NULLs appear,
168 if get_r_value_internal, that computed the predecessors, reached
169 the same block on two paths. In this case the same value reaches
170 this block on both paths, there is no definition in between. We need
171 not allocate a Phi where these path's merge, but we have to communicate
172 this fact to the caller. This happens by returning a pointer to the
173 node the caller _will_ allocate. (Yes, we predict the address. We can
174 do so because the nodes are allocated on the obstack.) The caller then
175 finds a pointer to itself and, when this routine is called again,
179 new_r_Phi_in (ir_graph *irg, ir_node *block, ir_mode *mode,
180 ir_node **in, int ins)
183 ir_node *res, *known;
185 /* allocate a new node on the obstack.
186 This can return a node to which some of the pointers in the in-array
188 Attention: the constructor copies the in array, i.e., the later changes
189 to the array in this routine do not affect the constructed node! If
190 the in array contains NULLs, there will be missing predecessors in the
192 Is this a possible internal state of the Phi node generation? */
193 #if USE_EXPICIT_PHI_IN_STACK
194 res = known = alloc_or_pop_from_Phi_in_stack(irg, block, mode, ins, in);
196 res = known = new_ir_node (irg, block, op_Phi, mode, ins, in);
198 /* The in-array can contain NULLs. These were returned by get_r_value_internal
199 if it reached the same block/definition on a second path.
200 The NULLs are replaced by the node itself to simplify the test in the
202 for (i=0; i < ins; ++i)
203 if (in[i] == NULL) in[i] = res;
205 /* This loop checks whether the Phi has more than one predecessor.
206 If so, it is a real Phi node and we break the loop. Else the
207 Phi node merges the same definition on several paths and therefore
209 for (i=0; i < ins; ++i)
211 if (in[i]==res || in[i]==known) continue;
219 /* i==ins: there is at most one predecessor, we don't need a phi node. */
221 #if USE_EXPICIT_PHI_IN_STACK
222 free_to_Phi_in_stack(res);
224 obstack_free (current_ir_graph->obst, res);
228 res = optimize (res);
232 /* return the pointer to the Phi node. This node might be deallocated! */
237 new_r_Const (ir_graph *irg, ir_node *block, ir_mode *mode, tarval *con)
240 res = new_ir_node (irg, block, op_Const, mode, 0, NULL);
242 res = optimize (res);
246 res = local_optimize_newby (res);
253 new_r_Id (ir_graph *irg, ir_node *block, ir_node *val, ir_mode *mode)
255 ir_node *in[1] = {val};
257 res = new_ir_node (irg, block, op_Id, mode, 1, in);
258 res = optimize (res);
264 new_r_Proj (ir_graph *irg, ir_node *block, ir_node *arg, ir_mode *mode, long proj)
266 ir_node *in[1] = {arg};
268 res = new_ir_node (irg, block, op_Proj, mode, 1, in);
269 res->attr.proj = proj;
270 res = optimize (res);
277 new_r_Conv (ir_graph *irg, ir_node *block, ir_node *op, ir_mode *mode)
279 ir_node *in[1] = {op};
281 res = new_ir_node (irg, block, op_Conv, mode, 1, in);
282 res = optimize (res);
289 new_r_Tuple (ir_graph *irg, ir_node *block, int arity, ir_node **in)
293 res = new_ir_node (irg, block, op_Tuple, mode_T, arity, in);
294 res = optimize (res);
300 new_r_Add (ir_graph *irg, ir_node *block,
301 ir_node *op1, ir_node *op2, ir_mode *mode)
303 ir_node *in[2] = {op1, op2};
305 res = new_ir_node (irg, block, op_Add, mode, 2, in);
306 res = optimize (res);
312 new_r_Sub (ir_graph *irg, ir_node *block,
313 ir_node *op1, ir_node *op2, ir_mode *mode)
315 ir_node *in[2] = {op1, op2};
317 res = new_ir_node (irg, block, op_Sub, mode, 2, in);
318 res = optimize (res);
324 new_r_Minus (ir_graph *irg, ir_node *block,
325 ir_node *op, ir_mode *mode)
327 ir_node *in[1] = {op};
329 res = new_ir_node (irg, block, op_Minus, mode, 1, in);
330 res = optimize (res);
336 new_r_Mul (ir_graph *irg, ir_node *block,
337 ir_node *op1, ir_node *op2, ir_mode *mode)
339 ir_node *in[2] = {op1, op2};
341 res = new_ir_node (irg, block, op_Mul, mode, 2, in);
342 res = optimize (res);
348 new_r_Quot (ir_graph *irg, ir_node *block,
349 ir_node *memop, ir_node *op1, ir_node *op2)
351 ir_node *in[3] = {memop, op1, op2};
353 res = new_ir_node (irg, block, op_Quot, mode_T, 2, in);
354 res = optimize (res);
360 new_r_DivMod (ir_graph *irg, ir_node *block,
361 ir_node *memop, ir_node *op1, ir_node *op2)
363 ir_node *in[3] = {memop, op1, op2};
365 res = new_ir_node (irg, block, op_DivMod, mode_T, 2, in);
366 res = optimize (res);
372 new_r_Div (ir_graph *irg, ir_node *block,
373 ir_node *memop, ir_node *op1, ir_node *op2)
375 ir_node *in[3] = {memop, op1, op2};
377 res = new_ir_node (irg, block, op_Div, mode_T, 2, in);
378 res = optimize (res);
384 new_r_Mod (ir_graph *irg, ir_node *block,
385 ir_node *memop, ir_node *op1, ir_node *op2)
387 ir_node *in[3] = {memop, op1, op2};
389 res = new_ir_node (irg, block, op_Mod, mode_T, 2, in);
390 res = optimize (res);
396 new_r_And (ir_graph *irg, ir_node *block,
397 ir_node *op1, ir_node *op2, ir_mode *mode)
399 ir_node *in[2] = {op1, op2};
401 res = new_ir_node (irg, block, op_And, mode, 2, in);
402 res = optimize (res);
408 new_r_Or (ir_graph *irg, ir_node *block,
409 ir_node *op1, ir_node *op2, ir_mode *mode)
411 ir_node *in[2] = {op1, op2};
413 res = new_ir_node (irg, block, op_Or, mode, 2, in);
414 res = optimize (res);
420 new_r_Eor (ir_graph *irg, ir_node *block,
421 ir_node *op1, ir_node *op2, ir_mode *mode)
423 ir_node *in[2] = {op1, op2};
425 res = new_ir_node (irg, block, op_Eor, mode, 2, in);
426 res = optimize (res);
432 new_r_Not (ir_graph *irg, ir_node *block,
433 ir_node *op, ir_mode *mode)
435 ir_node *in[1] = {op};
437 res = new_ir_node (irg, block, op_Not, mode, 1, in);
438 res = optimize (res);
444 new_r_Shl (ir_graph *irg, ir_node *block,
445 ir_node *op, ir_node *k, ir_mode *mode)
447 ir_node *in[2] = {op, k};
449 res = new_ir_node (irg, block, op_Shl, mode, 2, in);
450 res = optimize (res);
456 new_r_Shr (ir_graph *irg, ir_node *block,
457 ir_node *op, ir_node *k, ir_mode *mode)
459 ir_node *in[2] = {op, k};
461 res = new_ir_node (irg, block, op_Shr, mode, 2, in);
462 res = optimize (res);
468 new_r_Shrs (ir_graph *irg, ir_node *block,
469 ir_node *op, ir_node *k, ir_mode *mode)
471 ir_node *in[2] = {op, k};
473 res = new_ir_node (irg, block, op_Shrs, mode, 2, in);
474 res = optimize (res);
480 new_r_Rot (ir_graph *irg, ir_node *block,
481 ir_node *op, ir_node *k, ir_mode *mode)
483 ir_node *in[2] = {op, k};
485 res = new_ir_node (irg, block, op_Rot, mode, 2, in);
486 res = optimize (res);
492 new_r_Abs (ir_graph *irg, ir_node *block,
493 ir_node *op, ir_mode *mode)
495 ir_node *in[1] = {op};
497 res = new_ir_node (irg, block, op_Abs, mode, 1, in);
498 res = optimize (res);
504 new_r_Cmp (ir_graph *irg, ir_node *block,
505 ir_node *op1, ir_node *op2)
507 ir_node *in[2] = {op1, op2};
509 res = new_ir_node (irg, block, op_Cmp, mode_T, 2, in);
510 res = optimize (res);
516 new_r_Jmp (ir_graph *irg, ir_node *block)
520 res = new_ir_node (irg, block, op_Jmp, mode_X, 0, in);
521 res = optimize (res);
527 new_r_Cond (ir_graph *irg, ir_node *block, ir_node *c)
529 ir_node *in[1] = {c};
531 res = new_ir_node (irg, block, op_Cond, mode_T, 1, in);
532 res = optimize (res);
538 new_r_Call (ir_graph *irg, ir_node *block, ir_node *store,
539 ir_node *callee, int arity, ir_node **in, type_method *type)
546 NEW_ARR_A (ir_node *, r_in, r_arity);
549 memcpy (&r_in[2], in, sizeof (ir_node *) * arity);
551 res = new_ir_node (irg, block, op_Call, mode_T, r_arity, r_in);
553 set_Call_type(res, type);
554 res = optimize (res);
560 new_r_Return (ir_graph *irg, ir_node *block,
561 ir_node *store, int arity, ir_node **in)
569 NEW_ARR_A (ir_node *, r_in, r_arity);
573 memcpy (&r_in[1], in, sizeof (ir_node *) * arity);
575 res = new_ir_node (irg, block, op_Return, mode_X, r_arity, r_in);
577 res = optimize (res);
584 new_r_Raise (ir_graph *irg, ir_node *block, ir_node *store, ir_node *obj)
586 ir_node *in[2] = {store, obj};
588 res = new_ir_node (irg, block, op_Raise, mode_X, 2, in);
590 res = optimize (res);
596 new_r_Load (ir_graph *irg, ir_node *block,
597 ir_node *store, ir_node *adr)
599 ir_node *in[2] = {store, adr};
601 res = new_ir_node (irg, block, op_Load, mode_T, 2, in);
603 res = optimize (res);
609 new_r_Store (ir_graph *irg, ir_node *block,
610 ir_node *store, ir_node *adr, ir_node *val)
612 ir_node *in[3] = {store, adr, val};
614 res = new_ir_node (irg, block, op_Store, mode_T, 3, in);
616 res = optimize (res);
622 new_r_Alloc (ir_graph *irg, ir_node *block, ir_node *store,
623 ir_node *size, type *alloc_type, where_alloc where)
625 ir_node *in[2] = {store, size};
627 res = new_ir_node (irg, block, op_Alloc, mode_T, 2, in);
629 res->attr.a.where = where;
630 res->attr.a.type = alloc_type;
632 res = optimize (res);
638 new_r_Free (ir_graph *irg, ir_node *block, ir_node *store,
639 ir_node *ptr, ir_node *size, type *free_type)
641 ir_node *in[3] = {store, ptr, size};
643 res = new_ir_node (irg, block, op_Free, mode_T, 3, in);
645 res->attr.f = free_type;
647 res = optimize (res);
653 new_r_Sel (ir_graph *irg, ir_node *block, ir_node *store, ir_node *objptr,
654 int arity, ir_node **in, entity *ent)
661 NEW_ARR_A (ir_node *, r_in, r_arity);
664 memcpy (&r_in[2], in, sizeof (ir_node *) * arity);
665 res = new_ir_node (irg, block, op_Sel, mode_p, r_arity, r_in);
667 res->attr.s.ltyp = static_linkage;
668 res->attr.s.ent = ent;
670 res = optimize (res);
676 new_r_SymConst (ir_graph *irg, ir_node *block, type_or_id *value,
677 symconst_kind symkind)
681 res = new_ir_node (irg, block, op_SymConst, mode_I, 0, in);
683 res->attr.i.num = symkind;
684 if (symkind == linkage_ptr_info) {
685 res->attr.i.tori.ptrinfo = (ident *)value;
687 assert ( ( (symkind == type_tag)
688 || (symkind == size))
689 && (is_type(value)));
690 res->attr.i.tori.typ = (type *)value;
692 res = optimize (res);
698 new_r_Sync (ir_graph *irg, ir_node *block, int arity, ir_node **in)
702 res = new_ir_node (irg, block, op_Sync, mode_M, arity, in);
704 res = optimize (res);
710 new_r_Bad (ir_node *block)
712 return current_ir_graph->bad;
715 /***********************/
716 /** public interfaces */
717 /** construction tools */
724 res = new_ir_node (current_ir_graph, current_ir_graph->current_block,
725 op_Start, mode_T, 0, NULL);
727 res = optimize (res);
737 res = new_ir_node (current_ir_graph, current_ir_graph->current_block,
738 op_End, mode_X, -1, NULL);
740 res = optimize (res);
750 res = new_ir_node (current_ir_graph, NULL, op_Block, mode_R, -1, NULL);
751 current_ir_graph->current_block = res;
752 res->attr.block.matured = 0;
753 set_Block_block_visit(res, 0);
755 /* forget this optimization. use this only if mature !!!!
756 res = optimize (res); */
759 /** create a new dynamic array, which stores all parameters in irnodes */
760 /** using the same obstack as the whole irgraph */
761 res->attr.block.graph_arr = NEW_ARR_D (ir_node *, current_ir_graph->obst,
762 current_ir_graph->params);
764 /** initialize the parameter array */
765 memset(res->attr.block.graph_arr, 0, sizeof(ir_node *)*current_ir_graph->params);
771 get_r_value_internal (ir_node *block, int pos, ir_mode *mode);
773 /** This function computes the predecessors for a real Phi node, and then
774 allocates and returns this node. The routine called to allocate the
775 node might optimize it away and return a real value, or even a pointer
776 to a deallocated Phi node on top of the obstack!
777 This function is called with an in-array of proper size. **/
778 static inline ir_node *
779 phi_merge (ir_node *block, int pos, ir_mode *mode, ir_node **nin, int ins)
781 ir_node *prevBlock, *res;
784 /* This loop goes to all predecessor blocks of the block the Phi node is in
785 and there finds the operands of the Phi node by calling
786 get_r_value_internal. */
787 for (i = 1; i <= ins; ++i) {
788 assert (block->in[i]);
789 prevBlock = block->in[i]->in[0]; /* go past control flow op to prev block */
791 nin[i-1] = get_r_value_internal (prevBlock, pos, mode);
794 /* After collecting all predecessors into the array nin a new Phi node
795 with these predecessors is created. This constructor contains an
796 optimization: If all predecessors of the Phi node are identical it
797 returns the only operand instead of a new Phi node. If the value
798 passes two different control flow edges without being defined, and
799 this is the second path treated, a pointer to the node that will be
800 allocated for the first path (recurstion) is returned. We already
801 know the address of this node, as it is the next node to be allocated
802 and will be placed on top of the obstack. (The obstack is a _stack_!) */
803 res = new_r_Phi_in (current_ir_graph, block, mode, nin, ins);
805 /* Now we now the value "pos" and can enter it in the array with
806 all known local variables. Attention: this might be a pointer to
807 a node, that later will be allocated!!! See new_r_Phi_in.
808 If this is called in mature, after some set_value in the same block,
809 the proper value must not be overwritten:
811 get_value (makes Phi0, put's it into graph_arr)
812 set_value (overwrites Phi0 in graph_arr)
813 mature_block (upgrades Phi0, puts it again into graph_arr, overwriting
816 if (!block->attr.block.graph_arr[pos]) {
817 block->attr.block.graph_arr[pos] = res;
819 // printf(" value already computed by %s\n",
820 // id_to_str(block->attr.block.graph_arr[pos]->op->name));
826 /* This function returns the last definition of a variable. In case
827 this variable was last defined in a previous block, Phi nodes are
828 inserted. If the part of the firm graph containing the definition
829 is not yet constructed, a dummy Phi node is returned. */
831 get_r_value_internal (ir_node *block, int pos, ir_mode *mode)
834 /* There are 4 cases to treat.
836 1. The block is not mature and we visit it the first time. We can not
837 create a proper Phi node, therefore a Phi0, i.e., a Phi without
838 predecessors is returned. This node is added to the linked list (field
839 "link") of the containing block to be completed when this block is
840 matured. (Comlpletion will add a new Phi and turn the Phi0 into a Id
843 2. The value is already known in this block, graph_arr[pos] is set and we
844 visit the block the first time. We can return the value without
845 creating any new nodes.
847 3. The block is mature and we visit it the first time. A Phi node needs
848 to be created (phi_merge). If the Phi is not needed, as all it's
849 operands are the same value reaching the block through different
850 paths, it's optimizes away and the value itself is returned.
852 4. The block is mature, and we visit it the second time. Now two
853 subcases are possible:
854 * The value was computed completely the last time we were here.
855 This is the case if there is no loop. We can return the proper value.
856 * The recursion that visited this node and set the flag did not
857 return yet. We are computing a value in a loop and need to
858 break the recursion without knowing the result yet.
859 There is no simple check for the second subcase. Therefore we check
860 for a second visit and treat all such cases as the second subcase.
861 Anyways, the basic situation is the same: we reached a block
862 on two paths without finding a definition of the value: No Phi
863 nodes are needed on both paths.
864 We return this information "Two paths, no Phi needed" by a very tricky
865 implementation that relies on the fact that an obstack is a stack and
866 will return a node with the same address on different allocations.
867 Look also at phi_merge and get_r_phi_in to understand this.
870 /* case 4 -- already visited. */
871 if (block->visit == ir_visited) return NULL;
873 /* visited the first time */
874 block->visit = ir_visited;
876 /* Get the local valid value */
877 res = block->attr.block.graph_arr[pos];
879 /* case 2 -- If the value is actually computed, return it. */
880 if (res) { return res;};
882 if (block->attr.block.matured) { /* case 3 */
884 /* The Phi has the same amount of ins as the corresponding block. */
885 int ins = get_irn_arity(block); // ARR_LEN (block->in)-1;
887 NEW_ARR_A (ir_node *, nin, ins);
889 /* Phi merge collects the predecessors and then creates a node. */
890 res = phi_merge (block, pos, mode, nin, ins);
892 } else { /* case 1 */
893 /* The block is not mature, we don't know how many in's are needed. A Phi
894 with zero predecessors is created. Such a Phi node is called Phi0
895 node. (There is also an obsolete Phi0 opcode.) The Phi0 is then added
896 to the list of Phi0 nodes in this block to be matured by mature_block
898 The Phi0 has to remember the pos of it's internal value. If the real
899 Phi is computed, pos is used to update the array with the local
902 res = new_r_Phi0 (current_ir_graph, block, mode);
903 res->attr.phi0_pos = pos;
904 res->link = block->link;
908 /* If we get here, the frontend missed a use-before-definition error */
911 printf("Error: no value set\n");
912 assert (mode->code >= irm_f && mode->code <= irm_p);
913 res = new_r_Const (current_ir_graph, block, mode,
914 tarval_mode_null[mode->code]);
917 /* The local valid value is available now. */
918 block->attr.block.graph_arr[pos] = res;
923 /** Finalize a Block node, when all control flows are known. */
924 /** Acceptable parameters are only Block nodes. */
926 mature_block (ir_node *block)
933 assert (get_irn_opcode(block) == iro_Block);
935 if (!get_Block_matured(block)) {
937 /* turn the dynamic in-array into a static one. */
938 ins = ARR_LEN (block->in)-1;
939 NEW_ARR_A (ir_node *, nin, ins);
941 /* Traverse a chain of Phi nodes attached to this block and mature
943 for (n = block->link; n; n=next) {
946 exchange (n, phi_merge (block, n->attr.phi0_pos, n->mode, nin, ins));
949 block->attr.block.matured = 1;
951 block = optimize_in_place(block);
958 new_Phi (int arity, ir_node **in, ir_mode *mode)
960 return new_r_Phi (current_ir_graph, current_ir_graph->current_block,
965 new_Const (ir_mode *mode, tarval *con)
967 return new_r_Const (current_ir_graph, current_ir_graph->start_block,
972 new_Id (ir_node *val, ir_mode *mode)
974 return new_r_Id (current_ir_graph, current_ir_graph->current_block,
979 new_Proj (ir_node *arg, ir_mode *mode, long proj)
981 return new_r_Proj (current_ir_graph, current_ir_graph->current_block,
986 new_Conv (ir_node *op, ir_mode *mode)
988 return new_r_Conv (current_ir_graph, current_ir_graph->current_block,
993 new_Tuple (int arity, ir_node **in)
995 return new_r_Tuple (current_ir_graph, current_ir_graph->current_block,
1000 new_Add (ir_node *op1, ir_node *op2, ir_mode *mode)
1002 return new_r_Add (current_ir_graph, current_ir_graph->current_block,
1007 new_Sub (ir_node *op1, ir_node *op2, ir_mode *mode)
1009 return new_r_Sub (current_ir_graph, current_ir_graph->current_block,
1015 new_Minus (ir_node *op, ir_mode *mode)
1017 return new_r_Minus (current_ir_graph, current_ir_graph->current_block,
1022 new_Mul (ir_node *op1, ir_node *op2, ir_mode *mode)
1024 return new_r_Mul (current_ir_graph, current_ir_graph->current_block,
1029 new_Quot (ir_node *memop, ir_node *op1, ir_node *op2)
1031 return new_r_Quot (current_ir_graph, current_ir_graph->current_block,
1036 new_DivMod (ir_node *memop, ir_node *op1, ir_node *op2)
1038 return new_r_DivMod (current_ir_graph, current_ir_graph->current_block,
1043 new_Div (ir_node *memop, ir_node *op1, ir_node *op2)
1045 return new_r_Div (current_ir_graph, current_ir_graph->current_block,
1050 new_Mod (ir_node *memop, ir_node *op1, ir_node *op2)
1052 return new_r_Mod (current_ir_graph, current_ir_graph->current_block,
1057 new_And (ir_node *op1, ir_node *op2, ir_mode *mode)
1059 return new_r_And (current_ir_graph, current_ir_graph->current_block,
1064 new_Or (ir_node *op1, ir_node *op2, ir_mode *mode)
1066 return new_r_Or (current_ir_graph, current_ir_graph->current_block,
1071 new_Eor (ir_node *op1, ir_node *op2, ir_mode *mode)
1073 return new_r_Eor (current_ir_graph, current_ir_graph->current_block,
1078 new_Not (ir_node *op, ir_mode *mode)
1080 return new_r_Not (current_ir_graph, current_ir_graph->current_block,
1085 new_Shl (ir_node *op, ir_node *k, ir_mode *mode)
1087 return new_r_Shl (current_ir_graph, current_ir_graph->current_block,
1092 new_Shr (ir_node *op, ir_node *k, ir_mode *mode)
1094 return new_r_Shr (current_ir_graph, current_ir_graph->current_block,
1099 new_Shrs (ir_node *op, ir_node *k, ir_mode *mode)
1101 return new_r_Shrs (current_ir_graph, current_ir_graph->current_block,
1106 new_Rotate (ir_node *op, ir_node *k, ir_mode *mode)
1108 return new_r_Rot (current_ir_graph, current_ir_graph->current_block,
1113 new_Abs (ir_node *op, ir_mode *mode)
1115 return new_r_Abs (current_ir_graph, current_ir_graph->current_block,
1120 new_Cmp (ir_node *op1, ir_node *op2)
1122 return new_r_Cmp (current_ir_graph, current_ir_graph->current_block,
1129 return new_r_Jmp (current_ir_graph, current_ir_graph->current_block);
1133 new_Cond (ir_node *c)
1135 return new_r_Cond (current_ir_graph, current_ir_graph->current_block, c);
1139 new_Call (ir_node *store, ir_node *callee, int arity, ir_node **in,
1142 return new_r_Call (current_ir_graph, current_ir_graph->current_block,
1143 store, callee, arity, in, type);
1147 new_Return (ir_node* store, int arity, ir_node **in)
1149 return new_r_Return (current_ir_graph, current_ir_graph->current_block,
1154 new_Raise (ir_node *store, ir_node *obj)
1156 return new_r_Raise (current_ir_graph, current_ir_graph->current_block,
1161 new_Load (ir_node *store, ir_node *addr)
1163 return new_r_Load (current_ir_graph, current_ir_graph->current_block,
1168 new_Store (ir_node *store, ir_node *addr, ir_node *val)
1170 return new_r_Store (current_ir_graph, current_ir_graph->current_block,
1175 new_Alloc (ir_node *store, ir_node *size, type *alloc_type,
1178 return new_r_Alloc (current_ir_graph, current_ir_graph->current_block,
1179 store, size, alloc_type, where);
1183 new_Free (ir_node *store, ir_node *ptr, ir_node *size, type *free_type)
1185 return new_r_Free (current_ir_graph, current_ir_graph->current_block,
1186 store, ptr, size, free_type);
1190 new_simpleSel (ir_node *store, ir_node *objptr, entity *ent)
1191 /* GL: objptr was called frame before. Frame was a bad choice for the name
1192 as the operand could as well be a pointer to a dynamic object. */
1194 return new_r_Sel (current_ir_graph, current_ir_graph->current_block,
1195 store, objptr, 0, NULL, ent);
1199 new_Sel (ir_node *store, ir_node *objptr, int n_index, ir_node **index, entity *sel)
1201 return new_r_Sel (current_ir_graph, current_ir_graph->current_block,
1202 store, objptr, n_index, index, sel);
1206 new_SymConst (type_or_id *value, symconst_kind kind)
1208 return new_r_SymConst (current_ir_graph, current_ir_graph->current_block,
1213 new_Sync (int arity, ir_node** in)
1215 return new_r_Sync (current_ir_graph, current_ir_graph->current_block,
1223 return current_ir_graph->bad;
1226 /*************************************************************************/
1227 /* Comfortable interface with automatic Phi node construction. */
1228 /* (Uses also constructors of ?? interface, except new_Block. */
1229 /* add an adge to a jmp node */
1231 add_in_edge (ir_node *block, ir_node *jmp)
1233 if (block->attr.block.matured) {
1234 printf("Error: Block already matured!\n");
1237 assert (jmp != NULL);
1238 ARR_APP1 (ir_node *, block->in, jmp);
1242 /* changing the current block */
1244 switch_block (ir_node *target)
1246 current_ir_graph->current_block = target;
1249 /****************************/
1250 /* parameter administration */
1252 /* get a value from the parameter array from the current block by its index */
1254 get_value (int pos, ir_mode *mode)
1257 return get_r_value_internal (current_ir_graph->current_block, pos + 1, mode);
1260 /* set a value at position pos in the parameter array from the current block */
1262 set_value (int pos, ir_node *value)
1264 current_ir_graph->current_block->attr.block.graph_arr[pos + 1] = value;
1267 /* get the current store */
1271 /* GL: one could call get_value instead */
1273 return get_r_value_internal (current_ir_graph->current_block, 0, mode_M);
1276 /* set the current store */
1278 set_store (ir_node *store)
1280 /* GL: one could call set_value instead */
1281 current_ir_graph->current_block->attr.block.graph_arr[0] = store;
1284 /*************************************************************************/
1287 /* call once for each run of the library */