entity_t.h 16.2 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
2
/*
 * This file is part of libFirm.
3
 * Copyright (C) 2012 University of Karlsruhe.
Christian Würdig's avatar
Christian Würdig committed
4
5
 */

6
/**
7
 * @file
Michael Beck's avatar
Michael Beck committed
8
9
 * @brief   Representation of all program known entities -- private header.
 * @author  Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Michael Beck
10
 */
Michael Beck's avatar
Michael Beck committed
11
12
#ifndef FIRM_TR_ENTITY_T_H
#define FIRM_TR_ENTITY_T_H
Götz Lindenmaier's avatar
Götz Lindenmaier committed
13

14
#include <assert.h>
15
#include <stdbool.h>
16
#include <stdint.h>
17

18
#include "compiler.h"
19
#include "typerep.h"
Michael Beck's avatar
Michael Beck committed
20
#include "type_t.h"
21
#include "ident.h"
22

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#define get_entity_name(ent)                     _get_entity_name(ent)
#define get_entity_ident(ent)                    _get_entity_ident(ent)
#define set_entity_ident(ent, id)                _set_entity_ident(ent, id)
#define get_entity_owner(ent)                    _get_entity_owner(ent)
#define get_entity_ld_ident(ent)                 _get_entity_ld_ident(ent)
#define set_entity_ld_ident(ent, ld_ident)       _set_entity_ld_ident(ent, ld_ident)
#define get_entity_ld_name(ent)                  _get_entity_ld_name(ent)
#define get_entity_type(ent)                     _get_entity_type(ent)
#define get_entity_linkage(ent)                  _get_entity_linkage(ent)
#define get_entity_volatility(ent)               _get_entity_volatility(ent)
#define set_entity_volatility(ent, vol)          _set_entity_volatility(ent, vol)
#define set_entity_alignment(ent, alignment)     _set_entity_alignment(ent, alignment)
#define get_entity_alignment(ent)                _get_entity_alignment(ent)
#define get_entity_align(ent)                    _get_entity_align(ent)
#define set_entity_align(ent, a)                 _set_entity_align(ent, a)
#define is_entity_compiler_generated(ent)        _is_entity_compiler_generated(ent)
#define set_entity_compiler_generated(ent, flag) _set_entity_compiler_generated(ent, flag)
#define get_entity_usage(ent)                    _get_entity_usage(ent)
#define set_entity_usage(ent, flags)             _set_entity_usage(ent, flags)
42
#define get_entity_initializer(ent)              _get_entity_initializer(ent)
43
44
#define get_entity_offset(ent)                   _get_entity_offset(ent)
#define set_entity_offset(ent, offset)           _set_entity_offset(ent, offset)
45
46
47
48
#define get_entity_bitfield_offset(ent)          _get_entity_bitfield_offset(ent)
#define set_entity_bitfield_offset(ent, o)       _set_entity_bitfield_offset(ent, o)
#define get_entity_bitfield_size(ent)            _get_entity_bitfield_size(ent)
#define set_entity_bitfield_size(ent, s)         _set_entity_bitfield_size(ent, s)
49
50
51
#define get_entity_link(ent)                     _get_entity_link(ent)
#define set_entity_link(ent, l)                  _set_entity_link(ent, l)
#define get_entity_irg(ent)                      _get_entity_irg(ent)
52
#define get_entity_linktime_irg(ent)             _get_entity_linktime_irg(ent)
53
54
55
56
57
58
59
60
61
62
#define is_parameter_entity(ent)                 _is_parameter_entity(ent)
#define get_entity_parameter_number(ent)         _get_entity_parameter_number(ent)
#define get_entity_visited(ent)                  _get_entity_visited(ent)
#define set_entity_visited(ent, num)             _set_entity_visited(ent, num)
#define mark_entity_visited(ent)                 _mark_entity_visited(ent)
#define entity_visited(ent)                      _entity_visited(ent)
#define entity_not_visited(ent)                  _entity_not_visited(ent)
#define get_entity_dbg_info(ent)                 _get_entity_dbg_info(ent)
#define set_entity_dbg_info(ent, db)             _set_entity_dbg_info(ent, db)

