entity_t.h 15.4 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
typedef enum ir_entity_kind {
154
	IR_ENTITY_ALIAS,
Matthias Braun's avatar
Matthias Braun committed
155
156
	IR_ENTITY_COMPOUND_MEMBER,
	IR_ENTITY_LABEL,
157
158
159
	IR_ENTITY_METHOD,
	IR_ENTITY_NORMAL,
	IR_ENTITY_PARAMETER,
160
	IR_ENTITY_UNKNOWN,
Matthias Braun's avatar
Matthias Braun committed
161
} ir_entity_kind;
162

Michael Beck's avatar
Michael Beck committed
163
164
165
/**
 * An abstract data type to represent program entities.
 */
Michael Beck's avatar
Michael Beck committed
166
struct ir_entity {
167
168
169
170
171
172
173
174
	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. */
175
176
177
178
179
180
181
182
	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 */
183
184
	ir_visited_t visit;      /**< visited counter for walks of the type
	                              information. */
185
	dbg_info *dbi;           /**< A pointer to information for debug support. */
186
187
188
189
190
191
192
193
194
195
196
	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

197
	union {
198
199
		/** attributes for normal entities */
		normal_ent_attr          normal;
200
201
202
203
204
205
		/** 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;
206
		/** parameter number for parameter entities */
207
		parameter_ent_attr       parameter;
208
209
		/** alias attributes */
		alias_ent_attr           alias;
210
211
		/** additional properties shared by method+alias entities */
		mtp_additional_properties properties;
212
	} attr; /**< type specific attributes */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
213
214
};

215
/** Initialize the entity module. */
216
void ir_init_entity(ir_prog *irp);
217

Matthias Braun's avatar
Matthias Braun committed
218
219
220
221
222
223
/**
 * 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);

224
225
void set_entity_irg(ir_entity *ent, ir_graph *irg);

Michael Beck's avatar
Michael Beck committed
226
/* ----------------------- inline functions ------------------------ */
227
static inline bool is_entity(const void *thing)
228
{
229
	return get_kind(thing) == k_entity;
Michael Beck's avatar
Michael Beck committed
230
231
}

Matthias Braun's avatar
Matthias Braun committed
232
233
234
235
236
static inline ir_entity_kind get_entity_kind(const ir_entity *entity)
{
	return (ir_entity_kind)entity->entity_kind;
}

237
static inline ident *_get_entity_ident(const ir_entity *ent)
238
{
239
	assert(ent->kind == k_entity);
240
	return ent->name;
Michael Beck's avatar
Michael Beck committed
241
242
}

243
static inline const char *_get_entity_name(const ir_entity *ent)
244
{
245
	assert(ent->kind == k_entity);
246
	return get_id_str(get_entity_ident(ent));
Michael Beck's avatar
Michael Beck committed
247
248
}

249
250
static inline void _set_entity_ident(ir_entity *ent, ident *id)
{
251
	assert(ent->kind == k_entity);
252
	ent->name = id;
Michael Beck's avatar
Michael Beck committed
253
254
}

255
256
static inline ir_type *_get_entity_owner(const ir_entity *ent)
{
257
	assert(ent->kind == k_entity);
Matthias Braun's avatar
Matthias Braun committed
258
	return ent->owner;
Michael Beck's avatar
Michael Beck committed
259
260
}

261
static inline ident *_get_entity_ld_ident(const ir_entity *ent)
Michael Beck's avatar
Michael Beck committed
262
{
263
	assert(ent->kind == k_entity);
264
265
266
	if (ent->ld_name)
		return ent->ld_name;
	return ent->name;
Michael Beck's avatar
Michael Beck committed
267
268
}

269
270
static inline void _set_entity_ld_ident(ir_entity *ent, ident *ld_ident)
{
271
	assert(ent->kind == k_entity);
272
	ent->ld_name = ld_ident;
Michael Beck's avatar
Michael Beck committed
273
274
}

275
276
static inline const char *_get_entity_ld_name(const ir_entity *ent)
{
277
	assert(ent->kind == k_entity);
278
	return get_id_str(get_entity_ld_ident(ent));
Michael Beck's avatar
Michael Beck committed
279
280
}

