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