entity.c 43.2 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
/*
Michael Beck's avatar
Michael Beck committed
2
 * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
Christian Würdig's avatar
Christian Würdig committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 *
 * 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.
 */

Michael Beck's avatar
Michael Beck committed
20
21
22
23
24
/**
 * @file
 * @brief   Representation of all program known entities.
 * @author  Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Michael Beck
 * @version $Id$
25
 */
Matthias Braun's avatar
Matthias Braun committed
26
#include "config.h"
Boris Boesler's avatar
Boris Boesler committed
27

28
29
30
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
31

Michael Beck's avatar
Michael Beck committed
32
33
#include "firm_common_t.h"

Michael Beck's avatar
Michael Beck committed
34
35
36
37
38
39
#include "xmalloc.h"
#include "entity_t.h"
#include "array.h"
#include "irtools.h"
#include "irhooks.h"
#include "irprintf.h"
40

Michael Beck's avatar
Michael Beck committed
41
42
43
#include "irprog_t.h"
#include "ircons.h"
#include "tv_t.h"
44
45
46
#include "irdump.h"
#include "irgraph_t.h"
#include "callgraph.h"
47
#include "error.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
48

49
/*-----------------------------------------------------------------*/
Christian Schäfer's avatar
Christian Schäfer committed
50
/** general                                                       **/
51
/*-----------------------------------------------------------------*/
Christian Schäfer's avatar
Christian Schäfer committed
52

Michael Beck's avatar
Michael Beck committed
53
ir_entity *unknown_entity = NULL;
54

Michael Beck's avatar
Michael Beck committed
55
ir_entity *get_unknown_entity(void) { return unknown_entity; }
Christian Schäfer's avatar
Christian Schäfer committed
56

57
/** The name of the unknown entity. */
58
#define UNKNOWN_ENTITY_NAME "unknown_entity"
59

60
61
62
/*-----------------------------------------------------------------*/
/* ENTITY                                                          */
/*-----------------------------------------------------------------*/
63

64
65
66
/**
 * Add an entity to it's already set owner type.
 */
67
static inline void insert_entity_in_owner(ir_entity *ent) {
68
69
70
71
72
73
74
75
76
77
78
79
80
81
	ir_type *owner = ent->owner;
	switch (get_type_tpop_code(owner)) {
	case tpo_class:
		add_class_member(owner, ent);
		break;
	case tpo_struct:
		add_struct_member(owner, ent);
		break;
	case tpo_union:
		add_union_member(owner, ent);
		break;
	case tpo_array:
		set_array_element_entity(owner, ent);
		break;
82
83
	default:
		panic("Unsupported type kind");
84
85
	}
}  /* insert_entity_in_owner */
86

Michael Beck's avatar
Michael Beck committed
87
/**
88
89
90
91
92
93
94
95
 * Creates a new entity. This entity is NOT inserted in the owner type.
 *
 * @param db     debug info for this entity
 * @param owner  the owner type of the new entity
 * @param name   the name of the new entity
 * @param type   the type of the new entity
 *
 * @return the new created entity
Michael Beck's avatar
Michael Beck committed
96
 */
97
static inline ir_entity *
98
new_rd_entity(dbg_info *db, ir_type *owner, ident *name, ir_type *type)
Christian Schäfer's avatar
Christian Schäfer committed
99
{
100
101
102
103
104
	ir_entity *res;
	ir_graph *rem;

	assert(!id_contains_char(name, ' ') && "entity name should not contain spaces");

105
	res = XMALLOCZ(ir_entity);
106
107
108
109
110
111
112
113
114
115

	res->kind    = k_entity;
	res->name    = name;
	res->ld_name = NULL;
	res->type    = type;
	res->owner   = owner;

	res->allocation           = allocation_automatic;
	res->visibility           = visibility_local;
	res->volatility           = volatility_non_volatile;
116
	res->align                = align_is_aligned;
117
118
	res->stickyness           = stickyness_unsticky;
	res->peculiarity          = peculiarity_existent;
119
	res->usage                = ir_usage_unknown;
120
121
	res->final                = 0;
	res->compiler_gen         = 0;
Michael Beck's avatar
Michael Beck committed
122
	res->backend_marked       = 0;
123
124
125
126
127
128
129
	res->offset               = -1;
	res->offset_bit_remainder = 0;
	res->link                 = NULL;
	res->repr_class           = NULL;

	if (is_Method_type(type)) {
		symconst_symbol sym;
130
		ir_mode *mode = is_Method_type(type) ? mode_P_code : mode_P_data;
131
132
133
		sym.entity_p            = res;
		rem                     = current_ir_graph;
		current_ir_graph        = get_const_code_irg();
134
		res->value              = new_SymConst(mode, sym, symconst_addr_ent);
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
		current_ir_graph        = rem;
		res->allocation         = allocation_static;
		res->variability        = variability_constant;
		res->attr.mtd_attr.irg_add_properties = mtp_property_inherited;
		res->attr.mtd_attr.vtable_number      = VTABLE_NUM_NOT_SET;
		res->attr.mtd_attr.param_access       = NULL;
		res->attr.mtd_attr.param_weight       = NULL;
		res->attr.mtd_attr.irg                = NULL;
	} else if (is_compound_type(type)) {
		res->variability = variability_uninitialized;
		res->value       = NULL;
		res->attr.cmpd_attr.values    = NULL;
		res->attr.cmpd_attr.val_paths = NULL;
	} else {
		res->variability = variability_uninitialized;
		res->value       = NULL;
	}

	if (is_Class_type(owner)) {
		res->overwrites    = NEW_ARR_F(ir_entity *, 0);
		res->overwrittenby = NEW_ARR_F(ir_entity *, 0);
	} else {
		res->overwrites    = NULL;
		res->overwrittenby = NULL;
	}
160

161
#ifdef DEBUG_libfirm
162
	res->nr = get_irp_new_node_nr();
Florian Liekweg's avatar
Florian Liekweg committed
163
#endif /* DEBUG_libfirm */
164

165
166
	res->visit = 0;
	set_entity_dbg_info(res, db);
Christian Schäfer's avatar
Christian Schäfer committed
167

168
169
	return res;
}  /* new_rd_entity */
170

