irmemory.c 34.6 KB
Newer Older
1
/*
2
 * Copyright (C) 1995-2011 University of Karlsruhe.  All right reserved.
Matthias Braun's avatar
Matthias Braun committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 *
 * This file is part of libFirm.
 *
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file LICENSE.GPL included in the
 * packaging of this file.
 *
 * Licensees holding valid libFirm Professional Edition licenses may use
 * this file in accordance with the libFirm Commercial License.
 * Agreement provided with the Software.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

/**
 * @file
 * @brief    Memory disambiguator
 * @author   Michael Beck
 * @date     27.12.2006
25
26
27
28
 */
#include "config.h"

#include <stdlib.h>
29
#include <stdbool.h>
30

31
#include "adt/pmap.h"
32
33
34
#include "irnode_t.h"
#include "irgraph_t.h"
#include "irprog_t.h"
35
#include "irmemory_t.h"
36
37
38
39
40
41
#include "irmemory.h"
#include "irflag.h"
#include "hashptr.h"
#include "irflag.h"
#include "irouts.h"
#include "irgwalk.h"
Matthias Braun's avatar
Matthias Braun committed
42
#include "irprintf.h"
43
#include "debug.h"
44
#include "error.h"
45
#include "typerep.h"
46
#include "irpass.h"
47
48
49

/** The debug handle. */
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
50
DEBUG_ONLY(static firm_dbg_module_t *dbgcall = NULL;)
51
52
53
54

/** The source language specific language disambiguator function. */
static DISAMBIGUATOR_FUNC language_disambuigator = NULL;

55
56
57
/** The global memory disambiguator options. */
static unsigned global_mem_disamgig_opt = aa_opt_no_opt;

58
59
const char *get_ir_alias_relation_name(ir_alias_relation rel)
{
60
61
#define X(a) case a: return #a
	switch (rel) {
Michael Beck's avatar
Michael Beck committed
62
63
64
	X(ir_no_alias);
	X(ir_may_alias);
	X(ir_sure_alias);
65
66
	default:
		panic("UNKNOWN alias relation");
67
68
69
70
	}
#undef X
}

71
72
unsigned get_irg_memory_disambiguator_options(const ir_graph *irg)
{
Michael Beck's avatar
Michael Beck committed
73
	unsigned opt = irg->mem_disambig_opt;
74
75
76
	if (opt & aa_opt_inherited)
		return global_mem_disamgig_opt;
	return opt;
77
}
78

79
80
void set_irg_memory_disambiguator_options(ir_graph *irg, unsigned options)
{
Michael Beck's avatar
Michael Beck committed
81
	irg->mem_disambig_opt = options & ~aa_opt_inherited;
82
}
83

84
85
void set_irp_memory_disambiguator_options(unsigned options)
{
86
	global_mem_disamgig_opt = options;
87
}
88

89
90
91
ir_storage_class_class_t get_base_sc(ir_storage_class_class_t x)
{
	return x & ~ir_sc_modifiers;
92
}
93

94
/**
95
96
97
98
99
100
 * Find the base address and entity of an Sel node.
 *
 * @param sel  the node
 * @param pEnt after return points to the base entity.
 *
 * @return the base address.
101
 */
102
103
static ir_node *find_base_adr(const ir_node *sel, ir_entity **pEnt)
{
104
105
106
107
108
109
	ir_node *ptr = get_Sel_ptr(sel);

	while (is_Sel(ptr)) {
		sel = ptr;
		ptr = get_Sel_ptr(sel);
	}
110
	*pEnt = get_Sel_entity(sel);
111
	return ptr;
112
}
113

114
/**
Michael Beck's avatar
Michael Beck committed
115
116
 * Check if a given Const node is greater or equal a given size.
 *
Michael Beck's avatar
Michael Beck committed
117
118
119
 * @param cns   a Const node
 * @param size  a integer size
 *
Michael Beck's avatar
Michael Beck committed
120
 * @return ir_no_alias if the Const is greater, ir_may_alias else
121
 */
122
123
static ir_alias_relation check_const(const ir_node *cns, int size)
{
Matthias Braun's avatar
Matthias Braun committed
124
125
	ir_tarval *tv = get_Const_tarval(cns);
	ir_tarval *tv_size;
Michael Beck's avatar
Michael Beck committed
126
127

	if (size == 0)
Michael Beck's avatar
Michael Beck committed
128
		return tarval_is_null(tv) ? ir_may_alias : ir_no_alias;
Michael Beck's avatar
Michael Beck committed
129
	tv_size = new_tarval_from_long(size, get_tarval_mode(tv));
130
	return tarval_cmp(tv_size, tv) & (ir_relation_less_equal) ? ir_no_alias : ir_may_alias;
131
}
132

Michael Beck's avatar
Michael Beck committed
133
134
135
/**
 * Treat idx1 and idx2 as integer indexes and check if they differ always more than size.
 *
Michael Beck's avatar
Michael Beck committed
136
137
138
139
 * @param idx1  a node representing the first index
 * @param idx2  a node representing the second index
 * @param size  an integer size
 *
Michael Beck's avatar
Michael Beck committed
140
141
142
 * @return ir_sure_alias iff idx1 == idx2
 *         ir_no_alias iff they ALWAYS differ more than size
 *         ir_may_alias else
Michael Beck's avatar
Michael Beck committed
143
 */