63
64
65
66
typedef struct ir_initializer_base_t {
	ir_initializer_kind_t kind;
} ir_initializer_base_t;

Michael Beck's avatar
Michael Beck committed
67
68
69
/**
 * An compound initializer.
 */
70
71
typedef struct ir_initializer_compound_t {
	ir_initializer_base_t  base;
72
	size_t                 n_initializers;
73
74
75
	ir_initializer_t      *initializers[1];
} ir_initializer_compound_t;

Michael Beck's avatar
Michael Beck committed
76
77
78
/**
 * An initializer containing an ir_node,
 */
79
80
81
82
83
typedef struct ir_initializer_const_t {
	ir_initializer_base_t  base;
	ir_node               *value;
} ir_initializer_const_t ;

Michael Beck's avatar
Michael Beck committed
84
85
86
/**
 * An initializer containing a tarval.
 */
87
88
typedef struct ir_initializer_tarval_t {
	ir_initializer_base_t  base;
Matthias Braun's avatar
Matthias Braun committed
89
	ir_tarval             *value;
90
91
92
93
94
95
96
97
98
99
} ir_initializer_tarval_t ;

union ir_initializer_t {
	ir_initializer_kind_t      kind;
	ir_initializer_base_t      base;
	ir_initializer_compound_t  compound;
	ir_initializer_const_t     consti;
	ir_initializer_tarval_t    tarval;
};

100
101
102
103
typedef struct normal_ent_attr {
	ir_initializer_t *initializer; /**< entity initializer */
} normal_ent_attr;

104
/** The attributes for methods. */
105
typedef struct method_ent_attr {
106
107
108
	mtp_additional_properties properties; /**< Additional graph properties can
											   be stored in a entity if no irg
											   is available. Must be first. */
109
110
111
112
113
114
115
	ir_graph *irg;                 /**< The corresponding irg if known.
	                                    The ir_graph constructor automatically sets this field. */

	unsigned vtable_number;        /**< For a dynamically called method, the number assigned
	                                    in the virtual function table. */

	ptr_access_kind *param_access; /**< the parameter access */
116
117
	unsigned *param_weight;        /**< The weight of method's parameters. Parameters
	                                    with a high weight are good candidates for procedure cloning. */
118
119
} method_ent_attr;

120
121
122
123
124
/** additional attributes for code entities */
typedef struct code_ent_attr {
	ir_label_t  label;       /** label of the basic block */
} code_ent_attr;

125
126
127
128
129
130
131
132
typedef struct compound_member_ent_attr {
	int offset;               /**< Offset in bytes for this entity. Fixed
	                               when layout of owner is determined. */
	unsigned bitfield_offset; /**< for bitfields: offset in bits from base */
	unsigned bitfield_size;   /**< for bitfields: size of entity in bits,
	                               0 if entity is not a bitfield. */
} compound_member_ent_attr;

133
typedef struct parameter_ent_attr {
134
135
	compound_member_ent_attr  base; /**< a parameter is also a compound_member
	                                     of the frame type. */
136
137
138
139
140
141
142
143
144
145
	size_t   number; /**< corresponding parameter number */
	ir_mode *doubleword_low_mode;/**< entity is a lowered doubleword parameter,
								so additional stores because of calling
								convention are correctly performed.
	                            Matze: This is a hack. In an ideal
	                            wor^H^H^Hlibfirm we would first establish
	                            calling conventions and then perform doubleword
	                            lowering...) */
} parameter_ent_attr;

146
typedef struct alias_ent_attr {
147
148
149
	mtp_additional_properties properties; /**< Additional graph properties can
											   be stored in a entity if no irg
											   is available. Must be first. */
150
151
152
	ir_entity                *aliased;
} alias_ent_attr;