Michael Beck's avatar
Michael Beck committed
171
ir_entity *
172
new_d_entity(ir_type *owner, ident *name, ir_type *type, dbg_info *db) {
173
	ir_entity *res;
Michael Beck's avatar
Michael Beck committed
174

175
176
177
178
	assert(is_compound_type(owner));
	res = new_rd_entity(db, owner, name, type);
	/* Remember entity in it's owner. */
	insert_entity_in_owner(res);
179

180
181
182
	hook_new_entity(res);
	return res;
}  /* new_d_entity */
183

Michael Beck's avatar
Michael Beck committed
184
ir_entity *
185
new_entity(ir_type *owner, ident *name, ir_type *type) {
186
187
	return new_d_entity(owner, name, type, NULL);
}  /* new_entity */
188

189
190
191
192
193
/**
 * Free entity attributes.
 *
 * @param ent  the entity
 */
Michael Beck's avatar
Michael Beck committed
194
static void free_entity_attrs(ir_entity *ent) {
195
196
197
198
199
200
201
202
203
	int i;
	if (get_type_tpop(get_entity_owner(ent)) == type_class) {
		DEL_ARR_F(ent->overwrites);    ent->overwrites = NULL;
		DEL_ARR_F(ent->overwrittenby); ent->overwrittenby = NULL;
	} else {
		assert(ent->overwrites == NULL);
		assert(ent->overwrittenby == NULL);
	}
	if (is_compound_entity(ent)) {
204
205
206
207
208
209
210
211
		if (ent->has_initializer) {
			/* TODO: free initializers */
		} else {
			if (ent->attr.cmpd_attr.val_paths) {
				for (i = get_compound_ent_n_values(ent) - 1; i >= 0; --i)
					if (ent->attr.cmpd_attr.val_paths[i]) {
						/* free_compound_graph_path(ent->attr.cmpd_attr.val_paths[i]) ;  * @@@ warum nich? */
						/* Geht nich: wird mehrfach verwendet!!! ==> mehrfach frei gegeben. */
Andreas Zwinkau's avatar
Andreas Zwinkau committed
212
						/* DEL_ARR_F(ent->attr.cmpd_attr.val_paths); */
213
214
215
					}
					ent->attr.cmpd_attr.val_paths = NULL;
			}
Andreas Zwinkau's avatar
Andreas Zwinkau committed
216
217
218
			if (ent->attr.cmpd_attr.values) {
				/*DEL_ARR_F(ent->attr.cmpd_attr.values)*/;
			}
219
			ent->attr.cmpd_attr.values = NULL;
220
221
222
223
224
225
226
227
228
229
230
231
		}
	} else if (is_method_entity(ent)) {
		if (ent->attr.mtd_attr.param_access) {
			DEL_ARR_F(ent->attr.mtd_attr.param_access);
			ent->attr.mtd_attr.param_access = NULL;
		}
		if (ent->attr.mtd_attr.param_weight) {
			DEL_ARR_F(ent->attr.mtd_attr.param_weight);
			ent->attr.mtd_attr.param_weight = NULL;
		}
	}
}  /* free_entity_attrs */
Christian Schäfer's avatar
Christian Schäfer committed
232

233
234
235
236
237
238
239
/**
 * Creates a deep copy of an entity.
 */
static ir_entity *deep_entity_copy(ir_entity *old)
{
	ir_entity *newe = XMALLOC(ir_entity);

240
	*newe = *old;
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
	if (is_compound_entity(old)) {
		if (old->has_initializer) {
			/* FIXME: the initializers are NOT copied */
		} else {
			newe->attr.cmpd_attr.values    = NULL;
			newe->attr.cmpd_attr.val_paths = NULL;
			if (old->attr.cmpd_attr.values)
				newe->attr.cmpd_attr.values = DUP_ARR_F(ir_node *, old->attr.cmpd_attr.values);

			/* FIXME: the compound graph paths are NOT copied */
			if (old->attr.cmpd_attr.val_paths)
				newe->attr.cmpd_attr.val_paths = DUP_ARR_F(compound_graph_path *, old->attr.cmpd_attr.val_paths);
		}
	} else if (is_method_entity(old)) {
		/* do NOT copy them, reanalyze. This might be the best solution */
		newe->attr.mtd_attr.param_access = NULL;
		newe->attr.mtd_attr.param_weight = NULL;
	}

#ifdef DEBUG_libfirm
	newe->nr = get_irp_new_node_nr();
#endif
	return newe;
}
Michael Beck's avatar
Michael Beck committed
265
266
267
268
/*
 * Copies the entity if the new_owner is different from the
 * owner of the old entity,  else returns the old entity.
 */