281
282
static inline ir_type *_get_entity_type(const ir_entity *ent)
{
283
	assert(ent->kind == k_entity);
Matthias Braun's avatar
Matthias Braun committed
284
	return ent->type;
Michael Beck's avatar
Michael Beck committed
285
286
}

287
288
static inline ir_linkage _get_entity_linkage(const ir_entity *ent)
{
289
	assert(ent->kind == k_entity);
290
	return (ir_linkage) ent->linkage;
Michael Beck's avatar
Michael Beck committed
291
292
}

293
294
static inline ir_volatility _get_entity_volatility(const ir_entity *ent)
{
295
	assert(ent->kind == k_entity);
296
	return (ir_volatility) ent->volatility;
Michael Beck's avatar
Michael Beck committed
297
298
}

299
300
static inline void _set_entity_volatility(ir_entity *ent, ir_volatility vol)
{
301
	assert(ent->kind == k_entity);
302
	ent->volatility = vol;
Michael Beck's avatar
Michael Beck committed
303
304
}

305
306
static inline unsigned _get_entity_alignment(const ir_entity *ent)
{
307
	assert(ent->kind == k_entity);
Matthias Braun's avatar
Matthias Braun committed
308
309
310
	return ent->alignment;
}

311
312
static inline void _set_entity_alignment(ir_entity *ent, unsigned alignment)
{
313
	assert(ent->kind == k_entity);
Matthias Braun's avatar
Matthias Braun committed
314
315
316
	ent->alignment = alignment;
}

317
318
static inline ir_align _get_entity_aligned(const ir_entity *ent)
{
319
	assert(ent->kind == k_entity);
320
	return (ir_align) ent->aligned;
321
322
}

323
324
static inline void _set_entity_aligned(ir_entity *ent, ir_align a)
{
325
	assert(ent->kind == k_entity);
Matthias Braun's avatar
Matthias Braun committed
326
	ent->aligned = a;
327
328
}

329
330
static inline int _is_entity_compiler_generated(const ir_entity *ent)
{
331
	assert(ent->kind == k_entity);
Michael Beck's avatar
Michael Beck committed
332
333
334
	return ent->compiler_gen;
}

335
336
static inline void _set_entity_compiler_generated(ir_entity *ent, int flag)
{
337
	assert(ent->kind == k_entity);
Michael Beck's avatar
Michael Beck committed
338
339
340
	ent->compiler_gen = flag ? 1 : 0;
}

341
342
static inline ir_entity_usage _get_entity_usage(const ir_entity *ent)
{
343
	assert(ent->kind == k_entity);
344
	return (ir_entity_usage) ent->usage;
Michael Beck's avatar
Michael Beck committed
345
346
}

347
348
static inline void _set_entity_usage(ir_entity *ent, ir_entity_usage state)
{
349
	assert(ent->kind == k_entity);
350
	ent->usage = state;
Michael Beck's avatar
Michael Beck committed
351
352
}

353
354
355
356
357
358
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;
}

359
360
static inline ir_initializer_t *_get_entity_initializer(ir_entity const *const ent)
{
361
362
	assert(ent->entity_kind == IR_ENTITY_NORMAL);
	return ent->attr.normal.initializer;
363
364
}

365
366
static inline int _get_entity_offset(const ir_entity *ent)
{
367
	assert(is_entity_compound_member(ent));
368
	return ent->attr.compound_member.offset;
Michael Beck's avatar
Michael Beck committed
369
370
}

371
372
static inline void _set_entity_offset(ir_entity *ent, int offset)
{
373
	assert(is_entity_compound_member(ent));
374
	ent->attr.compound_member.offset = offset;
Michael Beck's avatar
Michael Beck committed
375
376
}

377
static inline unsigned _get_entity_bitfield_offset(const ir_entity *ent)
378
{
379
	assert(is_entity_compound_member(ent));
380
	return ent->attr.compound_member.bitfield_offset;
Michael Beck's avatar
Michael Beck committed
381
382
}

383
static inline void _set_entity_bitfield_offset(ir_entity *ent, unsigned offset)
384
{
385
	assert(is_entity_compound_member(ent));
386
387
388
389
390
	ent->attr.compound_member.bitfield_offset = offset;
}