Matthias Braun's avatar
Matthias Braun committed
153
154
155
156
typedef struct got_ent_attr {
	ir_entity *referenced;
} got_ent_attr;

Matthias Braun's avatar
Matthias Braun committed
157
typedef enum ir_entity_kind {
158
	IR_ENTITY_ALIAS,
Matthias Braun's avatar
Matthias Braun committed
159
160
	IR_ENTITY_COMPOUND_MEMBER,
	IR_ENTITY_LABEL,
161
162
163
	IR_ENTITY_METHOD,
	IR_ENTITY_NORMAL,
	IR_ENTITY_PARAMETER,
164
	IR_ENTITY_UNKNOWN,
Matthias Braun's avatar
Matthias Braun committed
165
	IR_ENTITY_GOTENTRY,
Matthias Braun's avatar
Matthias Braun committed
166
} ir_entity_kind;
167

Michael Beck's avatar
Michael Beck committed
168
169
170
/**
 * An abstract data type to represent program entities.
 */
Michael Beck's avatar
Michael Beck committed
171
struct ir_entity {
172
173
174
175
176
177
178
179
	firm_kind kind;          /**< The dynamic type tag for entity. */
	ident *name;             /**< The name of this entity. */
	ident *ld_name;          /**< Unique name of this entity, i.e., the mangled
	                              name. May be NULL to indicate that a default
	                              mangling based on the name should happen */
	ir_type *type;           /**< The type of this entity */
	ir_type *owner;          /**< The compound type (e.g. class type) this
							      entity belongs to. */
180
181
182
183
184
185
186
187
	ENUMBF(ir_entity_kind)  entity_kind:3; /**< entity kind */
	ENUMBF(ir_linkage)      linkage:6;     /**< Linkage type */
	ENUMBF(ir_volatility)   volatility:1;  /**< Volatility of entity content.*/
	ENUMBF(ir_align)        aligned:1;     /**< Alignment of entity content. */
	ENUMBF(ir_entity_usage) usage:4;       /**< Usage type of entity */
	ENUMBF(ir_visibility)   visibility:2;  /**< Visibility of entity. */
	bool compiler_gen:1; /**< If set, this entity was compiler generated. */
	uint16_t                alignment;     /**< entity alignment in bytes */
188
189
190
191
192
193
194
195
196
197
198
199
200
201
	ir_visited_t visit;      /**< visited counter for walks of the type
	                              information. */
	struct dbg_info *dbi;    /**< A pointer to information for debug support. */
	void *link;              /**< To store some intermediate information. */

	ir_entity **overwrites;  /**< A list of entities this entity overwrites. */
	ir_entity **overwrittenby; /**< A list of entities that overwrite this
	                                entity. */

#ifdef DEBUG_libfirm
	long nr;             /**< A unique node number for each node to make output
	                          readable. */
#endif

202
	union {
203
204
		/** attributes for normal entities */
		normal_ent_attr          normal;
205
206
207
208
209
210
		/** attributes for method entities */
		method_ent_attr          mtd_attr;
		/** fields for code entities */
		code_ent_attr            code_attr;
		/** compound member attributes */
		compound_member_ent_attr compound_member;
211
		/** parameter number for parameter entities */
212
		parameter_ent_attr       parameter;
213
214
		/** alias attributes */
		alias_ent_attr           alias;
Matthias Braun's avatar
Matthias Braun committed
215
216
		/** got entry attributes */
		got_ent_attr             got;
217
218
		/** additional properties shared by method+alias entities */
		mtp_additional_properties properties;
219
	} attr; /**< type specific attributes */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
220
221
};

222
/** Initialize the entity module. */
223
void ir_init_entity(ir_prog *irp);
224

Matthias Braun's avatar
Matthias Braun committed
225
226
227
228
229
230
/**
 * Creates an entity corresponding to the start address of a basic block
 * (the basic block is marked with a label id).
 */
ir_entity *new_label_entity(ir_label_t label);

