remove INLINE before global functions
[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(): args of %s[%li] -> 0x%08x\n",
82                 OPNAME (call), OPNUM (call), (void*) 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(): 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(): 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(): 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(): 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(): 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(): "));
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(): 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() (%s[%li]): pto = 0x%08x\n",
360                 OPNAME (load), OPNUM (load), (void*) 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() (%s[%li]): ptr = 0x%08x\n",
376                   OPNAME (ptr), OPNUM (ptr), (void*) 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() (%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() (%s[%li]): ptr_pto = 0x%08x\n",
408                 OPNAME (ptr), OPNUM (ptr), (void*) ptr_pto));
409   DBGPRINT (2, (stdout, "pto_store() (%s[%li]): val_pto = 0x%08x\n",
410                 OPNAME (val), OPNUM (val), (void*) 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():%i (%s[%li]): pto = 0x%08x\n",
421                 __LINE__, OPNAME (call), OPNUM (call),
422                 (void*) 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():%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():%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() (%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, "pto_node_node(): not handled: node[%li].op = %s\n",
495              get_irn_node_nr (node),
496              get_op_name (get_irn_op (node)));
497     assert (0 && "something not handled");
498   }
499 }
500
501
502 /* Callback function to execute in pre-order */
503 static void pto_node_pre (ir_node *node, void *env)
504 {
505   /* nothing */
506 }
507
508 /* Callback function to execute in post-order */
509 static void pto_node_post (ir_node *node, void *env)
510 {
511   pto_env_t *pto_env = (pto_env_t*) env;
512
513   DBGPRINT (999, (stdout, "pto_node_post() (%s[%li])\n",
514                 OPNAME (node), OPNUM (node)));
515
516   pto_node_node (node, pto_env);
517 }
518
519 /* Perform a single pass over the given graph */
520 static void pto_graph_pass (ir_graph *graph, void *pto_env)
521 {
522   irg_walk_mem (graph, pto_node_pre, pto_node_post, pto_env);
523 }
524
525 /* Continue PTO for one of the graphs called at a Call */
526 static void pto_call (ir_graph *graph, ir_node *call, pto_env_t *pto_env)
527 {
528   int change = FALSE;
529
530   /* only for debugging stuff: */
531   entity *ent = get_irg_entity (graph);
532   const char *ent_name = (char*) get_entity_name (ent);
533   const char *own_name = (char*) get_type_name (get_entity_owner (ent));
534
535   /* perform call */
536   DBGPRINT (2, (stdout, "pto_call() (%s[%li]) to \"%s.%s\"\n",
537                 OPNAME (call), OPNUM (call),
538                 own_name, ent_name));
539
540   if (! get_irg_is_mem_visited (graph)) {
541     /* handle direct call */
542     graph_info_t *ginfo = ecg_get_info (graph);
543
544     /* Save CTX */
545     int ctx_idx = find_ctx_idx (call, ginfo, get_curr_ctx ());
546     ctx_info_t *call_ctx = get_ctx (ginfo, ctx_idx);
547     ctx_info_t *old_ctx = set_curr_ctx (call_ctx);
548
549     DBGPRINT (1, (stdout, "%s>CTX: ", -- spaces));
550     DBGEXE (1, ecg_print_ctx (call_ctx, stdout));
551
552     /* Initialise Alloc Names and Node values */
553     pto_reset_graph_pto (graph, ctx_idx);
554
555     /* Compute Arguments */
556     set_graph_args (graph, call, pto_env);
557
558     /* Visit/Iterate Graph */
559     pto_graph (graph, ctx_idx, pto_env);
560
561     /* Restore CTX */
562     set_curr_ctx (old_ctx);
563
564     /* Get Return Value from Graph */
565     change |= set_graph_result (graph, call);
566
567     DBGPRINT (1, (stdout, "%s<CTX: ", spaces ++));
568     DBGEXE (1, ecg_print_ctx (call_ctx, stdout));
569
570     /* Don't need to reset alloc names unless we handle recursion here  */
571   } else {
572     pto_env_t *enc_env;
573     int rec_change;
574
575     /* handle recursion */
576     DBGPRINT (0, (stdout, "pto_call(): recursion into \"%s.%s\"\n",
577                   own_name, ent_name));
578     /* Find 'right' enclosing pto_env */
579     enc_env = pto_env;
580     while (graph != enc_env->graph) {
581       enc_env = enc_env->enc_env; /* talk about naming issues here */
582
583       /* since we're in a recursion loop, we *must* find an env for the callEd here: */
584       assert (NULL != enc_env->enc_env);
585     }
586
587     /* Re-Set arguments */
588     rec_change = add_graph_args (graph, call, pto_env);
589
590       DBGPRINT (1, (stdout, "pto_call(): return  in:"));
591       DBGEXE (1, pto_print_pto (get_irg_end_block (graph)));
592
593     if (rec_change) {
594       DBGPRINT (0, (stdout, "pto_call(): change args"));
595     }
596
597     rec_change |= set_graph_result (graph, call);
598
599     if (rec_change) {
600       DBGPRINT (0, (stdout, "pto_call(): return out:"));
601       DBGEXE (0, pto_print_pto (get_irg_end_block (graph)));
602     }
603
604 # if 0
605     /* appears that we don't need this: */
606     enc_env->change |= rec_change;
607 # endif /* 0 */
608   }
609
610   /* Todo: Set 'Unknown' Value as Return Value when the graph is not
611      known */
612
613   pto_env->change |= change;
614 }
615
616 static void pto_raise (ir_node *raise, pto_env_t *pto_env)
617 {
618   /* perform raise */
619   DBGPRINT (2, (stdout, "pto_raise() (%s[%li]): pto = 0x%08x\n",
620                 OPNAME (raise), OPNUM (raise), (void*) get_node_pto (raise)));
621 }
622
623 static void pto_end_block (ir_node *end_block, pto_env_t *pto_env)
624 {
625   /* perform end block */
626   type *tp = get_entity_type (get_irg_entity (get_irn_irg (end_block)));
627   pto_t *end_pto;
628   int i, n_ins;
629
630   if (0 == get_method_n_ress (tp)) {
631     return;
632   }
633
634   tp = get_method_res_type (tp, 0);
635
636   if (mode_P != get_type_mode (tp)) {
637     return;
638   }
639
640   DBGPRINT (2, (stdout, "pto_end_block() (%s[%li]): pto = 0x%08x\n",
641                 OPNAME (end_block), OPNUM (end_block),
642                 (void*) get_node_pto (end_block)));
643
644   end_pto = get_node_pto (end_block);
645
646   assert (end_pto);
647
648   n_ins = get_irn_arity (end_block);
649   for (i = 0; i < n_ins; i ++) {
650     ir_node *in = get_irn_n (end_block, i);
651
652     if (iro_Return == get_irn_opcode (in)) {
653       pto_t *in_pto = get_pto (in, pto_env);
654
655       pto_env->change |= qset_insert_all (end_pto->values, in_pto->values);
656     }
657   }
658 }
659
660 /* ===================================================
661    Exported Implementation:
662    =================================================== */
663 /* Main loop: Initialise and iterate over the given graph */
664 void pto_graph (ir_graph *graph, int ctx_idx, pto_env_t *enc_env)
665 {
666   int run;
667
668   /* Also exported, since we need it in 'pto.c' */
669   pto_env_t pto_env;
670   pto_env.enc_env = enc_env;
671   pto_env.graph   = graph;
672   pto_env.ctx_idx = ctx_idx;
673   pto_env.change  = TRUE;
674
675   /* HERE ("start"); */
676
677   DBGPRINT (2, (stdout, "pto_graph(): start for ctx %i\n",
678                 ctx_idx));
679
680   /* todo (here): iterate, obey 'changed' attribute */
681   run = 0;
682   while (0 != pto_env.change) {
683     run ++;
684     pto_env.change = FALSE;
685     pto_graph_pass (graph, &pto_env);
686   }
687
688   DBGPRINT (1, (stdout, "pto_graph(): %i runs on \"%s.%s\"\n",
689                 run,
690                 get_type_name (get_entity_owner (get_irg_entity (graph))),
691                 get_entity_name (get_irg_entity (graph))));
692   /* HERE ("end"); */
693 }
694
695 /* Set the PTO value for the given non-alloc node */
696 void set_node_pto (ir_node *node, pto_t *pto)
697 {
698   assert (op_Alloc != get_irn_op(node));
699
700   set_irn_link (node, (void*) pto);
701 }
702
703 /*Get the PTO value for the given non-alloc node */
704 pto_t *get_node_pto (ir_node *node)
705 {
706   assert (op_Alloc != get_irn_op(node));
707
708   return ((pto_t*) get_irn_link (node));
709 }
710
711 /* Set the PTO value for the given alloc node */
712 void set_alloc_pto (ir_node *alloc, alloc_pto_t *alloc_pto)
713 {
714   assert (op_Alloc == get_irn_op(alloc));
715
716   assert (alloc_pto);
717
718   set_irn_link (alloc, (void*) alloc_pto);
719 }
720
721 /*Get the current PTO value for the given alloc node */
722 pto_t *get_alloc_pto (ir_node *alloc)
723 {
724   alloc_pto_t *alloc_pto = get_irn_link (alloc);
725
726   assert (op_Alloc == get_irn_op(alloc));
727
728   assert (alloc_pto -> curr_pto);
729
730   return (alloc_pto -> curr_pto);
731 }
732
733 \f
734 /*
735   $Log$
736   Revision 1.12  2004/12/23 15:46:19  beck
737   removed unneeded allocations
738
739   Revision 1.11  2004/12/21 14:50:59  beck
740   removed C)) and GNUC constructs, add default returns
741
742   Revision 1.10  2004/12/20 17:34:35  liekweg
743   fix recursion handling
744
745   Revision 1.9  2004/12/15 13:31:18  liekweg
746   remove debugging stuff
747
748   Revision 1.8  2004/12/15 09:18:18  liekweg
749   pto_name.c
750
751   Revision 1.7  2004/12/06 12:55:06  liekweg
752   actually iterate
753
754   Revision 1.6  2004/12/02 16:17:51  beck
755   fixed config.h include
756
757   Revision 1.5  2004/11/30 14:47:54  liekweg
758   fix initialisation; do correct iteration
759
760   Revision 1.4  2004/11/26 15:59:40  liekweg
761   verify pto_{load,store}
762
763   Revision 1.3  2004/11/24 14:53:55  liekweg
764   Bugfixes
765
766   Revision 1.2  2004/11/20 21:21:56  liekweg
767   Finalise initialisation
768
769   Revision 1.1  2004/11/18 16:37:34  liekweg
770   rewritten
771
772
773 */