Inline gen_Minus_ex() into its only caller gen_Minus().
[libfirm] / ir / ana / trouts.c
1 /*
2  * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief    Reverse edges that reference types/entities.
23  * @author   Goetz Lindenmaier
24  * @date     29.10.2004
25  * @version  $Id$
26  */
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include "irnode.h"
32 #include "trouts.h"
33
34 #include "array.h"
35 #include "pmap.h"
36
37 #include "irprog_t.h"
38 #include "irgwalk.h"
39 #include "irnode.h"
40
41
42 /*------------------------------------------------------------------*/
43 /* We represent the fields in entities/types by hashmaps.           */
44 /*------------------------------------------------------------------*/
45
46 static pmap *entity_access_map = NULL;
47 static pmap *entity_reference_map = NULL;
48 static pmap *type_alloc_map = NULL;
49 static pmap *type_cast_map = NULL;
50 static pmap *type_pointertype_map = NULL;
51 static pmap *type_arraytype_map = NULL;
52
53 /**
54  * Return a flexible array containing all IR-nodes
55  * that access a given entity.
56  */
57 static ir_node **get_entity_access_array(ir_entity *ent) {
58   ir_node **res;
59   if (!entity_access_map) entity_access_map = pmap_create();
60
61   if (pmap_contains(entity_access_map, (void *)ent)) {
62     res = (ir_node **) pmap_get(entity_access_map, (void *)ent);
63   } else {
64     res = NEW_ARR_F(ir_node *, 0);
65     pmap_insert(entity_access_map, (void *)ent, (void *)res);
66   }
67
68   return res;
69 }
70 void set_entity_access_array(ir_entity *ent, ir_node **accs) {
71   ir_node **old = pmap_get(entity_access_map, (void *)ent);
72   if (old != accs)
73     pmap_insert(entity_access_map, (void *)ent, (void *)accs);
74 }
75
76 /**
77  * Return a flexible array containing all IR-nodes
78  * that reference a given entity.
79  */
80 static ir_node **get_entity_reference_array(ir_entity *ent) {
81   ir_node **res;
82   if (!entity_reference_map) entity_reference_map = pmap_create();
83
84   if (pmap_contains(entity_reference_map, (void *)ent)) {
85     res = (ir_node **) pmap_get(entity_reference_map, (void *)ent);
86   } else {
87     res = NEW_ARR_F(ir_node *, 0);
88     pmap_insert(entity_reference_map, (void *)ent, (void *)res);
89   }
90
91   return res;
92 }
93 void set_entity_reference_array(ir_entity *ent, ir_node **refs) {
94   ir_node **old = pmap_get(entity_reference_map, (void *)ent);
95   if (old != refs)
96     pmap_insert(entity_reference_map, (void *)ent, (void *)refs);
97 }
98
99 /**
100  * Return a flexible array containing all IR-nodes
101  * that allocate a given type.
102  */
103 static ir_node **get_type_alloc_array(ir_type *tp) {
104   ir_node **res;
105   if (!type_alloc_map) type_alloc_map = pmap_create();
106
107   if (pmap_contains(type_alloc_map, (void *)tp)) {
108     res = (ir_node **) pmap_get(type_alloc_map, (void *)tp);
109   } else {
110     res = NEW_ARR_F(ir_node *, 0);
111     pmap_insert(type_alloc_map, (void *)tp, (void *)res);
112   }
113
114   return res;
115 }
116 void set_type_alloc_array(ir_type *tp, ir_node **alls) {
117   ir_node **old = pmap_get(type_alloc_map, (void *)tp);
118   if (old != alls)
119     pmap_insert(type_alloc_map, (void *)tp, (void *)alls);
120 }
121
122 /**
123  * Return a flexible array containing all Cast-nodes
124  * that "create" a given type.
125  */
126 static ir_node **get_type_cast_array(ir_type *tp) {
127   ir_node **res;
128   if (!type_cast_map) type_cast_map = pmap_create();
129
130   if (pmap_contains(type_cast_map, (void *)tp)) {
131     res = (ir_node **) pmap_get(type_cast_map, (void *)tp);
132   } else {
133     res = NEW_ARR_F(ir_node *, 0);
134     pmap_insert(type_cast_map, (void *)tp, (void *)res);
135   }
136   return res;
137 }
138
139 void set_type_cast_array(ir_type *tp, ir_node **alls) {
140   ir_node **old = pmap_get(type_cast_map, (void *)tp);
141   if (old != alls)
142     pmap_insert(type_cast_map, (void *)tp, (void *)alls);
143 }
144
145 /**
146  * Return a flexible array containing all pointer
147  * types that points-to a given type.
148  */
149 static ir_type **get_type_pointertype_array(ir_type *tp) {
150   ir_type **res;
151   if (!type_pointertype_map) type_pointertype_map = pmap_create();
152
153   if (pmap_contains(type_pointertype_map, (void *)tp)) {
154     res = (ir_type **) pmap_get(type_pointertype_map, (void *)tp);
155   } else {
156     res = NEW_ARR_F(ir_type *, 0);
157     pmap_insert(type_pointertype_map, (void *)tp, (void *)res);
158   }
159
160   return res;
161 }
162 void set_type_pointertype_array(ir_type *tp, ir_type **pts) {
163   ir_type **old = pmap_get(type_pointertype_map, (void *)tp);
164   if (old != pts)
165     pmap_insert(type_pointertype_map, (void *)tp, (void *)pts);
166 }
167
168 /**
169  * Return a flexible array containing all array
170  * types that have a given type as element type.
171  */
172 static ir_type **get_type_arraytype_array(ir_type *tp) {
173   ir_type **res;
174   if (!type_arraytype_map) type_arraytype_map = pmap_create();
175
176   if (pmap_contains(type_arraytype_map, (void *)tp)) {
177     res = (ir_type **) pmap_get(type_arraytype_map, (void *)tp);
178   } else {
179     res = NEW_ARR_F(ir_type *, 0);
180     pmap_insert(type_arraytype_map, (void *)tp, (void *)res);
181   }
182
183   return res;
184 }
185
186 void set_type_arraytype_array(ir_type *tp, ir_type **pts) {
187   ir_type **old = pmap_get(type_arraytype_map, (void *)tp);
188   if (old != pts)
189     pmap_insert(type_arraytype_map, (void *)tp, (void *)pts);
190 }
191
192 /*------------------------------------------------------------------*/
193 /* Accessing the out data structures.                               */
194 /* These routines only work properly if firm is in state            */
195 /* trouts_consistent or trouts_inconsistent.                        */
196 /*------------------------------------------------------------------*/
197
198 /**------------------------------------------------------------------*/
199 /*   Access routines for entities                                    */
200 /**------------------------------------------------------------------*/
201
202 int get_entity_n_accesses(ir_entity *ent) {
203   ir_node ** accs;
204
205   assert(ent && is_entity(ent));
206
207   accs = get_entity_access_array(ent);
208   return ARR_LEN(accs);
209 }
210
211 ir_node *get_entity_access(ir_entity *ent, int pos) {
212   ir_node ** accs;
213
214   assert(0 <= pos && pos < get_entity_n_accesses(ent));
215
216   accs = get_entity_access_array(ent);
217   return accs[pos];
218 }
219
220 void add_entity_access(ir_entity *ent, ir_node *n) {
221   ir_node ** accs;
222
223   assert(ent && is_entity(ent));
224   assert(n && is_ir_node(n));
225
226   accs = get_entity_access_array(ent);
227   ARR_APP1(ir_node *, accs, n);
228   set_entity_access_array(ent, accs);
229 }
230
231 void set_entity_access(ir_entity *ent, int pos, ir_node *n) {
232   ir_node ** accs;
233
234   assert(0 <= pos && pos < get_entity_n_accesses(ent));
235   assert(n && is_ir_node(n));
236
237   accs = get_entity_access_array(ent);
238   accs[pos] = n;
239 }
240
241 /**------------------------------------------------------------------*/
242
243 int get_entity_n_references(ir_entity *ent) {
244   ir_node ** refs;
245
246   assert(ent && is_entity(ent));
247
248   refs = get_entity_reference_array(ent);
249   return ARR_LEN(refs);
250 }
251
252 ir_node *get_entity_reference(ir_entity *ent, int pos) {
253   ir_node ** refs;
254
255   assert(0 <= pos && pos < get_entity_n_references(ent));
256
257   refs = get_entity_reference_array(ent);
258   return refs[pos];
259 }
260
261 void add_entity_reference(ir_entity *ent, ir_node *n) {
262   ir_node ** refs;
263
264   assert(ent && is_entity(ent));
265   assert(n && is_ir_node(n));
266
267   refs = get_entity_reference_array(ent);
268   ARR_APP1(ir_node *, refs, n);
269   set_entity_reference_array(ent, refs);
270 }
271
272 void set_entity_reference(ir_entity *ent, int pos, ir_node *n) {
273   ir_node ** refs;
274
275   assert(0 <= pos && pos < get_entity_n_references(ent));
276   assert(n && is_ir_node(n));
277
278   refs = get_entity_reference_array(ent);
279   refs[pos] = n;
280 }
281
282
283 /**------------------------------------------------------------------*/
284 /*   Access routines for types                                       */
285 /**------------------------------------------------------------------*/
286
287 /* Number of Alloc nodes that create an instance of this type */
288 int get_type_n_allocs(ir_type *tp) {
289   ir_node **allocs;
290
291   assert(tp && is_type(tp));
292
293   allocs = get_type_alloc_array(tp);
294   return ARR_LEN(allocs);
295 }
296
297 /* Alloc node that creates an instance of this type */
298 ir_node *get_type_alloc(ir_type *tp, int pos) {
299   ir_node **allocs;
300   assert(0 <= pos && pos < get_type_n_allocs(tp));
301
302   allocs = get_type_alloc_array(tp);
303   return allocs[pos];
304 }
305
306 void add_type_alloc(ir_type *tp, ir_node *n) {
307   ir_node **allocs;
308
309   assert(tp && is_type(tp));
310   assert(n && is_ir_node(n));
311
312   allocs = get_type_alloc_array(tp);
313   ARR_APP1(ir_node *, allocs, n);
314   set_type_alloc_array(tp, allocs);
315 }
316
317 void set_type_alloc(ir_type *tp, int pos, ir_node *n) {
318   ir_node **allocs;
319
320   assert(0 <= pos && pos < get_type_n_allocs(tp));
321   assert(n && is_ir_node(n));
322
323   allocs = get_type_alloc_array(tp);
324   allocs[pos] = n;
325 }
326
327 /* Number of Cast nodes that create an instance of this type */
328 int get_type_n_casts(ir_type *tp) {
329   ir_node **casts;
330
331   assert(tp && is_type(tp));
332
333   casts = get_type_cast_array(tp);
334   return ARR_LEN(casts);
335 }
336
337
338 int get_class_n_upcasts(ir_type *clss) {
339   int i, n_casts = get_type_n_casts(clss);
340   int n_instances = 0;
341   for (i = 0; i < n_casts; ++i) {
342     ir_node *cast = get_type_cast(clss, i);
343     if (is_Cast_upcast(cast)) n_instances ++;
344   }
345   return n_instances;
346 }
347
348 int get_class_n_downcasts(ir_type *clss) {
349   int i, n_casts = get_type_n_casts(clss);
350   int n_instances = 0;
351   for (i = 0; i < n_casts; ++i) {
352     ir_node *cast = get_type_cast(clss, i);
353     if (is_Cast_downcast(cast)) n_instances ++;
354   }
355   return n_instances;
356 }
357
358
359 /* Cast node that creates an instance of this type */
360 ir_node *get_type_cast(ir_type *tp, int pos) {
361   ir_node **casts;
362   assert(0 <= pos && pos < get_type_n_casts(tp));
363
364   casts = get_type_cast_array(tp);
365   return casts[pos];
366 }
367
368 void add_type_cast(ir_type *tp, ir_node *n) {
369   ir_node **casts;
370
371   assert(tp && is_type(tp));
372   assert(n && is_ir_node(n));
373
374   casts = get_type_cast_array(tp);
375   ARR_APP1(ir_node *, casts, n);
376   set_type_cast_array(tp, casts);
377 }
378
379 void set_type_cast(ir_type *tp, int pos, ir_node *n) {
380   ir_node **casts;
381
382   assert(0 <= pos && pos < get_type_n_casts(tp));
383   assert(n && is_ir_node(n));
384
385   casts = get_type_cast_array(tp);
386   casts[pos] = n;
387 }
388
389 /**------------------------------------------------------------------*/
390
391 int get_type_n_pointertypes_to(ir_type *tp) {
392   ir_type ** pts;
393
394   assert(tp && is_type(tp));
395
396   pts = get_type_pointertype_array(tp);
397   return ARR_LEN(pts);
398 }
399
400 ir_type *get_type_pointertype_to(ir_type *tp, int pos) {
401   ir_type ** pts;
402
403   assert(0 <= pos && pos < get_type_n_pointertypes_to(tp));
404
405   pts = get_type_pointertype_array(tp);
406   return pts[pos];
407 }
408
409 void add_type_pointertype_to(ir_type *tp, ir_type *ptp) {
410   ir_type ** pts;
411
412   assert(tp && is_type(tp));
413   assert(ptp && is_Pointer_type(ptp));
414
415   pts = get_type_pointertype_array(tp);
416   ARR_APP1(ir_node *, pts, ptp);
417   set_type_pointertype_array(tp, pts);
418 }
419
420 void set_type_pointertype_to(ir_type *tp, int pos, ir_type *ptp) {
421   ir_type ** pts;
422
423   assert(0 <= pos && pos < get_type_n_pointertypes_to(tp));
424   assert(ptp && is_Pointer_type(ptp));
425
426   pts = get_type_pointertype_array(tp);
427   pts[pos] = ptp;
428 }
429
430
431 /**------------------------------------------------------------------*/
432
433 int   get_type_n_arraytypes_of(ir_type *tp) {
434   ir_type ** pts;
435
436   assert(tp && is_type(tp));
437
438   pts = get_type_arraytype_array(tp);
439   return ARR_LEN(pts);
440 }
441
442 ir_type *get_type_arraytype_of(ir_type *tp, int pos) {
443   ir_type ** pts;
444
445   assert(0 <= pos && pos < get_type_n_arraytypes_of(tp));
446
447   pts = get_type_arraytype_array(tp);
448   return pts[pos];
449 }
450
451 void  add_type_arraytype_of(ir_type *tp, ir_type *atp) {
452   ir_type ** pts;
453
454   assert(tp && is_type(tp));
455   assert(atp && is_Array_type(atp));
456
457   pts = get_type_arraytype_array(tp);
458   ARR_APP1(ir_node *, pts, atp);
459   set_type_arraytype_array(tp, pts);
460 }
461
462 void  set_type_arraytype_of(ir_type *tp, int pos, ir_type *atp) {
463   ir_type ** pts;
464
465   assert(0 <= pos && pos < get_type_n_arraytypes_of(tp));
466   assert(atp && is_Array_type(atp));
467
468   pts = get_type_arraytype_array(tp);
469   pts[pos] = atp;
470 }
471
472 /*------------------------------------------------------------------*/
473 /* Building and Removing the out datastructure                      */
474 /*------------------------------------------------------------------*/
475
476 static void init_trouts(void) {
477
478 }
479
480 /** The number of entities that can be accessed by this Sel node. */
481 static int get_Sel_n_accessed_entities(ir_node *sel) {
482         (void) sel;
483         return 1;
484 }
485
486 /** The entity that cat be accessed by this Sel node. */
487 static ir_entity *get_Sel_accessed_entity(ir_node *sel) {
488   return get_Sel_entity(sel);
489 }
490
491 /** An addr node is a SymConst or a Sel. */
492 static int get_addr_n_entities(ir_node *addr) {
493   int n_ents;
494
495   switch (get_irn_opcode(addr)) {
496   case iro_Sel:
497     /* Treat jack array sels? */
498     n_ents = get_Sel_n_accessed_entities(addr);
499     break;
500   case iro_SymConst:
501     if (get_SymConst_kind(addr) == symconst_addr_ent) {
502       n_ents = 1;
503       break;
504     }
505   default:
506     //assert(0 && "unexpected address expression");
507     n_ents = 0;
508   }
509
510   return n_ents;
511 }
512
513 /** An addr node is a SymConst or a Sel.
514     If Sel follow to outermost of compound. */
515 static ir_entity *get_addr_entity(ir_node *addr, int pos) {
516   ir_entity *ent;
517
518   switch (get_irn_opcode(addr)) {
519   case iro_Sel:
520     /* Treat jack array sels? They are compounds!  Follow to outermost entity.  */
521     while (is_Sel(get_Sel_ptr(addr))) {
522       addr = get_Sel_ptr(addr);
523     }
524     assert (0 <= pos && pos < get_Sel_n_accessed_entities(addr));
525     ent = get_Sel_accessed_entity(addr);
526     break;
527   case iro_SymConst:
528     if (get_SymConst_kind(addr) == symconst_addr_ent) {
529       assert(pos == 0);
530       ent = get_SymConst_entity(addr);
531       break;
532     }
533   default:
534     ent = NULL;
535   }
536
537   return ent;
538 }
539
540 static void chain_accesses(ir_node *n, void *env) {
541   int i, n_ents;
542   ir_node *addr;
543
544   (void) env;
545   if (get_irn_op(n) == op_Alloc) {
546     add_type_alloc(get_Alloc_type(n), n);
547     return;
548   } else
549
550   if (get_irn_op(n) == op_Cast) {
551     add_type_cast(get_Cast_type(n), n);
552     return;
553   } else
554
555   if (get_irn_op(n) == op_Sel) {
556     add_entity_reference(get_Sel_entity(n), n);
557     return;
558   } else if (get_irn_op(n) == op_SymConst && (get_SymConst_kind(n) == symconst_addr_ent)) {
559     add_entity_reference(get_SymConst_entity(n), n);
560     return;
561   } else
562
563   if (is_memop(n)) {
564     addr = get_memop_ptr(n);
565   } else if (get_irn_op(n) == op_Call) {
566     addr = get_Call_ptr(n);
567     if (! is_Sel(addr)) return;  /* Sels before Calls mean a Load / polymorphic Call. */
568   } else {
569     return;
570   }
571
572   n_ents = get_addr_n_entities(addr);  /* == 1 */
573   for (i = 0; i < n_ents; ++i) {
574     ir_entity *ent = get_addr_entity(addr, i);
575     if (ent)
576       add_entity_access(ent, n);
577     //else
578       //add_unrecognized_access(n);
579   }
580 }
581
582 static void chain_types(ir_type *tp) {
583   if (is_Pointer_type(tp)) {
584     add_type_pointertype_to(get_pointer_points_to_type(tp), tp);
585   } else if (is_Array_type(tp)) {
586     add_type_arraytype_of(get_array_element_type(tp), tp);
587   }
588 }
589
590 irg_outs_state get_trouts_state(void) {
591   return irp->trouts_state;
592 }
593 void           set_trouts_inconsistent(void) {
594   if (irp->trouts_state == outs_consistent)
595     irp->trouts_state = outs_inconsistent;
596 }
597
598
599 /* compute the field temperature. */
600 void compute_trouts(void) {
601   int i,
602       n_irgs = get_irp_n_irgs(),
603       n_types = get_irp_n_types();
604
605   free_trouts();
606   init_trouts();
607
608   /* Compute outs for irnodes. */
609   for (i = 0; i < n_irgs; i++) {
610     irg_walk_graph(get_irp_irg(i), NULL, chain_accesses, NULL);
611   }
612   walk_const_code(NULL, chain_accesses, NULL);
613
614   /* Compute outs for types */
615   for (i = 0; i < n_types; ++i) {
616     chain_types(get_irp_type(i));
617   }
618
619   irp->trouts_state = outs_consistent;
620 }
621
622
623 void free_trouts(void) {
624
625   if (entity_access_map) {
626     ir_node **accs;
627     for (accs = (ir_node **)pmap_first(entity_access_map);
628          accs;
629          accs = (ir_node **)pmap_next(entity_access_map))
630       ; //DEL_ARR_F(accs);
631     pmap_destroy(entity_access_map);
632     entity_access_map = NULL;
633   }
634
635   if (entity_reference_map) {
636     ir_node **refs;
637     for (refs = (ir_node **)pmap_first(entity_reference_map);
638          refs;
639          refs = (ir_node **)pmap_next(entity_reference_map))
640       ; //DEL_ARR_F(refs);
641     pmap_destroy(entity_reference_map);
642     entity_reference_map = NULL;
643   }
644
645   if (type_alloc_map) {
646     ir_node **alls;
647     for (alls = (ir_node **)pmap_first(type_alloc_map);
648          alls;
649          alls = (ir_node **)pmap_next(type_alloc_map))
650       ; //DEL_ARR_F(alls);
651     pmap_destroy(type_alloc_map);
652     type_alloc_map = NULL;
653   }
654
655   if (type_cast_map) {
656     ir_node **casts;
657     for (casts = (ir_node **)pmap_first(type_cast_map);
658          casts;
659          casts = (ir_node **)pmap_next(type_cast_map))
660       ; //DEL_ARR_F(alls);
661     pmap_destroy(type_cast_map);
662     type_cast_map = NULL;
663   }
664
665   if (type_pointertype_map) {
666     ir_node **pts;
667     for (pts = (ir_node **)pmap_first(type_pointertype_map);
668          pts;
669          pts = (ir_node **)pmap_next(type_pointertype_map))
670       ; //DEL_ARR_F(pts);
671     pmap_destroy(type_pointertype_map);
672     type_pointertype_map = NULL;
673   }
674
675   if (type_arraytype_map) {
676     ir_node **pts;
677     for (pts = (ir_node **)pmap_first(type_arraytype_map);
678          pts;
679          pts = (ir_node **)pmap_next(type_arraytype_map))
680       ; //DEL_ARR_F(pts);
681     pmap_destroy(type_arraytype_map);
682     type_arraytype_map = NULL;
683   }
684
685   irp->trouts_state = outs_none;
686 }