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