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