normalized names of functions, enums ...
[libfirm] / testprograms / recursions.c
1 /*
2  * Project:     libFIRM
3  * File name:   testprograms/recursion.c
4  * Purpose:     Empty methods that recur.
5  * Author:      Goetz Lindenmaier
6  * Modified by:
7  * Created:
8  * CVS-ID:      $Id$
9  * Copyright:   (c) 2004 Universität Karlsruhe
10  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
11  */
12
13 # include <stdio.h>
14 # include <string.h>
15
16 # include "irvrfy.h"
17 # include "irdump.h"
18 # include "firm.h"
19
20 /**
21 *
22
23 *
24 **/
25
26 ir_graph *make_method(char *name, int n_locs) {
27   type *proc_t   = new_type_method(new_id_from_str(name), 0, 0);
28   //set_method_param_type(proc_set_a, 0, class_p_ptr);
29   //set_method_param_type(proc_set_a, 1, prim_t_int);
30   entity *proc_e = new_entity(get_glob_type(), new_id_from_str (name), proc_t);
31   return new_ir_graph (proc_e, n_locs);
32 }
33
34
35 ir_node *make_Call(ir_graph *c, int n_args, ir_node **args) {
36   entity *ent = get_irg_entity(c);
37   type *mtp = get_entity_type(ent);
38   symconst_symbol sym;
39   sym.entity_p = ent;
40   ir_node *addr = new_SymConst(sym, symconst_addr_ent);
41   ir_node *call = new_Call(get_store(), addr, n_args, args, mtp);
42   set_store(new_Proj(call, mode_M, pn_Call_M_regular));
43   if (get_method_n_ress(mtp) == 1) {
44     type *restp = get_method_res_type(mtp, 0);
45     return new_Proj(new_Proj(call, mode_T, pn_Call_T_result), get_type_mode(restp), 0);
46   }
47   return NULL;
48 }
49
50 void close_method(int n_ins, ir_node **ins) {
51   ir_node *x =  new_Return (get_store(), n_ins, ins);
52   mature_immBlock (get_cur_block());
53   add_immBlock_pred  (get_cur_end_block(), x);
54   mature_immBlock (get_cur_end_block());
55   finalize_cons(current_ir_graph);
56 }
57
58
59 int
60 main(void)
61 {
62   init_firm (NULL);
63
64   set_opt_constant_folding(0);
65   set_opt_cse(0);
66
67   set_irp_prog_name(new_id_from_str("recursion"));
68
69   /** The callgraph of the heapsort excample */
70   ir_graph *mainp  = make_method("main", 0);
71   ir_graph *hs     = make_method("hs", 0);
72   ir_graph *ha     = make_method("ha", 0);
73   ir_graph *insert = make_method("insert", 0);
74   ir_graph *remove = make_method("remove", 0);
75   ir_graph *unheap = make_method("unheap", 0);
76   ir_graph *downh  = make_method("downh", 0);
77   ir_graph *exc    = make_method("exc", 0);
78
79   set_irp_main_irg(mainp);
80
81   current_ir_graph = mainp;
82   make_Call(hs, 0, NULL);
83   close_method(0, NULL);
84
85   current_ir_graph = hs;
86   make_Call(ha, 0, NULL);
87   make_Call(remove, 0, NULL);
88   close_method(0, NULL);
89
90   current_ir_graph = ha;
91   make_Call(insert, 0, NULL);
92   close_method(0, NULL);
93
94   current_ir_graph = insert;
95   make_Call(unheap, 0, NULL);
96   close_method(0, NULL);
97
98   current_ir_graph = remove;
99   make_Call(unheap, 0, NULL);
100   make_Call(downh, 0, NULL);
101   close_method(0, NULL);
102
103   current_ir_graph = unheap;
104   make_Call(exc, 0, NULL);
105   close_method(0, NULL);
106
107   current_ir_graph = downh;
108   make_Call(downh, 0, NULL);
109   make_Call(exc, 0, NULL);
110   close_method(0, NULL);
111
112   current_ir_graph = exc;
113   close_method(0, NULL);
114
115
116   /* A callgraph with a nested recursion. */
117   ir_graph *a  = make_method("a", 0);
118   ir_graph *b  = make_method("b", 0);
119   ir_graph *c  = make_method("c", 0);
120   ir_graph *d  = make_method("d", 0);
121
122   current_ir_graph = a;
123   make_Call(b, 0, NULL);
124   make_Call(c, 0, NULL);
125   make_Call(b, 0, NULL);
126   close_method(0, NULL);
127
128   current_ir_graph = b;
129   close_method(0, NULL);
130
131   current_ir_graph = c;
132   make_Call(b, 0, NULL);
133   make_Call(d, 0, NULL);
134   make_Call(a, 0, NULL);
135   close_method(0, NULL);
136
137   current_ir_graph = d;
138   make_Call(a, 0, NULL);
139   make_Call(d, 0, NULL);
140   close_method(0, NULL);
141
142   /* A callgraph with a self recursion */
143   ir_graph *self  = make_method("self", 0);
144
145   current_ir_graph = self;
146   make_Call(self, 0, NULL);
147   close_method(0, NULL);
148
149   /* A callgraph with a self recursion over several steps*/
150   ir_graph *self1 = make_method("self1", 0);
151   ir_graph *self2 = make_method("self2", 0);
152   ir_graph *self3 = make_method("self3", 0);
153   ir_graph *self4 = make_method("self4", 0);
154
155   current_ir_graph = self1;
156   make_Call(self2, 0, NULL);
157   close_method(0, NULL);
158
159   current_ir_graph = self2;
160   make_Call(self3, 0, NULL);
161   close_method(0, NULL);
162
163   current_ir_graph = self3;
164   make_Call(self4, 0, NULL);
165   close_method(0, NULL);
166
167   current_ir_graph = self4;
168   make_Call(self1, 0, NULL);
169   close_method(0, NULL);
170
171   printf("Dumping Callgraph.\n");
172
173   entity **free_methods;
174   int arr_len;
175   cgana(&arr_len, &free_methods, 0);
176   compute_callgraph();
177   find_callgraph_recursions();
178   dump_callgraph("");
179   cg_construct(arr_len, free_methods);
180
181   printf("Use xvcg to view these graphs:\n");
182   printf("/ben/goetz/bin/xvcg GRAPHNAME\n\n");
183   return (0);
184 }