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 */
23 #if USE_EXPICIT_PHI_IN_STACK
24 /* A stack needed for the automatic Phi node construction in constructor
32 /*********************************************** */
33 /** privat interfaces, for professional use only */
35 /* Constructs a Block with a fixed number of predecessors.*/
38 new_r_Block (ir_graph *irg, int arity, ir_node **in)
42 res = new_ir_node (current_ir_graph, NULL, op_Block, mode_R, arity, in);
49 new_r_Start (ir_graph *irg, ir_node *block)
53 res = new_ir_node (irg, block, op_Start, mode_T, 0, NULL);
60 new_r_End (ir_graph *irg, ir_node *block)
64 res = new_ir_node (irg, block, op_End, mode_X, -1, NULL);
70 /* Creates a Phi node with 0 predecessors */
72 new_r_Phi0 (ir_graph *irg, ir_node *block, ir_mode *mode)
76 res = new_ir_node (irg, block, op_Phi, mode, 0, NULL);
78 /* GL I'm not sure whether we should optimize this guy. *
79 res = optimize (res); ??? */
84 /* Creates a Phi node with all predecessors. Calling this constructor
85 is only allowed if the corresponding block is mature. */
87 new_r_Phi (ir_graph *irg, ir_node *block, int arity, ir_node **in, ir_mode *mode)
91 assert( get_Block_matured(block) );
92 assert( get_irn_arity(block) == arity );
94 res = new_ir_node (irg, block, op_Phi, mode, arity, in);
101 /* This is a stack used for allocating and deallocating nodes in
102 new_r_Phi_in. The original implementation used the obstack
103 to model this stack, now it is explicit. This reduces side effects.
105 #if USE_EXPICIT_PHI_IN_STACK
110 res = (Phi_in_stack *) malloc ( sizeof (Phi_in_stack));
112 res->stack = NEW_ARR_F (ir_node *, 1);
118 void free_to_Phi_in_stack(ir_node *phi) {
119 assert(get_irn_opcode(phi) == iro_Phi);
121 if (ARR_LEN(current_ir_graph->Phi_in_stack->stack) ==
122 current_ir_graph->Phi_in_stack->pos)
123 ARR_APP1 (ir_node *, current_ir_graph->Phi_in_stack->stack, phi);
125 current_ir_graph->Phi_in_stack->stack[current_ir_graph->Phi_in_stack->pos] = phi;
127 (current_ir_graph->Phi_in_stack->pos)++;
131 alloc_or_pop_from_Phi_in_stack(ir_graph *irg, ir_node *block, ir_mode *mode,
132 int arity, ir_node **in) {
134 ir_node **stack = current_ir_graph->Phi_in_stack->stack;
135 int pos = current_ir_graph->Phi_in_stack->pos;
139 /* We need to allocate a new node */
140 res = new_ir_node (irg, block, op_Phi, mode, arity, in);
142 /* reuse the old node and initialize it again. */
145 assert (res->kind == k_ir_node);
146 assert (res->op == op_Phi);
151 /* ???!!! How to free the old in array?? */
152 res->in = NEW_ARR_D (ir_node *, irg->obst, (arity+1));
154 memcpy (&res->in[1], in, sizeof (ir_node *) * arity);
156 (current_ir_graph->Phi_in_stack->pos)--;
163 /* Creates a Phi node with a given, fixed array **in of predecessors.
164 If the Phi node is unnecessary, as the same value reaches the block
165 through all control flow paths, it is eliminated and the value
166 returned directly. This constructor is only intended for use in
167 the automatic Phi node generation triggered by get_value or mature.
168 The implementation is quite tricky and depends on the fact, that
169 the nodes are allocated on a stack:
170 The in array contains predecessors and NULLs. The NULLs appear,
171 if get_r_value_internal, that computed the predecessors, reached
172 the same block on two paths. In this case the same value reaches
173 this block on both paths, there is no definition in between. We need
174 not allocate a Phi where these path's merge, but we have to communicate
175 this fact to the caller. This happens by returning a pointer to the
176 node the caller _will_ allocate. (Yes, we predict the address. We can
177 do so because the nodes are allocated on the obstack.) The caller then
178 finds a pointer to itself and, when this routine is called again,
182 new_r_Phi_in (ir_graph *irg, ir_node *block, ir_mode *mode,
183 ir_node **in, int ins)
186 ir_node *res, *known;
188 /* allocate a new node on the obstack.
189 This can return a node to which some of the pointers in the in-array
191 Attention: the constructor copies the in array, i.e., the later changes
192 to the array in this routine do not affect the constructed node! If
193 the in array contains NULLs, there will be missing predecessors in the
195 Is this a possible internal state of the Phi node generation? */
196 #if USE_EXPICIT_PHI_IN_STACK
197 res = known = alloc_or_pop_from_Phi_in_stack(irg, block, mode, ins, in);
199 res = known = new_ir_node (irg, block, op_Phi, mode, ins, in);
201 /* The in-array can contain NULLs. These were returned by get_r_value_internal
202 if it reached the same block/definition on a second path.
203 The NULLs are replaced by the node itself to simplify the test in the
205 for (i=0; i < ins; ++i)
206 if (in[i] == NULL) in[i] = res;
208 /* This loop checks whether the Phi has more than one predecessor.
209 If so, it is a real Phi node and we break the loop. Else the
210 Phi node merges the same definition on several paths and therefore
212 for (i=0; i < ins; ++i)
214 if (in[i]==res || in[i]==known) continue;
222 /* i==ins: there is at most one predecessor, we don't need a phi node. */
224 #if USE_EXPICIT_PHI_IN_STACK
225 free_to_Phi_in_stack(res);
227 obstack_free (current_ir_graph->obst, res);
231 res = optimize (res);
235 /* return the pointer to the Phi node. This node might be deallocated! */
240 new_r_Const (ir_graph *irg, ir_node *block, ir_mode *mode, tarval *con)
243 res = new_ir_node (irg, block, op_Const, mode, 0, NULL);
245 res = optimize (res);
249 res = local_optimize_newby (res);
256 new_r_Id (ir_graph *irg, ir_node *block, ir_node *val, ir_mode *mode)
258 ir_node *in[1] = {val};
260 res = new_ir_node (irg, block, op_Id, mode, 1, in);
261 res = optimize (res);
267 new_r_Proj (ir_graph *irg, ir_node *block, ir_node *arg, ir_mode *mode,
270 ir_node *in[1] = {arg};
272 res = new_ir_node (irg, block, op_Proj, mode, 1, in);
273 res->attr.proj = proj;
276 assert(get_Proj_pred(res));
277 assert(get_nodes_Block(get_Proj_pred(res)));
279 res = optimize (res);
287 new_r_Conv (ir_graph *irg, ir_node *block, ir_node *op, ir_mode *mode)
289 ir_node *in[1] = {op};
291 res = new_ir_node (irg, block, op_Conv, mode, 1, in);
292 res = optimize (res);
299 new_r_Tuple (ir_graph *irg, ir_node *block, int arity, ir_node **in)
303 res = new_ir_node (irg, block, op_Tuple, mode_T, arity, in);
304 res = optimize (res);
310 new_r_Add (ir_graph *irg, ir_node *block,
311 ir_node *op1, ir_node *op2, ir_mode *mode)
313 ir_node *in[2] = {op1, op2};
315 res = new_ir_node (irg, block, op_Add, mode, 2, in);
316 res = optimize (res);
322 new_r_Sub (ir_graph *irg, ir_node *block,
323 ir_node *op1, ir_node *op2, ir_mode *mode)
325 ir_node *in[2] = {op1, op2};
327 res = new_ir_node (irg, block, op_Sub, mode, 2, in);
328 res = optimize (res);
334 new_r_Minus (ir_graph *irg, ir_node *block,
335 ir_node *op, ir_mode *mode)
337 ir_node *in[1] = {op};
339 res = new_ir_node (irg, block, op_Minus, mode, 1, in);
340 res = optimize (res);
346 new_r_Mul (ir_graph *irg, ir_node *block,
347 ir_node *op1, ir_node *op2, ir_mode *mode)
349 ir_node *in[2] = {op1, op2};
351 res = new_ir_node (irg, block, op_Mul, mode, 2, in);
352 res = optimize (res);
358 new_r_Quot (ir_graph *irg, ir_node *block,
359 ir_node *memop, ir_node *op1, ir_node *op2)
361 ir_node *in[3] = {memop, op1, op2};
363 res = new_ir_node (irg, block, op_Quot, mode_T, 3, in);
364 res = optimize (res);
370 new_r_DivMod (ir_graph *irg, ir_node *block,
371 ir_node *memop, ir_node *op1, ir_node *op2)
373 ir_node *in[3] = {memop, op1, op2};
375 res = new_ir_node (irg, block, op_DivMod, mode_T, 3, in);
376 res = optimize (res);
382 new_r_Div (ir_graph *irg, ir_node *block,
383 ir_node *memop, ir_node *op1, ir_node *op2)
385 ir_node *in[3] = {memop, op1, op2};
387 res = new_ir_node (irg, block, op_Div, mode_T, 3, in);
388 res = optimize (res);
394 new_r_Mod (ir_graph *irg, ir_node *block,
395 ir_node *memop, ir_node *op1, ir_node *op2)
397 ir_node *in[3] = {memop, op1, op2};
399 res = new_ir_node (irg, block, op_Mod, mode_T, 3, in);
400 res = optimize (res);
406 new_r_And (ir_graph *irg, ir_node *block,
407 ir_node *op1, ir_node *op2, ir_mode *mode)
409 ir_node *in[2] = {op1, op2};
411 res = new_ir_node (irg, block, op_And, mode, 2, in);
412 res = optimize (res);
418 new_r_Or (ir_graph *irg, ir_node *block,
419 ir_node *op1, ir_node *op2, ir_mode *mode)
421 ir_node *in[2] = {op1, op2};
423 res = new_ir_node (irg, block, op_Or, mode, 2, in);
424 res = optimize (res);
430 new_r_Eor (ir_graph *irg, ir_node *block,
431 ir_node *op1, ir_node *op2, ir_mode *mode)
433 ir_node *in[2] = {op1, op2};
435 res = new_ir_node (irg, block, op_Eor, mode, 2, in);
436 res = optimize (res);
442 new_r_Not (ir_graph *irg, ir_node *block,
443 ir_node *op, ir_mode *mode)
445 ir_node *in[1] = {op};
447 res = new_ir_node (irg, block, op_Not, mode, 1, in);
448 res = optimize (res);
454 new_r_Shl (ir_graph *irg, ir_node *block,
455 ir_node *op, ir_node *k, ir_mode *mode)
457 ir_node *in[2] = {op, k};
459 res = new_ir_node (irg, block, op_Shl, mode, 2, in);
460 res = optimize (res);
466 new_r_Shr (ir_graph *irg, ir_node *block,
467 ir_node *op, ir_node *k, ir_mode *mode)
469 ir_node *in[2] = {op, k};
471 res = new_ir_node (irg, block, op_Shr, mode, 2, in);
472 res = optimize (res);
478 new_r_Shrs (ir_graph *irg, ir_node *block,
479 ir_node *op, ir_node *k, ir_mode *mode)
481 ir_node *in[2] = {op, k};
483 res = new_ir_node (irg, block, op_Shrs, mode, 2, in);
484 res = optimize (res);
490 new_r_Rot (ir_graph *irg, ir_node *block,
491 ir_node *op, ir_node *k, ir_mode *mode)
493 ir_node *in[2] = {op, k};
495 res = new_ir_node (irg, block, op_Rot, mode, 2, in);
496 res = optimize (res);
502 new_r_Abs (ir_graph *irg, ir_node *block,
503 ir_node *op, ir_mode *mode)
505 ir_node *in[1] = {op};
507 res = new_ir_node (irg, block, op_Abs, mode, 1, in);
508 res = optimize (res);
514 new_r_Cmp (ir_graph *irg, ir_node *block,
515 ir_node *op1, ir_node *op2)
517 ir_node *in[2] = {op1, op2};
519 res = new_ir_node (irg, block, op_Cmp, mode_T, 2, in);
520 res = optimize (res);
526 new_r_Jmp (ir_graph *irg, ir_node *block)
530 res = new_ir_node (irg, block, op_Jmp, mode_X, 0, in);
531 res = optimize (res);
537 new_r_Cond (ir_graph *irg, ir_node *block, ir_node *c)
539 ir_node *in[1] = {c};
541 res = new_ir_node (irg, block, op_Cond, mode_T, 1, in);
542 res = optimize (res);
548 new_r_Call (ir_graph *irg, ir_node *block, ir_node *store,
549 ir_node *callee, int arity, ir_node **in, type_method *type)
556 NEW_ARR_A (ir_node *, r_in, r_arity);
559 memcpy (&r_in[2], in, sizeof (ir_node *) * arity);
561 res = new_ir_node (irg, block, op_Call, mode_T, r_arity, r_in);
563 set_Call_type(res, type);
564 res = optimize (res);
570 new_r_Return (ir_graph *irg, ir_node *block,
571 ir_node *store, int arity, ir_node **in)
578 NEW_ARR_A (ir_node *, r_in, r_arity);
580 memcpy (&r_in[1], in, sizeof (ir_node *) * arity);
581 res = new_ir_node (irg, block, op_Return, mode_X, r_arity, r_in);
582 res = optimize (res);
588 new_r_Raise (ir_graph *irg, ir_node *block, ir_node *store, ir_node *obj)
590 ir_node *in[2] = {store, obj};
592 res = new_ir_node (irg, block, op_Raise, mode_X, 2, in);
594 res = optimize (res);
600 new_r_Load (ir_graph *irg, ir_node *block,
601 ir_node *store, ir_node *adr)
603 ir_node *in[2] = {store, adr};
605 res = new_ir_node (irg, block, op_Load, mode_T, 2, in);
607 res = optimize (res);
613 new_r_Store (ir_graph *irg, ir_node *block,
614 ir_node *store, ir_node *adr, ir_node *val)
616 ir_node *in[3] = {store, adr, val};
618 res = new_ir_node (irg, block, op_Store, mode_T, 3, in);
620 res = optimize (res);
626 new_r_Alloc (ir_graph *irg, ir_node *block, ir_node *store,
627 ir_node *size, type *alloc_type, where_alloc where)
629 ir_node *in[2] = {store, size};
631 res = new_ir_node (irg, block, op_Alloc, mode_T, 2, in);
633 res->attr.a.where = where;
634 res->attr.a.type = alloc_type;
636 res = optimize (res);
642 new_r_Free (ir_graph *irg, ir_node *block, ir_node *store,
643 ir_node *ptr, ir_node *size, type *free_type)
645 ir_node *in[3] = {store, ptr, size};
647 res = new_ir_node (irg, block, op_Free, mode_T, 3, in);
649 res->attr.f = free_type;
651 res = optimize (res);
657 new_r_Sel (ir_graph *irg, ir_node *block, ir_node *store, ir_node *objptr,
658 int arity, ir_node **in, entity *ent)
665 NEW_ARR_A (ir_node *, r_in, r_arity);
668 memcpy (&r_in[2], in, sizeof (ir_node *) * arity);
669 res = new_ir_node (irg, block, op_Sel, mode_p, r_arity, r_in);
671 res->attr.s.ltyp = static_linkage;
672 res->attr.s.ent = ent;
674 res = optimize (res);
680 new_r_SymConst (ir_graph *irg, ir_node *block, type_or_id *value,
681 symconst_kind symkind)
685 res = new_ir_node (irg, block, op_SymConst, mode_I, 0, in);
687 res->attr.i.num = symkind;
688 if (symkind == linkage_ptr_info) {
689 res->attr.i.tori.ptrinfo = (ident *)value;
691 assert ( ( (symkind == type_tag)
692 || (symkind == size))
693 && (is_type(value)));
694 res->attr.i.tori.typ = (type *)value;
696 res = optimize (res);
702 new_r_Sync (ir_graph *irg, ir_node *block, int arity, ir_node **in)
706 res = new_ir_node (irg, block, op_Sync, mode_M, arity, in);
708 res = optimize (res);
716 return current_ir_graph->bad;
719 /***********************/
720 /** public interfaces */
721 /** construction tools */
728 res = new_ir_node (current_ir_graph, current_ir_graph->current_block,
729 op_Start, mode_T, 0, NULL);
731 res = optimize (res);
741 res = new_ir_node (current_ir_graph, current_ir_graph->current_block,
742 op_End, mode_X, -1, NULL);
744 res = optimize (res);
754 res = new_ir_node (current_ir_graph, NULL, op_Block, mode_R, -1, NULL);
755 current_ir_graph->current_block = res;
756 res->attr.block.matured = 0;
757 set_Block_block_visited(res, 0);
759 /* forget this optimization. use this only if mature !!!!
760 res = optimize (res); */
763 /** create a new dynamic array, which stores all parameters in irnodes */
764 /** using the same obstack as the whole irgraph */
765 res->attr.block.graph_arr = NEW_ARR_D (ir_node *, current_ir_graph->obst,
766 current_ir_graph->params);
768 /** initialize the parameter array */
769 memset(res->attr.block.graph_arr, 0, sizeof(ir_node *)*current_ir_graph->params);
775 get_r_value_internal (ir_node *block, int pos, ir_mode *mode);
777 /** This function computes the predecessors for a real Phi node, and then
778 allocates and returns this node. The routine called to allocate the
779 node might optimize it away and return a real value, or even a pointer
780 to a deallocated Phi node on top of the obstack!
781 This function is called with an in-array of proper size. **/
782 static inline ir_node *
783 phi_merge (ir_node *block, int pos, ir_mode *mode, ir_node **nin, int ins)
785 ir_node *prevBlock, *res;
788 /* This loop goes to all predecessor blocks of the block the Phi node is in
789 and there finds the operands of the Phi node by calling
790 get_r_value_internal. */
791 for (i = 1; i <= ins; ++i) {
792 assert (block->in[i]);
793 prevBlock = block->in[i]->in[0]; /* go past control flow op to prev block */
795 nin[i-1] = get_r_value_internal (prevBlock, pos, mode);
798 /* After collecting all predecessors into the array nin a new Phi node
799 with these predecessors is created. This constructor contains an
800 optimization: If all predecessors of the Phi node are identical it
801 returns the only operand instead of a new Phi node. If the value
802 passes two different control flow edges without being defined, and
803 this is the second path treated, a pointer to the node that will be
804 allocated for the first path (recurstion) is returned. We already
805 know the address of this node, as it is the next node to be allocated
806 and will be placed on top of the obstack. (The obstack is a _stack_!) */
807 res = new_r_Phi_in (current_ir_graph, block, mode, nin, ins);
809 /* Now we now the value "pos" and can enter it in the array with
810 all known local variables. Attention: this might be a pointer to
811 a node, that later will be allocated!!! See new_r_Phi_in.
812 If this is called in mature, after some set_value in the same block,
813 the proper value must not be overwritten:
815 get_value (makes Phi0, put's it into graph_arr)
816 set_value (overwrites Phi0 in graph_arr)
817 mature_block (upgrades Phi0, puts it again into graph_arr, overwriting
820 if (!block->attr.block.graph_arr[pos]) {
821 block->attr.block.graph_arr[pos] = res;
823 // printf(" value already computed by %s\n",
824 // id_to_str(block->attr.block.graph_arr[pos]->op->name));
830 /* This function returns the last definition of a variable. In case
831 this variable was last defined in a previous block, Phi nodes are
832 inserted. If the part of the firm graph containing the definition
833 is not yet constructed, a dummy Phi node is returned. */
835 get_r_value_internal (ir_node *block, int pos, ir_mode *mode)
838 /* There are 4 cases to treat.
840 1. The block is not mature and we visit it the first time. We can not
841 create a proper Phi node, therefore a Phi0, i.e., a Phi without
842 predecessors is returned. This node is added to the linked list (field
843 "link") of the containing block to be completed when this block is
844 matured. (Comlpletion will add a new Phi and turn the Phi0 into a Id
847 2. The value is already known in this block, graph_arr[pos] is set and we
848 visit the block the first time. We can return the value without
849 creating any new nodes.
851 3. The block is mature and we visit it the first time. A Phi node needs
852 to be created (phi_merge). If the Phi is not needed, as all it's
853 operands are the same value reaching the block through different
854 paths, it's optimizes away and the value itself is returned.
856 4. The block is mature, and we visit it the second time. Now two
857 subcases are possible:
858 * The value was computed completely the last time we were here.
859 This is the case if there is no loop. We can return the proper value.
860 * The recursion that visited this node and set the flag did not
861 return yet. We are computing a value in a loop and need to
862 break the recursion without knowing the result yet.
863 There is no simple check for the second subcase. Therefore we check
864 for a second visit and treat all such cases as the second subcase.
865 Anyways, the basic situation is the same: we reached a block
866 on two paths without finding a definition of the value: No Phi
867 nodes are needed on both paths.
868 We return this information "Two paths, no Phi needed" by a very tricky
869 implementation that relies on the fact that an obstack is a stack and
870 will return a node with the same address on different allocations.
871 Look also at phi_merge and get_r_phi_in to understand this.
874 /* case 4 -- already visited. */
875 if (get_irn_visited(block) == get_irg_visited(current_ir_graph)) return NULL;
877 /* visited the first time */
878 set_irn_visited(block, get_irg_visited(current_ir_graph));
880 /* Get the local valid value */
881 res = block->attr.block.graph_arr[pos];
883 /* case 2 -- If the value is actually computed, return it. */
884 if (res) { return res;};
886 if (block->attr.block.matured) { /* case 3 */
888 /* The Phi has the same amount of ins as the corresponding block. */
889 int ins = get_irn_arity(block); // ARR_LEN (block->in)-1;
891 NEW_ARR_A (ir_node *, nin, ins);
893 /* Phi merge collects the predecessors and then creates a node. */
894 res = phi_merge (block, pos, mode, nin, ins);
896 } else { /* case 1 */
897 /* The block is not mature, we don't know how many in's are needed. A Phi
898 with zero predecessors is created. Such a Phi node is called Phi0
899 node. (There is also an obsolete Phi0 opcode.) The Phi0 is then added
900 to the list of Phi0 nodes in this block to be matured by mature_block
902 The Phi0 has to remember the pos of it's internal value. If the real
903 Phi is computed, pos is used to update the array with the local
906 res = new_r_Phi0 (current_ir_graph, block, mode);
907 res->attr.phi0_pos = pos;
908 res->link = block->link;
912 /* If we get here, the frontend missed a use-before-definition error */
915 printf("Error: no value set\n");
916 assert (mode->code >= irm_f && mode->code <= irm_p);
917 res = new_r_Const (current_ir_graph, block, mode,
918 tarval_mode_null[mode->code]);
921 /* The local valid value is available now. */
922 block->attr.block.graph_arr[pos] = res;
927 /** Finalize a Block node, when all control flows are known. */
928 /** Acceptable parameters are only Block nodes. */
930 mature_block (ir_node *block)
937 assert (get_irn_opcode(block) == iro_Block);
939 if (!get_Block_matured(block)) {
941 /* turn the dynamic in-array into a static one. */
942 ins = ARR_LEN (block->in)-1;
943 NEW_ARR_A (ir_node *, nin, ins);
945 /* Traverse a chain of Phi nodes attached to this block and mature
947 for (n = block->link; n; n=next) {
948 inc_irg_visited(current_ir_graph);
950 exchange (n, phi_merge (block, n->attr.phi0_pos, n->mode, nin, ins));
953 block->attr.block.matured = 1;
955 block = optimize_in_place(block);
962 new_Phi (int arity, ir_node **in, ir_mode *mode)
964 return new_r_Phi (current_ir_graph, current_ir_graph->current_block,
969 new_Const (ir_mode *mode, tarval *con)
971 return new_r_Const (current_ir_graph, current_ir_graph->start_block,
976 new_Id (ir_node *val, ir_mode *mode)
978 return new_r_Id (current_ir_graph, current_ir_graph->current_block,
983 new_Proj (ir_node *arg, ir_mode *mode, long proj)
985 return new_r_Proj (current_ir_graph, current_ir_graph->current_block,
990 new_Conv (ir_node *op, ir_mode *mode)
992 return new_r_Conv (current_ir_graph, current_ir_graph->current_block,
997 new_Tuple (int arity, ir_node **in)
999 return new_r_Tuple (current_ir_graph, current_ir_graph->current_block,
1004 new_Add (ir_node *op1, ir_node *op2, ir_mode *mode)
1006 return new_r_Add (current_ir_graph, current_ir_graph->current_block,
1011 new_Sub (ir_node *op1, ir_node *op2, ir_mode *mode)
1013 return new_r_Sub (current_ir_graph, current_ir_graph->current_block,
1019 new_Minus (ir_node *op, ir_mode *mode)
1021 return new_r_Minus (current_ir_graph, current_ir_graph->current_block,
1026 new_Mul (ir_node *op1, ir_node *op2, ir_mode *mode)
1028 return new_r_Mul (current_ir_graph, current_ir_graph->current_block,
1033 new_Quot (ir_node *memop, ir_node *op1, ir_node *op2)
1035 return new_r_Quot (current_ir_graph, current_ir_graph->current_block,
1040 new_DivMod (ir_node *memop, ir_node *op1, ir_node *op2)
1042 return new_r_DivMod (current_ir_graph, current_ir_graph->current_block,
1047 new_Div (ir_node *memop, ir_node *op1, ir_node *op2)
1049 return new_r_Div (current_ir_graph, current_ir_graph->current_block,
1054 new_Mod (ir_node *memop, ir_node *op1, ir_node *op2)
1056 return new_r_Mod (current_ir_graph, current_ir_graph->current_block,
1061 new_And (ir_node *op1, ir_node *op2, ir_mode *mode)
1063 return new_r_And (current_ir_graph, current_ir_graph->current_block,
1068 new_Or (ir_node *op1, ir_node *op2, ir_mode *mode)
1070 return new_r_Or (current_ir_graph, current_ir_graph->current_block,
1075 new_Eor (ir_node *op1, ir_node *op2, ir_mode *mode)
1077 return new_r_Eor (current_ir_graph, current_ir_graph->current_block,
1082 new_Not (ir_node *op, ir_mode *mode)
1084 return new_r_Not (current_ir_graph, current_ir_graph->current_block,
1089 new_Shl (ir_node *op, ir_node *k, ir_mode *mode)
1091 return new_r_Shl (current_ir_graph, current_ir_graph->current_block,
1096 new_Shr (ir_node *op, ir_node *k, ir_mode *mode)
1098 return new_r_Shr (current_ir_graph, current_ir_graph->current_block,
1103 new_Shrs (ir_node *op, ir_node *k, ir_mode *mode)
1105 return new_r_Shrs (current_ir_graph, current_ir_graph->current_block,
1110 new_Rotate (ir_node *op, ir_node *k, ir_mode *mode)
1112 return new_r_Rot (current_ir_graph, current_ir_graph->current_block,
1117 new_Abs (ir_node *op, ir_mode *mode)
1119 return new_r_Abs (current_ir_graph, current_ir_graph->current_block,
1124 new_Cmp (ir_node *op1, ir_node *op2)
1126 return new_r_Cmp (current_ir_graph, current_ir_graph->current_block,
1133 return new_r_Jmp (current_ir_graph, current_ir_graph->current_block);
1137 new_Cond (ir_node *c)
1139 return new_r_Cond (current_ir_graph, current_ir_graph->current_block, c);
1143 new_Call (ir_node *store, ir_node *callee, int arity, ir_node **in,
1146 return new_r_Call (current_ir_graph, current_ir_graph->current_block,
1147 store, callee, arity, in, type);
1151 new_Return (ir_node* store, int arity, ir_node **in)
1153 return new_r_Return (current_ir_graph, current_ir_graph->current_block,
1158 new_Raise (ir_node *store, ir_node *obj)
1160 return new_r_Raise (current_ir_graph, current_ir_graph->current_block,
1165 new_Load (ir_node *store, ir_node *addr)
1167 return new_r_Load (current_ir_graph, current_ir_graph->current_block,
1172 new_Store (ir_node *store, ir_node *addr, ir_node *val)
1174 return new_r_Store (current_ir_graph, current_ir_graph->current_block,
1179 new_Alloc (ir_node *store, ir_node *size, type *alloc_type,
1182 return new_r_Alloc (current_ir_graph, current_ir_graph->current_block,
1183 store, size, alloc_type, where);
1187 new_Free (ir_node *store, ir_node *ptr, ir_node *size, type *free_type)
1189 return new_r_Free (current_ir_graph, current_ir_graph->current_block,
1190 store, ptr, size, free_type);
1194 new_simpleSel (ir_node *store, ir_node *objptr, entity *ent)
1195 /* GL: objptr was called frame before. Frame was a bad choice for the name
1196 as the operand could as well be a pointer to a dynamic object. */
1198 return new_r_Sel (current_ir_graph, current_ir_graph->current_block,
1199 store, objptr, 0, NULL, ent);
1203 new_Sel (ir_node *store, ir_node *objptr, int n_index, ir_node **index, entity *sel)
1205 return new_r_Sel (current_ir_graph, current_ir_graph->current_block,
1206 store, objptr, n_index, index, sel);
1210 new_SymConst (type_or_id *value, symconst_kind kind)
1212 return new_r_SymConst (current_ir_graph, current_ir_graph->current_block,
1217 new_Sync (int arity, ir_node** in)
1219 return new_r_Sync (current_ir_graph, current_ir_graph->current_block,
1227 return current_ir_graph->bad;
1230 /*************************************************************************/
1231 /* Comfortable interface with automatic Phi node construction. */
1232 /* (Uses also constructors of ?? interface, except new_Block. */
1233 /* add an adge to a jmp node */
1235 add_in_edge (ir_node *block, ir_node *jmp)
1237 if (block->attr.block.matured) {
1238 printf("Error: Block already matured!\n");
1241 assert (jmp != NULL);
1242 ARR_APP1 (ir_node *, block->in, jmp);
1246 /* changing the current block */
1248 switch_block (ir_node *target)
1250 current_ir_graph->current_block = target;
1253 /****************************/
1254 /* parameter administration */
1256 /* get a value from the parameter array from the current block by its index */
1258 get_value (int pos, ir_mode *mode)
1260 inc_irg_visited(current_ir_graph);
1261 return get_r_value_internal (current_ir_graph->current_block, pos + 1, mode);
1264 /* set a value at position pos in the parameter array from the current block */
1266 set_value (int pos, ir_node *value)
1268 current_ir_graph->current_block->attr.block.graph_arr[pos + 1] = value;
1271 /* get the current store */
1275 /* GL: one could call get_value instead */
1276 inc_irg_visited(current_ir_graph);
1277 return get_r_value_internal (current_ir_graph->current_block, 0, mode_M);
1280 /* set the current store */
1282 set_store (ir_node *store)
1284 /* GL: one could call set_value instead */
1285 current_ir_graph->current_block->attr.block.graph_arr[0] = store;
1288 /*************************************************************************/
1291 /* call once for each run of the library */