rename tarval to ir_tarval
[libfirm] / ir / ana / irmemory.c
1 /*
2  * Copyright (C) 1995-2008 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    Memory disambiguator
23  * @author   Michael Beck
24  * @date     27.12.2006
25  * @version  $Id$
26  */
27 #include "config.h"
28
29 #include <stdlib.h>
30 #include <stdbool.h>
31
32 #include "adt/pmap.h"
33 #include "irnode_t.h"
34 #include "irgraph_t.h"
35 #include "irprog_t.h"
36 #include "irmemory_t.h"
37 #include "irmemory.h"
38 #include "irflag.h"
39 #include "hashptr.h"
40 #include "irflag.h"
41 #include "irouts.h"
42 #include "irgwalk.h"
43 #include "irprintf.h"
44 #include "debug.h"
45 #include "error.h"
46 #include "typerep.h"
47 #include "irpass.h"
48
49 /** The debug handle. */
50 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
51 DEBUG_ONLY(static firm_dbg_module_t *dbgcall = NULL;)
52
53 /** The source language specific language disambiguator function. */
54 static DISAMBIGUATOR_FUNC language_disambuigator = NULL;
55
56 /** The global memory disambiguator options. */
57 static unsigned global_mem_disamgig_opt = aa_opt_no_opt;
58
59 /* Returns a human readable name for an alias relation. */
60 const char *get_ir_alias_relation_name(ir_alias_relation rel)
61 {
62 #define X(a) case a: return #a
63         switch (rel) {
64         X(ir_no_alias);
65         X(ir_may_alias);
66         X(ir_sure_alias);
67         default:
68                 panic("UNKNOWN alias relation");
69         }
70 #undef X
71 }
72
73 /* Get the memory disambiguator options for a graph. */
74 unsigned get_irg_memory_disambiguator_options(const ir_graph *irg)
75 {
76         unsigned opt = irg->mem_disambig_opt;
77         if (opt & aa_opt_inherited)
78                 return global_mem_disamgig_opt;
79         return opt;
80 }  /* get_irg_memory_disambiguator_options */
81
82 /*  Set the memory disambiguator options for a graph. */
83 void set_irg_memory_disambiguator_options(ir_graph *irg, unsigned options)
84 {
85         irg->mem_disambig_opt = options & ~aa_opt_inherited;
86 }  /* set_irg_memory_disambiguator_options */
87
88 /* Set the global disambiguator options for all graphs not having local options. */
89 void set_irp_memory_disambiguator_options(unsigned options)
90 {
91         global_mem_disamgig_opt = options;
92 }  /* set_irp_memory_disambiguator_options */
93
94 /**
95  * Find the base address and entity of an Sel node.
96  *
97  * @param sel  the node
98  * @param pEnt after return points to the base entity.
99  *
100  * @return the base address.
101  */
102 static ir_node *find_base_adr(const ir_node *sel, ir_entity **pEnt)
103 {
104         ir_node *ptr = get_Sel_ptr(sel);
105
106         while (is_Sel(ptr)) {
107                 sel = ptr;
108                 ptr = get_Sel_ptr(sel);
109         }
110         *pEnt = get_Sel_entity(sel);
111         return ptr;
112 }  /* find_base_adr */
113
114 /**
115  * Check if a given Const node is greater or equal a given size.
116  *
117  * @param cns   a Const node
118  * @param size  a integer size
119  *
120  * @return ir_no_alias if the Const is greater, ir_may_alias else
121  */
122 static ir_alias_relation check_const(const ir_node *cns, int size)
123 {
124         ir_tarval *tv = get_Const_tarval(cns);
125         ir_tarval *tv_size;
126
127         if (size == 0)
128                 return tarval_is_null(tv) ? ir_may_alias : ir_no_alias;
129         tv_size = new_tarval_from_long(size, get_tarval_mode(tv));
130         return tarval_cmp(tv_size, tv) & (pn_Cmp_Eq|pn_Cmp_Lt) ? ir_no_alias : ir_may_alias;
131 }  /* check_const */
132
133 /**
134  * Treat idx1 and idx2 as integer indexes and check if they differ always more than size.
135  *
136  * @param idx1  a node representing the first index
137  * @param idx2  a node representing the second index
138  * @param size  an integer size
139  *
140  * @return ir_sure_alias iff idx1 == idx2
141  *         ir_no_alias iff they ALWAYS differ more than size
142  *         ir_may_alias else
143  */
144 static ir_alias_relation different_index(const ir_node *idx1, const ir_node *idx2, int size)
145 {
146         if (idx1 == idx2)
147                 return ir_sure_alias;
148         if (is_Const(idx1) && is_Const(idx2)) {
149                 /* both are const, we can compare them */
150                 ir_tarval *tv1 = get_Const_tarval(idx1);
151                 ir_tarval *tv2 = get_Const_tarval(idx2);
152                 ir_tarval *tv, *tv_size;
153                 ir_mode *m1, *m2;
154
155                 if (size == 0)
156                         return tv1 == tv2 ? ir_sure_alias : ir_no_alias;
157
158                 /* arg, modes may be different */
159                 m1 = get_tarval_mode(tv1);
160                 m2 = get_tarval_mode(tv2);
161                 if (m1 != m2) {
162                         int size = get_mode_size_bits(m1) - get_mode_size_bits(m2);
163
164                         if (size < 0) {
165                                 /* m1 is a small mode, cast up */
166                                 m1 = mode_is_signed(m1) ? find_signed_mode(m2) : find_unsigned_mode(m2);
167                                 if (m1 == NULL) {
168                                         /* should NOT happen, but if it does we give up here */
169                                         return ir_may_alias;
170                                 }
171                                 tv1 = tarval_convert_to(tv1, m1);
172                         } else if (size > 0) {
173                                 /* m2 is a small mode, cast up */
174                                 m2 = mode_is_signed(m2) ? find_signed_mode(m1) : find_unsigned_mode(m1);
175                                 if (m2 == NULL) {
176                                         /* should NOT happen, but if it does we give up here */
177                                         return ir_may_alias;
178                                 }
179                                 tv2 = tarval_convert_to(tv2, m2);
180                         }
181                         /* here the size should be identical, check for signed */
182                         if (get_mode_sign(m1) != get_mode_sign(m2)) {
183                                 /* find the signed */
184                                 if (mode_is_signed(m2)) {
185                                         ir_tarval *t = tv1;
186                                         ir_mode *tm = m1;
187                                         tv1 = tv2; m1 = m2;
188                                         tv2 = t;   m2 = tm;
189                                 }
190
191                                 /* m1 is now the signed one */
192                                 if (!tarval_is_negative(tv1)) {
193                                         /* tv1 is signed, but >= 0, simply cast into unsigned */
194                                         tv1 = tarval_convert_to(tv1, m2);
195                                 } else {
196                                         tv_size = new_tarval_from_long(size, m2);
197
198                                         if (tarval_cmp(tv2, tv_size) & (pn_Cmp_Eq|pn_Cmp_Gt)) {
199                                                 /* tv1 is negative and tv2 >= tv_size, so the difference is bigger than size */
200                                                 return ir_no_alias;
201                                         }
202                                         /* tv_size > tv2, so we can subtract without overflow */
203                                         tv2 = tarval_sub(tv_size, tv2, NULL);
204
205                                         /* tv1 is < 0, so we can negate it */
206                                         tv1 = tarval_neg(tv1);
207
208                                         /* cast it into unsigned. for two-complement it does the right thing for MIN_INT */
209                                         tv1 = tarval_convert_to(tv1, m2);
210
211                                         /* now we can compare without overflow */
212                                         return tarval_cmp(tv1, tv2) & (pn_Cmp_Eq|pn_Cmp_Gt) ? ir_no_alias : ir_may_alias;
213                                 }
214                         }
215                 }
216                 if (tarval_cmp(tv1, tv2) == pn_Cmp_Gt) {
217                         ir_tarval *t = tv1;
218                         tv1 = tv2;
219                         tv2 = t;
220                 }
221                 /* tv1 is now the "smaller" one */
222                 tv      = tarval_sub(tv2, tv1, NULL);
223                 tv_size = new_tarval_from_long(size, get_tarval_mode(tv));
224                 return tarval_cmp(tv_size, tv) & (pn_Cmp_Eq|pn_Cmp_Lt) ? ir_no_alias : ir_may_alias;
225         }
226
227         /* Note: we rely here on the fact that normalization puts constants on the RIGHT side */
228         if (is_Add(idx1)) {
229                 ir_node *l1 = get_Add_left(idx1);
230                 ir_node *r1 = get_Add_right(idx1);
231
232                 if (l1 == idx2) {
233                         /* x + c == y */
234                         if (is_Const(r1))
235                                 return check_const(r1, size);
236                 }
237                 if (is_Add(idx2)) {
238                         /* both are Adds, check if they are of x + a == x + b kind */
239                         ir_node *l2 = get_Add_left(idx2);
240                         ir_node *r2 = get_Add_right(idx2);
241
242                         if (l1 == l2)
243                                 return different_index(r1, r2, size);
244                         else if (l1 == r2)
245                                 return different_index(r1, l2, size);
246                         else if (r1 == r2)
247                                 return different_index(l1, l2, size);
248                         else if (r1 == l2)
249                                 return different_index(l1, r2, size);
250                 }
251         }
252         if (is_Add(idx2)) {
253                 ir_node *l2 = get_Add_left(idx2);
254                 ir_node *r2 = get_Add_right(idx2);
255
256                 if (l2 == idx1) {
257                         /* x + c == y */
258                         if (is_Const(r2))
259                                 return check_const(r2, size);
260                 }
261         }
262
263         if (is_Sub(idx1)) {
264                 ir_node *l1 = get_Sub_left(idx1);
265                 ir_node *r1 = get_Sub_right(idx1);
266
267                 if (l1 == idx2) {
268                         /* x - c == y */
269                         if (is_Const(r1))
270                                 return check_const(r1, size);
271                 }
272
273                 if (is_Sub(idx2)) {
274                         /* both are Subs, check if they are of x - a == x - b kind */
275                         ir_node *l2 = get_Sub_left(idx2);
276
277                         if (l1 == l2) {
278                                 ir_node *r2 = get_Sub_right(idx2);
279                                 return different_index(r1, r2, size);
280                         }
281                 }
282         }
283         if (is_Sub(idx2)) {
284                 ir_node *l2 = get_Sub_left(idx2);
285                 ir_node *r2 = get_Sub_right(idx2);
286
287                 if (l2 == idx1) {
288                         /* x - c == y */
289                         if (is_Const(r2))
290                                 return check_const(r2, size);
291                 }
292
293         }
294         return ir_may_alias;
295 }  /* different_index */
296
297 /**
298  * Two Sel addresses have the same base address, check if there offsets are
299  * different.
300  *
301  * @param adr1  The first address.
302  * @param adr2  The second address.
303  */
304 static ir_alias_relation different_sel_offsets(const ir_node *sel1, const ir_node *sel2)
305 {
306         /* seems to be broken */
307         (void) sel1;
308         (void) sel2;
309 #if 0
310         ir_entity *ent1 = get_Sel_entity(sel1);
311         ir_entity *ent2 = get_Sel_entity(sel2);
312         int i, check_arr = 0;
313
314         if (ent1 == ent2)
315                 check_arr = 1;
316         else {
317                 ir_type *tp1 = get_entity_type(ent1);
318                 ir_type *tp2 = get_entity_type(ent2);
319
320                 if (tp1 == tp2)
321                         check_arr = 1;
322                 else if (get_type_state(tp1) == layout_fixed && get_type_state(tp2) == layout_fixed &&
323                          get_type_size_bits(tp1) == get_type_size_bits(tp2))
324                         check_arr = 1;
325         }
326         if (check_arr) {
327                 /* we select an entity of same size, check for indexes */
328                 int n = get_Sel_n_indexs(sel1);
329                 int have_no = 0;
330
331                 if (n > 0 && n == get_Sel_n_indexs(sel2)) {
332                         /* same non-zero number of indexes, an array access, check */
333                         for (i = 0; i < n; ++i) {
334                                 ir_node *idx1 = get_Sel_index(sel1, i);
335                                 ir_node *idx2 = get_Sel_index(sel2, i);
336                                 ir_alias_relation res = different_index(idx1, idx2, 0); /* we can safely IGNORE the size here if it's at least >0 */
337
338                                 if (res == may_alias)
339                                         return may_alias;
340                                 else if (res == no_alias)
341                                         have_no = 1;
342                         }
343                         /* if we have at least one no_alias, there is no alias relation, else we have sure */
344                         return have_no > 0 ? no_alias : sure_alias;
345                 }
346         }
347 #else
348         (void) different_index;
349 #endif
350         return ir_may_alias;
351 }  /* different_sel_offsets */
352
353 /**
354  * Determine the alias relation by checking if adr1 and adr2 are pointer
355  * to different type.
356  *
357  * @param adr1    The first address.
358  * @param adr2    The second address.
359  */
360 static ir_alias_relation different_types(const ir_node *adr1, const ir_node *adr2)
361 {
362         ir_entity *ent1 = NULL, *ent2 = NULL;
363
364         if (is_Global(adr1))
365                 ent1 = get_Global_entity(adr1);
366         else if (is_Sel(adr1))
367                 ent1 = get_Sel_entity(adr1);
368
369         if (is_Global(adr2))
370                 ent2 = get_Global_entity(adr2);
371         else if (is_Sel(adr2))
372                 ent2 = get_Sel_entity(adr2);
373
374         if (ent1 != NULL && ent2 != NULL) {
375                 ir_type *tp1 = get_entity_type(ent1);
376                 ir_type *tp2 = get_entity_type(ent2);
377
378                 if (tp1 != tp2) {
379                         /* do deref until no pointer types are found */
380                         while (is_Pointer_type(tp1) && is_Pointer_type(tp2)) {
381                                 tp1 = get_pointer_points_to_type(tp1);
382                                 tp2 = get_pointer_points_to_type(tp2);
383                         }
384
385                         if (get_type_tpop(tp1) != get_type_tpop(tp2)) {
386                                 /* different type structure */
387                                 return ir_no_alias;
388                         }
389                         if (is_Class_type(tp1)) {
390                                 /* check class hierarchy */
391                                 if (! is_SubClass_of(tp1, tp2) &&
392                                         ! is_SubClass_of(tp2, tp1))
393                                         return ir_no_alias;
394                         } else {
395                                 /* different types */
396                                 return ir_no_alias;
397                         }
398                 }
399         }
400         return ir_may_alias;
401 }  /* different_types */
402
403 /**
404  * Returns non-zero if a node is a result on a malloc-like routine.
405  *
406  * @param node  the Proj node to test
407  */
408 static int is_malloc_Result(const ir_node *node)
409 {
410         node = get_Proj_pred(node);
411         if (! is_Proj(node))
412                 return 0;
413         node = get_Proj_pred(node);
414         if (! is_Call(node))
415                 return 0;
416         node = get_Call_ptr(node);
417         if (is_Global(node)) {
418                 ir_entity *ent = get_Global_entity(node);
419
420                 if (get_entity_additional_properties(ent) & mtp_property_malloc)
421                         return 1;
422                 return 0;
423         }
424         return 0;
425 }  /* is_malloc_Result */
426
427 ir_storage_class_class_t classify_pointer(const ir_node *irn,
428                                           const ir_entity *ent)
429 {
430         ir_graph *irg = get_irn_irg(irn);
431         ir_storage_class_class_t res = ir_sc_pointer;
432         if (is_Global(irn)) {
433                 ir_entity *entity = get_Global_entity(irn);
434                 res = ir_sc_globalvar;
435                 if (! (get_entity_usage(entity) & ir_usage_address_taken))
436                         res |= ir_sc_modifier_nottaken;
437         } else if (irn == get_irg_frame(irg)) {
438                 res = ir_sc_localvar;
439                 if (ent != NULL && !(get_entity_usage(ent) & ir_usage_address_taken))
440                         res |= ir_sc_modifier_nottaken;
441         } else if (irn == get_irg_tls(irg)) {
442                 res = ir_sc_tls;
443                 if (ent != NULL && !(get_entity_usage(ent) & ir_usage_address_taken))
444                         res |= ir_sc_modifier_nottaken;
445         } else if (is_Proj(irn) && is_malloc_Result(irn)) {
446                 return ir_sc_malloced;
447         } else if (is_Const(irn)) {
448                 return ir_sc_globaladdr;
449         } else if (is_arg_Proj(irn)) {
450                 res |= ir_sc_modifier_argument;
451         }
452
453         return res;
454 }
455
456 /**
457  * If adr represents a Bitfield Sel, skip it
458  */
459 static const ir_node *skip_Bitfield_Sels(const ir_node *adr)
460 {
461         if (is_Sel(adr)) {
462                 ir_entity *ent     = get_Sel_entity(adr);
463                 ir_type   *bf_type = get_entity_type(ent);
464
465                 /* is it a bitfield type? */
466                 if (is_Primitive_type(bf_type) && get_primitive_base_type(bf_type) != NULL)
467                         adr = get_Sel_ptr(adr);
468         }
469         return adr;
470 }
471
472 /**
473  * Determine the alias relation between two addresses.
474  *
475  * @param addr1  pointer address of the first memory operation
476  * @param mode1  the mode of the accessed data through addr1
477  * @param addr2  pointer address of the second memory operation
478  * @param mode2  the mode of the accessed data through addr2
479  *
480  * @return found memory relation
481  */
482 static ir_alias_relation _get_alias_relation(
483         const ir_node *adr1, const ir_mode *mode1,
484         const ir_node *adr2, const ir_mode *mode2)
485 {
486         ir_entity             *ent1, *ent2;
487         unsigned              options;
488         long                  offset1 = 0;
489         long                  offset2 = 0;
490         const ir_node         *base1;
491         const ir_node         *base2;
492         const ir_node         *orig_adr1 = adr1;
493         const ir_node         *orig_adr2 = adr2;
494         ir_graph              *irg;
495         unsigned              mode_size;
496         ir_storage_class_class_t class1, class2, mod1, mod2;
497         int                   have_const_offsets;
498
499         if (! get_opt_alias_analysis())
500                 return ir_may_alias;
501
502         if (adr1 == adr2)
503                 return ir_sure_alias;
504
505         irg = get_irn_irg(adr1);
506         options = get_irg_memory_disambiguator_options(irg);
507
508         /* The Armageddon switch */
509         if (options & aa_opt_no_alias)
510                 return ir_no_alias;
511
512         /* do the addresses have constants offsets?
513          *  Note: nodes are normalized to have constants at right inputs,
514          *        sub X, C is normalized to add X, -C
515          */
516         have_const_offsets = 1;
517         while (is_Add(adr1)) {
518                 ir_node *add_right = get_Add_right(adr1);
519                 if (is_Const(add_right) && !mode_is_reference(get_irn_mode(add_right))) {
520                         ir_tarval *tv  = get_Const_tarval(add_right);
521                         offset1    += get_tarval_long(tv);
522                         adr1        = get_Add_left(adr1);
523                 } else if (mode_is_reference(get_irn_mode(add_right))) {
524                         adr1 = add_right;
525                         have_const_offsets = 0;
526                 } else {
527                         adr1 = get_Add_left(adr1);
528                         have_const_offsets = 0;
529                 }
530         }
531         while (is_Add(adr2)) {
532                 ir_node *add_right = get_Add_right(adr2);
533                 if (is_Const(add_right) && !mode_is_reference(get_irn_mode(add_right))) {
534                         ir_tarval *tv  = get_Const_tarval(add_right);
535                         offset2    += get_tarval_long(tv);
536                         adr2        = get_Add_left(adr2);
537                 } else if (mode_is_reference(get_irn_mode(add_right))) {
538                         adr2 = add_right;
539                         have_const_offsets = 0;
540                 } else {
541                         adr2 = get_Add_left(adr2);
542                         have_const_offsets = 0;
543                 }
544         }
545
546         mode_size = get_mode_size_bytes(mode1);
547         if (get_mode_size_bytes(mode2) > mode_size) {
548                 mode_size = get_mode_size_bytes(mode2);
549         }
550
551         /* same base address -> compare offsets if possible.
552          * FIXME: type long is not sufficient for this task ...
553          */
554         if (adr1 == adr2 && have_const_offsets) {
555                 if ((unsigned long)labs(offset2 - offset1) >= mode_size)
556                         return ir_no_alias;
557                 else
558                         return ir_sure_alias;
559         }
560
561         /*
562          * Bitfields can be constructed as Sels from its base address.
563          * As they have different entities, the disambiguator would find that they are
564          * alias free. While this is true for it's values, it is false for the addresses
565          * (strictly speaking, the Sel's are NOT the addresses of the bitfields).
566          * So, skip those bitfield selecting Sel's.
567          */
568         adr1 = skip_Bitfield_Sels(adr1);
569         adr2 = skip_Bitfield_Sels(adr2);
570
571         /* skip Sels */
572         base1 = adr1;
573         base2 = adr2;
574         ent1  = NULL;
575         ent2  = NULL;
576         if (is_Sel(adr1)) {
577                 base1 = find_base_adr(adr1, &ent1);
578         }
579         if (is_Sel(adr2)) {
580                 base2 = find_base_adr(adr2, &ent2);
581         }
582
583         /* same base address -> compare Sel entities */
584         if (base1 == base2 && ent1 != NULL && ent2 != NULL) {
585                 if (ent1 != ent2)
586                         return ir_no_alias;
587                 else if (have_const_offsets)
588                         return different_sel_offsets(adr1, adr2);
589         }
590
591         mod1 = classify_pointer(base1, ent1);
592         mod2 = classify_pointer(base2, ent2);
593
594         class1 = GET_BASE_SC(mod1);
595         class2 = GET_BASE_SC(mod2);
596
597         if (class1 == ir_sc_pointer || class2 == ir_sc_pointer) {
598                 /* swap pointer class to class1 */
599                 if (class2 == ir_sc_pointer) {
600                         ir_storage_class_class_t temp = mod1;
601                         mod1 = mod2;
602                         mod2 = temp;
603                         class1 = GET_BASE_SC(mod1);
604                         class2 = GET_BASE_SC(mod2);
605                 }
606                 /* a pointer and an object whose address was never taken */
607                 if (mod2 & ir_sc_modifier_nottaken) {
608                         return ir_no_alias;
609                 }
610                 if (mod1 & ir_sc_modifier_argument) {
611                         if ( (options & aa_opt_no_alias_args)
612                                         && (mod2 & ir_sc_modifier_argument))
613                                 return ir_no_alias;
614                         if ( (options & aa_opt_no_alias_args_global)
615                                         && (class2 == ir_sc_globalvar
616                                                 || class2 == ir_sc_tls
617                                                 || class2 == ir_sc_globaladdr))
618                                 return ir_no_alias;
619                 }
620         } else if (class1 != class2) {
621                 /* two objects from different memory spaces */
622                 return ir_no_alias;
623         } else {
624                 /* both classes are equal */
625                 if (class1 == ir_sc_globalvar) {
626                         ir_entity *entity1 = get_SymConst_entity(base1);
627                         ir_entity *entity2 = get_SymConst_entity(base2);
628                         if (entity1 != entity2)
629                                 return ir_no_alias;
630
631                         /* for some reason CSE didn't happen yet for the 2 SymConsts... */
632                         return ir_may_alias;
633                 } else if (class1 == ir_sc_globaladdr) {
634                         ir_tarval *tv = get_Const_tarval(base1);
635                         offset1      += get_tarval_long(tv);
636                         tv            = get_Const_tarval(base2);
637                         offset2      += get_tarval_long(tv);
638
639                         if ((unsigned long)labs(offset2 - offset1) >= mode_size)
640                                 return ir_no_alias;
641                         else
642                                 return ir_sure_alias;
643                 }
644         }
645
646         /* Type based alias analysis */
647         if (options & aa_opt_type_based) {
648                 ir_alias_relation rel;
649
650                 if (options & aa_opt_byte_type_may_alias) {
651                         if (get_mode_size_bits(mode1) == 8 || get_mode_size_bits(mode2) == 8) {
652                                 /* One of the modes address a byte. Assume a ir_may_alias and leave
653                                    the type based check. */
654                                 goto leave_type_based_alias;
655                         }
656                 }
657                 /* cheap check: If the mode sizes did not match, the types MUST be different */
658                 if (get_mode_size_bits(mode1) != get_mode_size_bits(mode2))
659                         return ir_no_alias;
660
661                 /* cheap test: if only one is a reference mode, no alias */
662                 if (mode_is_reference(mode1) != mode_is_reference(mode2))
663                         return ir_no_alias;
664
665                 /* cheap test: if arithmetic is different, no alias */
666                 if (get_mode_arithmetic(mode1) != get_mode_arithmetic(mode2))
667                         return ir_no_alias;
668
669                 /* try rule R5 */
670                 rel = different_types(orig_adr1, orig_adr2);
671                 if (rel != ir_may_alias)
672                         return rel;
673 leave_type_based_alias:;
674         }
675
676         /* do we have a language specific memory disambiguator? */
677         if (language_disambuigator != NULL) {
678                 ir_alias_relation rel = language_disambuigator(orig_adr1, mode1, orig_adr2, mode2);
679                 if (rel != ir_may_alias)
680                         return rel;
681         }
682
683         /* access points-to information here */
684         return ir_may_alias;
685 }  /* _get_alias_relation */
686
687 /*
688  * Determine the alias relation between two addresses.
689  */
690 ir_alias_relation get_alias_relation(
691         const ir_node *adr1, const ir_mode *mode1,
692         const ir_node *adr2, const ir_mode *mode2)
693 {
694         ir_alias_relation rel = _get_alias_relation(adr1, mode1, adr2, mode2);
695         DB((dbg, LEVEL_1, "alias(%+F, %+F) = %s\n", adr1, adr2, get_ir_alias_relation_name(rel)));
696         return rel;
697 }  /* get_alias_relation */
698
699 /* Set a source language specific memory disambiguator function. */
700 void set_language_memory_disambiguator(DISAMBIGUATOR_FUNC func)
701 {
702         language_disambuigator = func;
703 }  /* set_language_memory_disambiguator */
704
705 /** The result cache for the memory disambiguator. */
706 static set *result_cache = NULL;
707
708 /** An entry in the relation cache. */
709 typedef struct mem_disambig_entry {
710         const ir_node     *adr1;    /**< The first address. */
711         const ir_mode     *mode1;   /**< The first address mode. */
712         const ir_node     *adr2;    /**< The second address. */
713         const ir_mode     *mode2;   /**< The second address mode. */
714         ir_alias_relation result;   /**< The alias relation result. */
715 } mem_disambig_entry;
716
717 #define HASH_ENTRY(adr1, adr2)  (HASH_PTR(adr1) ^ HASH_PTR(adr2))
718
719 /**
720  * Compare two relation cache entries.
721  */
722 static int cmp_mem_disambig_entry(const void *elt, const void *key, size_t size)
723 {
724         const mem_disambig_entry *p1 = elt;
725         const mem_disambig_entry *p2 = key;
726         (void) size;
727
728         return p1->adr1 == p2->adr1 && p1->adr2 == p2->adr2 &&
729                p1->mode1 == p2->mode1 && p1->mode2 == p2->mode2;
730 }  /* cmp_mem_disambig_entry */
731
732 /**
733  * Initialize the relation cache.
734  */
735 void mem_disambig_init(void)
736 {
737         result_cache = new_set(cmp_mem_disambig_entry, 8);
738 }  /* mem_disambig_init */
739
740 /*
741  * Determine the alias relation between two addresses.
742  */
743 ir_alias_relation get_alias_relation_ex(
744         const ir_node *adr1, const ir_mode *mode1,
745         const ir_node *adr2, const ir_mode *mode2)
746 {
747         mem_disambig_entry key, *entry;
748
749         ir_fprintf(stderr, "%+F <-> %+F\n", adr1, adr2);
750
751         if (! get_opt_alias_analysis())
752                 return ir_may_alias;
753
754         if (get_irn_opcode(adr1) > get_irn_opcode(adr2)) {
755                 const ir_node *t = adr1;
756                 adr1 = adr2;
757                 adr2 = t;
758         }
759
760         key.adr1  = adr1;
761         key.adr2  = adr2;
762         key.mode1 = mode1;
763         key.mode2 = mode2;
764         entry = set_find(result_cache, &key, sizeof(key), HASH_ENTRY(adr1, adr2));
765         if (entry != NULL)
766                 return entry->result;
767
768         key.result = get_alias_relation(adr1, mode1, adr2, mode2);
769
770         set_insert(result_cache, &key, sizeof(key), HASH_ENTRY(adr1, adr2));
771         return key.result;
772 }  /* get_alias_relation_ex */
773
774 /* Free the relation cache. */
775 void mem_disambig_term(void)
776 {
777         if (result_cache != NULL) {
778                 del_set(result_cache);
779                 result_cache = NULL;
780         }
781 }  /* mem_disambig_term */
782
783 /**
784  * Check the mode of a Load/Store with the mode of the entity
785  * that is accessed.
786  * If the mode of the entity and the Load/Store mode do not match, we
787  * have the bad reinterpret case:
788  *
789  * int i;
790  * char b = *(char *)&i;
791  *
792  * We do NOT count this as one value and return address_taken
793  * in that case.
794  * However, we support an often used case. If the mode is two-complement
795  * we allow casts between signed/unsigned.
796  *
797  * @param mode     the mode of the Load/Store
798  * @param ent_mode the mode of the accessed entity
799  *
800  * @return non-zero if the Load/Store is a hidden cast, zero else
801  */
802 static int is_hidden_cast(const ir_mode *mode, const ir_mode *ent_mode)
803 {
804         if (ent_mode == NULL)
805                 return false;
806
807         if (ent_mode != mode) {
808                 if (ent_mode == NULL ||
809                         get_mode_size_bits(ent_mode) != get_mode_size_bits(mode) ||
810                         get_mode_sort(ent_mode) != get_mode_sort(mode) ||
811                         get_mode_arithmetic(ent_mode) != irma_twos_complement ||
812                         get_mode_arithmetic(mode) != irma_twos_complement)
813                         return true;
814         }
815         return false;
816 }  /* is_hidden_cast */
817
818 /**
819  * Determine the usage state of a node (or its successor Sels).
820  *
821  * @param irn  the node
822  */
823 static ir_entity_usage determine_entity_usage(const ir_node *irn, ir_entity *entity)
824 {
825         int       i;
826         ir_mode   *emode, *mode;
827         ir_node   *value;
828         ir_type   *tp;
829         ir_entity_usage res = 0;
830
831         for (i = get_irn_n_outs(irn) - 1; i >= 0; --i) {
832                 ir_node *succ = get_irn_out(irn, i);
833
834                 switch (get_irn_opcode(succ)) {
835                 case iro_Load:
836                         /* beware: irn might be a Id node here, so irn might be not
837                            equal to get_Load_ptr(succ) */
838                         res |= ir_usage_read;
839
840                         /* check if this load is not a hidden conversion */
841                         mode  = get_Load_mode(succ);
842                         emode = get_type_mode(get_entity_type(entity));
843                         if (is_hidden_cast(mode, emode))
844                                 res |= ir_usage_reinterpret_cast;
845                         break;
846
847                 case iro_Store:
848                         /* check that the node is not the Store's value */
849                         if (irn == get_Store_value(succ)) {
850                                 res |= ir_usage_unknown;
851                         }
852                         if (irn == get_Store_ptr(succ)) {
853                                 res |= ir_usage_write;
854
855                                 /* check if this Store is not a hidden conversion */
856                                 value = get_Store_value(succ);
857                                 mode  = get_irn_mode(value);
858                                 emode = get_type_mode(get_entity_type(entity));
859                                 if (is_hidden_cast(mode, emode))
860                                         res |= ir_usage_reinterpret_cast;
861                         }
862                         assert(irn != get_Store_mem(succ));
863                         break;
864
865                 case iro_CopyB:
866                         /* CopyB are like Loads/Stores */
867                         tp  = get_entity_type(entity);
868                         if (tp != get_CopyB_type(succ)) {
869                                 /* bad, different types, might be a hidden conversion */
870                                 res |= ir_usage_reinterpret_cast;
871                         }
872                         if (irn == get_CopyB_dst(succ)) {
873                                 res |= ir_usage_write;
874                         } else {
875                                 assert(irn == get_CopyB_src(succ));
876                                 res |= ir_usage_read;
877                         }
878                         break;
879
880                 case iro_Add:
881                 case iro_Sub:
882                         /* Check the successor of irn. */
883                         res |= determine_entity_usage(succ, entity);
884                         break;
885                 case iro_Sel: {
886                         ir_entity *entity = get_Sel_entity(succ);
887                         /* this analysis can't handle unions correctly */
888                         if (is_Union_type(get_entity_owner(entity))) {
889                                 res |= ir_usage_unknown;
890                                 break;
891                         }
892                         /* Check the successor of irn. */
893                         res |= determine_entity_usage(succ, entity);
894                         break;
895                 }
896
897                 case iro_Call:
898                         if (irn == get_Call_ptr(succ)) {
899                                 /* TODO: we could check for reinterpret casts here...
900                                  * But I doubt anyone is interested in that bit for
901                                  * function entities and I'm too lazy to write the code now.
902                                  */
903                                 res |= ir_usage_read;
904                         } else {
905                                 assert(irn != get_Call_mem(succ));
906                                 res |= ir_usage_unknown;
907                         }
908                         break;
909
910                 /* skip identities */
911                 case iro_Id:
912                         res |= determine_entity_usage(succ, entity);
913                         break;
914
915                 /* skip tuples */
916                 case iro_Tuple: {
917                         int input_nr;
918                         for (input_nr = get_Tuple_n_preds(succ) - 1; input_nr >= 0;
919                                         --input_nr) {
920                                 ir_node *pred = get_Tuple_pred(succ, input_nr);
921                                 if (pred == irn) {
922                                         int k;
923                                         /* we found one input */
924                                         for (k = get_irn_n_outs(succ) - 1; k >= 0; --k) {
925                                                 ir_node *proj = get_irn_out(succ, k);
926
927                                                 if (is_Proj(proj) && get_Proj_proj(proj) == input_nr) {
928                                                         res |= determine_entity_usage(proj, entity);
929                                                         break;
930                                                 }
931                                         }
932                                 }
933                         }
934                         break;
935                 }
936
937                 default:
938                         /* another op, we don't know anything (we could do more advanced
939                          * things like a dataflow analysis here) */
940                         res |= ir_usage_unknown;
941                         break;
942                 }
943         }
944
945         return res;
946 }
947
948 /**
949  * Update the usage flags of all frame entities.
950  */
951 static void analyse_irg_entity_usage(ir_graph *irg)
952 {
953         ir_type *ft = get_irg_frame_type(irg);
954         ir_node *irg_frame;
955         int i, j, k, static_link_arg;
956
957         /* set initial state to not_taken, as this is the "smallest" state */
958         for (i = get_class_n_members(ft) - 1; i >= 0; --i) {
959                 ir_entity *ent = get_class_member(ft, i);
960
961                 /* methods can only be analyzed globally */
962                 if (! is_method_entity(ent)) {
963                         ir_entity_usage flags = 0;
964                         if (get_entity_linkage(ent) & IR_LINKAGE_HIDDEN_USER)
965                                 flags = ir_usage_unknown;
966                         set_entity_usage(ent, flags);
967                 }
968         }
969
970         assure_irg_outs(irg);
971
972         irg_frame = get_irg_frame(irg);
973
974         for (i = get_irn_n_outs(irg_frame) - 1; i >= 0; --i) {
975                 ir_node        *succ = get_irn_out(irg_frame, i);
976                 ir_entity      *entity;
977                 ir_entity_usage flags;
978
979                 if (!is_Sel(succ))
980                         continue;
981
982                 entity = get_Sel_entity(succ);
983                 flags  = get_entity_usage(entity);
984                 flags |= determine_entity_usage(succ, entity);
985                 set_entity_usage(entity, flags);
986         }
987
988         /* check inner functions accessing outer frame */
989         static_link_arg = 0;
990         for (i = get_class_n_members(ft) - 1; i >= 0; --i) {
991                 ir_entity *ent = get_class_member(ft, i);
992                 ir_graph  *inner_irg;
993                 ir_node   *args;
994
995                 if (! is_method_entity(ent))
996                         continue;
997
998                 inner_irg = get_entity_irg(ent);
999                 if (inner_irg == NULL)
1000                         continue;
1001
1002                 assure_irg_outs(inner_irg);
1003                 args = get_irg_args(inner_irg);
1004                 for (j = get_irn_n_outs(args) - 1; j >= 0; --j) {
1005                         ir_node *arg = get_irn_out(args, j);
1006
1007                         if (get_Proj_proj(arg) == static_link_arg) {
1008                                 for (k = get_irn_n_outs(arg) - 1; k >= 0; --k) {
1009                                         ir_node *succ = get_irn_out(arg, k);
1010
1011                                         if (is_Sel(succ)) {
1012                                                 ir_entity *entity = get_Sel_entity(succ);
1013
1014                                                 if (get_entity_owner(entity) == ft) {
1015                                                         /* found an access to the outer frame */
1016                                                         ir_entity_usage flags;
1017
1018                                                         flags  = get_entity_usage(entity);
1019                                                         flags |= determine_entity_usage(succ, entity);
1020                                                         set_entity_usage(entity, flags);
1021                                                 }
1022                                         }
1023                                 }
1024                         }
1025                 }
1026         }
1027
1028
1029         /* now computed */
1030         irg->entity_usage_state = ir_entity_usage_computed;
1031 }
1032
1033 ir_entity_usage_computed_state get_irg_entity_usage_state(const ir_graph *irg)
1034 {
1035         return irg->entity_usage_state;
1036 }
1037
1038 void set_irg_entity_usage_state(ir_graph *irg, ir_entity_usage_computed_state state)
1039 {
1040         irg->entity_usage_state = state;
1041 }
1042
1043 void assure_irg_entity_usage_computed(ir_graph *irg)
1044 {
1045         if (irg->entity_usage_state != ir_entity_usage_not_computed)
1046                 return;
1047
1048         analyse_irg_entity_usage(irg);
1049 }
1050
1051
1052 /**
1053  * Initialize the entity_usage flag for a global type like type.
1054  */
1055 static void init_entity_usage(ir_type *tp)
1056 {
1057         int i;
1058
1059         /* We have to be conservative: All external visible entities are unknown */
1060         for (i = get_compound_n_members(tp) - 1; i >= 0; --i) {
1061                 ir_entity       *ent  = get_compound_member(tp, i);
1062                 ir_entity_usage flags = ir_usage_none;
1063
1064                 if (entity_is_externally_visible(ent)) {
1065                         flags |= ir_usage_unknown;
1066                 }
1067                 set_entity_usage(ent, flags);
1068         }
1069 }
1070
1071 /**
1072  * Mark all entities used in the initializer as unknown usage.
1073  *
1074  * @param initializer  the initializer to check
1075  */
1076 static void check_initializer_nodes(ir_initializer_t *initializer)
1077 {
1078         unsigned i;
1079         ir_node  *n;
1080
1081         switch (initializer->kind) {
1082         case IR_INITIALIZER_CONST:
1083                 /* let's check if it's an address */
1084                 n = initializer->consti.value;
1085                 if (is_Global(n)) {
1086                         ir_entity *ent = get_Global_entity(n);
1087                         set_entity_usage(ent, ir_usage_unknown);
1088                 }
1089                 return;
1090         case IR_INITIALIZER_TARVAL:
1091         case IR_INITIALIZER_NULL:
1092                 return;
1093         case IR_INITIALIZER_COMPOUND:
1094                 for (i = 0; i < initializer->compound.n_initializers; ++i) {
1095                         ir_initializer_t *sub_initializer
1096                                 = initializer->compound.initializers[i];
1097                         check_initializer_nodes(sub_initializer);
1098                 }
1099                 return;
1100         }
1101         panic("invalid initializer found");
1102 }  /* check_initializer_nodes */
1103
1104 /**
1105  * Mark all entities used in the initializer for the given entity as unknown
1106  * usage.
1107  *
1108  * @param ent  the entity
1109  */
1110 static void check_initializer(ir_entity *ent)
1111 {
1112         ir_node *n;
1113         int i;
1114
1115         /* Beware: Methods are always initialized with "themself". This does not
1116          * count as a taken address.
1117          * TODO: this initialisation with "themself" is wrong and should be removed
1118          */
1119         if (is_Method_type(get_entity_type(ent)))
1120                 return;
1121
1122         if (ent->initializer != NULL) {
1123                 check_initializer_nodes(ent->initializer);
1124         } else if (entity_has_compound_ent_values(ent)) {
1125                 for (i = get_compound_ent_n_values(ent) - 1; i >= 0; --i) {
1126                         n = get_compound_ent_value(ent, i);
1127
1128                         /* let's check if it's an address */
1129                         if (is_Global(n)) {
1130                                 ir_entity *ent = get_Global_entity(n);
1131                                 set_entity_usage(ent, ir_usage_unknown);
1132                         }
1133                 }
1134         }
1135 }
1136
1137
1138 /**
1139  * Mark all entities used in initializers as unknown usage.
1140  *
1141  * @param tp  a compound type
1142  */
1143 static void check_initializers(ir_type *tp)
1144 {
1145         int i;
1146
1147         for (i = get_compound_n_members(tp) - 1; i >= 0; --i) {
1148                 ir_entity *ent = get_compound_member(tp, i);
1149
1150                 check_initializer(ent);
1151         }
1152 }  /* check_initializers */
1153
1154 #ifdef DEBUG_libfirm
1155 /**
1156  * Print the entity usage flags of all entities of a given type for debugging.
1157  *
1158  * @param tp  a compound type
1159  */
1160 static void print_entity_usage_flags(ir_type *tp)
1161 {
1162         int i;
1163         for (i = get_compound_n_members(tp) - 1; i >= 0; --i) {
1164                 ir_entity *ent = get_compound_member(tp, i);
1165                 ir_entity_usage flags = get_entity_usage(ent);
1166
1167                 if (flags == 0)
1168                         continue;
1169                 ir_printf("%+F:", ent);
1170                 if (flags & ir_usage_address_taken)
1171                         printf(" address_taken");
1172                 if (flags & ir_usage_read)
1173                         printf(" read");
1174                 if (flags & ir_usage_write)
1175                         printf(" write");
1176                 if (flags & ir_usage_reinterpret_cast)
1177                         printf(" reinterp_cast");
1178                 printf("\n");
1179         }
1180 }
1181 #endif /* DEBUG_libfirm */
1182
1183 /**
1184  * Post-walker: check for global entity address
1185  */
1186 static void check_global_address(ir_node *irn, void *env)
1187 {
1188         ir_node *tls = env;
1189         ir_entity *ent;
1190         ir_entity_usage flags;
1191
1192         if (is_Global(irn)) {
1193                 /* A global. */
1194                 ent = get_Global_entity(irn);
1195         } else if (is_Sel(irn) && get_Sel_ptr(irn) == tls) {
1196                 /* A TLS variable. */
1197                 ent = get_Sel_entity(irn);
1198         } else
1199                 return;
1200
1201         flags = get_entity_usage(ent);
1202         flags |= determine_entity_usage(irn, ent);
1203         set_entity_usage(ent, flags);
1204 }  /* check_global_address */
1205
1206 /**
1207  * Update the entity usage flags of all global entities.
1208  */
1209 static void analyse_irp_globals_entity_usage(void)
1210 {
1211         int i;
1212         ir_segment_t s;
1213
1214         for (s = IR_SEGMENT_FIRST; s <= IR_SEGMENT_LAST; ++s) {
1215                 ir_type *type = get_segment_type(s);
1216                 init_entity_usage(type);
1217         }
1218
1219         for (s = IR_SEGMENT_FIRST; s <= IR_SEGMENT_LAST; ++s) {
1220                 ir_type *type = get_segment_type(s);
1221                 check_initializers(type);
1222         }
1223
1224         for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
1225                 ir_graph *irg = get_irp_irg(i);
1226
1227                 assure_irg_outs(irg);
1228                 irg_walk_graph(irg, NULL, check_global_address, get_irg_tls(irg));
1229         }
1230
1231 #ifdef DEBUG_libfirm
1232         if (firm_dbg_get_mask(dbg) & LEVEL_1) {
1233                 ir_segment_t s;
1234                 for (s = IR_SEGMENT_FIRST; s <= IR_SEGMENT_LAST; ++s) {
1235                         print_entity_usage_flags(get_segment_type(s));
1236                 }
1237         }
1238 #endif /* DEBUG_libfirm */
1239
1240         /* now computed */
1241         irp->globals_entity_usage_state = ir_entity_usage_computed;
1242 }
1243
1244 /* Returns the current address taken state of the globals. */
1245 ir_entity_usage_computed_state get_irp_globals_entity_usage_state(void)
1246 {
1247         return irp->globals_entity_usage_state;
1248 }
1249
1250 /* Sets the current address taken state of the graph. */
1251 void set_irp_globals_entity_usage_state(ir_entity_usage_computed_state state)
1252 {
1253         irp->globals_entity_usage_state = state;
1254 }
1255
1256 /* Assure that the address taken flag is computed for the globals. */
1257 void assure_irp_globals_entity_usage_computed(void)
1258 {
1259         if (irp->globals_entity_usage_state != ir_entity_usage_not_computed)
1260                 return;
1261
1262         analyse_irp_globals_entity_usage();
1263 }
1264
1265 void firm_init_memory_disambiguator(void)
1266 {
1267         FIRM_DBG_REGISTER(dbg, "firm.ana.irmemory");
1268         FIRM_DBG_REGISTER(dbgcall, "firm.opt.cc");
1269 }
1270
1271
1272 /** Maps method types to cloned method types. */
1273 static pmap *mtp_map;
1274
1275 /**
1276  * Clone a method type if not already cloned.
1277  *
1278  * @param tp  the type to clone
1279  */
1280 static ir_type *clone_type_and_cache(ir_type *tp)
1281 {
1282         ir_type *res;
1283         pmap_entry *e = pmap_find(mtp_map, tp);
1284
1285         if (e)
1286                 return e->value;
1287
1288         res = clone_type_method(tp);
1289         pmap_insert(mtp_map, tp, res);
1290
1291         return res;
1292 }  /* clone_type_and_cache */
1293
1294 /**
1295  * Walker: clone all call types of Calls to methods having the
1296  * mtp_property_private property set.
1297  */
1298 static void update_calls_to_private(ir_node *call, void *env)
1299 {
1300         (void) env;
1301         if (is_Call(call)) {
1302                 ir_node *ptr = get_Call_ptr(call);
1303
1304                 if (is_SymConst(ptr)) {
1305                         ir_entity *ent = get_SymConst_entity(ptr);
1306                         ir_type *ctp = get_Call_type(call);
1307
1308                         if (get_entity_additional_properties(ent) & mtp_property_private) {
1309                                 if ((get_method_additional_properties(ctp) & mtp_property_private) == 0) {
1310                                         ctp = clone_type_and_cache(ctp);
1311                                         set_method_additional_property(ctp, mtp_property_private);
1312                                         set_Call_type(call, ctp);
1313                                         DB((dbgcall, LEVEL_1, "changed call to private method %+F using cloned type %+F\n", ent, ctp));
1314                                 }
1315                         }
1316                 }
1317         }
1318 }  /* update_calls_to_private */
1319
1320 /* Mark all private methods, i.e. those of which all call sites are known. */
1321 void mark_private_methods(void)
1322 {
1323         int i;
1324         int changed = 0;
1325
1326         assure_irp_globals_entity_usage_computed();
1327
1328         mtp_map = pmap_create();
1329
1330         /* first step: change the calling conventions of the local non-escaped entities */
1331         for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
1332                 ir_graph        *irg   = get_irp_irg(i);
1333                 ir_entity       *ent   = get_irg_entity(irg);
1334                 ir_entity_usage  flags = get_entity_usage(ent);
1335
1336                 if (!entity_is_externally_visible(ent) &&
1337                     !(flags & ir_usage_address_taken)) {
1338                         ir_type *mtp = get_entity_type(ent);
1339
1340                         set_entity_additional_property(ent, mtp_property_private);
1341                         DB((dbgcall, LEVEL_1, "found private method %+F\n", ent));
1342                         if ((get_method_additional_properties(mtp) & mtp_property_private) == 0) {
1343                                 /* need a new type */
1344                                 mtp = clone_type_and_cache(mtp);
1345                                 set_method_additional_property(mtp, mtp_property_private);
1346                                 set_entity_type(ent, mtp);
1347                                 DB((dbgcall, LEVEL_2, "changed entity type of %+F to %+F\n", ent, mtp));
1348                                 changed = 1;
1349                         }
1350                 }
1351         }
1352
1353         if (changed)
1354                 all_irg_walk(NULL, update_calls_to_private, NULL);
1355
1356         pmap_destroy(mtp_map);
1357 }  /* mark_private_methods */
1358
1359 /* create a pass for mark_private_methods() */
1360 ir_prog_pass_t *mark_private_methods_pass(const char *name)
1361 {
1362         return def_prog_pass(name ? name : "mark_private_methods", mark_private_methods);
1363 }  /* mark_private_methods_pass */