Michael Beck's avatar
Michael Beck committed
269
270
ir_entity *
copy_entity_own(ir_entity *old, ir_type *new_owner) {
271
272
273
	ir_entity *newe;
	assert(is_entity(old));
	assert(is_compound_type(new_owner));
274
	assert(get_type_state(new_owner) != layout_fixed);
275

276
277
278
279
280
	if (old->owner == new_owner)
		return old;

	/* create a deep copy so we are safe of aliasing and double-freeing. */
	newe = deep_entity_copy(old);
281
	newe->owner = new_owner;
282

283
284
285
286
	if (is_Class_type(new_owner)) {
		newe->overwrites    = NEW_ARR_F(ir_entity *, 0);
		newe->overwrittenby = NEW_ARR_F(ir_entity *, 0);
	}
287

288
289
290
	insert_entity_in_owner(newe);
	return newe;
}  /* copy_entity_own */
291

Michael Beck's avatar
Michael Beck committed
292
293
ir_entity *
copy_entity_name(ir_entity *old, ident *new_name) {
294
295
296
297
	ir_entity *newe;
	assert(old && old->kind == k_entity);

	if (old->name == new_name) return old;
298
	newe = deep_entity_copy(old);
299
300
	newe->name = new_name;
	newe->ld_name = NULL;
301

302
303
304
305
306
	if (is_Class_type(newe->owner)) {
		newe->overwrites    = DUP_ARR_F(ir_entity *, old->overwrites);
		newe->overwrittenby = DUP_ARR_F(ir_entity *, old->overwrittenby);
	}
	insert_entity_in_owner(newe);
307

308
309
	return newe;
}  /* copy_entity_name */
310

311
void
312
313
314
315
316
317
free_entity(ir_entity *ent) {
	assert(ent && ent->kind == k_entity);
	free_entity_attrs(ent);
	ent->kind = k_BAD;
	free(ent);
}  /* free_entity */
318

319
/* Outputs a unique number for this node */
320
long
321
322
get_entity_nr(const ir_entity *ent) {
	assert(ent && ent->kind == k_entity);
323
#ifdef DEBUG_libfirm
324
	return ent->nr;
325
#else
326
	return (long)PTR_TO_INT(ent);
327
#endif
328
}  /* get_entity_nr */
329

330
const char *
Michael Beck's avatar
Michael Beck committed
331
(get_entity_name)(const ir_entity *ent) {
332
333
	return _get_entity_name(ent);
}  /* get_entity_name */
Christian Schäfer's avatar
Christian Schäfer committed
334
335

ident *
Michael Beck's avatar
Michael Beck committed
336
(get_entity_ident)(const ir_entity *ent) {
337
338
	return _get_entity_ident(ent);
}  /* get_entity_ident */
Michael Beck's avatar
Michael Beck committed
339
340

void
Michael Beck's avatar
Michael Beck committed
341
(set_entity_ident)(ir_entity *ent, ident *id) {
342
343
	_set_entity_ident(ent, id);
}  /* set_entity_ident */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
344

345
ir_type *
Michael Beck's avatar
Michael Beck committed
346
(get_entity_owner)(ir_entity *ent) {
347
348
	return _get_entity_owner(ent);
}  /* get_entity_owner */
Christian Schäfer's avatar
Christian Schäfer committed
349

350
void
Michael Beck's avatar
Michael Beck committed
351
set_entity_owner(ir_entity *ent, ir_type *owner) {
352
353
354
355
	assert(is_entity(ent));
	assert(is_compound_type(owner));
	ent->owner = owner;
}  /* set_entity_owner */
Christian Schäfer's avatar
Christian Schäfer committed
356

357
ident *
Michael Beck's avatar
Michael Beck committed
358
(get_entity_ld_ident)(ir_entity *ent) {
359
360
	return _get_entity_ld_ident(ent);
}  /* get_entity_ld_ident */
361

362
void
Michael Beck's avatar
Michael Beck committed
363
(set_entity_ld_ident)(ir_entity *ent, ident *ld_ident) {
364
365
	_set_entity_ld_ident(ent, ld_ident);
}  /* set_entity_ld_ident */
Christian Schäfer's avatar
Christian Schäfer committed
366

367
const char *
Michael Beck's avatar
Michael Beck committed
368
(get_entity_ld_name)(ir_entity *ent) {
369
370
	return _get_entity_ld_name(ent);
}  /* get_entity_ld_name */
371

372
ir_type *
Michael Beck's avatar
Michael Beck committed
373
(get_entity_type)(ir_entity *ent) {
374
375
	return _get_entity_type(ent);
}  /* get_entity_type */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
376

377
void
Michael Beck's avatar
Michael Beck committed
378
(set_entity_type)(ir_entity *ent, ir_type *type) {
379
380
	_set_entity_type(ent, type);
}  /* set_entity_type */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
381

382
ir_allocation
Michael Beck's avatar
Michael Beck committed
383
(get_entity_allocation)(const ir_entity *ent) {
384
385
	return _get_entity_allocation(ent);
}  /* get_entity_allocation */
386

387
void
Michael Beck's avatar
Michael Beck committed
388
(set_entity_allocation)(ir_entity *ent, ir_allocation al) {
389
390
	_set_entity_allocation(ent, al);
}  /* set_entity_allocation */
391

392
/* return the name of the visibility */
Moritz Kroll's avatar
typo    
Moritz Kroll committed
393
const char *get_allocation_name(ir_allocation al)
394
{
395
#define X(a)    case a: return #a
Moritz Kroll's avatar
typo    
Moritz Kroll committed
396
	switch (al) {
397
398
399
400
	X(allocation_automatic);
	X(allocation_parameter);
	X(allocation_dynamic);
	X(allocation_static);
401
    default: return "BAD VALUE";
402
	}
403
#undef X
404
}  /* get_allocation_name */
405

406
ir_visibility
Michael Beck's avatar
Michael Beck committed
407
(get_entity_visibility)(const ir_entity *ent) {
408
409
	return _get_entity_visibility(ent);
}  /* get_entity_visibility */
410