Matthias Braun's avatar
Matthias Braun committed
231
232
233
234
235
236
/**
 * Create an entity representing an entry in the global offset table used for
 * position independent code (PIC) code.
 */
ir_entity *new_got_entry_entity(ir_entity *reference);

237
238
void set_entity_irg(ir_entity *ent, ir_graph *irg);

Michael Beck's avatar
Michael Beck committed
239
/* ----------------------- inline functions ------------------------ */
240
static inline bool is_entity(const void *thing)
241
{
242
	return get_kind(thing) == k_entity;
Michael Beck's avatar
Michael Beck committed
243
244
}

Matthias Braun's avatar
Matthias Braun committed
245
246
247
248
249
static inline ir_entity_kind get_entity_kind(const ir_entity *entity)
{
	return (ir_entity_kind)entity->entity_kind;
}

250
static inline ident *_get_entity_ident(const ir_entity *ent)
251
{
252
	assert(ent->kind == k_entity);
253
	return ent->name;
Michael Beck's avatar
Michael Beck committed
254
255
}

256
static inline const char *_get_entity_name(const ir_entity *ent)
257
{
258
	assert(ent->kind == k_entity);
259
	return get_id_str(get_entity_ident(ent));
Michael Beck's avatar
Michael Beck committed
260
261
}

262
263
static inline void _set_entity_ident(ir_entity *ent, ident *id)
{
264
	assert(ent->kind == k_entity);
265
	ent->name = id;
Michael Beck's avatar
Michael Beck committed
266
267
}

268
269
static inline ir_type *_get_entity_owner(const ir_entity *ent)
{
270
	assert(ent->kind == k_entity);
Matthias Braun's avatar
Matthias Braun committed
271
	return ent->owner;
Michael Beck's avatar
Michael Beck committed
272
273
}

274
static inline ident *_get_entity_ld_ident(const ir_entity *ent)
Michael Beck's avatar
Michael Beck committed
275
{
276
	assert(ent->kind == k_entity);
277
278
279
	if (ent->ld_name)
		return ent->ld_name;
	return ent->name;
Michael Beck's avatar
Michael Beck committed
280
281
}

282
283
static inline void _set_entity_ld_ident(ir_entity *ent, ident *ld_ident)
{
284
	assert(ent->kind == k_entity);
285
	ent->ld_name = ld_ident;
Michael Beck's avatar
Michael Beck committed
286
287
}

288
289
static inline const char *_get_entity_ld_name(const ir_entity *ent)
{
290
	assert(ent->kind == k_entity);
291
	return get_id_str(get_entity_ld_ident(ent));
Michael Beck's avatar
Michael Beck committed
292
293
}

294
295
static inline ir_type *_get_entity_type(const ir_entity *ent)
{
296
	assert(ent->kind == k_entity);
Matthias Braun's avatar
Matthias Braun committed
297
	return ent->type;
Michael Beck's avatar
Michael Beck committed
298
299
}

300
301
static inline ir_linkage _get_entity_linkage(const ir_entity *ent)
{
302
	assert(ent->kind == k_entity);
303
	return (ir_linkage) ent->linkage;
Michael Beck's avatar
Michael Beck committed
304
305
}

306
307
static inline ir_volatility _get_entity_volatility(const ir_entity *ent)
{
308
	assert(ent->kind == k_entity);
309
	return (ir_volatility) ent->volatility;
Michael Beck's avatar
Michael Beck committed
310
311
}

312
313
static inline void _set_entity_volatility(ir_entity *ent, ir_volatility vol)
{
314
	assert(ent->kind == k_entity);
315
	ent->volatility = vol;
Michael Beck's avatar
Michael Beck committed
316
317
}

318
319
static inline unsigned _get_entity_alignment(const ir_entity *ent)
{
320
	assert(ent->kind == k_entity);
Matthias Braun's avatar
Matthias Braun committed
321
322
323
	return ent->alignment;
}