static inline unsigned _get_entity_bitfield_size(const ir_entity *entity)
{
391
	assert(is_entity_compound_member(entity));
392
393
394
395
396
	return entity->attr.compound_member.bitfield_size;
}

static inline void _set_entity_bitfield_size(ir_entity *entity, unsigned size)
{
397
	assert(is_entity_compound_member(entity));
398
	entity->attr.compound_member.bitfield_size = size;
Michael Beck's avatar
Michael Beck committed
399
400
}

401
402
static inline void *_get_entity_link(const ir_entity *ent)
{
403
	assert(ent->kind == k_entity);
404
	return ent->link;
Michael Beck's avatar
Michael Beck committed
405
406
}

407
408
static inline void _set_entity_link(ir_entity *ent, void *l)
{
409
	assert(ent->kind == k_entity);
410
	ent->link = l;
Michael Beck's avatar
Michael Beck committed
411
412
}

413
414
static inline ir_graph *_get_entity_irg(const ir_entity *ent)
{
415
	assert(ent->kind == k_entity);
416
	assert(ent->entity_kind == IR_ENTITY_METHOD);
417
	return ent->attr.mtd_attr.irg;
Michael Beck's avatar
Michael Beck committed
418
419
}

420
421
static inline ir_graph *_get_entity_linktime_irg(const ir_entity *entity)
{
422
	/* weak entities might get replaced by non-weak entities at linktime
423
424
425
	 * so we can't return a definite graph. */
	if (get_entity_linkage(entity) & IR_LINKAGE_WEAK)
		return NULL;
426
427
428
	/* only method entities have an irg field (alias etc. does not) */
	if (entity->entity_kind != IR_ENTITY_METHOD)
		return NULL;
429
430
431
	return get_entity_irg(entity);
}

Matthias Braun's avatar
Matthias Braun committed
432
433
static inline ir_visited_t _get_entity_visited(const ir_entity *ent)
{
434
	assert(ent->kind == k_entity);
435
	return ent->visit;
Michael Beck's avatar
Michael Beck committed
436
437
}

Matthias Braun's avatar
Matthias Braun committed
438
439
static inline void _set_entity_visited(ir_entity *ent, ir_visited_t num)
{
440
	assert(ent->kind == k_entity);
441
	ent->visit = num;
Michael Beck's avatar
Michael Beck committed
442
443
}

Matthias Braun's avatar
Matthias Braun committed
444
445
static inline void _mark_entity_visited(ir_entity *ent)
{
446
	assert(ent->kind == k_entity);
447
	ent->visit = firm_type_visited;
Michael Beck's avatar
Michael Beck committed
448
449
}

Matthias Braun's avatar
Matthias Braun committed
450
451
static inline int _entity_visited(const ir_entity *ent)
{
452
	return _get_entity_visited(ent) >= firm_type_visited;
Michael Beck's avatar
Michael Beck committed
453
454
}

Matthias Braun's avatar
Matthias Braun committed
455
456
static inline int _entity_not_visited(const ir_entity *ent)
{
457
	return _get_entity_visited(ent) < firm_type_visited;
Michael Beck's avatar
Michael Beck committed
458
459
}

460
461
static inline int _is_parameter_entity(const ir_entity *entity)
{
Matthias Braun's avatar
Matthias Braun committed
462
	return entity->entity_kind == IR_ENTITY_PARAMETER;
463
464
465
466
}

static inline size_t _get_entity_parameter_number(const ir_entity *entity)
{
467
	assert(is_parameter_entity(entity));
468
469
470
	return entity->attr.parameter.number;
}

Matthias Braun's avatar
Matthias Braun committed
471
472
static inline dbg_info *_get_entity_dbg_info(const ir_entity *ent)
{
473
474
475
	return ent->dbi;
}

Matthias Braun's avatar
Matthias Braun committed
476
477
static inline void _set_entity_dbg_info(ir_entity *ent, dbg_info *db)
{
478
479
480
	ent->dbi = db;
}

Matthias Braun's avatar
Matthias Braun committed
481
#endif