411
void
Michael Beck's avatar
Michael Beck committed
412
set_entity_visibility(ir_entity *ent, ir_visibility vis) {
413
414
415
416
417
418
419
420
	assert(ent && ent->kind == k_entity);
	if (vis != visibility_local)
		assert((ent->allocation == allocation_static) ||
		(ent->allocation == allocation_automatic));
		/* @@@ Test that the owner type is not local, but how??
	&& get_class_visibility(get_entity_owner(ent)) != local));*/
	ent->visibility = vis;
}  /* set_entity_visibility */
421

422
/* return the name of the visibility */
423
const char *get_visibility_name(ir_visibility vis)
424
{
425
#define X(a)    case a: return #a
426
427
428
429
	switch (vis) {
	X(visibility_local);
	X(visibility_external_visible);
	X(visibility_external_allocated);
430
    default: return "BAD VALUE";
431
	}
432
#undef X
433
}  /* get_visibility_name */
434

435
ir_variability
Michael Beck's avatar
Michael Beck committed
436
(get_entity_variability)(const ir_entity *ent) {
437
438
	return _get_entity_variability(ent);
}  /* get_entity_variability */
439

440
void
441
set_entity_variability(ir_entity *ent, ir_variability var)
442
{
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
	assert(ent && ent->kind == k_entity);
	if (var == variability_part_constant)
		assert(is_Class_type(ent->type) || is_Struct_type(ent->type));

	if ((is_compound_type(ent->type)) &&
		(ent->variability == variability_uninitialized) && (var != variability_uninitialized)) {
		/* Allocate data structures for constant values */
		ent->attr.cmpd_attr.values    = NEW_ARR_F(ir_node *, 0);
		ent->attr.cmpd_attr.val_paths = NEW_ARR_F(compound_graph_path *, 0);
	}
	if ((is_atomic_type(ent->type)) &&
		(ent->variability == variability_uninitialized) && (var != variability_uninitialized)) {
		/* Set default constant value. */
		ent->value = new_rd_Unknown(get_const_code_irg(), get_type_mode(ent->type));
	}

	if ((is_compound_type(ent->type)) &&
		(var == variability_uninitialized) && (ent->variability != variability_uninitialized)) {
		/* Free data structures for constant values */
		DEL_ARR_F(ent->attr.cmpd_attr.values);    ent->attr.cmpd_attr.values    = NULL;
		DEL_ARR_F(ent->attr.cmpd_attr.val_paths); ent->attr.cmpd_attr.val_paths = NULL;
	}
	ent->variability = var;
}  /* set_entity_variability */
467

468
/* return the name of the variability */
469
const char *get_variability_name(ir_variability var)
470
{
471
#define X(a)    case a: return #a
472
473
474
475
476
	switch (var) {
	X(variability_uninitialized);
	X(variability_initialized);
	X(variability_part_constant);
	X(variability_constant);
477
    default: return "BAD VALUE";
478
	}
479
#undef X
480
}  /* get_variability_name */
Götz Lindenmaier's avatar
a    
Götz Lindenmaier committed
481

482
ir_volatility
Michael Beck's avatar
Michael Beck committed
483
(get_entity_volatility)(const ir_entity *ent) {
484
485
	return _get_entity_volatility(ent);
}  /* get_entity_volatility */
Götz Lindenmaier's avatar
a    
Götz Lindenmaier committed
486

487
void
Michael Beck's avatar
Michael Beck committed
488
(set_entity_volatility)(ir_entity *ent, ir_volatility vol) {
489
490
	_set_entity_volatility(ent, vol);
}  /* set_entity_volatility */
Götz Lindenmaier's avatar
a    
Götz Lindenmaier committed
491

Michael Beck's avatar
Michael Beck committed
492
/* Return the name of the volatility. */
493
const char *get_volatility_name(ir_volatility var)
494
{
495
#define X(a)    case a: return #a
496
497
498
	switch (var) {
	X(volatility_non_volatile);
	X(volatility_is_volatile);
499
    default: return "BAD VALUE";
500
	}
501
#undef X
502
}  /* get_volatility_name */
503

504
505
506
507
508
509
510
511
512
513
ir_align
(get_entity_align)(const ir_entity *ent) {
	return _get_entity_align(ent);
}  /* get_entity_align */

void
(set_entity_align)(ir_entity *ent, ir_align a) {
	_set_entity_align(ent, a);
}  /* set_entity_align */

Michael Beck's avatar
Michael Beck committed
514
515
516
517
518
519
520
/* Return the name of the alignment. */
const char *get_align_name(ir_align a)
{
#define X(a)    case a: return #a
	switch (a) {
	X(align_non_aligned);
	X(align_is_aligned);
521
	default: return "BAD VALUE";
Michael Beck's avatar
Michael Beck committed
522
523
524
525
	}
#undef X
}  /* get_align_name */

526
ir_peculiarity
Michael Beck's avatar
Michael Beck committed
527
(get_entity_peculiarity)(const ir_entity *ent) {
528
529
	return _get_entity_peculiarity(ent);
}  /* get_entity_peculiarity */
530

531
void
Michael Beck's avatar
Michael Beck committed
532
(set_entity_peculiarity)(ir_entity *ent, ir_peculiarity pec) {
533
534
	_set_entity_peculiarity(ent, pec);
}  /* set_entity_peculiarity */
535

536
/* Checks if an entity cannot be overridden anymore. */
Michael Beck's avatar
Michael Beck committed
537
538
539
int (is_entity_final)(const ir_entity *ent) {
	return _is_entity_final(ent);
}  /* is_entity_final */
540
541