324
325
static inline void _set_entity_alignment(ir_entity *ent, unsigned alignment)
{
326
	assert(ent->kind == k_entity);
Matthias Braun's avatar
Matthias Braun committed
327
328
329
	ent->alignment = alignment;
}

330
331
static inline ir_align _get_entity_aligned(const ir_entity *ent)
{
332
	assert(ent->kind == k_entity);
333
	return (ir_align) ent->aligned;
334
335
}

336
337
static inline void _set_entity_aligned(ir_entity *ent, ir_align a)
{
338
	assert(ent->kind == k_entity);
Matthias Braun's avatar
Matthias Braun committed
339
	ent->aligned = a;
340
341
}

342
343
static inline int _is_entity_compiler_generated(const ir_entity *ent)
{
344
	assert(ent->kind == k_entity);
Michael Beck's avatar
Michael Beck committed
345
346
347
	return ent->compiler_gen;
}

348
349
static inline void _set_entity_compiler_generated(ir_entity *ent, int flag)
{
350
	assert(ent->kind == k_entity);
Michael Beck's avatar
Michael Beck committed
351
352
353
	ent->compiler_gen = flag ? 1 : 0;
}

354
355
static inline ir_entity_usage _get_entity_usage(const ir_entity *ent)
{
356
	assert(ent->kind == k_entity);
357
	return (ir_entity_usage) ent->usage;
Michael Beck's avatar
Michael Beck committed
358
359
}

360
361
static inline void _set_entity_usage(ir_entity *ent, ir_entity_usage state)
{
362
	assert(ent->kind == k_entity);
363
	ent->usage = state;
Michael Beck's avatar
Michael Beck committed
364
365
}

366
367
368
369
370
371
static inline bool is_entity_compound_member(const ir_entity *entity)
{
	return entity->entity_kind == IR_ENTITY_COMPOUND_MEMBER
	    || entity->entity_kind == IR_ENTITY_PARAMETER;
}

372
373
static inline ir_initializer_t *_get_entity_initializer(ir_entity const *const ent)
{
374
375
	assert(ent->entity_kind == IR_ENTITY_NORMAL);
	return ent->attr.normal.initializer;
376
377
}

378
379
static inline int _get_entity_offset(const ir_entity *ent)
{
380
381
382
	assert(ent->entity_kind == IR_ENTITY_COMPOUND_MEMBER
	       || ent->entity_kind == IR_ENTITY_PARAMETER);
	return ent->attr.compound_member.offset;
Michael Beck's avatar
Michael Beck committed
383
384
}

385
386
static inline void _set_entity_offset(ir_entity *ent, int offset)
{
387
388
389
	assert(ent->entity_kind == IR_ENTITY_COMPOUND_MEMBER
	       || ent->entity_kind == IR_ENTITY_PARAMETER);
	ent->attr.compound_member.offset = offset;
Michael Beck's avatar
Michael Beck committed
390
391
}

392
static inline unsigned _get_entity_bitfield_offset(const ir_entity *ent)
393
{
394
395
396
	assert(ent->entity_kind == IR_ENTITY_COMPOUND_MEMBER
	       || ent->entity_kind == IR_ENTITY_PARAMETER);
	return ent->attr.compound_member.bitfield_offset;
Michael Beck's avatar
Michael Beck committed
397
398
}

399
static inline void _set_entity_bitfield_offset(ir_entity *ent, unsigned offset)
400
{
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
	assert(ent->entity_kind == IR_ENTITY_COMPOUND_MEMBER
	       || ent->entity_kind == IR_ENTITY_PARAMETER);
	ent->attr.compound_member.bitfield_offset = offset;
}

static inline unsigned _get_entity_bitfield_size(const ir_entity *entity)
{
	assert(entity->entity_kind == IR_ENTITY_COMPOUND_MEMBER
	       || entity->entity_kind == IR_ENTITY_PARAMETER);
	return entity->attr.compound_member.bitfield_size;
}

