3 * File name: ir/tr/entity.c
4 * Purpose: Representation of all program known entities.
5 * Author: Martin Trapp, Christian Schaefer
6 * Modified by: Goetz Lindenmaier
9 * Copyright: (c) 1998-2003 Universität Karlsruhe
10 * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
24 #include "firm_common_t.h"
27 # include "entity_t.h"
29 # include "typegmod.h"
34 /* All this is needed to build the constant node for methods: */
35 # include "irprog_t.h"
40 # include "irdump.h" /* for output if errors occur. */
43 # include "callgraph.h" /* for dumping debug output */
45 /*******************************************************************/
47 /*******************************************************************/
49 entity *unknown_entity = NULL;
51 entity *get_unknown_entity(void) { return unknown_entity; }
53 #define UNKNOWN_ENTITY_NAME "unknown_entity"
55 /*-----------------------------------------------------------------*/
57 /*-----------------------------------------------------------------*/
59 static INLINE void insert_entity_in_owner (entity *ent) {
60 type *owner = ent->owner;
61 switch (get_type_tpop_code(owner)) {
63 add_class_member (owner, ent);
66 add_struct_member (owner, ent);
69 add_union_member (owner, ent);
72 set_array_element_entity(owner, ent);
79 * Creates a new entity. This entity is NOT inserted in the owner type.
81 * @param db debug info for this entity
82 * @param owner the owner type of the new entity
83 * @param name the name of the new entity
84 * @param type the type of the new entity
86 * @return the new created entity
88 static INLINE entity *
89 new_rd_entity (dbg_info *db, type *owner, ident *name, type *type)
94 assert(!id_contains_char(name, ' ') && "entity name should not contain spaces");
96 res = xmalloc(sizeof(*res));
97 memset(res, 0, sizeof(*res));
105 if (get_type_tpop(type) == type_method)
106 res->allocation = allocation_static;
108 res->allocation = allocation_automatic;
110 res->visibility = visibility_local;
112 if (is_Method_type(type)) {
115 res->variability = variability_constant;
116 rem = current_ir_graph;
117 current_ir_graph = get_const_code_irg();
118 res->value = new_SymConst(sym, symconst_addr_ent);
119 current_ir_graph = rem;
120 res->irg_add_properties = 0;
123 res->variability = variability_uninitialized;
126 res->val_paths = NULL;
129 res->volatility = volatility_non_volatile;
130 res->stickyness = stickyness_unsticky;
133 res->peculiarity = peculiarity_existent;
135 if (is_Class_type(owner)) {
136 res->overwrites = NEW_ARR_F(entity *, 0);
137 res->overwrittenby = NEW_ARR_F(entity *, 0);
139 res->overwrites = NULL;
140 res->overwrittenby = NULL;
145 res->nr = get_irp_new_node_nr();
146 #endif /* DEBUG_libfirm */
149 set_entity_dbg_info(res, db);
155 new_d_entity (type *owner, ident *name, type *type, dbg_info *db) {
158 assert_legal_owner_of_ent(owner);
159 res = new_rd_entity(db, owner, name, type);
160 /* Remember entity in it's owner. */
161 insert_entity_in_owner (res);
163 hook_new_entity(res);
168 new_entity (type *owner, ident *name, type *type) {
169 return new_d_entity(owner, name, type, NULL);
175 static void free_entity_attrs(entity *ent) {
177 if (get_type_tpop(get_entity_owner(ent)) == type_class) {
178 DEL_ARR_F(ent->overwrites); ent->overwrites = NULL;
179 DEL_ARR_F(ent->overwrittenby); ent->overwrittenby = NULL;
181 assert(ent->overwrites == NULL);
182 assert(ent->overwrittenby == NULL);
184 /* if (ent->values) DEL_ARR_F(ent->values); *//* @@@ warum nich? */
185 if (ent->val_paths) {
186 if (is_compound_entity(ent))
187 for (i = 0; i < get_compound_ent_n_values(ent); i++)
188 if (ent->val_paths[i]) ;
189 /* free_compound_graph_path(ent->val_paths[i]) ; * @@@ warum nich? */
190 /* Geht nich: wird mehrfach verwendet!!! ==> mehrfach frei gegeben. */
191 /* DEL_ARR_F(ent->val_paths); */
193 ent->val_paths = NULL;
198 copy_entity_own (entity *old, type *new_owner) {
200 assert(old && old->kind == k_entity);
201 assert_legal_owner_of_ent(new_owner);
203 if (old->owner == new_owner) return old;
204 newe = xmalloc(sizeof(*newe));
205 memcpy (newe, old, sizeof(*newe));
206 newe->owner = new_owner;
207 if (is_Class_type(new_owner)) {
208 newe->overwrites = NEW_ARR_F(entity *, 0);
209 newe->overwrittenby = NEW_ARR_F(entity *, 0);
212 newe->nr = get_irp_new_node_nr();
215 insert_entity_in_owner (newe);
221 copy_entity_name (entity *old, ident *new_name) {
223 assert(old && old->kind == k_entity);
225 if (old->name == new_name) return old;
226 newe = xmalloc(sizeof(*newe));
227 memcpy(newe, old, sizeof(*newe));
228 newe->name = new_name;
229 newe->ld_name = NULL;
230 if (is_Class_type(newe->owner)) {
231 newe->overwrites = DUP_ARR_F(entity *, old->overwrites);
232 newe->overwrittenby = DUP_ARR_F(entity *, old->overwrittenby);
235 newe->nr = get_irp_new_node_nr();
238 insert_entity_in_owner (newe);
245 free_entity (entity *ent) {
246 assert(ent && ent->kind == k_entity);
247 free_entity_attrs(ent);
252 /* Outputs a unique number for this node */
254 get_entity_nr(entity *ent) {
255 assert(ent && ent->kind == k_entity);
264 (get_entity_name)(const entity *ent) {
265 return _get_entity_name(ent);
269 (get_entity_ident)(const entity *ent) {
270 return get_entity_ident(ent);
274 void set_entitye_ld_name (entity *, char *ld_name);
275 void set_entity_ld_ident (entity *, ident *ld_ident);
279 (get_entity_owner)(entity *ent) {
280 return _get_entity_owner(ent);
284 set_entity_owner (entity *ent, type *owner) {
285 assert(ent && ent->kind == k_entity);
286 assert_legal_owner_of_ent(owner);
290 void /* should this go into type.c? */
291 assert_legal_owner_of_ent(type *owner) {
292 assert(get_type_tpop_code(owner) == tpo_class ||
293 get_type_tpop_code(owner) == tpo_union ||
294 get_type_tpop_code(owner) == tpo_struct ||
295 get_type_tpop_code(owner) == tpo_array); /* Yes, array has an entity
296 -- to select fields! */
300 (get_entity_ld_ident)(entity *ent) {
301 return _get_entity_ld_ident(ent);
305 (set_entity_ld_ident)(entity *ent, ident *ld_ident) {
306 _set_entity_ld_ident(ent, ld_ident);
310 (get_entity_ld_name)(entity *ent) {
311 return _get_entity_ld_name(ent);
315 (get_entity_type)(entity *ent) {
316 return _get_entity_type(ent);
320 (set_entity_type)(entity *ent, type *type) {
321 _set_entity_type(ent, type);
325 (get_entity_allocation)(const entity *ent) {
326 return _get_entity_allocation(ent);
330 (set_entity_allocation)(entity *ent, ent_allocation al) {
331 _set_entity_allocation(ent, al);
334 /* return the name of the visibility */
335 const char *get_allocation_name(ent_allocation all)
337 #define X(a) case a: return #a
339 X(allocation_automatic);
340 X(allocation_parameter);
341 X(allocation_dynamic);
342 X(allocation_static);
343 default: return "BAD VALUE";
350 (get_entity_visibility)(const entity *ent) {
351 return _get_entity_visibility(ent);
355 set_entity_visibility (entity *ent, visibility vis) {
356 assert(ent && ent->kind == k_entity);
357 if (vis != visibility_local)
358 assert((ent->allocation == allocation_static) ||
359 (ent->allocation == allocation_automatic));
360 /* @@@ Test that the owner type is not local, but how??
361 && get_class_visibility(get_entity_owner(ent)) != local));*/
362 ent->visibility = vis;
365 /* return the name of the visibility */
366 const char *get_visibility_name(visibility vis)
368 #define X(a) case a: return #a
371 X(visibility_external_visible);
372 X(visibility_external_allocated);
373 default: return "BAD VALUE";
379 (get_entity_variability)(const entity *ent) {
380 return _get_entity_variability(ent);
384 set_entity_variability (entity *ent, ent_variability var)
386 assert(ent && ent->kind == k_entity);
387 if (var == variability_part_constant)
388 assert(is_Class_type(ent->type) || is_Struct_type(ent->type));
390 if ((is_compound_type(ent->type)) &&
391 (ent->variability == variability_uninitialized) && (var != variability_uninitialized)) {
392 /* Allocate datastructures for constant values */
393 ent->values = NEW_ARR_F(ir_node *, 0);
394 ent->val_paths = NEW_ARR_F(compound_graph_path *, 0);
396 if ((is_atomic_type(ent->type)) &&
397 (ent->variability == variability_uninitialized) && (var != variability_uninitialized)) {
398 /* Set default constant value. */
399 ent->value = new_rd_Unknown(get_const_code_irg(), get_type_mode(ent->type));
402 if ((is_compound_type(ent->type)) &&
403 (var == variability_uninitialized) && (ent->variability != variability_uninitialized)) {
404 /* Free datastructures for constant values */
405 DEL_ARR_F(ent->values); ent->values = NULL;
406 DEL_ARR_F(ent->val_paths); ent->val_paths = NULL;
408 ent->variability = var;
411 /* return the name of the variablity */
412 const char *get_variability_name(ent_variability var)
414 #define X(a) case a: return #a
416 X(variability_uninitialized);
417 X(variability_initialized);
418 X(variability_part_constant);
419 X(variability_constant);
420 default: return "BAD VALUE";
426 (get_entity_volatility)(const entity *ent) {
427 return _get_entity_volatility(ent);
431 (set_entity_volatility)(entity *ent, ent_volatility vol) {
432 _set_entity_volatility(ent, vol);
435 /* return the name of the volatility */
436 const char *get_volatility_name(ent_volatility var)
438 #define X(a) case a: return #a
440 X(volatility_non_volatile);
441 X(volatility_is_volatile);
442 default: return "BAD VALUE";
448 (get_entity_peculiarity)(const entity *ent) {
449 return _get_entity_peculiarity(ent);
453 (set_entity_peculiarity)(entity *ent, peculiarity pec) {
454 _set_entity_peculiarity(ent, pec);
457 /* return the name of the peculiarity */
458 const char *get_peculiarity_name(peculiarity var)
460 #define X(a) case a: return #a
462 X(peculiarity_description);
463 X(peculiarity_inherited);
464 X(peculiarity_existent);
465 default: return "BAD VALUE";
470 /* Get the entity's stickyness */
472 (get_entity_stickyness)(const entity *ent) {
473 return _get_entity_stickyness(ent);
476 /* Set the entity's stickyness */
478 (set_entity_stickyness)(entity *ent, ent_stickyness stickyness) {
479 _set_entity_stickyness(ent, stickyness);
482 /* Set has no effect for existent entities of type method. */
484 get_atomic_ent_value(entity *ent)
486 assert(ent && is_atomic_entity(ent));
487 assert(ent->variability != variability_uninitialized);
488 return skip_Id (ent->value);
492 set_atomic_ent_value(entity *ent, ir_node *val) {
493 assert(is_atomic_entity(ent) && (ent->variability != variability_uninitialized));
494 if (is_Method_type(ent->type) && (ent->peculiarity == peculiarity_existent))
499 /* Returns true if the the node is representable as code on
501 int is_irn_const_expression(ir_node *n) {
504 /* we are in danger iff an exception will arise. TODO: be more precisely,
505 * for instance Div. will NOT rise if divisor != 0
507 if (is_binop(n) && !is_fragile_op(n))
508 return is_irn_const_expression(get_binop_left(n)) && is_irn_const_expression(get_binop_right(n));
511 switch(get_irn_opcode(n)) {
518 return is_irn_const_expression(get_irn_n(n, 0));
527 ir_node *copy_const_value(ir_node *n) {
531 /* @@@ GL I think we should implement this using the routines from irgopt for
532 dead node elimination/inlineing. */
535 switch(get_irn_opcode(n)) {
537 nn = new_Const(m, get_Const_tarval(n)); set_Const_type(nn, get_Const_type(n));
538 //nn = new_rd_Const_type(get_irn_dbg_info(n), current_ir_graph, get_cur_block(),
539 // m, get_Const_tarval(n), get_Const_type(n));
542 nn = new_d_SymConst_type(NULL, get_SymConst_symbol(n), get_SymConst_kind(n),
543 get_SymConst_value_type(n));
546 nn = new_Add(copy_const_value(get_Add_left(n)),
547 copy_const_value(get_Add_right(n)), m); break;
549 nn = new_Sub(copy_const_value(get_Sub_left(n)),
550 copy_const_value(get_Sub_right(n)), m); break;
552 nn = new_Mul(copy_const_value(get_Mul_left(n)),
553 copy_const_value(get_Mul_right(n)), m); break;
555 nn = new_And(copy_const_value(get_And_left(n)),
556 copy_const_value(get_And_right(n)), m); break;
558 nn = new_Or(copy_const_value(get_Or_left(n)),
559 copy_const_value(get_Or_right(n)), m); break;
561 nn = new_Eor(copy_const_value(get_Eor_left(n)),
562 copy_const_value(get_Eor_right(n)), m); break;
564 nn = new_Cast(copy_const_value(get_Cast_op(n)), get_Cast_type(n)); break;
566 nn = new_Conv(copy_const_value(get_Conv_op(n)), m); break;
568 nn = new_Unknown(m); break;
571 assert(0 && "opcode invalid or not implemented");
578 /* Creates a new compound graph path. */
579 compound_graph_path *
580 new_compound_graph_path(type *tp, int length) {
581 compound_graph_path *res;
583 assert(is_type(tp) && is_compound_type(tp));
586 res = xmalloc(sizeof(*res) + (length-1) * sizeof(res->list[0]));
587 memset(res, 0, sizeof(*res) + (length-1) * sizeof(res->list[0]));
588 res->kind = k_ir_compound_graph_path;
595 /* Frees an graph path object */
596 void free_compound_graph_path (compound_graph_path *gr) {
597 assert(gr && is_compound_graph_path(gr));
602 /* Returns non-zero if an object is a compound graph path */
603 int is_compound_graph_path(void *thing) {
604 return (get_kind(thing) == k_ir_compound_graph_path);
607 /* Checks whether the path up to pos is correct. If the path contains a NULL,
608 * assumes the path is not complete and returns 'true'. */
609 int is_proper_compound_graph_path(compound_graph_path *gr, int pos) {
612 type *owner = gr->tp;
614 for (i = 0; i <= pos; i++) {
615 node = get_compound_graph_path_node(gr, i);
617 /* Path not yet complete. */
619 if (get_entity_owner(node) != owner)
621 owner = get_entity_type(node);
623 if (pos == get_compound_graph_path_length(gr))
624 if (!is_atomic_type(owner))
629 /* Returns the length of a graph path */
630 int get_compound_graph_path_length(compound_graph_path *gr) {
631 assert(gr && is_compound_graph_path(gr));
636 get_compound_graph_path_node(compound_graph_path *gr, int pos) {
637 assert(gr && is_compound_graph_path(gr));
638 assert(pos >= 0 && pos < gr->len);
639 return gr->list[pos].node;
643 set_compound_graph_path_node(compound_graph_path *gr, int pos, entity *node) {
644 assert(gr && is_compound_graph_path(gr));
645 assert(pos >= 0 && pos < gr->len);
646 assert(is_entity(node));
647 gr->list[pos].node = node;
648 assert(is_proper_compound_graph_path(gr, pos));
652 get_compound_graph_path_array_index(compound_graph_path *gr, int pos) {
653 assert(gr && is_compound_graph_path(gr));
654 assert(pos >= 0 && pos < gr->len);
655 return gr->list[pos].index;
659 set_compound_graph_path_array_index(compound_graph_path *gr, int pos, int index) {
660 assert(gr && is_compound_graph_path(gr));
661 assert(pos >= 0 && pos < gr->len);
662 gr->list[pos].index = index;
665 /* A value of a compound entity is a pair of value and the corresponding path to a member of
668 add_compound_ent_value_w_path(entity *ent, ir_node *val, compound_graph_path *path) {
669 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
670 ARR_APP1 (ir_node *, ent->values, val);
671 ARR_APP1 (compound_graph_path *, ent->val_paths, path);
675 set_compound_ent_value_w_path(entity *ent, ir_node *val, compound_graph_path *path, int pos) {
676 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
677 ent->values[pos] = val;
678 ent->val_paths[pos] = path;
682 get_compound_ent_n_values(entity *ent) {
683 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
684 return (ARR_LEN (ent->values));
688 get_compound_ent_value(entity *ent, int pos) {
689 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
690 return ent->values[pos];
693 compound_graph_path *
694 get_compound_ent_value_path(entity *ent, int pos) {
695 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
696 return ent->val_paths[pos];
700 * Returns non-zero, if two compound_graph_pathes are equal
702 static int equal_paths(compound_graph_path *path1, int *visited_indicees, compound_graph_path *path2) {
704 int len1 = get_compound_graph_path_length(path1);
705 int len2 = get_compound_graph_path_length(path2);
707 if (len2 > len1) return false;
709 for (i = 0; i < len1; i++) {
711 entity *node1 = get_compound_graph_path_node(path1, i);
712 entity *node2 = get_compound_graph_path_node(path2, i);
714 if (node1 != node2) return false;
716 tp = get_entity_owner(node1);
717 if (is_Array_type(tp)) {
720 /* Compute the index of this node. */
721 assert(get_array_n_dimensions(tp) == 1 && "multidim not implemented");
723 low = get_array_lower_bound_int(tp, 0);
724 if (low + visited_indicees[i] < get_compound_graph_path_array_index(path2, i)) {
725 visited_indicees[i]++;
729 assert(low + visited_indicees[i] == get_compound_graph_path_array_index(path2, i));
735 /* Returns the position of a value with the given path.
736 * The path must contain array indicees for all array element entities. */
737 int get_compound_ent_pos_by_path(entity *ent, compound_graph_path *path) {
738 int i, n_paths = get_compound_ent_n_values(ent);
739 int *visited_indicees = (int *)xcalloc(get_compound_graph_path_length(path), sizeof(int));
740 for (i = 0; i < n_paths; i ++) {
741 if (equal_paths(get_compound_ent_value_path(ent, i), visited_indicees, path))
748 printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
749 printf("Entity %s : ", get_entity_name(ent));
750 for (j = 0; j < get_compound_graph_path_length(path); ++j) {
751 entity *node = get_compound_graph_path_node(path, j);
752 printf("%s", get_entity_name(node));
753 if (is_Array_type(get_entity_owner(node)))
754 printf("[%d]", get_compound_graph_path_array_index(path, j));
756 printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
760 assert(0 && "path not found");
764 /* Returns a constant value given the access path.
765 * The path must contain array indicees for all array element entities. */
766 ir_node *get_compound_ent_value_by_path(entity *ent, compound_graph_path *path) {
767 return get_compound_ent_value(ent, get_compound_ent_pos_by_path(ent, path));
772 remove_compound_ent_value(entity *ent, entity *value_ent) {
774 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
775 for (i = 0; i < (ARR_LEN (ent->val_paths)); i++) {
776 compound_graph_path *path = ent->val_paths[i];
777 if (path->list[path->len-1].node == value_ent) {
778 for(; i < (ARR_LEN (ent->val_paths))-1; i++) {
779 ent->val_paths[i] = ent->val_paths[i+1];
780 ent->values[i] = ent->values[i+1];
782 ARR_SETLEN(entity*, ent->val_paths, ARR_LEN(ent->val_paths) - 1);
783 ARR_SETLEN(ir_node*, ent->values, ARR_LEN(ent->values) - 1);
790 add_compound_ent_value(entity *ent, ir_node *val, entity *member) {
791 compound_graph_path *path;
792 type *owner_tp = get_entity_owner(member);
793 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
794 path = new_compound_graph_path(get_entity_type(ent), 1);
795 path->list[0].node = member;
796 if (is_Array_type(owner_tp)) {
800 assert(get_array_n_dimensions(owner_tp) == 1 && has_array_lower_bound(owner_tp, 0));
801 max = get_array_lower_bound_int(owner_tp, 0) -1;
802 for (i = 0; i < get_compound_ent_n_values(ent); ++i) {
803 int index = get_compound_graph_path_array_index(get_compound_ent_value_path(ent, i), 0);
808 path->list[0].index = max + 1;
810 add_compound_ent_value_w_path(ent, val, path);
813 /* Copies the firm subgraph referenced by val to const_code_irg and adds
814 the node as constant initialization to ent.
815 The subgraph may not contain control flow operations.
817 copy_and_add_compound_ent_value(entity *ent, ir_node *val, entity *member) {
818 ir_graph *rem = current_ir_graph;
820 assert(get_entity_variability(ent) != variability_uninitialized);
821 current_ir_graph = get_const_code_irg();
823 val = copy_const_value(val);
824 add_compound_ent_value(ent, val, member);
825 current_ir_graph = rem;
828 /* Copies the value i of the entity to current_block in current_ir_graph.
830 copy_compound_ent_value(entity *ent, int pos) {
831 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
832 return copy_const_value(ent->values[pos+1]);
836 get_compound_ent_value_member(entity *ent, int pos) {
837 compound_graph_path *path;
838 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
839 path = get_compound_ent_value_path(ent, pos);
841 return get_compound_graph_path_node(path, get_compound_graph_path_length(path)-1);
845 set_compound_ent_value(entity *ent, ir_node *val, entity *member, int pos) {
846 compound_graph_path *path;
847 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
848 path = get_compound_ent_value_path(ent, pos);
849 set_compound_graph_path_node(path, 0, member);
850 set_compound_ent_value_w_path(ent, val, path, pos);
854 set_array_entity_values(entity *ent, tarval **values, int num_vals) {
856 ir_graph *rem = current_ir_graph;
857 type *arrtp = get_entity_type(ent);
859 type *elttp = get_array_element_type(arrtp);
861 assert(is_Array_type(arrtp));
862 assert(get_array_n_dimensions(arrtp) == 1);
863 /* One bound is sufficient, the number of constant fields makes the
865 assert(get_array_lower_bound (arrtp, 0) || get_array_upper_bound (arrtp, 0));
866 assert(get_entity_variability(ent) != variability_uninitialized);
867 current_ir_graph = get_const_code_irg();
869 for (i = 0; i < num_vals; i++) {
870 val = new_Const_type(values[i], elttp);
871 add_compound_ent_value(ent, val, get_array_element_entity(arrtp));
872 set_compound_graph_path_array_index(get_compound_ent_value_path(ent, i), 0, i);
874 current_ir_graph = rem;
877 int get_compound_ent_value_offset_bits(entity *ent, int pos) {
878 compound_graph_path *path;
882 assert(get_type_state(get_entity_type(ent)) == layout_fixed);
884 path = get_compound_ent_value_path(ent, pos);
885 path_len = get_compound_graph_path_length(path);
887 for (i = 0; i < path_len; ++i) {
888 entity *node = get_compound_graph_path_node(path, i);
889 type *node_tp = get_entity_type(node);
890 type *owner_tp = get_entity_owner(node);
891 if (is_Array_type(owner_tp)) {
892 int size = get_type_size_bits(node_tp);
893 int align = get_type_alignment_bits(node_tp);
897 assert(size % align == 0);
898 /* ansonsten aufrunden */
900 offset += size * get_compound_graph_path_array_index(path, i);
902 offset += get_entity_offset_bits(node);
908 int get_compound_ent_value_offset_bytes(entity *ent, int pos) {
909 int offset = get_compound_ent_value_offset_bits(ent, pos);
910 assert(offset % 8 == 0);
915 static void init_index(type *arr) {
919 assert(get_array_n_dimensions(arr) == 1);
921 if (has_array_lower_bound(arr, dim))
922 init = get_array_lower_bound_int(arr, 0) -1;
924 init = get_array_upper_bound_int(arr, 0) +1;
926 set_entity_link(get_array_element_entity(arr), INT_TO_PTR(init));
930 static int get_next_index(entity *elem_ent) {
931 type *arr = get_entity_owner(elem_ent);
935 assert(get_array_n_dimensions(arr) == 1);
937 if (has_array_lower_bound(arr, dim)) {
938 next = PTR_TO_INT(get_entity_link(elem_ent)) + 1;
939 if (has_array_upper_bound(arr, dim)) {
940 int upper = get_array_upper_bound_int(arr, dim);
941 if (next == upper) next = get_array_lower_bound_int(arr, dim);
944 next = PTR_TO_INT(get_entity_link(elem_ent)) - 1;
945 if (has_array_lower_bound(arr, dim)) {
946 int upper = get_array_upper_bound_int(arr, dim);
947 if (next == upper) next = get_array_upper_bound_int(arr, dim);
951 set_entity_link(elem_ent, INT_TO_PTR(next));
955 /* Compute the array indices in compound graph paths of initialized entities.
957 * All arrays must have fixed lower and upper bounds. One array can
958 * have an open bound. If there are several open bounds, we do
959 * nothing. There must be initializer elements for all array
960 * elements. Uses the link field in the array element entities. The
961 * array bounds must be representable as ints.
963 * (If the bounds are not representable as ints we have to represent
964 * the indices as firm nodes. But still we must be able to
965 * evaluate the index against the upper bound.)
967 void compute_compound_ent_array_indicees(entity *ent) {
968 type *tp = get_entity_type(ent);
970 entity *unknown_bound_entity = NULL;
972 if (!is_compound_type(tp) ||
973 (ent->variability == variability_uninitialized)) return ;
975 n_vals = get_compound_ent_n_values(ent);
976 if (n_vals == 0) return;
978 /* We can not compute the indexes if there is more than one array
979 with an unknown bound. For this remember the first entity that
980 represents such an array. It could be ent. */
981 if (is_Array_type(tp)) {
984 assert(get_array_n_dimensions(tp) == 1 && "other not implemented");
985 if (!has_array_lower_bound(tp, dim) || !has_array_upper_bound(tp, dim))
986 unknown_bound_entity = ent;
989 /* Initialize the entity links to lower bound -1 and test all path elements
991 for (i = 0; i < n_vals; ++i) {
992 compound_graph_path *path = get_compound_ent_value_path(ent, i);
993 int j, path_len = get_compound_graph_path_length(path);
994 for (j = 0; j < path_len; ++j) {
995 entity *node = get_compound_graph_path_node(path, j);
996 type *elem_tp = get_entity_type(node);
998 if (is_Array_type(elem_tp)) {
1000 assert(get_array_n_dimensions(elem_tp) == 1 && "other not implemented");
1001 if (!has_array_lower_bound(elem_tp, dim) || !has_array_upper_bound(elem_tp, dim)) {
1002 if (!unknown_bound_entity) unknown_bound_entity = node;
1003 if (node != unknown_bound_entity) return;
1006 init_index(elem_tp);
1011 /* Finally compute the indexes ... */
1012 for (i = 0; i < n_vals; ++i) {
1013 compound_graph_path *path = get_compound_ent_value_path(ent, i);
1014 int j, path_len = get_compound_graph_path_length(path);
1015 for (j = 0; j < path_len; ++j) {
1016 entity *node = get_compound_graph_path_node(path, j);
1017 type *owner_tp = get_entity_owner(node);
1018 if (is_Array_type(owner_tp))
1019 set_compound_graph_path_array_index (path, j, get_next_index(node));
1024 /** resize: double the allocated buffer */
1025 static int *resize (int *buf, int *size) {
1026 int new_size = *size * 2;
1027 int *new_buf = xcalloc(new_size, sizeof(new_buf[0]));
1028 memcpy(new_buf, buf, *size);
1034 /* We sort the elements by placing them at their bit offset in an
1035 array where each entry represents one bit called permutation. In
1036 fact, we do not place the values themselves, as we would have to
1037 copy two things, the value and the path. We only remember the
1038 position in the old order. Each value should have a distinct
1039 position in the permutation.
1041 A second iteration now permutes the actual elements into two
1043 void sort_compound_ent_values(entity *ent) {
1051 ir_node **my_values;
1052 compound_graph_path **my_paths;
1054 assert(get_type_state(get_entity_type(ent)) == layout_fixed);
1056 tp = get_entity_type(ent);
1057 n_vals = get_compound_ent_n_values(ent);
1058 tp_size = get_type_size_bits(tp);
1060 if (!is_compound_type(tp) ||
1061 (ent->variability == variability_uninitialized) ||
1062 (get_type_state(tp) != layout_fixed) ||
1063 (n_vals == 0) ) return;
1065 /* estimated upper bound for size. Better: use flexible array ... */
1066 size = ((tp_size > (n_vals * 32)) ? tp_size : (n_vals * 32)) * 4;
1067 permutation = xcalloc(size, sizeof(permutation[0]));
1069 for (i = 0; i < n_vals; ++i) {
1070 int pos = get_compound_ent_value_offset_bits(ent, i);
1071 while (pos >= size) {
1072 permutation = resize(permutation, &size);
1075 assert(permutation[pos] == 0 && "two values with the same offset");
1076 permutation[pos] = i + 1; /* We initialized with 0, so we can not distinguish entry 0.
1077 So inc all entries by one. */
1078 //fprintf(stderr, "i: %d, pos: %d \n", i, pos);
1082 my_values = NEW_ARR_F(ir_node *, n_vals);
1083 my_paths = NEW_ARR_F(compound_graph_path *, n_vals);
1084 for (i = 0; i < size; ++i) {
1085 int pos = permutation[i];
1087 //fprintf(stderr, "pos: %d i: %d next %d \n", i, pos, next);
1088 assert(next < n_vals);
1089 pos--; /* We increased the pos by one */
1090 my_values[next] = get_compound_ent_value (ent, pos);
1091 my_paths [next] = get_compound_ent_value_path(ent, pos);
1097 DEL_ARR_F(ent->values);
1098 ent->values = my_values;
1099 DEL_ARR_F(ent->val_paths);
1100 ent->val_paths = my_paths;
1104 (get_entity_offset_bytes)(const entity *ent) {
1105 return _get_entity_offset_bytes(ent);
1109 (get_entity_offset_bits)(const entity *ent) {
1110 return _get_entity_offset_bits(ent);
1114 (set_entity_offset_bytes)(entity *ent, int offset) {
1115 _set_entity_offset_bytes(ent, offset);
1119 (set_entity_offset_bits)(entity *ent, int offset) {
1120 _set_entity_offset_bits(ent, offset);
1124 add_entity_overwrites(entity *ent, entity *overwritten) {
1125 assert(ent && is_Class_type(get_entity_owner(ent)));
1126 ARR_APP1(entity *, ent->overwrites, overwritten);
1127 ARR_APP1(entity *, overwritten->overwrittenby, ent);
1131 get_entity_n_overwrites(entity *ent) {
1132 assert(ent && is_Class_type(get_entity_owner(ent)));
1133 return (ARR_LEN(ent->overwrites));
1137 get_entity_overwrites_index(entity *ent, entity *overwritten) {
1139 assert(ent && is_Class_type(get_entity_owner(ent)));
1140 for (i = 0; i < get_entity_n_overwrites(ent); i++)
1141 if (get_entity_overwrites(ent, i) == overwritten)
1147 get_entity_overwrites (entity *ent, int pos) {
1148 assert(ent && is_Class_type(get_entity_owner(ent)));
1149 assert(pos < get_entity_n_overwrites(ent));
1150 return ent->overwrites[pos];
1154 set_entity_overwrites (entity *ent, int pos, entity *overwritten) {
1155 assert(ent && is_Class_type(get_entity_owner(ent)));
1156 assert(pos < get_entity_n_overwrites(ent));
1157 ent->overwrites[pos] = overwritten;
1161 remove_entity_overwrites(entity *ent, entity *overwritten) {
1163 assert(ent && is_Class_type(get_entity_owner(ent)));
1164 for (i = 0; i < (ARR_LEN (ent->overwrites)); i++)
1165 if (ent->overwrites[i] == overwritten) {
1166 for(; i < (ARR_LEN (ent->overwrites))-1; i++)
1167 ent->overwrites[i] = ent->overwrites[i+1];
1168 ARR_SETLEN(entity*, ent->overwrites, ARR_LEN(ent->overwrites) - 1);
1174 add_entity_overwrittenby (entity *ent, entity *overwrites) {
1175 assert(ent && is_Class_type(get_entity_owner(ent)));
1176 add_entity_overwrites(overwrites, ent);
1180 get_entity_n_overwrittenby (entity *ent) {
1181 assert(ent && is_Class_type(get_entity_owner(ent)));
1182 return (ARR_LEN (ent->overwrittenby));
1186 get_entity_overwrittenby_index(entity *ent, entity *overwrites) {
1188 assert(ent && is_Class_type(get_entity_owner(ent)));
1189 for (i = 0; i < get_entity_n_overwrittenby(ent); i++)
1190 if (get_entity_overwrittenby(ent, i) == overwrites)
1196 get_entity_overwrittenby (entity *ent, int pos) {
1197 assert(ent && is_Class_type(get_entity_owner(ent)));
1198 assert(pos < get_entity_n_overwrittenby(ent));
1199 return ent->overwrittenby[pos];
1203 set_entity_overwrittenby (entity *ent, int pos, entity *overwrites) {
1204 assert(ent && is_Class_type(get_entity_owner(ent)));
1205 assert(pos < get_entity_n_overwrittenby(ent));
1206 ent->overwrittenby[pos] = overwrites;
1209 void remove_entity_overwrittenby(entity *ent, entity *overwrites) {
1211 assert(ent && is_Class_type(get_entity_owner(ent)));
1212 for (i = 0; i < (ARR_LEN (ent->overwrittenby)); i++)
1213 if (ent->overwrittenby[i] == overwrites) {
1214 for(; i < (ARR_LEN (ent->overwrittenby))-1; i++)
1215 ent->overwrittenby[i] = ent->overwrittenby[i+1];
1216 ARR_SETLEN(entity*, ent->overwrittenby, ARR_LEN(ent->overwrittenby) - 1);
1221 /* A link to store intermediate information */
1223 (get_entity_link)(const entity *ent) {
1224 return _get_entity_link(ent);
1228 (set_entity_link)(entity *ent, void *l) {
1229 _set_entity_link(ent, l);
1233 (get_entity_irg)(const entity *ent) {
1234 return _get_entity_irg(ent);
1238 set_entity_irg(entity *ent, ir_graph *irg) {
1239 assert(ent && is_Method_type(get_entity_type(ent)));
1240 /* Wie kann man die Referenz auf einen IRG löschen, z.B. wenn die
1241 * Methode selbst nicht mehr aufgerufen werden kann, die Entität
1242 * aber erhalten bleiben soll? Wandle die Entitaet in description oder
1245 assert((irg && ent->peculiarity == peculiarity_existent) ||
1246 (!irg && (ent->peculiarity == peculiarity_existent)
1247 && (ent -> visibility == visibility_external_allocated)) ||
1248 (!irg && ent->peculiarity == peculiarity_description) ||
1249 (!irg && ent->peculiarity == peculiarity_inherited));
1254 (is_entity)(const void *thing) {
1255 return _is_entity(thing);
1258 int is_atomic_entity(entity *ent) {
1259 type* t = get_entity_type(ent);
1260 assert(ent && ent->kind == k_entity);
1261 return (is_Primitive_type(t) || is_Pointer_type(t) ||
1262 is_Enumeration_type(t) || is_Method_type(t));
1265 int is_compound_entity(entity *ent) {
1266 type* t = get_entity_type(ent);
1267 assert(ent && ent->kind == k_entity);
1268 return (is_Class_type(t) || is_Struct_type(t) ||
1269 is_Array_type(t) || is_Union_type(t));
1273 * @todo not implemented!!! */
1274 bool equal_entity(entity *ent1, entity *ent2) {
1275 fprintf(stderr, " calling unimplemented equal entity!!! \n");
1280 unsigned long (get_entity_visited)(entity *ent) {
1281 return _get_entity_visited(ent);
1284 void (set_entity_visited)(entity *ent, unsigned long num) {
1285 _set_entity_visited(ent, num);
1288 /* Sets visited field in entity to entity_visited. */
1289 void (mark_entity_visited)(entity *ent) {
1290 _mark_entity_visited(ent);
1293 int (entity_visited)(entity *ent) {
1294 return _entity_visited(ent);
1297 int (entity_not_visited)(entity *ent) {
1298 return _entity_not_visited(ent);
1301 unsigned (get_entity_additional_properties)(const entity *ent) {
1302 return _get_entity_additional_properties(ent);
1305 void (set_entity_additional_properties)(entity *ent, unsigned property_mask) {
1306 _set_entity_additional_properties(ent, property_mask);
1309 void (set_entity_additional_property)(entity *ent, unsigned flag) {
1310 _set_entity_additional_property(ent, (irg_additional_property)flag);
1313 /* Returns the calling convention of an entities graph. */
1314 unsigned (get_entity_calling_convention)(const entity *ent) {
1315 return _get_entity_calling_convention(ent);
1318 /* Sets the calling convention of an entities graph. */
1319 void (set_entity_calling_convention)(entity *ent, unsigned cc_mask) {
1320 _set_entity_calling_convention(ent, cc_mask);
1323 void firm_init_entity(void)
1325 symconst_symbol sym;
1327 assert(firm_unknown_type && "Call init_type() before firm_init_entity()!");
1328 assert(!unknown_entity && "Call firm_init_entity() only once!");
1329 unknown_entity = new_rd_entity(NULL, firm_unknown_type, new_id_from_str(UNKNOWN_ENTITY_NAME), firm_unknown_type);
1330 set_entity_visibility(unknown_entity, visibility_external_allocated);
1331 set_entity_ld_ident(unknown_entity, get_entity_ident(unknown_entity));
1333 sym.entity_p = unknown_entity;
1334 current_ir_graph = get_const_code_irg();
1335 unknown_entity->value = new_SymConst(sym, symconst_addr_ent);