/* Sets/resets the final flag of an entity. */
Michael Beck's avatar
Michael Beck committed
542
void (set_entity_final)(ir_entity *ent, int final) {
Michael Beck's avatar
Michael Beck committed
543
544
	_set_entity_final(ent, final);
}  /* set_entity_final */
545

546
/* Checks if an entity is compiler generated */
Michael Beck's avatar
Michael Beck committed
547
548
int (is_entity_compiler_generated)(const ir_entity *ent) {
	return _is_entity_compiler_generated(ent);
549
}  /* is_entity_compiler_generated */
550
551

/* Sets/resets the compiler generated flag */
Michael Beck's avatar
Michael Beck committed
552
553
void (set_entity_compiler_generated)(ir_entity *ent, int flag) {
	_set_entity_compiler_generated(ent, flag);
554
}  /* set_entity_compiler_generated */
555

Michael Beck's avatar
Michael Beck committed
556
557
558
559
560
561
562
563
564
565
/* Checks if an entity is marked by the backend */
int (is_entity_backend_marked)(const ir_entity *ent) {
	return _is_entity_backend_marked(ent);
}  /* is_entity_backend_marked */

/* Sets/resets the compiler generated flag */
void (set_entity_backend_marked)(ir_entity *ent, int flag) {
	_set_entity_backend_marked(ent, flag);
}  /* set_entity_backend_marked */

566
567
568
ir_entity_usage (get_entity_usage)(const ir_entity *ent) {
	return _get_entity_usage(ent);
}
Michael Beck's avatar
Michael Beck committed
569

570
571
572
void (set_entity_usage)(ir_entity *ent, ir_entity_usage flags) {
	_set_entity_usage(ent, flags);
}
573

Michael Beck's avatar
Michael Beck committed
574
/* Get the entity's stickyness */
575
ir_stickyness
Michael Beck's avatar
Michael Beck committed
576
(get_entity_stickyness)(const ir_entity *ent) {
577
578
	return _get_entity_stickyness(ent);
}  /* get_entity_stickyness */
579

Michael Beck's avatar
Michael Beck committed
580
581
/* Set the entity's stickyness */
void
Michael Beck's avatar
Michael Beck committed
582
(set_entity_stickyness)(ir_entity *ent, ir_stickyness stickyness) {
583
584
	_set_entity_stickyness(ent, stickyness);
}  /* set_entity_stickyness */
585

Götz Lindenmaier's avatar
Götz Lindenmaier committed
586
/* Set has no effect for existent entities of type method. */
587
ir_node *
Michael Beck's avatar
Michael Beck committed
588
get_atomic_ent_value(ir_entity *ent)
589
{
590
591
592
593
	assert(ent && is_atomic_entity(ent));
	assert(ent->variability != variability_uninitialized);
	return skip_Id(ent->value);
}  /* get_atomic_ent_value */
594

595
void
Michael Beck's avatar
Michael Beck committed
596
set_atomic_ent_value(ir_entity *ent, ir_node *val) {
597
598
599
	assert(is_atomic_entity(ent) && (ent->variability != variability_uninitialized));
	if (is_Method_type(ent->type) && (ent->peculiarity == peculiarity_existent))
		return;
600
	assert(is_Dummy(val) || get_irn_mode(val) == get_type_mode(ent->type));
601
602
	ent->value = val;
}  /* set_atomic_ent_value */
603

Matthias Heil's avatar
Matthias Heil committed
604
605
606
/* Returns true if the the node is representable as code on
 *  const_code_irg. */
int is_irn_const_expression(ir_node *n) {
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
	ir_mode *m;

	/* we are in danger iff an exception will arise. TODO: be more precisely,
	 * for instance Div. will NOT rise if divisor != 0
	 */
	if (is_binop(n) && !is_fragile_op(n))
		return is_irn_const_expression(get_binop_left(n)) && is_irn_const_expression(get_binop_right(n));

	m = get_irn_mode(n);
	switch (get_irn_opcode(n)) {
	case iro_Const:
	case iro_SymConst:
	case iro_Unknown:
		return 1;
	case iro_Conv:
	case iro_Cast:
		return is_irn_const_expression(get_irn_n(n, 0));
	default:
		break;
	}
	return 0;
}  /* is_irn_const_expression */
Matthias Heil's avatar
Matthias Heil committed
629

630
631
632
633
634
/*
 * Copies a firm subgraph that complies to the restrictions for
 * constant expressions to current_block in current_ir_graph.
 */
ir_node *copy_const_value(dbg_info *dbg, ir_node *n) {
635
636
637
638
639
640
641
642
643
	ir_node *nn;
	ir_mode *m;

	/* @@@ GL I think  we should implement this using the routines from irgopt for
	       dead node elimination/inlineing. */

	m = get_irn_mode(n);
	switch (get_irn_opcode(n)) {
	case iro_Const:
644
		nn = new_d_Const_type(dbg, get_Const_tarval(n), get_Const_type(n));
645
646
		break;
	case iro_SymConst:
647
		nn = new_d_SymConst_type(dbg, get_irn_mode(n), get_SymConst_symbol(n), get_SymConst_kind(n),
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
			get_SymConst_value_type(n));
		break;
	case iro_Add:
		nn = new_d_Add(dbg, copy_const_value(dbg, get_Add_left(n)),
			copy_const_value(dbg, get_Add_right(n)), m); break;
	case iro_Sub:
		nn = new_d_Sub(dbg, copy_const_value(dbg, get_Sub_left(n)),
			copy_const_value(dbg, get_Sub_right(n)), m); break;
	case iro_Mul:
		nn = new_d_Mul(dbg, copy_const_value(dbg, get_Mul_left(n)),
			copy_const_value(dbg, get_Mul_right(n)), m); break;
	case iro_And:
		nn = new_d_And(dbg, copy_const_value(dbg, get_And_left(n)),
			copy_const_value(dbg, get_And_right(n)), m); break;
	case iro_Or:
		nn = new_d_Or(dbg, copy_const_value(dbg, get_Or_left(n)),
			copy_const_value(dbg, get_Or_right(n)), m); break;
	case iro_Eor:
		nn = new_d_Eor(dbg, copy_const_value(dbg, get_Eor_left(n)),
			copy_const_value(dbg, get_Eor_right(n)), m); break;
	case iro_Cast:
		nn = new_d_Cast(dbg, copy_const_value(dbg, get_Cast_op(n)), get_Cast_type(n)); break;
	case iro_Conv:
		nn = new_d_Conv(dbg, copy_const_value(dbg, get_Conv_op(n)), m); break;
	case iro_Unknown:
		nn = new_d_Unknown(m); break;
	default:
		assert(0 && "opcode invalid or not implemented");
		nn = NULL;
		break;
	}
	return nn;
}  /* copy_const_value */
681

