add license info to ana2
[libfirm] / ir / ana2 / pto_comp.c
1 /* -*- c -*- */
2
3 /*
4  * Copyrigth (C) 1995-2007 University of Karlsruhe.  All right reserved.
5  *
6  * This file is part of libFirm.
7  *
8  * This file may be distributed and/or modified under the terms of the
9  * GNU General Public License version 2 as published by the Free Software
10  * Foundation and appearing in the file LICENSE.GPL included in the
11  * packaging of this file.
12  *
13  * Licensees holding valid libFirm Professional Edition licenses may use
14  * this file in accordance with the libFirm Commercial License.
15  * Agreement provided with the Software.
16  *
17  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
18  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE.
20  */
21
22 /**
23  * @file
24  * @brief   Main Implementation of PTO
25  * @author  Florian
26  * @date    Sat Nov 13 19:35:27 CET 2004
27  * @version $Id$
28  */
29 # ifdef HAVE_CONFIG_H
30 #  include "config.h"
31 # endif
32
33 /*
34   pto_comp: Main Implementation of PTO
35 */
36
37 # include <string.h>            /* for memset */
38
39 # include "pto_comp.h"
40 # include "pto_util.h"
41 # include "pto_name.h"
42 # include "pto_ctx.h"
43 # include "pto_mod.h"
44
45 # include "irnode_t.h"
46 # include "irprog_t.h"
47 # include "xmalloc.h"
48 # include "irmemwalk.h"
49
50 # include "pto_debug.h"
51 # include "pto_init.h"
52
53 # include "ecg.h"
54
55 # include "gnu_ext.h"
56
57 /* Local Defines: */
58
59 /* Local Data Types: */
60 typedef struct pto_env_str {
61   struct pto_env_str *enc_env;
62   ir_graph *graph;
63   int ctx_idx;
64   int change;
65 } pto_env_t;
66
67
68 /* Local Variables: */
69
70 /* Debug only: */
71 char *spaces = NULL;
72
73 /* Local Prototypes: */
74 static pto_t *get_pto (ir_node*, pto_env_t*);
75 static void pto_call (ir_graph*, ir_node*, pto_env_t*);
76 static void pto_raise (ir_node*, pto_env_t*);
77 static void pto_load (ir_node*, pto_env_t*);
78 static void pto_store (ir_node*, pto_env_t*);
79 static void pto_method (ir_node*, pto_env_t*);
80 static void pto_end_block (ir_node*, pto_env_t*);
81
82 /* ===================================================
83    Local Implementation:
84    =================================================== */
85 /* Add values of the actual arguments to the formal arguments */
86 static int add_graph_args (ir_graph *graph, ir_node *call, pto_env_t *env)
87 {
88   int change = FALSE;
89   ir_type *meth = get_entity_type (get_irg_entity (graph));
90   ir_node **args = get_irg_proj_args (graph);
91   int i, n_args;
92
93   assert(op_Call == get_irn_op(call));
94
95   n_args = get_Call_n_params (call);
96
97   DBGPRINT (1, (stdout, "%s: args of %s[%li] -> 0x%08x\n",
98                 __FUNCTION__,
99                 OPNAME (call), OPNUM (call), (int) graph));
100
101   for (i = 0; i < n_args; i ++) {
102     if (NULL != args [i]) {
103       if (mode_P == get_type_mode (get_method_param_type (meth, i))) {
104         ir_node *call_arg = get_Call_param (call, i);
105         pto_t *arg_pto = get_pto (call_arg, env);
106         pto_t *frm_pto = get_node_pto (args [i]);
107
108         assert (arg_pto);
109         assert (frm_pto);
110
111         change |= qset_insert_all (frm_pto->values, arg_pto->values);
112
113         DBGPRINT (2, (stdout, "%s: arg [%i]: -> %s[%li] (%i) -> %s[%li] (%i)\n",
114                       __FUNCTION__,
115                       i,
116                       OPNAME (call_arg), OPNUM (call_arg),
117                       arg_pto->values->id,
118                       OPNAME (args [i]), OPNUM (args [i]),
119                       frm_pto->values->id));
120       }
121     }
122   }
123
124   return (change);
125 }
126
127 /* Transfer the actual arguments to the formal arguments */
128 static void set_graph_args (ir_graph *graph, ir_node *call, pto_env_t *env)
129 {
130   ir_type *meth = get_entity_type (get_irg_entity (graph));
131   ir_node **args = get_irg_proj_args (graph);
132   int i, n_args;
133
134   assert (op_Call == get_irn_op(call));
135
136   n_args = get_Call_n_params (call);
137
138   for (i = 0; i < n_args; i ++) {
139     if (NULL != args [i]) {
140       if (mode_P == get_type_mode (get_method_param_type (meth, i))) {
141         ir_node *call_arg = get_Call_param (call, i);
142         pto_t *pto = get_pto (call_arg, env);
143         assert (pto);
144         set_node_pto (args [i], pto);
145
146         DBGPRINT (1, (stdout, "%s: arg [%i]: %s[%li] -> %s[%li] (%i)\n",
147                       __FUNCTION__,
148                       i,
149                       OPNAME (call_arg), OPNUM (call_arg),
150                       OPNAME (args [i]), OPNUM (args [i]),
151                       pto->values->id));
152       }
153     }
154   }
155 }
156
157 /* Transfer the graph's result to the call */
158 static int set_graph_result (ir_graph *graph, ir_node *call)
159 {
160   ir_type *tp = get_entity_type (get_irg_entity (graph));
161   ir_node *end_block;
162   pto_t *ret_pto, *call_pto;
163   int change;
164
165   if (0 == get_method_n_ress (tp)) {
166     return (FALSE);
167   }
168
169   tp = get_method_res_type (tp, 0);
170
171   if (mode_P != get_type_mode (tp)) {
172     set_node_pto (call, NULL);
173
174     return (FALSE);
175   }
176
177   end_block = get_irg_end_block (graph);
178   ret_pto = get_node_pto (end_block);
179
180   call_pto = get_node_pto (call);
181
182   assert (call_pto);
183
184   DBGPRINT (1, (stdout, "%s: before change args\n", __FUNCTION__));
185   DBGEXE (1, pto_print_pto (end_block));
186   DBGEXE (1, pto_print_pto (call));
187
188   change = qset_insert_all (call_pto->values, ret_pto->values);
189
190   if (change) {
191     DBGPRINT (1, (stdout, "%s: after change args\n", __FUNCTION__));
192     DBGEXE (1, pto_print_pto (end_block));
193     DBGEXE (1, pto_print_pto (call));
194     /* assert (0); */
195   }
196
197   return (change);
198 }
199
200 /* Propagation of PTO values */
201 static pto_t *get_pto_proj (ir_node *proj, pto_env_t *env)
202 {
203   ir_node *proj_in = get_Proj_pred (proj);
204   const ir_opcode in_op = get_irn_opcode (proj_in);
205   pto_t *in_pto = NULL;
206   pto_t *proj_pto = NULL; /* get_node_pto (proj); */
207
208   ir_node *proj_in_in = NULL;
209
210   switch (in_op) {
211   case (iro_Start):             /* ProjT (Start) */
212     assert (0 && "pto from ProjT(Start) requested");
213
214     return (NULL);
215   case (iro_Proj): {            /* ProjT (Start), ProjT (Call) */
216     ir_opcode in_in_op;
217     long proj_in_proj;
218
219     proj_in_in = get_Proj_pred (proj_in);
220     in_in_op = get_irn_opcode (proj_in_in);
221     proj_in_proj = get_Proj_proj (proj_in);
222
223     assert ((pn_Start_T_args == proj_in_proj) ||
224             (pn_Call_T_result == proj_in_proj));
225
226     switch (in_in_op) {
227     case (iro_Start):           /* ProjArg (ProjT (Start)) */
228       /* then the pto value must have been set to the node */
229       proj_pto = get_node_pto (proj);
230       assert (proj_pto);
231
232       return (proj_pto);
233     case (iro_Call):            /* ProjV (ProjT (Call)) */
234       if (NULL != proj_pto) {
235         return (proj_pto);
236       } else {
237         in_pto = get_pto (proj_in, env);
238         set_node_pto (proj, in_pto);
239
240         assert (in_pto);
241
242         return (in_pto);
243       }
244     default: assert (0 && "Proj(Proj(?))");
245     }
246     /* done with case (in_op == iro_Proj) */
247   }
248
249   case (iro_Load):              /* ProjV (Load) */
250     assert (pn_Load_res == get_Proj_proj(proj));
251     /* FALLTHROUGH */
252   case (iro_Call):              /* ProjT (Call) */
253     /* FALLTHROUGH */
254   case (iro_Alloc):             /* ProjV (Alloc) */
255     if (NULL != proj_pto) {
256       return (proj_pto);
257     } else {
258       in_pto = get_pto (proj_in, env);
259       assert (in_pto);
260
261       set_node_pto (proj, in_pto);
262       return (in_pto);
263     }
264   default:
265     fprintf (stderr, "get_pto_proj(/*todo*/): not handled: proj (%s[%li])\n",
266              get_op_name (get_irn_op (proj_in)),
267              get_irn_node_nr (proj_in));
268     assert (0 && "Proj(?)");
269     return NULL;
270   }
271
272 }
273
274 static pto_t *get_pto_phi (ir_node *phi, pto_env_t *env)
275 {
276   pto_t *pto;
277   int change = FALSE;
278   int i, n_ins;
279
280   assert (mode_P == get_irn_mode (phi));
281
282   pto = get_node_pto (phi);
283   assert (pto);                 /* must be initialised */
284
285   n_ins = get_irn_arity (phi);
286   for (i = 0; i < n_ins; i ++) {
287     ir_node *in = get_irn_n (phi, i);
288     pto_t *in_pto = get_pto (in, env);
289
290     assert (in_pto);
291
292     change |= qset_insert_all (pto->values, in_pto->values);
293   }
294
295   env->change |= change;
296
297   return (pto);
298 }
299
300 static pto_t *get_pto_sel (ir_node *sel, pto_env_t *env)
301 {
302   pto_t *pto = NULL; /* get_node_pto (sel); */
303
304   if (NULL == pto) {
305     ir_node *in = get_Sel_ptr (sel);
306
307     pto = get_pto (in, env);
308     set_node_pto (sel, pto);
309   }
310
311   return (pto);
312 }
313
314 static pto_t *get_pto_ret (ir_node *ret, pto_env_t *env)
315 {
316   pto_t *pto = NULL; /* get_node_pto (ret); */
317
318   if (NULL == pto) {
319     ir_node *in = get_Return_res (ret, 0);
320
321     pto = get_pto (in, env);
322     set_node_pto (ret, pto);
323   }
324
325   assert (pto);
326
327   DBGPRINT (9, (stdout, "%s: ", __FUNCTION__));
328   DBGEXE (9, pto_print_pto (ret));
329
330   return (pto);
331 }
332
333
334 /* Dispatch to propagate PTO values */
335 static pto_t *get_pto (ir_node *node, pto_env_t *env)
336 {
337   const ir_opcode op = get_irn_opcode (node);
338
339   DBGPRINT (2, (stdout, "%s (%s[%li])\n",
340                 __FUNCTION__,
341                 OPNAME (node), OPNUM (node)));
342
343   switch (op) {
344   case (iro_Cast):   return (get_pto (get_Cast_op (node), env));
345   case (iro_Proj):   return (get_pto_proj  (node, env));
346   case (iro_Phi):    return (get_pto_phi   (node, env));
347   case (iro_Sel):    return (get_pto_sel   (node, env));
348   case (iro_Alloc):  return (get_alloc_pto (node));
349   case (iro_Return): return (get_pto_ret   (node, env));
350
351   case (iro_Call):              /* FALLTHROUGH */
352   case (iro_Load):              /* FALLTHROUGH */
353   case (iro_Const):             /* FALLTHROUGH */
354   case (iro_SymConst):{
355     pto_t *pto = get_node_pto (node);
356
357     assert (pto);
358     return (pto);
359   }
360   default:
361     /* stopgap measure */
362     fprintf (stderr, "%s: not handled: node[%li].op = %s\n",
363              __FUNCTION__,
364              get_irn_node_nr (node),
365              get_op_name (get_irn_op (node)));
366     assert (0 && "something not handled");
367     return NULL;
368   }
369 }
370
371
372 /* Actions for the nodes: */
373 static void pto_load (ir_node *load, pto_env_t *pto_env)
374 {
375   ir_node *ptr;
376   ir_entity *ent;
377
378   /* perform load */
379   DBGPRINT (2, (stdout, "%s (%s[%li]): pto = 0x%08x\n",
380                 __FUNCTION__,
381                 OPNAME (load), OPNUM (load), (int) get_node_pto (load)));
382
383   ptr = get_Load_ptr (load);
384
385   if (is_dummy_load_ptr (ptr)) {
386     return;
387   }
388
389   ent = get_ptr_ent (ptr);
390
391   if (mode_P == get_type_mode (get_entity_type (ent))) {
392     pto_t *ptr_pto = get_pto (ptr, pto_env);
393
394     assert (ptr_pto);
395
396     DBGPRINT (1, (stdout, "%s (%s[%li]): ptr = 0x%08x\n",
397                   __FUNCTION__,
398                   OPNAME (ptr), OPNUM (ptr), (int) ptr_pto));
399
400     pto_env->change |= mod_load (load, ent, ptr_pto);
401   }
402 }
403
404 static void pto_store (ir_node *store, pto_env_t *pto_env)
405 {
406   ir_node *ptr, *val;
407   ir_entity *ent;
408   pto_t *ptr_pto, *val_pto;
409
410   /* perform store */
411   DBGPRINT (2, (stdout, "%s (%s[%li]) (no pto)\n",
412                 __FUNCTION__,
413                 OPNAME (store), OPNUM (store)));
414
415   ptr = get_Store_ptr (store);
416   val = get_Store_value (store);
417
418   if (mode_P != get_irn_mode (val)) {
419     return;
420   }
421
422   ent = get_ptr_ent (ptr);
423
424   ptr_pto = get_pto (ptr, pto_env);
425   val_pto = get_pto (val, pto_env);
426
427   assert (ptr_pto);
428   assert (val_pto);
429
430   DBGPRINT (2, (stdout, "%s (%s[%li]): ptr_pto = 0x%08x\n",
431                 __FUNCTION__,
432                 OPNAME (ptr), OPNUM (ptr), (int) ptr_pto));
433   DBGPRINT (2, (stdout, "%s (%s[%li]): val_pto = 0x%08x\n",
434                 __FUNCTION__,
435                 OPNAME (val), OPNUM (val), (int) val_pto));
436
437   pto_env->change |= mod_store (store, ent, ptr_pto, val_pto);
438 }
439
440 static void pto_method (ir_node *call, pto_env_t *pto_env)
441 {
442   int i;
443   callEd_info_t *callEd_info;
444
445   DBGPRINT (2, (stdout, "%s:%i (%s[%li]): pto = 0x%08x\n",
446                 __FUNCTION__, __LINE__, OPNAME (call), OPNUM (call),
447                 (int) get_node_pto (call)));
448
449   callEd_info = ecg_get_callEd_info (call);
450
451   if (NULL == callEd_info) {
452     DBGPRINT (2, (stdout, "%s:%i (%s[%li]), no graph\n",
453                   __FUNCTION__, __LINE__, OPNAME (call), OPNUM (call)));
454   }
455
456   i = 0;
457   while (NULL != callEd_info) {
458     DBGPRINT (2, (stdout, "%s:%i (%s[%li]), graph %i\n",
459                   __FUNCTION__, __LINE__, OPNAME (call), OPNUM (call), i ++));
460
461     pto_call (callEd_info->callEd, call, pto_env);
462
463     callEd_info = callEd_info->prev;
464   }
465 }
466
467 /* Perform the appropriate action on the given node */
468 static void pto_node_node(ir_node *node, pto_env_t *pto_env)
469 {
470   ir_opcode op = get_irn_opcode (node);
471
472   DBGPRINT (1, (stdout, "%s (%s[%li])\n",
473                 __FUNCTION__, OPNAME (node), OPNUM (node)));
474
475   switch (op) {
476   case (iro_Start): /* nothing */ break;
477   case (iro_Load):
478     pto_load (node, pto_env);
479     break;
480
481   case (iro_Store):
482     pto_store (node, pto_env);
483     break;
484
485   case (iro_Call):
486     pto_method (node, pto_env);
487     break;
488
489   case (iro_Raise):
490     pto_raise (node, pto_env);
491     break;
492
493   case (iro_Return):
494     /* nothing to do */
495     break;
496
497   case (iro_Alloc):
498     /* nothing to do */
499     break;
500
501   case (iro_Block):
502     pto_end_block (node, pto_env);
503     break;
504
505   case (iro_Phi):
506     /* must be a PhiM */
507     assert (mode_M == get_irn_mode (node));
508     /* nothing to do */
509     break;
510
511     /* uninteresting stuff: */
512   case (iro_Div):
513   case (iro_Quot):
514   case (iro_Mod):
515   case (iro_DivMod): /* nothing to do */ break;
516
517   default:
518     /* stopgap measure */
519     fprintf (stderr, "%s: not handled: node[%li].op = %s\n",
520              __FUNCTION__,
521              get_irn_node_nr (node),
522              get_op_name (get_irn_op (node)));
523     assert (0 && "something not handled");
524   }
525 }
526
527
528 /* Callback function to execute in pre-order */
529 static void pto_node_pre (ir_node *node, void *env)
530 {
531   /* nothing */
532 }
533
534 /* Callback function to execute in post-order */
535 static void pto_node_post (ir_node *node, void *env)
536 {
537   pto_env_t *pto_env = (pto_env_t*) env;
538
539   DBGPRINT (999, (stdout, "%s (%s[%li])\n",
540                   __FUNCTION__,
541                 OPNAME (node), OPNUM (node)));
542
543   pto_node_node (node, pto_env);
544 }
545
546 /* Perform a single pass over the given graph */
547 static void pto_graph_pass (ir_graph *graph, void *pto_env)
548 {
549   irg_walk_mem (graph, pto_node_pre, pto_node_post, pto_env);
550 }
551
552 /* Continue PTO for one of the graphs called at a Call */
553 static void pto_call (ir_graph *graph, ir_node *call, pto_env_t *pto_env)
554 {
555   int change = FALSE;
556
557   /* only for debugging stuff: */
558   ir_entity *ent = get_irg_entity (graph);
559   const char *ent_name = (char*) get_entity_name (ent);
560   const char *own_name = (char*) get_type_name (get_entity_owner (ent));
561
562   /* perform call */
563   DBGPRINT (2, (stdout, "%s (%s[%li]) to \"%s.%s\"\n",
564                 __FUNCTION__,
565                 OPNAME (call), OPNUM (call),
566                 own_name, ent_name));
567
568   if (! get_irg_is_mem_visited (graph)) {
569     /* handle direct call */
570     graph_info_t *ginfo = ecg_get_info (graph);
571
572     /* Save CTX */
573     int ctx_idx = find_ctx_idx (call, ginfo, get_curr_ctx ());
574     ctx_info_t *call_ctx = get_ctx (ginfo, ctx_idx);
575     ctx_info_t *old_ctx = set_curr_ctx (call_ctx);
576
577     DBGPRINT (1, (stdout, "%s>CTX: ", -- spaces));
578     DBGEXE (1, ecg_print_ctx (call_ctx, stdout));
579
580     /* Initialise Alloc Names and Node values */
581     pto_reset_graph_pto (graph, ctx_idx);
582
583     /* Compute Arguments */
584     set_graph_args (graph, call, pto_env);
585
586     /* Visit/Iterate Graph */
587     pto_graph (graph, ctx_idx, pto_env);
588
589     /* Restore CTX */
590     set_curr_ctx (old_ctx);
591
592     /* Get Return Value from Graph */
593     change |= set_graph_result (graph, call);
594
595     DBGPRINT (1, (stdout, "%s<CTX: ", spaces ++));
596     DBGEXE (1, ecg_print_ctx (call_ctx, stdout));
597
598     /* Don't need to reset alloc names unless we handle recursion here  */
599   } else {
600     pto_env_t *enc_env;
601     int rec_change;
602
603     /* handle recursion */
604     DBGPRINT (0, (stdout, "%s: recursion into \"%s.%s\"\n",
605                   __FUNCTION__,
606                   own_name, ent_name));
607     /* Find 'right' enclosing pto_env */
608     enc_env = pto_env;
609     while (graph != enc_env->graph) {
610       enc_env = enc_env->enc_env; /* talk about naming issues here */
611
612       /* since we're in a recursion loop, we *must* find an env for the callEd here: */
613       assert (NULL != enc_env->enc_env);
614     }
615
616     /* Re-Set arguments */
617     rec_change = add_graph_args (graph, call, pto_env);
618
619       DBGPRINT (1, (stdout, "%s: return  in:", __FUNCTION__));
620       DBGEXE (1, pto_print_pto (get_irg_end_block (graph)));
621
622     if (rec_change) {
623       DBGPRINT (0, (stdout, "%s: change args\n", __FUNCTION__));
624     }
625
626     rec_change |= set_graph_result (graph, call);
627
628     if (rec_change) {
629       DBGPRINT (1, (stdout, "%s: return out:", __FUNCTION__));
630       DBGEXE (1, pto_print_pto (get_irg_end_block (graph)));
631     }
632
633 # if 0
634     /* appears that we don't need this: */
635     enc_env->change |= rec_change;
636 # endif /* 0 */
637   }
638
639   /* Todo: Set 'Unknown' Value as Return Value when the graph is not
640      known */
641
642   pto_env->change |= change;
643 }
644
645 static void pto_raise (ir_node *raise, pto_env_t *pto_env)
646 {
647   /* perform raise */
648   DBGPRINT (2, (stdout, "%s (%s[%li]): pto = 0x%08x\n",
649                 __FUNCTION__,
650                 OPNAME (raise), OPNUM (raise), (int) get_node_pto (raise)));
651 }
652
653 static void pto_end_block (ir_node *end_block, pto_env_t *pto_env)
654 {
655   /* perform end block */
656   ir_type *tp = get_entity_type (get_irg_entity (get_irn_irg (end_block)));
657   pto_t *end_pto;
658   int i, n_ins;
659
660   if (0 == get_method_n_ress (tp)) {
661     return;
662   }
663
664   tp = get_method_res_type (tp, 0);
665
666   if (! mode_is_reference(get_type_mode (tp))) {
667     return;
668   }
669
670   DBGPRINT (2, (stdout, "%s (%s[%li]): pto = 0x%08x\n",
671                 __FUNCTION__,
672                 OPNAME (end_block), OPNUM (end_block),
673                 (int) get_node_pto (end_block)));
674
675   end_pto = get_node_pto (end_block);
676
677   assert (end_pto);
678
679   n_ins = get_irn_arity (end_block);
680   for (i = 0; i < n_ins; i ++) {
681     ir_node *in = get_irn_n (end_block, i);
682
683     if (iro_Return == get_irn_opcode (in)) {
684       pto_t *in_pto = get_pto (in, pto_env);
685
686       pto_env->change |= qset_insert_all (end_pto->values, in_pto->values);
687     }
688   }
689 }
690
691 /* ===================================================
692    Exported Implementation:
693    =================================================== */
694 /* Main loop: Initialise and iterate over the given graph */
695 void pto_graph (ir_graph *graph, int ctx_idx, pto_env_t *enc_env)
696 {
697   int run;
698   pto_env_t *pto_env;
699
700   /* Also exported, since we need it in 'pto.c' */
701   pto_env = xmalloc (sizeof (pto_env_t));
702   pto_env->enc_env = enc_env;
703   pto_env->graph   = graph;
704   pto_env->ctx_idx = ctx_idx;
705   pto_env->change  = TRUE;
706
707   /* HERE ("start"); */
708
709   DBGPRINT (2, (stdout, "%s: start for ctx %i\n",
710                 __FUNCTION__,
711                 ctx_idx));
712
713   /* todo (here): iterate, obey 'changed' attribute */
714   run = 0;
715   while (0 != pto_env->change) {
716     run ++;
717     pto_env->change = FALSE;
718     pto_graph_pass (graph, pto_env);
719   }
720
721   DBGPRINT (1, (stdout, "%s: %i runs on \"%s.%s\"\n",
722                 __FUNCTION__,
723                 run,
724                 get_type_name (get_entity_owner (get_irg_entity (graph))),
725                 get_entity_name (get_irg_entity (graph))));
726   memset (pto_env, 0, sizeof (pto_env_t));
727   free (pto_env);
728   /* HERE ("end"); */
729 }
730
731 /* Set the PTO value for the given non-alloc node */
732 void set_node_pto (ir_node *node, pto_t *pto)
733 {
734   assert (op_Alloc != get_irn_op(node));
735
736   set_irn_link (node, (void*) pto);
737 }
738
739 /*Get the PTO value for the given non-alloc node */
740 pto_t *get_node_pto (ir_node *node)
741 {
742   assert (op_Alloc != get_irn_op(node));
743
744   return ((pto_t*) get_irn_link (node));
745 }
746
747 /* Set the PTO value for the given alloc node */
748 void set_alloc_pto (ir_node *alloc, alloc_pto_t *alloc_pto)
749 {
750   assert (op_Alloc == get_irn_op(alloc));
751
752   assert (alloc_pto);
753
754   set_irn_link (alloc, (void*) alloc_pto);
755 }
756
757 /*Get the current PTO value for the given alloc node */
758 pto_t *get_alloc_pto (ir_node *alloc)
759 {
760   alloc_pto_t *alloc_pto = get_irn_link (alloc);
761
762   assert (op_Alloc == get_irn_op(alloc));
763
764   assert (alloc_pto -> curr_pto);
765
766   return (alloc_pto -> curr_pto);
767 }
768
769 \f
770 /*
771   $Log$
772   Revision 1.21  2007/03/22 10:39:33  matze
773   a bunch of fixes to make firm work with NDEBUG and without DEBUG_libfirm
774
775   Revision 1.20  2007/01/16 15:45:42  beck
776   renamed type opcode to ir_opcode
777
778   Revision 1.19  2006/12/13 19:46:47  beck
779   rename type entity into ir_entity
780
781   Revision 1.18  2006/01/13 22:57:41  beck
782   renamed all types 'type' to 'ir_type'
783   used mode_is_reference instead of != mode_P test
784
785   Revision 1.17  2005/02/25 16:48:21  liekweg
786   fix typo
787
788   Revision 1.16  2005/01/27 15:51:19  liekweg
789   whitespace change
790
791   Revision 1.15  2005/01/14 14:14:26  liekweg
792   fix gnu extension, fix fprintf's
793
794   Revision 1.14  2005/01/14 13:37:26  liekweg
795   fix allocation (size); don't cast malloc
796
797   Revision 1.13  2005/01/10 17:26:34  liekweg
798   fixup printfs, don't put environments on the stack
799
800   Revision 1.12  2004/12/23 15:46:19  beck
801   removed unneeded allocations
802
803   Revision 1.11  2004/12/21 14:50:59  beck
804   removed C)) and GNUC constructs, add default returns
805
806   Revision 1.10  2004/12/20 17:34:35  liekweg
807   fix recursion handling
808
809   Revision 1.9  2004/12/15 13:31:18  liekweg
810   remove debugging stuff
811
812   Revision 1.8  2004/12/15 09:18:18  liekweg
813   pto_name.c
814
815   Revision 1.7  2004/12/06 12:55:06  liekweg
816   actually iterate
817
818   Revision 1.6  2004/12/02 16:17:51  beck
819   fixed config.h include
820
821   Revision 1.5  2004/11/30 14:47:54  liekweg
822   fix initialisation; do correct iteration
823
824   Revision 1.4  2004/11/26 15:59:40  liekweg
825   verify pto_{load,store}
826
827   Revision 1.3  2004/11/24 14:53:55  liekweg
828   Bugfixes
829
830   Revision 1.2  2004/11/20 21:21:56  liekweg
831   Finalise initialisation
832
833   Revision 1.1  2004/11/18 16:37:34  liekweg
834   rewritten
835
836
837 */