144
145
static ir_alias_relation different_index(const ir_node *idx1, const ir_node *idx2, int size)
{
146
	if (idx1 == idx2)
Michael Beck's avatar
Michael Beck committed
147
		return ir_sure_alias;
148
149
	if (is_Const(idx1) && is_Const(idx2)) {
		/* both are const, we can compare them */
Matthias Braun's avatar
Matthias Braun committed
150
151
152
		ir_tarval *tv1 = get_Const_tarval(idx1);
		ir_tarval *tv2 = get_Const_tarval(idx2);
		ir_tarval *tv, *tv_size;
153
		ir_mode *m1, *m2;
Michael Beck's avatar
Michael Beck committed
154
155

		if (size == 0)
Michael Beck's avatar
Michael Beck committed
156
			return tv1 == tv2 ? ir_sure_alias : ir_no_alias;
Michael Beck's avatar
Michael Beck committed
157

158
159
160
161
162
163
164
165
166
167
168
		/* arg, modes may be different */
		m1 = get_tarval_mode(tv1);
		m2 = get_tarval_mode(tv2);
		if (m1 != m2) {
			int size = get_mode_size_bits(m1) - get_mode_size_bits(m2);

			if (size < 0) {
				/* m1 is a small mode, cast up */
				m1 = mode_is_signed(m1) ? find_signed_mode(m2) : find_unsigned_mode(m2);
				if (m1 == NULL) {
					/* should NOT happen, but if it does we give up here */
Michael Beck's avatar
Michael Beck committed
169
					return ir_may_alias;
170
171
172
173
174
175
176
				}
				tv1 = tarval_convert_to(tv1, m1);
			} else if (size > 0) {
				/* m2 is a small mode, cast up */
				m2 = mode_is_signed(m2) ? find_signed_mode(m1) : find_unsigned_mode(m1);
				if (m2 == NULL) {
					/* should NOT happen, but if it does we give up here */
Michael Beck's avatar
Michael Beck committed
177
					return ir_may_alias;
178
179
180
181
182
183
184
				}
				tv2 = tarval_convert_to(tv2, m2);
			}
			/* here the size should be identical, check for signed */
			if (get_mode_sign(m1) != get_mode_sign(m2)) {
				/* find the signed */
				if (mode_is_signed(m2)) {
Matthias Braun's avatar
Matthias Braun committed
185
					ir_tarval *t = tv1;
186
187
188
189
190
191
					ir_mode *tm = m1;
					tv1 = tv2; m1 = m2;
					tv2 = t;   m2 = tm;
				}

				/* m1 is now the signed one */
192
				if (!tarval_is_negative(tv1)) {
193
194
195
196
197
					/* tv1 is signed, but >= 0, simply cast into unsigned */
					tv1 = tarval_convert_to(tv1, m2);
				} else {
					tv_size = new_tarval_from_long(size, m2);

198
					if (tarval_cmp(tv2, tv_size) & (ir_relation_greater_equal)) {
199
						/* tv1 is negative and tv2 >= tv_size, so the difference is bigger than size */
Michael Beck's avatar
Michael Beck committed
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
206
207
208
209
210
211

					/* tv1 is < 0, so we can negate it */
					tv1 = tarval_neg(tv1);

					/* cast it into unsigned. for two-complement it does the right thing for MIN_INT */
					tv1 = tarval_convert_to(tv1, m2);

					/* now we can compare without overflow */
212
					return tarval_cmp(tv1, tv2) & (ir_relation_greater_equal) ? ir_no_alias : ir_may_alias;
213
214
215
				}
			}
		}
216
		if (tarval_cmp(tv1, tv2) == ir_relation_greater) {
Matthias Braun's avatar
Matthias Braun committed
217
			ir_tarval *t = tv1;
Michael Beck's avatar
Michael Beck committed
218
219
220
221
			tv1 = tv2;
			tv2 = t;
		}
		/* tv1 is now the "smaller" one */
222
		tv      = tarval_sub(tv2, tv1, NULL);
Michael Beck's avatar
Michael Beck committed
223
		tv_size = new_tarval_from_long(size, get_tarval_mode(tv));
224
		return tarval_cmp(tv_size, tv) & (ir_relation_less_equal) ? ir_no_alias : ir_may_alias;
225
226
227
228
229
230
231
232
233
	}

	/* Note: we rely here on the fact that normalization puts constants on the RIGHT side */
	if (is_Add(idx1)) {
		ir_node *l1 = get_Add_left(idx1);
		ir_node *r1 = get_Add_right(idx1);

		if (l1 == idx2) {
			/* x + c == y */
Michael Beck's avatar
Michael Beck committed
234
235
			if (is_Const(r1))
				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
240
241
242
			ir_node *l2 = get_Add_left(idx2);
			ir_node *r2 = get_Add_right(idx2);

			if (l1 == l2)
Michael Beck's avatar
Michael Beck committed
243
				return different_index(r1, r2, size);
244
			else if (l1 == r2)
Michael Beck's avatar
Michael Beck committed
245
				return different_index(r1, l2, size);
246
			else if (r1 == r2)
Michael Beck's avatar
Michael Beck committed
247
				return different_index(l1, l2, size);
248
			else if (r1 == l2)
Michael Beck's avatar
Michael Beck committed
249
				return different_index(l1, r2, size);
250
251
252
253
254
255
256
257
		}
	}
	if (is_Add(idx2)) {
		ir_node *l2 = get_Add_left(idx2);
		ir_node *r2 = get_Add_right(idx2);

		if (l2 == idx1) {
			/* x + c == y */
Michael Beck's avatar
Michael Beck committed
258
259
			if (is_Const(r2))
				return check_const(r2, size);
260
261
262
263
264
265
266
267
268
		}
	}

	if (is_Sub(idx1)) {
		ir_node *l1 = get_Sub_left(idx1);
		ir_node *r1 = get_Sub_right(idx1);

		if (l1 == idx2) {
			/* x - c == y */
Michael Beck's avatar
Michael Beck committed
269
270
			if (is_Const(r1))
				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
276
277
278
			ir_node *l2 = get_Sub_left(idx2);

			if (l1 == l2) {
				ir_node *r2 = get_Sub_right(idx2);
Michael Beck's avatar
Michael Beck committed
279
				return different_index(r1, r2, size);
280
281
282
283
284
285
286
287
288
			}
		}
	}
	if (is_Sub(idx2)) {
		ir_node *l2 = get_Sub_left(idx2);
		ir_node *r2 = get_Sub_right(idx2);

		if (l2 == idx1) {
			/* x - c == y */
Michael Beck's avatar
Michael Beck committed
289
290
			if (is_Const(r2))
				return check_const(r2, size);
291
292
293
		}

	}
Michael Beck's avatar
Michael Beck committed
294
	return ir_may_alias;
295
}
296
297

/**
298
 * Two Sel addresses have the same base address, check if their offsets are
299
 * different.
300
301
302
303
 *
 * @param adr1  The first address.
 * @param adr2  The second address.
 */
304
305
static ir_alias_relation different_sel_offsets(const ir_node *sel1, const ir_node *sel2)
{
306
	/* seems to be broken */
307
308
	(void) sel1;
	(void) sel2;
309
#if 0
310
311
312
313
314
315
316
317
318
319
320
321
322
	ir_entity *ent1 = get_Sel_entity(sel1);
	ir_entity *ent2 = get_Sel_entity(sel2);
	int i, check_arr = 0;

	if (ent1 == ent2)
		check_arr = 1;
	else {
		ir_type *tp1 = get_entity_type(ent1);
		ir_type *tp2 = get_entity_type(ent2);

		if (tp1 == tp2)
			check_arr = 1;
		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
325
326
327
328
329
330
331
332
333
334
335
			check_arr = 1;
	}
	if (check_arr) {
		/* we select an entity of same size, check for indexes */
		int n = get_Sel_n_indexs(sel1);
		int have_no = 0;

		if (n > 0 && n == get_Sel_n_indexs(sel2)) {
			/* same non-zero number of indexes, an array access, check */
			for (i = 0; i < n; ++i) {
				ir_node *idx1 = get_Sel_index(sel1, i);
				ir_node *idx2 = get_Sel_index(sel2, i);
Michael Beck's avatar
Michael Beck committed
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
339
340
341
342
343
344
345
346

				if (res == may_alias)
					return may_alias;
				else if (res == no_alias)
					have_no = 1;
			}
			/* if we have at least one no_alias, there is no alias relation, else we have sure */
			return have_no > 0 ? no_alias : sure_alias;
		}
	}
Matthias Braun's avatar
Matthias Braun committed
347
348
#else
	(void) different_index;
349
#endif
Michael Beck's avatar
Michael Beck committed
350
	return ir_may_alias;
351
}
352

353
354
355
/**
 * Determine the alias relation by checking if adr1 and adr2 are pointer
 * to different type.
356
357
358
 *
 * @param adr1    The first address.
 * @param adr2    The second address.
359
 */
Michael Beck's avatar
Michael Beck committed
360
static ir_alias_relation different_types(const ir_node *adr1, const ir_node *adr2)
361
362
363
{
	ir_entity *ent1 = NULL, *ent2 = NULL;

364
365
	if (is_SymConst_addr_ent(adr1))
		ent1 = get_SymConst_entity(adr1);
366
367
368
	else if (is_Sel(adr1))
		ent1 = get_Sel_entity(adr1);

369
370
	if (is_SymConst_addr_ent(adr2))
		ent2 = get_SymConst_entity(adr2);
371
372
373
374
375
376
377
378
	else if (is_Sel(adr2))
		ent2 = get_Sel_entity(adr2);

	if (ent1 != NULL && ent2 != NULL) {
		ir_type *tp1 = get_entity_type(ent1);
		ir_type *tp2 = get_entity_type(ent2);

		if (tp1 != tp2) {
Michael Beck's avatar
Michael Beck committed
379
380
381
382
			/* do deref until no pointer types are found */
			while (is_Pointer_type(tp1) && is_Pointer_type(tp2)) {
				tp1 = get_pointer_points_to_type(tp1);
				tp2 = get_pointer_points_to_type(tp2);
383
384
385
386
			}

			if (get_type_tpop(tp1) != get_type_tpop(tp2)) {
				/* different type structure */
Michael Beck's avatar
Michael Beck committed
387
				return ir_no_alias;
388
389
390
391
392
			}
			if (is_Class_type(tp1)) {
				/* check class hierarchy */
				if (! is_SubClass_of(tp1, tp2) &&
					! is_SubClass_of(tp2, tp1))
Michael Beck's avatar
Michael Beck committed
393
					return ir_no_alias;
394
395
			} else {
				/* different types */
Michael Beck's avatar
Michael Beck committed
396
				return ir_no_alias;
397
398
399
			}
		}
	}
Michael Beck's avatar
Michael Beck committed
400
	return ir_may_alias;
401
}
402

403
404
405
406
407
/**
 * Returns non-zero if a node is a result on a malloc-like routine.
 *
 * @param node  the Proj node to test
 */
408
409
static int is_malloc_Result(const ir_node *node)
{
410
411
412
413
414
415
416
	node = get_Proj_pred(node);
	if (! is_Proj(node))
		return 0;
	node = get_Proj_pred(node);
	if (! is_Call(node))
		return 0;
	node = get_Call_ptr(node);
417
418
	if (is_SymConst_addr_ent(node)) {
		ir_entity *ent = get_SymConst_entity(node);
419
420
421
422
423
424

		if (get_entity_additional_properties(ent) & mtp_property_malloc)
			return 1;
		return 0;
	}
	return 0;
425
}
426

427
428
ir_storage_class_class_t classify_pointer(const ir_node *irn,
                                          const ir_entity *ent)
429
{
430
	ir_graph *irg = get_irn_irg(irn);
Michael Beck's avatar
Michael Beck committed
431
	ir_storage_class_class_t res = ir_sc_pointer;
432
433
	if (is_SymConst_addr_ent(irn)) {
		ir_entity *entity = get_SymConst_entity(irn);
434
435
		ir_type   *owner  = get_entity_owner(entity);
		res = owner == get_tls_type() ? ir_sc_tls : ir_sc_globalvar;
436
		if (! (get_entity_usage(entity) & ir_usage_address_taken))
Michael Beck's avatar
Michael Beck committed
437
			res |= ir_sc_modifier_nottaken;
Michael Beck's avatar
Fixed:    
Michael Beck committed
438
	} else if (irn == get_irg_frame(irg)) {
Michael Beck's avatar
Michael Beck committed
439
		res = ir_sc_localvar;
440
		if (ent != NULL && !(get_entity_usage(ent) & ir_usage_address_taken))
Michael Beck's avatar
Michael Beck committed
441
			res |= ir_sc_modifier_nottaken;
442
	} else if (is_Proj(irn) && is_malloc_Result(irn)) {
Michael Beck's avatar
Michael Beck committed
443
		return ir_sc_malloced;
444
445
	} else if (is_Const(irn)) {
		return ir_sc_globaladdr;
446
447
	} else if (is_arg_Proj(irn)) {
		res |= ir_sc_modifier_argument;
448
449
	}

Michael Beck's avatar
Fixed:    
Michael Beck committed
450
	return res;
451
452
}

453
454
455
/**
 * If adr represents a Bitfield Sel, skip it
 */
456
457
static const ir_node *skip_Bitfield_Sels(const ir_node *adr)
{
458
459
460
461
462
463
464
465
466
467
468
	if (is_Sel(adr)) {
		ir_entity *ent     = get_Sel_entity(adr);
		ir_type   *bf_type = get_entity_type(ent);

		/* is it a bitfield type? */
		if (is_Primitive_type(bf_type) && get_primitive_base_type(bf_type) != NULL)
			adr = get_Sel_ptr(adr);
	}
	return adr;
}

469
470
/**
 * Determine the alias relation between two addresses.
Michael Beck's avatar
Michael Beck committed
471
472
473
474
475
476
 *
 * @param addr1  pointer address of the first memory operation
 * @param mode1  the mode of the accessed data through addr1
 * @param addr2  pointer address of the second memory operation
 * @param mode2  the mode of the accessed data through addr2
 *
Michael Beck's avatar
Michael Beck committed
477
 * @return found memory relation
478
479
 */
static ir_alias_relation _get_alias_relation(
Michael Beck's avatar
Michael Beck committed
480
481
	const ir_node *adr1, const ir_mode *mode1,
	const ir_node *adr2, const ir_mode *mode2)
482
{
483
	ir_entity             *ent1, *ent2;
Michael Beck's avatar
Fixed:    
Michael Beck committed
484
485
486
	unsigned              options;
	long                  offset1 = 0;
	long                  offset2 = 0;
Michael Beck's avatar
Michael Beck committed
487
488
489
490
	const ir_node         *base1;
	const ir_node         *base2;
	const ir_node         *orig_adr1 = adr1;
	const ir_node         *orig_adr2 = adr2;
491
	ir_graph              *irg;
Michael Beck's avatar
Fixed:    
Michael Beck committed
492
	unsigned              mode_size;
493
	ir_storage_class_class_t class1, class2, mod1, mod2;
Michael Beck's avatar
Fixed:    
Michael Beck committed
494
	int                   have_const_offsets;
495
496

	if (! get_opt_alias_analysis())
Michael Beck's avatar
Michael Beck committed
497
		return ir_may_alias;
498
499

	if (adr1 == adr2)
Michael Beck's avatar
Michael Beck committed
500
		return ir_sure_alias;
501

502
	irg = get_irn_irg(adr1);
503
504
505
506
	options = get_irg_memory_disambiguator_options(irg);

	/* The Armageddon switch */
	if (options & aa_opt_no_alias)
Michael Beck's avatar
Michael Beck committed
507
		return ir_no_alias;
508

509
510
511
	/* do the addresses have constants offsets?
	 *  Note: nodes are normalized to have constants at right inputs,
	 *        sub X, C is normalized to add X, -C
Michael Beck's avatar
Fixed:    
Michael Beck committed
512
513
	 */
	have_const_offsets = 1;
514
515
	while (is_Add(adr1)) {
		ir_node *add_right = get_Add_right(adr1);
Michael Beck's avatar
Michael Beck committed
516
		if (is_Const(add_right) && !mode_is_reference(get_irn_mode(add_right))) {
Matthias Braun's avatar
Matthias Braun committed
517
			ir_tarval *tv  = get_Const_tarval(add_right);
518
519
			offset1    += get_tarval_long(tv);
			adr1        = get_Add_left(adr1);
Michael Beck's avatar
Fixed:    
Michael Beck committed
520
521
522
523
524
525
		} else if (mode_is_reference(get_irn_mode(add_right))) {
			adr1 = add_right;
			have_const_offsets = 0;
		} else {
			adr1 = get_Add_left(adr1);
			have_const_offsets = 0;
526
527
528
529
		}
	}
	while (is_Add(adr2)) {
		ir_node *add_right = get_Add_right(adr2);
Michael Beck's avatar
Michael Beck committed
530
		if (is_Const(add_right) && !mode_is_reference(get_irn_mode(add_right))) {
Matthias Braun's avatar
Matthias Braun committed
531
			ir_tarval *tv  = get_Const_tarval(add_right);
532
533
			offset2    += get_tarval_long(tv);
			adr2        = get_Add_left(adr2);
Michael Beck's avatar
Fixed:    
Michael Beck committed
534
535
536
537
538
539
		} else if (mode_is_reference(get_irn_mode(add_right))) {
			adr2 = add_right;
			have_const_offsets = 0;
		} else {
			adr2 = get_Add_left(adr2);
			have_const_offsets = 0;
540
		}
541
542
	}

543
544
545
546
	mode_size = get_mode_size_bytes(mode1);
	if (get_mode_size_bytes(mode2) > mode_size) {
		mode_size = get_mode_size_bytes(mode2);
	}
547

Michael Beck's avatar
Fixed:    
Michael Beck committed
548
549
550
551
552
	/* same base address -> compare offsets if possible.
	 * FIXME: type long is not sufficient for this task ...
	 */
	if (adr1 == adr2 && have_const_offsets) {
		if ((unsigned long)labs(offset2 - offset1) >= mode_size)
Michael Beck's avatar
Michael Beck committed
553
			return ir_no_alias;
554
		else
Michael Beck's avatar
Michael Beck committed
555
			return ir_sure_alias;
556
	}
557

558
559
560
	/*
	 * Bitfields can be constructed as Sels from its base address.
	 * As they have different entities, the disambiguator would find that they are
561
	 * alias free. While this is true for its values, it is false for the addresses
562
563
564
565
566
567
	 * (strictly speaking, the Sel's are NOT the addresses of the bitfields).
	 * So, skip those bitfield selecting Sel's.
	 */
	adr1 = skip_Bitfield_Sels(adr1);
	adr2 = skip_Bitfield_Sels(adr2);

Michael Beck's avatar
Michael Beck committed
568
	/* skip Sels */
569
570
	base1 = adr1;
	base2 = adr2;
Michael Beck's avatar
Fixed:    
Michael Beck committed
571
572
	ent1  = NULL;
	ent2  = NULL;
573
	if (is_Sel(adr1)) {
Michael Beck's avatar
Fixed:    
Michael Beck committed
574
		base1 = find_base_adr(adr1, &ent1);
575
576
	}
	if (is_Sel(adr2)) {
Michael Beck's avatar
Fixed:    
Michael Beck committed
577
		base2 = find_base_adr(adr2, &ent2);
578
	}
579

Michael Beck's avatar
Michael Beck committed
580
	/* same base address -> compare Sel entities */
Michael Beck's avatar
Fixed:    
Michael Beck committed
581
	if (base1 == base2 && ent1 != NULL && ent2 != NULL) {
582
		if (ent1 != ent2)
Michael Beck's avatar
Michael Beck committed
583
			return ir_no_alias;
Michael Beck's avatar
Fixed:    
Michael Beck committed
584
585
		else if (have_const_offsets)
			return different_sel_offsets(adr1, adr2);
586
	}
587

588
589
	mod1 = classify_pointer(base1, ent1);
	mod2 = classify_pointer(base2, ent2);
590

591
592
	class1 = get_base_sc(mod1);
	class2 = get_base_sc(mod2);
Michael Beck's avatar
Michael Beck committed
593

594
595
596
597
598
599
600
601
602
603
	/* struct-access cannot alias with variables */
	if (ent1 == NULL && ent2 != NULL && is_compound_type(get_entity_owner(ent2))
		&& (class1 == ir_sc_globalvar || class1 == ir_sc_localvar || class1 == ir_sc_tls || class1 == ir_sc_globaladdr)) {
		return ir_no_alias;
	}
	if (ent2 == NULL && ent1 != NULL && is_compound_type(get_entity_owner(ent1))
		&& (class2 == ir_sc_globalvar || class2 == ir_sc_localvar || class2 == ir_sc_tls || class2 == ir_sc_globaladdr)) {
		return ir_no_alias;
	}

604
605
606
607
608
609
	if (class1 == ir_sc_pointer || class2 == ir_sc_pointer) {
		/* swap pointer class to class1 */
		if (class2 == ir_sc_pointer) {
			ir_storage_class_class_t temp = mod1;
			mod1 = mod2;
			mod2 = temp;
610
611
			class1 = get_base_sc(mod1);
			class2 = get_base_sc(mod2);
Michael Beck's avatar
Michael Beck committed
612
		}
613
614
		/* a pointer and an object whose address was never taken */
		if (mod2 & ir_sc_modifier_nottaken) {
Michael Beck's avatar
Michael Beck committed
615
616
			return ir_no_alias;
		}
617
618
619
		if (mod1 & ir_sc_modifier_argument) {
			if ( (options & aa_opt_no_alias_args)
					&& (mod2 & ir_sc_modifier_argument))
620
				return ir_no_alias;
621
622
623
624
			if ( (options & aa_opt_no_alias_args_global)
					&& (class2 == ir_sc_globalvar
						|| class2 == ir_sc_tls
						|| class2 == ir_sc_globaladdr))
625
626
				return ir_no_alias;
		}
Michael Beck's avatar
Michael Beck committed
627
628
629
630
631
632
633
634
635
636
637
638
639
	} else if (class1 != class2) {
		/* two objects from different memory spaces */
		return ir_no_alias;
	} else {
		/* both classes are equal */
		if (class1 == ir_sc_globalvar) {
			ir_entity *entity1 = get_SymConst_entity(base1);
			ir_entity *entity2 = get_SymConst_entity(base2);
			if (entity1 != entity2)
				return ir_no_alias;

			/* for some reason CSE didn't happen yet for the 2 SymConsts... */
			return ir_may_alias;
640
		} else if (class1 == ir_sc_globaladdr) {
Matthias Braun's avatar
Matthias Braun committed
641
642
643
644
			ir_tarval *tv = get_Const_tarval(base1);
			offset1      += get_tarval_long(tv);
			tv            = get_Const_tarval(base2);
			offset2      += get_tarval_long(tv);
645
646
647
648
649

			if ((unsigned long)labs(offset2 - offset1) >= mode_size)
				return ir_no_alias;
			else
				return ir_sure_alias;
Michael Beck's avatar
Michael Beck committed
650
651
652
653
		}
	}

	/* Type based alias analysis */
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
	if (options & aa_opt_type_based) {
		ir_alias_relation rel;

		if (options & aa_opt_byte_type_may_alias) {
			if (get_mode_size_bits(mode1) == 8 || get_mode_size_bits(mode2) == 8) {
				/* One of the modes address a byte. Assume a ir_may_alias and leave
				   the type based check. */
				goto leave_type_based_alias;
			}
		}
		/* cheap check: If the mode sizes did not match, the types MUST be different */
		if (get_mode_size_bits(mode1) != get_mode_size_bits(mode2))
			return ir_no_alias;

		/* cheap test: if only one is a reference mode, no alias */
		if (mode_is_reference(mode1) != mode_is_reference(mode2))
			return ir_no_alias;

Michael Beck's avatar
Michael Beck committed
672
673
674
675
		/* cheap test: if arithmetic is different, no alias */
		if (get_mode_arithmetic(mode1) != get_mode_arithmetic(mode2))
			return ir_no_alias;

676
677
678
679
680
681
682
		/* try rule R5 */
		rel = different_types(orig_adr1, orig_adr2);
		if (rel != ir_may_alias)
			return rel;
leave_type_based_alias:;
	}

683
	/* do we have a language specific memory disambiguator? */
684
	if (language_disambuigator != NULL) {
685
		ir_alias_relation rel = language_disambuigator(orig_adr1, mode1, orig_adr2, mode2);
Michael Beck's avatar
Michael Beck committed
686
		if (rel != ir_may_alias)
687
688
689
690
			return rel;
	}

	/* access points-to information here */
Michael Beck's avatar
Michael Beck committed
691
	return ir_may_alias;
692
}
693
694

ir_alias_relation get_alias_relation(
Michael Beck's avatar
Michael Beck committed
695
696
	const ir_node *adr1, const ir_mode *mode1,
	const ir_node *adr2, const ir_mode *mode2)
697
{
698
	ir_alias_relation rel = _get_alias_relation(adr1, mode1, adr2, mode2);
699
	DB((dbg, LEVEL_1, "alias(%+F, %+F) = %s\n", adr1, adr2, get_ir_alias_relation_name(rel)));
700
	return rel;
701
}
702

703
704
void set_language_memory_disambiguator(DISAMBIGUATOR_FUNC func)
{
705
	language_disambuigator = func;
706
}
707
708
709
710
711
712

/** The result cache for the memory disambiguator. */
static set *result_cache = NULL;

/** An entry in the relation cache. */
typedef struct mem_disambig_entry {
713
714
715
716
	const ir_node     *adr1;    /**< The first address. */
	const ir_mode     *mode1;   /**< The first address mode. */
	const ir_node     *adr2;    /**< The second address. */
	const ir_mode     *mode2;   /**< The second address mode. */
717
718
719
	ir_alias_relation result;   /**< The alias relation result. */
} mem_disambig_entry;

720
#define HASH_ENTRY(adr1, adr2)  (hash_ptr(adr1) ^ hash_ptr(adr2))
721
722
723
724

/**
 * Compare two relation cache entries.
 */
725
726
static int cmp_mem_disambig_entry(const void *elt, const void *key, size_t size)
{
727
728
	const mem_disambig_entry *p1 = (const mem_disambig_entry*) elt;
	const mem_disambig_entry *p2 = (const mem_disambig_entry*) key;
Matthias Braun's avatar
Matthias Braun committed
729
	(void) size;
730

Michael Beck's avatar
Michael Beck committed
731
732
	return p1->adr1 == p2->adr1 && p1->adr2 == p2->adr2 &&
	       p1->mode1 == p2->mode1 && p1->mode2 == p2->mode2;
733
}
734

735
736
void mem_disambig_init(void)
{
737
	result_cache = new_set(cmp_mem_disambig_entry, 8);
738
}
739
740

ir_alias_relation get_alias_relation_ex(
Michael Beck's avatar
Michael Beck committed
741
742
	const ir_node *adr1, const ir_mode *mode1,
	const ir_node *adr2, const ir_mode *mode2)
743
744
745
{
	mem_disambig_entry key, *entry;

746
747
	ir_fprintf(stderr, "%+F <-> %+F\n", adr1, adr2);

748
	if (! get_opt_alias_analysis())
Michael Beck's avatar
Michael Beck committed
749
		return ir_may_alias;
750
751

	if (get_irn_opcode(adr1) > get_irn_opcode(adr2)) {
Michael Beck's avatar
Michael Beck committed
752
		const ir_node *t = adr1;
753
754
755
756
		adr1 = adr2;
		adr2 = t;
	}

Michael Beck's avatar
Michael Beck committed
757
758
759
760
	key.adr1  = adr1;
	key.adr2  = adr2;
	key.mode1 = mode1;
	key.mode2 = mode2;
761
	entry = (mem_disambig_entry*) set_find(result_cache, &key, sizeof(key), HASH_ENTRY(adr1, adr2));
762
	if (entry != NULL)
763
764
		return entry->result;

765
	key.result = get_alias_relation(adr1, mode1, adr2, mode2);
766
767
768

	set_insert(result_cache, &key, sizeof(key), HASH_ENTRY(adr1, adr2));
	return key.result;
769
}
770

771
772
void mem_disambig_term(void)
{
773
	if (result_cache != NULL) {
774
775
776
		del_set(result_cache);
		result_cache = NULL;
	}
777
}
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797

/**
 * Check the mode of a Load/Store with the mode of the entity
 * that is accessed.
 * If the mode of the entity and the Load/Store mode do not match, we
 * have the bad reinterpret case:
 *
 * int i;
 * char b = *(char *)&i;
 *
 * We do NOT count this as one value and return address_taken
 * in that case.
 * However, we support an often used case. If the mode is two-complement
 * we allow casts between signed/unsigned.
 *
 * @param mode     the mode of the Load/Store
 * @param ent_mode the mode of the accessed entity
 *
 * @return non-zero if the Load/Store is a hidden cast, zero else
 */
798
799
static int is_hidden_cast(const ir_mode *mode, const ir_mode *ent_mode)
{
800
801
802
	if (ent_mode == NULL)
		return false;

803
804
805
806
807
	if (ent_mode != mode) {
		if (ent_mode == NULL ||
			get_mode_size_bits(ent_mode) != get_mode_size_bits(mode) ||
			get_mode_arithmetic(ent_mode) != irma_twos_complement ||
			get_mode_arithmetic(mode) != irma_twos_complement)
808
			return true;
809
	}
810
	return false;
811
}
812
813

/**
Christoph Mallon's avatar
Christoph Mallon committed
814
 * Determine the usage state of a node (or its successor Sels).
815
816
817
 *
 * @param irn  the node
 */
818
819
static ir_entity_usage determine_entity_usage(const ir_node *irn, ir_entity *entity)
{
820
	int       i;
821
822
823
	ir_mode   *emode, *mode;
	ir_node   *value;
	ir_type   *tp;
824
	unsigned   res = 0;
825
826
827
828
829
830

	for (i = get_irn_n_outs(irn) - 1; i >= 0; --i) {
		ir_node *succ = get_irn_out(irn, i);

		switch (get_irn_opcode(succ)) {
		case iro_Load:
831
832
			/* beware: irn might be a Id node here, so irn might be not
			   equal to get_Load_ptr(succ) */
833
834
			res |= ir_usage_read;

835
			/* check if this load is not a hidden conversion */
836
837
			mode  = get_Load_mode(succ);
			emode = get_type_mode(get_entity_type(entity));
838
			if (is_hidden_cast(mode, emode))
839
				res |= ir_usage_reinterpret_cast;
840
841
842
843
			break;

		case iro_Store:
			/* check that the node is not the Store's value */
844
845
846
847
848
849
850
851
852
853
854
855
856
857
			if (irn == get_Store_value(succ)) {
				res |= ir_usage_unknown;
			}
			if (irn == get_Store_ptr(succ)) {
				res |= ir_usage_write;

				/* check if this Store is not a hidden conversion */
				value = get_Store_value(succ);
				mode  = get_irn_mode(value);
				emode = get_type_mode(get_entity_type(entity));
				if (is_hidden_cast(mode, emode))
					res |= ir_usage_reinterpret_cast;
			}
			assert(irn != get_Store_mem(succ));
858
859
			break;

860
861
		case iro_CopyB:
			/* CopyB are like Loads/Stores */
Matthias Braun's avatar
fix    
Matthias Braun committed
862
			tp  = get_entity_type(entity);
863
864
			if (tp != get_CopyB_type(succ)) {
				/* bad, different types, might be a hidden conversion */
865
866
867
868
869
870
871
				res |= ir_usage_reinterpret_cast;
			}
			if (irn == get_CopyB_dst(succ)) {
				res |= ir_usage_write;
			} else {
				assert(irn == get_CopyB_src(succ));
				res |= ir_usage_read;
872
873
874
			}
			break;

875
876
		case iro_Add:
		case iro_Sub:
877
878
879
			/* Check the successor of irn. */
			res |= determine_entity_usage(succ, entity);
			break;
880
		case iro_Sel: {
881
			ir_entity *sel_entity = get_Sel_entity(succ);
Michael Beck's avatar
Michael Beck committed
882
			/* this analysis can't handle unions correctly */
883
			if (is_Union_type(get_entity_owner(sel_entity))) {
Matthias Braun's avatar
fix    
Matthias Braun committed
884
				res |= ir_usage_unknown;
885
886
				break;
			}
887
			/* Check the successor of irn. */
888
			res |= determine_entity_usage(succ, sel_entity);
889
890
891
892
			break;
		}

		case iro_Call:
893
894
895
896
897
898
899
900
901
			if (irn == get_Call_ptr(succ)) {
				/* TODO: we could check for reinterpret casts here...
				 * But I doubt anyone is interested in that bit for
				 * function entities and I'm too lazy to write the code now.
				 */
				res |= ir_usage_read;
			} else {
				assert(irn != get_Call_mem(succ));
				res |= ir_usage_unknown;
902
903
			}
			break;
904

905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
		/* skip identities */
		case iro_Id:
			res |= determine_entity_usage(succ, entity);
			break;

		/* skip tuples */
		case iro_Tuple: {
			int input_nr;
			for (input_nr = get_Tuple_n_preds(succ) - 1; input_nr >= 0;
					--input_nr) {
				ir_node *pred = get_Tuple_pred(succ, input_nr);
				if (pred == irn) {
					int k;
					/* we found one input */
					for (k = get_irn_n_outs(succ) - 1; k >= 0; --k) {
						ir_node *proj = get_irn_out(succ, k);

						if (is_Proj(proj) && get_Proj_proj(proj) == input_nr) {
							res |= determine_entity_usage(proj, entity);
							break;
						}
					}
				}
			}
			break;
		}
931

932
		default:
933
934
			/* another op, we don't know anything (we could do more advanced
			 * things like a dataflow analysis here) */
935
936
			res |= ir_usage_unknown;
			break;
937
938
		}
	}
939

940
	return (ir_entity_usage) res;
941
}
942
943

/**
944
 * Update the usage flags of all frame entities.
945
 */
946
947
static void analyse_irg_entity_usage(ir_graph *irg)
{
948
	ir_type *ft = get_irg_frame_type(irg);
949
	ir_node *irg_frame;
Michael Beck's avatar
Michael Beck committed
950
951
	size_t i, n;
	int j, k, static_link_arg;
952

953
954
	assure_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS);

955
	/* set initial state to not_taken, as this is the "smallest" state */
Michael Beck's avatar
Michael Beck committed
956
	for (i = 0, n = get_class_n_members(ft); i < n; ++i) {
957
		ir_entity *ent = get_class_member(ft, i);
958

959
960
		/* methods can only be analyzed globally */
		if (! is_method_entity(ent)) {
961
			ir_entity_usage flags = ir_usage_none;
Matthias Braun's avatar
Matthias Braun committed
962
963
			if (get_entity_linkage(ent) & IR_LINKAGE_HIDDEN_USER)
				flags = ir_usage_unknown;
964
965
			set_entity_usage(ent, flags);
		}
966
967
968
969
	}

	irg_frame = get_irg_frame(irg);

Michael Beck's avatar
Michael Beck committed
970
971
	for (j = get_irn_n_outs(irg_frame) - 1; j >= 0; --j) {
		ir_node        *succ = get_irn_out(irg_frame, j);
972
		ir_entity      *entity;
973
		unsigned        flags;
974

Michael Beck's avatar
Michael Beck committed
975
		if (!is_Sel(succ))
976
			continue;
977

978
979
980
		entity = get_Sel_entity(succ);
		flags  = get_entity_usage(entity);
		flags |= determine_entity_usage(succ, entity);
981
		set_entity_usage(entity, (ir_entity_usage) flags);
982
	}
983

984
985
	/* check inner functions accessing outer frame */
	static_link_arg = 0;
Michael Beck's avatar
Michael Beck committed
986
	for (i = 0, n = get_class_n_members(ft); i < n; ++i) {
987
		ir_entity *ent = get_class_member(ft, i);
988
989
		ir_graph  *inner_irg;
		ir_node   *args;
990

991
992
		if (! is_method_entity(ent))
			continue;
993

994
		inner_irg = get_entity_irg(ent);
Matthias Braun's avatar
Matthias Braun committed
995
996
997
		if (inner_irg == NULL)
			continue;

998
999
1000
1001
		assure_irg_outs(inner_irg);
		args = get_irg_args(inner_irg);
		for (j = get_irn_n_outs(args) - 1; j >= 0; --j) {
			ir_node *arg = get_irn_out(args, j);
1002

1003
1004
1005
			if (get_Proj_proj(arg) == static_link_arg) {
				for (k = get_irn_n_outs(arg) - 1; k >= 0; --k) {
					ir_node *succ = get_irn_out(arg, k);
1006

1007
1008
					if (is_Sel(succ)) {
						ir_entity *entity = get_Sel_entity(succ);
1009

1010
1011
						if (get_entity_owner(entity) == ft) {
							/* found an access to the outer frame */
1012
							unsigned flags;
1013

1014
1015
							flags  = get_entity_usage(entity);
							flags |= determine_entity_usage(succ, entity);
1016
							set_entity_usage(entity, (ir_entity_usage) flags);
1017
1018
1019
1020
1021
1022
1023
						}
					}
				}
			}
		}
	}

1024
	/* now computed */
1025
	add_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_ENTITY_USAGE);
1026
}
1027

Matthias Braun's avatar
Matthias Braun committed
1028
1029
void assure_irg_entity_usage_computed(ir_graph *irg)
{
1030
	if (irg_has_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_ENTITY_USAGE))
1031
		return;
1032

1033
1034
	analyse_irg_entity_usage(irg);
}
1035

1036