682
683
684
685
686
687
688
689
690
691
692
693
694
695
/** Return the name of the initializer kind. */
const char *get_initializer_kind_name(ir_initializer_kind_t ini)
{
#define X(a)    case a: return #a
	switch (ini) {
	X(IR_INITIALIZER_CONST);
	X(IR_INITIALIZER_TARVAL);
	X(IR_INITIALIZER_NULL);
	X(IR_INITIALIZER_COMPOUND);
    default: return "BAD VALUE";
	}
#undef X
}

696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
static ir_initializer_t null_initializer = { IR_INITIALIZER_NULL };

ir_initializer_t *get_initializer_null(void)
{
	return &null_initializer;
}

ir_initializer_t *create_initializer_const(ir_node *value)
{
	struct obstack *obst = get_irg_obstack(get_const_code_irg());

	ir_initializer_t *initializer
		= obstack_alloc(obst, sizeof(ir_initializer_const_t));
	initializer->kind         = IR_INITIALIZER_CONST;
	initializer->consti.value = value;

	return initializer;
}

ir_initializer_t *create_initializer_tarval(tarval *tv)
{
	struct obstack *obst = get_irg_obstack(get_const_code_irg());

	ir_initializer_t *initializer
		= obstack_alloc(obst, sizeof(ir_initializer_tarval_t));
	initializer->kind         = IR_INITIALIZER_TARVAL;
	initializer->tarval.value = tv;

	return initializer;
}

ir_initializer_t *create_initializer_compound(unsigned n_entries)
{
	struct obstack *obst = get_irg_obstack(get_const_code_irg());

	size_t i;
Michael Beck's avatar
Michael Beck committed
732
733
	size_t size  = sizeof(ir_initializer_compound_t)
	             + (n_entries-1) * sizeof(ir_initializer_t*);
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748

	ir_initializer_t *initializer = obstack_alloc(obst, size);
	initializer->kind                    = IR_INITIALIZER_COMPOUND;
	initializer->compound.n_initializers = n_entries;

	for(i = 0; i < n_entries; ++i) {
		initializer->compound.initializers[i] = get_initializer_null();
	}

	return initializer;
}

ir_node *get_initializer_const_value(const ir_initializer_t *initializer)
{
	assert(initializer->kind == IR_INITIALIZER_CONST);
749
	return skip_Id(initializer->consti.value);
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
}

tarval *get_initializer_tarval_value(const ir_initializer_t *initializer)
{
	assert(initializer->kind == IR_INITIALIZER_TARVAL);
	return initializer->tarval.value;
}

unsigned get_initializer_compound_n_entries(const ir_initializer_t *initializer)
{
	assert(initializer->kind == IR_INITIALIZER_COMPOUND);
	return initializer->compound.n_initializers;
}

void set_initializer_compound_value(ir_initializer_t *initializer,
                                    unsigned index, ir_initializer_t *value)
{
	assert(initializer->kind == IR_INITIALIZER_COMPOUND);
	assert(index < initializer->compound.n_initializers);

	initializer->compound.initializers[index] = value;
}

ir_initializer_t *get_initializer_compound_value(
		const ir_initializer_t *initializer, unsigned index)
{
	assert(initializer->kind == IR_INITIALIZER_COMPOUND);
	assert(index < initializer->compound.n_initializers);

	return initializer->compound.initializers[index];
}

ir_initializer_kind_t get_initializer_kind(const ir_initializer_t *initializer)
{
	return initializer->kind;
}

static void check_entity_initializer(ir_entity *entity)
{
	/* TODO */
	(void) entity;
}

void set_entity_initializer(ir_entity *entity, ir_initializer_t *initializer)
{
	entity->attr.initializer = initializer;
	entity->has_initializer  = 1;
	check_entity_initializer(entity);
}

800
801
802
803
804
int has_entity_initializer(const ir_entity *entity)
{
	return entity->has_initializer;
}

805
806
807
808
809
810
ir_initializer_t *get_entity_initializer(const ir_entity *entity)
{
	assert(entity->has_initializer);
	return entity->attr.initializer;
}

Michael Beck's avatar
Michael Beck committed
811
/* Creates a new compound graph path. */
812
compound_graph_path *
813
new_compound_graph_path(ir_type *tp, int length) {
814
	compound_graph_path *res;
Michael Beck's avatar
Michael Beck committed
815

816
817
	assert(is_compound_type(tp));
	assert(length > 0);
818

819
820
821
822
823
	res = xmalloc(sizeof(*res) + (length-1) * sizeof(res->list[0]));
	memset(res, 0, sizeof(*res) + (length-1) * sizeof(res->list[0]));
	res->kind         = k_ir_compound_graph_path;
	res->tp           = tp;
	res->len          = length;
Michael Beck's avatar
Michael Beck committed
824

825
826
	return res;
}  /* new_compound_graph_path */
827