static inline void _set_entity_bitfield_size(ir_entity *entity, unsigned size)
{
	assert(entity->entity_kind == IR_ENTITY_COMPOUND_MEMBER
	       || entity->entity_kind == IR_ENTITY_PARAMETER);
	entity->attr.compound_member.bitfield_size = size;
Michael Beck's avatar
Michael Beck committed
418
419
}

420
421
static inline void *_get_entity_link(const ir_entity *ent)
{
422
	assert(ent->kind == k_entity);
423
	return ent->link;
Michael Beck's avatar
Michael Beck committed
424
425
}

426
427
static inline void _set_entity_link(ir_entity *ent, void *l)
{
428
	assert(ent->kind == k_entity);
429
	ent->link = l;
Michael Beck's avatar
Michael Beck committed
430
431
}

432
433
static inline ir_graph *_get_entity_irg(const ir_entity *ent)
{
434
	assert(ent->kind == k_entity);
435
	assert(ent->entity_kind == IR_ENTITY_METHOD);
436
	return ent->attr.mtd_attr.irg;
Michael Beck's avatar
Michael Beck committed
437
438
}

439
440
static inline ir_graph *_get_entity_linktime_irg(const ir_entity *entity)
{
441
	/* weak entities might get replaced by non-weak entities at linktime
442
443
444
	 * so we can't return a definite graph. */
	if (get_entity_linkage(entity) & IR_LINKAGE_WEAK)
		return NULL;
445
446
447
	/* only method entities have an irg field (alias etc. does not) */
	if (entity->entity_kind != IR_ENTITY_METHOD)
		return NULL;
448
449
450
	return get_entity_irg(entity);
}

Matthias Braun's avatar
Matthias Braun committed
451
452
static inline ir_visited_t _get_entity_visited(const ir_entity *ent)
{
453
	assert(ent->kind == k_entity);
454
	return ent->visit;
Michael Beck's avatar
Michael Beck committed
455
456
}

Matthias Braun's avatar
Matthias Braun committed
457
458
static inline void _set_entity_visited(ir_entity *ent, ir_visited_t num)
{
459
	assert(ent->kind == k_entity);
460
	ent->visit = num;
Michael Beck's avatar
Michael Beck committed
461
462
}

Matthias Braun's avatar
Matthias Braun committed
463
464
static inline void _mark_entity_visited(ir_entity *ent)
{
465
	assert(ent->kind == k_entity);
466
	ent->visit = firm_type_visited;
Michael Beck's avatar
Michael Beck committed
467
468
}

Matthias Braun's avatar
Matthias Braun committed
469
470
static inline int _entity_visited(const ir_entity *ent)
{
471
	return _get_entity_visited(ent) >= firm_type_visited;
Michael Beck's avatar
Michael Beck committed
472
473
}

Matthias Braun's avatar
Matthias Braun committed
474
475
static inline int _entity_not_visited(const ir_entity *ent)
{
476
	return _get_entity_visited(ent) < firm_type_visited;
Michael Beck's avatar
Michael Beck committed
477
478
}

479
480
static inline int _is_parameter_entity(const ir_entity *entity)
{
Matthias Braun's avatar
Matthias Braun committed
481
	return entity->entity_kind == IR_ENTITY_PARAMETER;
482
483
484
485
}

static inline size_t _get_entity_parameter_number(const ir_entity *entity)
{
Matthias Braun's avatar
Matthias Braun committed
486
	assert(entity->entity_kind == IR_ENTITY_PARAMETER);
487
488
489
	return entity->attr.parameter.number;
}

Matthias Braun's avatar
Matthias Braun committed
490
491
static inline dbg_info *_get_entity_dbg_info(const ir_entity *ent)
{
492
493
494
	return ent->dbi;
}

Matthias Braun's avatar
Matthias Braun committed
495
496
static inline void _set_entity_dbg_info(ir_entity *ent, dbg_info *db)
{
497
498
499
	ent->dbi = db;
}

Matthias Braun's avatar
Matthias Braun committed
500
#endif