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