Michael Beck's avatar
Michael Beck committed
828
829
/* Frees an graph path object */
void free_compound_graph_path (compound_graph_path *gr) {
830
831
832
833
	assert(gr && is_compound_graph_path(gr));
	gr->kind = k_BAD;
	free(gr);
}  /* free_compound_graph_path */
834

Michael Beck's avatar
Michael Beck committed
835
/* Returns non-zero if an object is a compound graph path */
836
int is_compound_graph_path(const void *thing) {
837
838
	return (get_kind(thing) == k_ir_compound_graph_path);
}  /* is_compound_graph_path */
839

Michael Beck's avatar
Michael Beck committed
840
841
/* Checks whether the path up to pos is correct. If the path contains a NULL,
 *  assumes the path is not complete and returns 'true'. */
842
int is_proper_compound_graph_path(compound_graph_path *gr, int pos) {
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
	int i;
	ir_entity *node;
	ir_type *owner = gr->tp;

	for (i = 0; i <= pos; i++) {
		node = get_compound_graph_path_node(gr, i);
		if (node == NULL)
			/* Path not yet complete. */
			return 1;
		if (get_entity_owner(node) != owner)
			return 0;
		owner = get_entity_type(node);
	}
	if (pos == get_compound_graph_path_length(gr))
		if (!is_atomic_type(owner))
			return 0;
		return 1;
}  /* is_proper_compound_graph_path */
861

Michael Beck's avatar
Michael Beck committed
862
/* Returns the length of a graph path */
863
int get_compound_graph_path_length(const compound_graph_path *gr) {
864
865
866
	assert(gr && is_compound_graph_path(gr));
	return gr->len;
}  /* get_compound_graph_path_length */
867

Michael Beck's avatar
Michael Beck committed
868
ir_entity *
869
get_compound_graph_path_node(const compound_graph_path *gr, int pos) {
870
871
872
873
	assert(gr && is_compound_graph_path(gr));
	assert(pos >= 0 && pos < gr->len);
	return gr->list[pos].node;
}  /* get_compound_graph_path_node */
874

875
void
Michael Beck's avatar
Michael Beck committed
876
set_compound_graph_path_node(compound_graph_path *gr, int pos, ir_entity *node) {
877
878
879
880
881
882
	assert(gr && is_compound_graph_path(gr));
	assert(pos >= 0 && pos < gr->len);
	assert(is_entity(node));
	gr->list[pos].node = node;
	assert(is_proper_compound_graph_path(gr, pos));
}  /* set_compound_graph_path_node */
883

884
int
885
get_compound_graph_path_array_index(const compound_graph_path *gr, int pos) {
886
887
888
889
	assert(gr && is_compound_graph_path(gr));
	assert(pos >= 0 && pos < gr->len);
	return gr->list[pos].index;
}  /* get_compound_graph_path_array_index */
890
891
892

void
set_compound_graph_path_array_index(compound_graph_path *gr, int pos, int index) {
893
894
895
896
	assert(gr && is_compound_graph_path(gr));
	assert(pos >= 0 && pos < gr->len);
	gr->list[pos].index = index;
}  /* set_compound_graph_path_array_index */
897

898
899
900
901
902
903
ir_type *
get_compound_graph_path_type(const compound_graph_path *gr) {
	assert(gr && is_compound_graph_path(gr));
	return gr->tp;
}

904
/* A value of a compound entity is a pair of value and the corresponding path to a member of
905
   the compound. */
906
void
Michael Beck's avatar
Michael Beck committed
907
add_compound_ent_value_w_path(ir_entity *ent, ir_node *val, compound_graph_path *path) {
908
909
910
911
912
	assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
	assert(is_compound_graph_path(path));
	ARR_APP1(ir_node *, ent->attr.cmpd_attr.values, val);
	ARR_APP1(compound_graph_path *, ent->attr.cmpd_attr.val_paths, path);
}  /* add_compound_ent_value_w_path */
913

914
void
Michael Beck's avatar
Michael Beck committed
915
set_compound_ent_value_w_path(ir_entity *ent, ir_node *val, compound_graph_path *path, int pos) {
916
917
918
919
920
921
	assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
	assert(is_compound_graph_path(path));
	assert(0 <= pos && pos < ARR_LEN(ent->attr.cmpd_attr.values));
	ent->attr.cmpd_attr.values[pos]    = val;
	ent->attr.cmpd_attr.val_paths[pos] = path;
}  /* set_compound_ent_value_w_path */
922

923
int
Michael Beck's avatar
Michael Beck committed
924
get_compound_ent_n_values(ir_entity *ent) {
925
	assert(!ent->has_initializer);
926
927
928
	assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
	return ARR_LEN(ent->attr.cmpd_attr.values);
}  /* get_compound_ent_n_values */
929

Michael Beck's avatar
Michael Beck committed
930
ir_node *
Michael Beck's avatar
Michael Beck committed
931
get_compound_ent_value(ir_entity *ent, int pos) {
932
	assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
933
	assert(!ent->has_initializer);
934
	assert(0 <= pos && pos < ARR_LEN(ent->attr.cmpd_attr.values));
935
	return skip_Id(ent->attr.cmpd_attr.values[pos]);
936
}  /* get_compound_ent_value */
937

938
compound_graph_path *
Michael Beck's avatar
Michael Beck committed
939
get_compound_ent_value_path(ir_entity *ent, int pos) {
940
	assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
941
	assert(!ent->has_initializer);
942
943
944
	assert(0 <= pos && pos < ARR_LEN(ent->attr.cmpd_attr.val_paths));
	return ent->attr.cmpd_attr.val_paths[pos];
}  /* get_compound_ent_value_path */
945

Michael Beck's avatar
Michael Beck committed
946
947
/**
 * Returns non-zero, if two compound_graph_pathes are equal
948
949
950
 *
 * @param path1            the first path
 * @param path2            the second path
Michael Beck's avatar
Michael Beck committed
951
 */
Michael Beck's avatar
Michael Beck committed
952
static int equal_paths(compound_graph_path *path1, compound_graph_path *path2) {
953
954
955
	int i;
	int len1 = get_compound_graph_path_length(path1);
	int len2 = get_compound_graph_path_length(path2);
956

957
958
959
960
961
962
963
964
965
966
967
	if (len2 != len1) return 0;

	for (i = 0; i < len1; i++) {
		ir_type *tp;
		ir_entity *node1 = get_compound_graph_path_node(path1, i);
		ir_entity *node2 = get_compound_graph_path_node(path2, i);

		if (node1 != node2) return 0;

		tp = get_entity_owner(node1);
		if (is_Array_type(tp)) {
Michael Beck's avatar
Michael Beck committed
968
969
970
			int index1 = get_compound_graph_path_array_index(path1, i);
			int index2 = get_compound_graph_path_array_index(path2, i);
			if (index1 != index2)
971
972
973
974
975
976
977
978
979
980
				return 0;
		}
	}
	return 1;
}  /* equal_paths */

/**
 * Returns the position of a value with the given path.
 * The path must contain array indices for all array element entities.
 *
Michael Beck's avatar
Michael Beck committed
981
982
 * @todo  This implementation is very slow (O(number of initializers * |path|)
 *        and should be replaced when the new tree oriented
983
984
985
986
987
988
 *        value representation is finally implemented.
 */
static int get_compound_ent_pos_by_path(ir_entity *ent, compound_graph_path *path) {
	int i, n_paths = get_compound_ent_n_values(ent);

	for (i = 0; i < n_paths; i ++) {
Michael Beck's avatar
Michael Beck committed
989
990
		compound_graph_path *gr = get_compound_ent_value_path(ent, i);
		if (equal_paths(gr, path))
991
992
993
994
			return i;
	}
	return -1;
}  /* get_compound_ent_pos_by_path */
995
996

/* Returns a constant value given the access path.
997
 *  The path must contain array indices for all array element entities. */
Michael Beck's avatar
Michael Beck committed
998
ir_node *get_compound_ent_value_by_path(ir_entity *ent, compound_graph_path *path) {
Michael Beck's avatar
Michael Beck committed
999
1000
1001
1002
	int pos = get_compound_ent_pos_by_path(ent, path);
	if (pos >= 0)
		return get_compound_ent_value(ent, pos);
	return NULL;
1003
}  /* get_compound_ent_value_by_path */
1004
1005


1006
void
Michael Beck's avatar
Michael Beck committed
1007
remove_compound_ent_value(ir_entity *ent, ir_entity *value_ent) {
1008
	int i, n;
1009
	assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
1010
1011
1012

	n = ARR_LEN(ent->attr.cmpd_attr.val_paths);
	for (i = 0; i < n; ++i) {
1013
1014
		compound_graph_path *path = ent->attr.cmpd_attr.val_paths[i];
		if (path->list[path->len-1].node == value_ent) {
1015
			for (; i < n - 1; ++i) {
1016
1017
1018
				ent->attr.cmpd_attr.val_paths[i] = ent->attr.cmpd_attr.val_paths[i+1];
				ent->attr.cmpd_attr.values[i]    = ent->attr.cmpd_attr.values[i+1];
			}
1019
1020
			ARR_SETLEN(ir_entity*, ent->attr.cmpd_attr.val_paths, n - 1);
			ARR_SETLEN(ir_node*,   ent->attr.cmpd_attr.values,    n - 1);
1021
1022
1023
1024
			break;
		}
	}
}  /* remove_compound_ent_value */
1025

1026
void
Michael Beck's avatar
Michael Beck committed
1027
add_compound_ent_value(ir_entity *ent, ir_node *val, ir_entity *member) {
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
	compound_graph_path *path;
	ir_type *owner_tp = get_entity_owner(member);
	assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
	path = new_compound_graph_path(get_entity_type(ent), 1);
	path->list[0].node = member;
	if (is_Array_type(owner_tp)) {
		int max;
		int i, n;

		assert(get_array_n_dimensions(owner_tp) == 1 && has_array_lower_bound(owner_tp, 0));
		max = get_array_lower_bound_int(owner_tp, 0) -1;
		for (i = 0, n = get_compound_ent_n_values(ent); i < n; ++i) {
			int index = get_compound_graph_path_array_index(get_compound_ent_value_path(ent, i), 0);
			if (index > max) {
				max = index;
			}
		}
		path->list[0].index = max + 1;
	}
	add_compound_ent_value_w_path(ent, val, path);
}  /* add_compound_ent_value */
Boris Boesler's avatar
Boris Boesler committed
1049

1050

1051
ir_entity *
Michael Beck's avatar
Michael Beck committed
1052
get_compound_ent_value_member(ir_entity *ent, int pos) {
1053
1054
1055
	compound_graph_path *path;
	assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
	path = get_compound_ent_value_path(ent, pos);
1056