From: Matthias Braun Date: Wed, 3 Feb 2010 19:31:48 +0000 (+0000) Subject: Rework linkage types in firm. X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=2bc2dd4bd4f64982e9c5d2f1ea70d63d0eb10044;p=libfirm Rework linkage types in firm. - Merge stickyness, visibility and variability into ir_linkage - Add proper support for common symbols, weak symbols and C++ COMDAT stuff - Mark OO-features type_visibility, peculiarity and allocation as deprecated OO feature will be separated from firm core into higher levels in the long run - Rework, simplify and fix bugs in begnuas.c [r27030] --- diff --git a/include/libfirm/compound_path.h b/include/libfirm/compound_path.h index 238d24b94..6cf40e14f 100644 --- a/include/libfirm/compound_path.h +++ b/include/libfirm/compound_path.h @@ -104,14 +104,14 @@ void set_compound_ent_value_w_path(ir_entity *ent, ir_node *val, compound_graph_ * @deprecated * Returns the access path for value at position pos. */ -compound_graph_path *get_compound_ent_value_path(ir_entity *ent, int pos); +compound_graph_path *get_compound_ent_value_path(const ir_entity *ent, int pos); /** * @deprecated * Returns a constant value given the access path. * The path must contain array indices for all array element entities. */ -ir_node *get_compound_ent_value_by_path(ir_entity *ent, +ir_node *get_compound_ent_value_by_path(const ir_entity *ent, compound_graph_path *path); /** @@ -135,7 +135,7 @@ void add_compound_ent_value(ir_entity *ent, ir_node *val, ir_entity *member); * @deprecated * Returns the last member in the path */ -ir_entity *get_compound_ent_value_member(ir_entity *ent, int pos); +ir_entity *get_compound_ent_value_member(const ir_entity *ent, int pos); /** * @deprecated @@ -164,7 +164,7 @@ void set_array_entity_values(ir_entity *ent, tarval **values, int num_vals); * @param ent Any entity of compound type with at least pos initialization values. * @param pos The position of the value for which the offset is requested. */ -unsigned get_compound_ent_value_offset_bit_remainder(ir_entity *ent, int pos); +unsigned get_compound_ent_value_offset_bit_remainder(const ir_entity *ent, int pos); /** * @deprecated @@ -176,19 +176,25 @@ unsigned get_compound_ent_value_offset_bit_remainder(ir_entity *ent, int pos); * @param ent Any entity of compound type with at least pos initialization values. * @param pos The position of the value for which the offset is requested. */ -unsigned get_compound_ent_value_offset_bytes(ir_entity *ent, int pos); +unsigned get_compound_ent_value_offset_bytes(const ir_entity *ent, int pos); /** * @deprecated * Returns the number of constant values needed to initialize the entity. * Asserts if the entity has variability_uninitialized. */ -int get_compound_ent_n_values(ir_entity *ent); +int get_compound_ent_n_values(const ir_entity *ent); /** * @deprecated * Returns a constant value given the position. */ -ir_node *get_compound_ent_value(ir_entity *ent, int pos); +ir_node *get_compound_ent_value(const ir_entity *ent, int pos); + +/** + * @deprecated + * return 1 if entity has a compound_graph-style initializer + */ +int entity_has_compound_ent_values(const ir_entity *entity); #endif diff --git a/include/libfirm/irdump.h b/include/libfirm/irdump.h index 45de03e27..518c040cf 100644 --- a/include/libfirm/irdump.h +++ b/include/libfirm/irdump.h @@ -489,7 +489,6 @@ typedef enum { dump_verbosity_entconsts = 0x00000020, /**< Dump entity constants. */ dump_verbosity_accessStats = 0x00000100, /**< Dump entity access statistics. */ - dump_verbosity_csv = 0x00000200, /**< Dump access statistics as comma separated list. */ dump_verbosity_noClassTypes = 0x00001000, /**< Dump no class types. */ dump_verbosity_noStructTypes = 0x00002000, /**< Dump no struct types. */ diff --git a/include/libfirm/typerep.h b/include/libfirm/typerep.h index 76fb5b3ec..cfc500f60 100644 --- a/include/libfirm/typerep.h +++ b/include/libfirm/typerep.h @@ -52,15 +52,8 @@ * * - owner: A compound type this entity is a part of. * - type: The type of this entity. - * - name: The string that represents this entity in the source program. - * - allocation: A flag saying whether the entity is dynamically or statically - * allocated (values: dynamic_allocated, static_allocated, - * automatic_allocated). - * - visibility: A flag indicating the visibility of this entity (values: local, - * external_visible, external_allocated) - * - variability: A flag indicating the variability of this entity (values: - * uninitialized, initialized, part_constant, constant) - * - volatility: @@@ + * - name: The string that represents this entity in the source program + * - linkage: A flag indicating how the linker treats a symbol * - offset: The offset of the entity within the compound object in bytes. Only set * if the owner in the state "layout_fixed". * - offset_bits_remainder: The offset bit remainder of a bitfield entity (in a compound) @@ -74,12 +67,6 @@ * - link: A void* to associate some additional information with the entity. * - irg: If the entity is a method this is the ir graph that represents the * code of the method. - * - peculiarity: The peculiarity of the entity. If the entity is a method this - * indicates whether the entity represents - * a real method or whether it only exists to describe an interface. - * In that case there nowhere exists code for this entity and this entity - * is never dynamically used in the code. - * Values: description, existent. Default: existent. * - visited: visited flag. Master flag is type_visited. * * These fields can only be accessed via access functions. @@ -87,46 +74,102 @@ * @see ir_type, ir_entity */ -/** This enumeration flags the visibility of entities and types. - * - * This is necessary for partial compilation. - * We rely on the ordering of the flags. +/** + * linkage specifies how the linker treats symbols */ typedef enum { - visibility_local, /**< The entity is only visible locally. This is the default for - entities. - The type is only visible locally. All instances are allocated - locally, and no pointer to entities of this type are passed - out of this compilation unit. */ - visibility_external_visible, /**< The entity is visible to other external program parts, but - it is defined here. It may not be optimized away. The entity must - be static_allocated. - For types: entities of this type can be accessed externally. No - instances of this type are allocated externally. */ - visibility_external_allocated /**< The entity is defined and allocated externally. This compilation - must not allocate memory for this entity. The entity must - be static_allocated. This can also be an external defined - method. - For types: entities of this type are allocated and accessed from - external code. Default for types. */ -} ir_visibility; + IR_LINKAGE_DEFAULT = 0, + /** + * A symbol whose definition won't change in a program. + * Optimisation might replace loads from this entity with constants. + * Also most linkers put such data in a constant segment which is shared + * between multiple running instances of the same application. + */ + IR_LINKAGE_CONSTANT = 1 << 0, + /** + * The entity is a weak symbol. + * A weak symbol is overridden by a non-weak symbol if one exists. + * Most linkers only support the IR_LINKAGE_WEAK in combination with + * IR_LINKAGE_MERGE. + */ + IR_LINKAGE_WEAK = 1 << 1, + /** + * The entity is local to the compilation unit. + * A local entity will not be exported by the linker and is not visible + * in other compilation units. Note that the entity might still be accessed + * indirectly from other units through pointers. + */ + IR_LINKAGE_LOCAL = 1 << 2, + /** + * The entity is defined in another compilation. + */ + IR_LINKAGE_EXTERN = 1 << 3, + /** + * The entity may be removed when it isn't referenced anywhere in the + * compilation unit even if it is exported (non-local). + * Typically used for C++ instantiated template code (,,COMDAT'' section). + */ + IR_LINKAGE_GARBAGE_COLLECT = 1 << 5, + /** + * The linker will try to merge entities with same name from different + * compilation units. This is the usual behaviour for global variables + * without explicit initialisation in C (``COMMON'' symbols). It's also + * typically used in C++ for instantiated template code (,,COMDAT'' section) + */ + IR_LINKAGE_MERGE = 1 << 6, + /** + * Some entity uses are potentially hidden from the compiler. + * (For example because they happen in an asm("") statement. This flag + * should be set for __attribute__((used)) in C code). + * Setting this flag prohibits that the compiler making assumptions about + * read/write behaviour to global variables or changing calling conventions + * from cdecl to fastcall. + */ + IR_LINKAGE_HIDDEN_USER = 1 << 7, +} ir_linkage; + +/** + * The following are some common combinations of linkage types seen in the + * C/C++ languages + */ +enum ir_common_linkages { + /** C "common" symbol */ + IR_LINKAGE_COMMON = IR_LINKAGE_MERGE, + /** C "weak" symbol */ + IR_LINKAGE_WEAKSYM = IR_LINKAGE_WEAK | IR_LINKAGE_MERGE, + /** C++ comdat code */ + IR_LINKAGE_COMDAT = IR_LINKAGE_GARBAGE_COLLECT | IR_LINKAGE_GARBAGE_COLLECT +}; -/** This enumeration flags the peculiarity of entities and types. */ -typedef enum { - peculiarity_description, /**< Represents only a description. The entity/type is never - allocated, no code/data exists for this entity/type. - @@@ eventually rename to descriptive (adjective as the others!)*/ - peculiarity_inherited, /**< Describes explicitly that other entities are - inherited to the owner of this entity. - Overwrites must refer to at least one other - entity. If this is a method entity there exists - no irg for this entity, only for one of the - overwritten ones. - Only for entity. */ - peculiarity_existent /**< The entity/type (can) exist. - @@@ eventually rename to 'real' i.e., 'echt' - This serves better as opposition to description _and_ inherited.*/ -} ir_peculiarity; +/** + * Return 1 if the entity is visible outside the current compilation unit. + * (The entity might still be accessible indirectly through pointers) + * This is a convenience function and does the same as + * (get_entity_linkage(entity) & IR_LINKAGE_LOCAL) == 0 + */ +int entity_is_externally_visible(const ir_entity *entity); + +/** + * Return 1 if the entity has a definition (initializer) in the current + * compilation unit + */ +int entity_has_definition(const ir_entity *entity); + +/** + * Return 1 if the entity is/will be defined in the current compilation unit. + * This is a convenience function for + * (get_entity_linkage(entity) & IR_LINKAGE_EXTERN) == 0. + * + * In contrast to entity_has_definition(entity) you have no guarantee here that + * the entity actually has a firm initializer. + */ +int entity_is_defined_here(const ir_entity *entity); + +/** + * Return 1 if the entity is constant. Constant means the entities value + * won't change at all when the program is running. + */ +int entity_is_constant(const ir_entity *entity); /** * Creates a new entity. @@ -157,10 +200,6 @@ ir_entity *new_d_entity(ir_type *owner, ident *name, ir_type *tp, dbg_info *db); * Automatically inserts the new entity as a member of owner. * Resets the overwrites/overwritten_by fields. * Keeps the old atomic value. - * @@@ Maybe we should change this. If peculiarity of a method - * is existent, we should add a new SymConst that points to - * itself and not to the origin. Right now we have to change - * the peculiarity and then set a new atomic value by hand. */ ir_entity *copy_entity_own(ir_entity *old, ir_type *new_owner); @@ -197,89 +236,57 @@ void set_entity_ident(ir_entity *ent, ident *id); * Else it generates a name with mangle_entity() * and remembers this new name internally. */ -ident *get_entity_ld_ident(ir_entity *ent); +ident *get_entity_ld_ident(const ir_entity *ent); /** Sets the mangled name of the entity. */ void set_entity_ld_ident(ir_entity *ent, ident *ld_ident); /** Returns the mangled name of the entity as a string. */ -const char *get_entity_ld_name(ir_entity *ent); +const char *get_entity_ld_name(const ir_entity *ent); /** Returns the owner of the entity. */ -ir_type *get_entity_owner(ir_entity *ent); +ir_type *get_entity_owner(const ir_entity *ent); /** Sets the owner field in entity to owner. Don't forget to add ent to owner!! */ void set_entity_owner(ir_entity *ent, ir_type *owner); /** Returns the type of an entity. */ -ir_type *get_entity_type(ir_entity *ent); +ir_type *get_entity_type(const ir_entity *ent); /** Sets the type of an entity. */ void set_entity_type(ir_entity *ent, ir_type *tp); -/** The allocation type. */ -typedef enum { - allocation_automatic, /**< The entity is allocated during runtime, implicitly - as component of a compound type. This is the default. */ - allocation_parameter, /**< The entity is a parameter. It is also automatic allocated. - We distinguish the allocation of parameters from the allocation - of local variables as their placement depends on the calling - conventions. */ - allocation_dynamic, /**< The entity is allocated during runtime, explicitly - by an Alloc node. */ - allocation_static /**< The entity is allocated statically. We can use a - Const as address of the entity. This is the default for methods. */ -} ir_allocation; - -/** Returns the allocation type of an entity. */ -ir_allocation get_entity_allocation(const ir_entity *ent); - -/** Sets the allocation type of an entity. */ -void set_entity_allocation(ir_entity *ent, ir_allocation al); - -/** Return the name of the allocation type. */ -const char *get_allocation_name(ir_allocation al); - -/** Returns the visibility of an entity. */ -ir_visibility get_entity_visibility(const ir_entity *ent); - -/** Sets the visibility of an entity. */ -void set_entity_visibility(ir_entity *ent, ir_visibility vis); - -/** Return the name of the visibility */ -const char *get_visibility_name(ir_visibility vis); +/** Returns the linkage of an entity. */ +ir_linkage get_entity_linkage(const ir_entity *entity); -/** This enumeration flags the variability of entities. */ -typedef enum { - variability_uninitialized, /**< The content of the entity is completely unknown. Default. */ - variability_initialized, /**< After allocation the entity is initialized with the - value given somewhere in the entity. */ - variability_part_constant, /**< For entities of compound types. - The members of the entity are mixed constant, - initialized or uninitialized. */ - variability_constant /**< The entity is constant. */ -} ir_variability; - -/** Returns the variability of an entity. */ -ir_variability get_entity_variability(const ir_entity *ent); +/** Sets the linkage of an entity. */ +void set_entity_linkage(ir_entity *entity, ir_linkage linkage); +void add_entity_linkage(ir_entity *entity, ir_linkage linkage); +void remove_entity_linkage(ir_entity *entity, ir_linkage linkage); -/** Sets the variability of an entity. */ -void set_entity_variability(ir_entity *ent, ir_variability var); +/** Returns 1 if the value of a global symbol never changes in a program */ +int is_entity_constant(const ir_entity *ent); -/** Return the name of the variability. */ -const char *get_variability_name(ir_variability var); - -/** This enumeration flags the volatility of entities and Loads/Stores. */ +/** + * This enumeration flags the volatility of entities and Loads/Stores. + * @deprecated + */ typedef enum { volatility_non_volatile, /**< The entity is not volatile. Default. */ volatility_is_volatile /**< The entity is volatile. */ } ir_volatility; -/** Returns the volatility of an entity. */ +/** + * Returns the volatility of an entity. + * @deprecated + */ ir_volatility get_entity_volatility(const ir_entity *ent); -/** Sets the volatility of an entity. */ +/** + * Sets the volatility of an entity. + * @deprecated + */ void set_entity_volatility(ir_entity *ent, ir_volatility vol); /** Return the name of the volatility. */ @@ -288,40 +295,36 @@ const char *get_volatility_name(ir_volatility var); /** Returns alignment of entity in bytes */ unsigned get_entity_alignment(const ir_entity *entity); -/** Sets alignment for entity in bytes */ +/** Allows you to override the type alignment for an entity. + * @param alignment alignment in bytes + */ void set_entity_alignment(ir_entity *entity, unsigned alignment); -/** This enumeration flags the align of Loads/Stores. */ + +/** + * This enumeration flags the align of Loads/Stores. + * @deprecated + */ typedef enum { align_non_aligned, /**< The entity is not aligned. */ align_is_aligned /**< The entity is aligned. Default */ } ir_align; -/** Returns indication wether entity is aligned in memory. */ +/** + * Returns indication wether entity is aligned in memory. + * @deprecated + */ ir_align get_entity_aligned(const ir_entity *ent); -/** Sets indication wether entity is aligned in memory */ +/** + * Sets indication wether entity is aligned in memory + * @deprecated + */ void set_entity_aligned(ir_entity *ent, ir_align a); /** Return the name of the alignment. */ const char *get_align_name(ir_align a); -/** This enumeration flags the stickyness of an entity. */ -typedef enum { - stickyness_unsticky, /**< The entity can be removed from - the program, unless contraindicated - by other attributes. Default. */ - stickyness_sticky /**< The entity must remain in the - program in any case. There might be external - callers. */ -} ir_stickyness; - -/** Get the entity's stickyness. */ -ir_stickyness get_entity_stickyness(const ir_entity *ent); - -/** Set the entity's stickyness. */ -void set_entity_stickyness(ir_entity *ent, ir_stickyness stickyness); - /** Returns the offset of an entity (in a compound) in bytes. Only set if layout = fixed. */ int get_entity_offset(const ir_entity *ent); @@ -342,9 +345,7 @@ void set_entity_link(ir_entity *ent, void *l); /* -- Fields of method entities -- */ /** The entity knows the corresponding irg if the entity is a method. - This allows to get from a Call to the called irg. - Only entities of peculiarity "existent" can have a corresponding irg, - else the field is fixed to NULL. (Get returns NULL, set asserts.) */ + This allows to get from a Call to the called irg. */ ir_graph *get_entity_irg(const ir_entity *ent); void set_entity_irg(ir_entity *ent, ir_graph *irg); @@ -354,18 +355,6 @@ unsigned get_entity_vtable_number(const ir_entity *ent); /** Sets the entity vtable number. */ void set_entity_vtable_number(ir_entity *ent, unsigned vtable_number); -/** Return the peculiarity of an entity. */ -ir_peculiarity get_entity_peculiarity(const ir_entity *ent); - -/** Sets the peculiarity of an entity. */ -void set_entity_peculiarity(ir_entity *ent, ir_peculiarity pec); - -/** Checks if an entity cannot be overridden anymore. */ -int is_entity_final(const ir_entity *ent); - -/** Sets/resets the final flag of an entity. */ -void set_entity_final(ir_entity *ent, int final); - /** Set label number of an entity with code type */ void set_entity_label(ir_entity *ent, ir_label_t label); /** Return label number of an entity with code type */ @@ -518,16 +507,16 @@ ir_initializer_t *get_entity_initializer(const ir_entity *entity); Overwrittenby is the inverse of overwrites. Both add routines add both relations, they only differ in the order of arguments. */ void add_entity_overwrites(ir_entity *ent, ir_entity *overwritten); -int get_entity_n_overwrites(ir_entity *ent); -int get_entity_overwrites_index(ir_entity *ent, ir_entity *overwritten); -ir_entity *get_entity_overwrites(ir_entity *ent, int pos); +int get_entity_n_overwrites(const ir_entity *ent); +int get_entity_overwrites_index(const ir_entity *ent, ir_entity *overwritten); +ir_entity *get_entity_overwrites(const ir_entity *ent, int pos); void set_entity_overwrites(ir_entity *ent, int pos, ir_entity *overwritten); void remove_entity_overwrites(ir_entity *ent, ir_entity *overwritten); void add_entity_overwrittenby(ir_entity *ent, ir_entity *overwrites); -int get_entity_n_overwrittenby(ir_entity *ent); -int get_entity_overwrittenby_index(ir_entity *ent, ir_entity *overwrites); -ir_entity *get_entity_overwrittenby(ir_entity *ent, int pos); +int get_entity_n_overwrittenby(const ir_entity *ent); +int get_entity_overwrittenby_index(const ir_entity *ent, ir_entity *overwrites); +ir_entity *get_entity_overwrittenby(const ir_entity *ent, int pos); void set_entity_overwrittenby(ir_entity *ent, int pos, ir_entity *overwrites); void remove_entity_overwrittenby(ir_entity *ent, ir_entity *overwrites); @@ -546,12 +535,12 @@ int is_entity(const void *thing); * * @note This is a different classification than from is_primitive_type(). */ -int is_atomic_entity(ir_entity *ent); +int is_atomic_entity(const ir_entity *ent); /** Returns true if the type of the entity is a class, structure, array or union type. */ -int is_compound_entity(ir_entity *ent); +int is_compound_entity(const ir_entity *ent); /** Returns true if the type of the entity is a Method type. */ -int is_method_entity(ir_entity *ent); +int is_method_entity(const ir_entity *ent); /** Outputs a unique number for this entity if libfirm is compiled for * debugging, (configure with --enable-debug) else returns the address @@ -560,7 +549,7 @@ int is_method_entity(ir_entity *ent); long get_entity_nr(const ir_entity *ent); /** Returns the entities visited count. */ -ir_visited_t get_entity_visited(ir_entity *ent); +ir_visited_t get_entity_visited(const ir_entity *ent); /** Sets the entities visited count. */ void set_entity_visited(ir_entity *ent, ir_visited_t num); @@ -569,10 +558,10 @@ void set_entity_visited(ir_entity *ent, ir_visited_t num); void mark_entity_visited(ir_entity *ent); /** Returns true if this entity was visited. */ -int entity_visited(ir_entity *ent); +int entity_visited(const ir_entity *ent); /** Returns true if this entity was not visited. */ -int entity_not_visited(ir_entity *ent); +int entity_not_visited(const ir_entity *ent); /** * Returns the mask of the additional entity properties. @@ -581,7 +570,7 @@ int entity_not_visited(ir_entity *ent); * set_entity_additional_properties() or * set_entity_additional_property(). */ -unsigned get_entity_additional_properties(ir_entity *ent); +unsigned get_entity_additional_properties(const ir_entity *ent); /** Sets the mask of the additional graph properties. */ void set_entity_additional_properties(ir_entity *ent, unsigned property_mask); @@ -613,14 +602,10 @@ ir_type *get_entity_repr_class(const ir_entity *ent); * - ld_name = "unknown_entity" * - owner = unknown_type * - type = unknown_type - * - allocation = allocation_automatic - * - visibility = visibility_external_allocated * - offset = -1 - * - variability = variability_uninitialized * - value = SymConst(unknown_entity) * - values = NULL * - val_paths = NULL - * - peculiarity = peculiarity_existent * - volatility = volatility_non_volatile * - stickyness = stickyness_unsticky * - ld_name = NULL @@ -1135,49 +1120,6 @@ tp_opcode get_type_tpop_code(const ir_type *tp); */ void ir_print_type(char *buffer, size_t buffer_size, const ir_type *tp); -/** The visibility of a type. - * - * The visibility of a type indicates, whether entities of this type - * are accessed or allocated in external code. - * - * An entity of a type is allocated in external code, if the external - * code declares a variable of this type, or dynamically allocates - * an entity of this type. If the external code declares a (compound) - * type, that contains entities of this type, the visibility also - * must be external_allocated. - * - * The visibility must be higher than that of all entities, if the - * type is a compound. Here it is questionable, what happens with - * static entities. If these are accessed external by direct reference, - * (a static call to a method, that is also in the dispatch table) - * it should not affect the visibility of the type. - * - * - * @@@ Do we need a visibility for types? - * I change the layout of types radically when doing type splitting. - * I need to know, which fields of classes are accessed in the RTS, - * e.g., [_length. I may not move [_length to the split part. - * The layout though, is a property of the type. - * - * One could also think of changing the mode of a type ... - * - * But, we could also output macros to access the fields, e.g., - * ACCESS_[_length (X) X->length // conventional - * ACCESS_[_length (X) X->_split_ref->length // with type splitting - * - * For now I implement this function, that returns the visibility - * based on the visibility of the entities of a compound ... - * - * This function returns visibility_external_visible if one or more - * entities of a compound type have visibility_external_visible. - * Entities of types are never visibility_external_allocated (right?). - * Else returns visibility_local. - */ -ir_visibility get_type_visibility(const ir_type *tp); -void set_type_visibility(ir_type *tp, ir_visibility v); - - - /** The state of the type layout. */ typedef enum { layout_undefined, /**< The layout of this type is not defined. @@ -1319,7 +1261,6 @@ int is_type(const void *thing); * - the same supertypes -- the C-pointers are compared --> no recursive call. * - the same number of subtypes. Subtypes are not compared, * as this could cause a cyclic test. - * - the same peculiarity * - they are structure types and have the same members * - they are method types and have * - the same parameter types @@ -1395,15 +1336,6 @@ int smaller_type(ir_type *st, ir_type *lt); * * - supertypes: A list of direct superclasses. * - * - peculiarity: The peculiarity of this class. If the class is of peculiarity - * "description" it only is a description of requirements to a class, - * as, e.g., a Java interface. The class will never be allocated. - * Peculiarity inherited is only possible for entities. An entity - * is of peculiarity inherited if the compiler generated the entity - * to explicitly resolve inheritance. An inherited method entity has - * no value for irg. - * Values: description, existent, inherited. Default: existent. - * * - type_info: An entity representing the type information of this class. * This entity can be of arbitrari type, Firm did not use it yet. * It allows to express the coupling of a type with an entity @@ -1548,14 +1480,6 @@ void remove_class_supertype(ir_type *clss, ir_type *supertype); #define set_class_base_type(clss, basetype, pos) set_class_supertype(clss, basetype, pos) #define remove_class_base_type(clss, basetype) remove_class_supertype(clss, basetype) -/** Returns a human readable string for a peculiarity. */ -const char *get_peculiarity_name(ir_peculiarity p); - -/** Returns the peculiarity of the class. */ -ir_peculiarity get_class_peculiarity(const ir_type *clss); -/** Sets the peculiarity of the class. */ -void set_class_peculiarity(ir_type *clss, ir_peculiarity pec); - /** Returns the type info entity of a class. */ ir_entity *get_class_type_info(const ir_type *clss); @@ -2231,14 +2155,17 @@ int get_compound_n_members(const ir_type *tp); * @param pos The number of the member. * * @return The member entity at position pos. - * - * @see get_compound_n_members() for justification of existence. */ ir_entity *get_compound_member(const ir_type *tp, int pos); /** Returns index of member in tp, -1 if not contained. */ int get_compound_member_index(const ir_type *tp, ir_entity *member); +/** + * layout members of a struct/union or class type in a default way. + */ +void default_layout_compound_type(ir_type *tp); + /** * Checks whether a type is a compound type. * @@ -2500,11 +2427,6 @@ typedef void entity_walk_func(ir_entity *ent, void *env); */ void walk_types_entities(ir_type *tp, entity_walk_func *doit, void *env); -/** - * layout members of a struct/union or class type in a default way. - */ -void default_layout_compound_type(ir_type *tp); - /** * If we have the closed world assumption, we can calculate the * finalization of classes and entities by inspecting the class hierarchy. @@ -2513,4 +2435,51 @@ void default_layout_compound_type(ir_type *tp); */ void types_calc_finalization(void); +/** + * @deprecated + */ +typedef enum { + visibility_local, + visibility_external_visible, + visibility_external_allocated +} ir_visibility; + +/** @deprecated */ +ir_visibility get_type_visibility(const ir_type *tp); +/** @deprecated */ +void set_type_visibility(ir_type *tp, ir_visibility v); + +/** @deprecated */ +typedef enum { + allocation_automatic, + allocation_parameter, + allocation_dynamic, + allocation_static +} ir_allocation; +/** @deprecated */ +ir_allocation get_entity_allocation(const ir_entity *ent); +/** @deprecated */ +void set_entity_allocation(ir_entity *ent, ir_allocation al); + +/** @deprecated */ +typedef enum { + peculiarity_existent, + peculiarity_description, + peculiarity_inherited +} ir_peculiarity; +/** @deprecated */ +ir_peculiarity get_entity_peculiarity(const ir_entity *ent); +/** @deprecated */ +void set_entity_peculiarity(ir_entity *ent, ir_peculiarity pec); + +/** @deprecated */ +int is_entity_final(const ir_entity *ent); +/** @deprecated */ +void set_entity_final(ir_entity *ent, int final); + +/** @deprecated */ +ir_peculiarity get_class_peculiarity(const ir_type *clss); +/** @deprecated */ +void set_class_peculiarity(ir_type *clss, ir_peculiarity pec); + #endif diff --git a/ir/ana/cgana.c b/ir/ana/cgana.c index c5f0b1f5c..c63da592d 100644 --- a/ir/ana/cgana.c +++ b/ir/ana/cgana.c @@ -33,7 +33,7 @@ */ #include "config.h" -# include +#include #include "cgana.h" #include "rta.h" @@ -74,17 +74,6 @@ static eset *entities = NULL; /* call target computations. */ /*--------------------------------------------------------------------------*/ -/** Returns the entity that contains the implementation of the inherited - * entity if available, else returns the entity passed. */ -static ir_entity *get_inherited_methods_implementation(ir_entity *inh_meth) { - ir_node *value = get_atomic_ent_value(inh_meth); - assert(value && "constant entity without value"); - assert(is_SymConst_addr_ent(value) && - "Complex constant values not supported -- address of method should be straight constant!"); - - return get_SymConst_entity(value); -} - /** Collect the entity representing the implementation of this * method (not the same if inherited) and all entities for overwriting * implementations in "set". @@ -98,18 +87,12 @@ static ir_entity *get_inherited_methods_implementation(ir_entity *inh_meth) { * @param size Number of entities in set. * @param open */ -static void collect_impls(ir_entity *method, eset *set, int *size, int *open) { +static void collect_impls(ir_entity *method, eset *set, int *size, int *open) +{ int i; - ir_entity *impl; - - /* Add the implementation to the set if it contains an irg, else - remember that there are more methods called. */ - impl = method; - if (get_entity_peculiarity(method) == peculiarity_inherited) - impl = get_inherited_methods_implementation(method); - if (get_entity_peculiarity(method) != peculiarity_description) { - eset_insert(set, impl); + if (get_entity_irg(method) != NULL) { + eset_insert(set, method); ++(*size); } @@ -128,7 +111,8 @@ static void collect_impls(ir_entity *method, eset *set, int *size, int *open) { * * @param method */ -static ir_entity ** get_impl_methods(ir_entity * method) { +static ir_entity ** get_impl_methods(ir_entity * method) +{ eset * set = eset_create(); int size = 0; ir_entity ** arr; @@ -177,7 +161,8 @@ static ir_entity ** get_impl_methods(ir_entity * method) { * @param node The node to analyze * @param env A map that maps names of entities to the entities. */ -static void sel_methods_walker(ir_node *node, void *env) { +static void sel_methods_walker(ir_node *node, void *env) +{ pmap *ldname_map = env; ir_entity **arr; @@ -201,7 +186,6 @@ static void sel_methods_walker(ir_node *node, void *env) { } } else if (is_Sel(node) && is_Method_type(get_entity_type(get_Sel_entity(node)))) { ir_entity *ent = get_SymConst_entity(get_atomic_ent_value(get_Sel_entity(node))); - assert(get_entity_peculiarity(ent) != peculiarity_inherited); if (!eset_contains(entities, ent)) { /* Entity not yet handled. Find all (internal or external) @@ -220,7 +204,7 @@ static void sel_methods_walker(ir_node *node, void *env) { * We could not call it, but it may be description: * We call a method in a dead part of the program. */ - assert(get_entity_peculiarity(ent) == peculiarity_description); + assert(get_entity_irg(ent) == NULL); } else if (get_opt_closed_world() && get_opt_dyn_meth_dispatch() && (ARR_LEN(arr) == 1 && arr[0] != NULL)) { @@ -232,8 +216,7 @@ static void sel_methods_walker(ir_node *node, void *env) { * This method must exists. */ set_irg_current_block(current_ir_graph, get_nodes_block(node)); - assert(get_entity_peculiarity(get_SymConst_entity(get_atomic_ent_value(arr[0]))) == - peculiarity_existent); + assert(get_entity_irg(arr[0]) != NULL); new_node = copy_const_value(get_irn_dbg_info(node), get_atomic_ent_value(arr[0])); DBG_OPT_POLY(node, new_node); exchange(node, new_node); @@ -252,7 +235,8 @@ static void sel_methods_walker(ir_node *node, void *env) { * Finally asserts if there is a SymConst(name) if there could be a * SymConst(ent). */ -static void sel_methods_init(void) { +static void sel_methods_init(void) +{ int i; pmap *ldname_map = pmap_create(); /* Map entity names to entities: to replace SymConst(name) by SymConst(ent). */ @@ -261,7 +245,7 @@ static void sel_methods_init(void) { for (i = get_irp_n_irgs() - 1; i >= 0; --i) { ir_entity * ent = get_irg_entity(get_irp_irg(i)); /* only external visible methods are allowed to call by a SymConst_ptr_name */ - if (get_entity_visibility(ent) != visibility_local) { + if (entity_is_externally_visible(ent)) { pmap_insert(ldname_map, (void *)get_entity_ld_ident(ent), ent); } } @@ -283,14 +267,14 @@ static void sel_methods_init(void) { * * @param sel the Sel node */ -static ir_entity ** get_Sel_arr(ir_node * sel) { +static ir_entity ** get_Sel_arr(ir_node * sel) +{ static ir_entity ** NULL_ARRAY = NULL; ir_entity * ent; ir_entity ** arr; assert(is_Sel(sel)); ent = get_Sel_entity(sel); - ent = get_inherited_methods_implementation(ent); assert(is_Method_type(get_entity_type(ent))); /* what else? */ arr = get_entity_link(ent); @@ -311,14 +295,16 @@ static ir_entity ** get_Sel_arr(ir_node * sel) { * * @param sel the Sel node */ -static int get_Sel_n_methods(ir_node * sel) { +static int get_Sel_n_methods(ir_node * sel) +{ return ARR_LEN(get_Sel_arr(sel)); } /** * Returns the ith possible called method entity at a Sel node. */ -static ir_entity * get_Sel_method(ir_node * sel, int pos) { +static ir_entity * get_Sel_method(ir_node * sel, int pos) +{ ir_entity ** arr = get_Sel_arr(sel); assert(pos >= 0 && pos < ARR_LEN(arr)); return arr[pos]; @@ -327,7 +313,8 @@ static ir_entity * get_Sel_method(ir_node * sel, int pos) { /* forward */ static void free_mark(ir_node * node, eset * set); -static void free_mark_proj(ir_node * node, long n, eset * set) { +static void free_mark_proj(ir_node * node, long n, eset * set) +{ assert(get_irn_mode(node) == mode_T); if (get_irn_link(node) == MARK) { /* already visited */ @@ -381,7 +368,8 @@ static void free_mark_proj(ir_node * node, long n, eset * set) { * @param node the current visited node * @param set the set of all free methods */ -static void free_mark(ir_node *node, eset * set) { +static void free_mark(ir_node *node, eset * set) +{ int i; if (get_irn_link(node) == MARK) @@ -425,7 +413,8 @@ static void free_mark(ir_node *node, eset * set) { /** * post-walker. Find method addresses. */ -static void free_ana_walker(ir_node *node, void *env) { +static void free_ana_walker(ir_node *node, void *env) +{ eset *set = env; int i; @@ -529,28 +518,16 @@ static void add_method_address(ir_entity *ent, eset *set) ir_type *tp; int i; - /* do not check uninitialized values */ - if (get_entity_variability(ent) == variability_uninitialized) + /* ignore methods: these of course reference it's address + * TODO: remove this later once this incorrect self-intialisation is gone + */ + tp = get_entity_type(ent); + if (is_Method_type(tp)) return; - if (ent->has_initializer) { + if (ent->initializer != NULL) { add_method_address_inititializer(get_entity_initializer(ent), set); - } else if (is_atomic_entity(ent)) { - tp = get_entity_type(ent); - - /* ignore methods: these of course reference it's address */ - if (is_Method_type(tp)) - return; - - /* let's check if it's the address of a function */ - n = get_atomic_ent_value(ent); - if (is_Global(n)) { - ent = get_Global_entity(n); - - if (is_Method_type(get_entity_type(ent))) - eset_insert(set, ent); - } - } else { + } else if (entity_has_compound_ent_values(ent)) { for (i = get_compound_ent_n_values(ent) - 1; i >= 0; --i) { n = get_compound_ent_value(ent, i); @@ -569,9 +546,9 @@ static void add_method_address(ir_entity *ent, eset *set) * returns a list of 'free' methods, i.e., the methods that can be called * from external or via function pointers. * - * Die Datenstrukturen f�r sel-Methoden (sel_methods) mu� vor dem + * Die Datenstrukturen für sel-Methoden (sel_methods) muß vor dem * Aufruf von "get_free_methods" aufgebaut sein. Die (internen) - * SymConst(name)-Operationen m�ssen in passende SymConst(ent)-Operationen + * SymConst(name)-Operationen müssen in passende SymConst(ent)-Operationen * umgewandelt worden sein, d.h. SymConst-Operationen verweisen immer * auf eine echt externe Methode. */ @@ -585,13 +562,13 @@ static ir_entity **get_free_methods(int *length) ir_type *tp; for (i = get_irp_n_irgs() - 1; i >= 0; --i) { + ir_linkage linkage; irg = get_irp_irg(i); ent = get_irg_entity(irg); - if (get_entity_visibility(ent) != visibility_local) { - /* insert non-local (external) methods. */ - eset_insert(free_set, ent); - } else if (get_entity_stickyness(ent) == stickyness_sticky) { - /* insert "sticky" methods. */ + linkage = get_entity_linkage(ent); + + if (!(linkage & IR_LINKAGE_LOCAL) + || (linkage & IR_LINKAGE_HIDDEN_USER)) { eset_insert(free_set, ent); } @@ -636,7 +613,8 @@ static ir_entity **get_free_methods(int *length) static void callee_ana_node(ir_node * node, eset * methods); -static void callee_ana_proj(ir_node *node, long n, eset *methods) { +static void callee_ana_proj(ir_node *node, long n, eset *methods) +{ assert(get_irn_mode(node) == mode_T); if (get_irn_link(node) == MARK) { /* already visited */ @@ -676,7 +654,8 @@ static void callee_ana_proj(ir_node *node, long n, eset *methods) { * @param node the node representing the call address * @param methods after call contains the set of all possibly called entities */ -static void callee_ana_node(ir_node *node, eset *methods) { +static void callee_ana_node(ir_node *node, eset *methods) +{ int i; assert(mode_is_reference(get_irn_mode(node)) || is_Bad(node)); @@ -756,7 +735,8 @@ static void callee_ana_node(ir_node *node, eset *methods) { * Walker: Analyses every Call node and calculates an array of possible * callees for that call. */ -static void callee_walker(ir_node *call, void *env) { +static void callee_walker(ir_node *call, void *env) +{ (void) env; if (is_Call(call)) { eset *methods = eset_create(); @@ -784,7 +764,8 @@ static void callee_walker(ir_node *call, void *env) { /** * Walker: Removes all tuple. */ -static void remove_Tuples(ir_node *proj, void *env) { +static void remove_Tuples(ir_node *proj, void *env) +{ ir_node *nn; (void) env; if (! is_Proj(proj)) return; @@ -799,7 +780,8 @@ static void remove_Tuples(ir_node *proj, void *env) { * inside the Call (@see set_Call_callee()). * Uses the sel_methods set with much be already calculated. */ -static void callee_ana(void) { +static void callee_ana(void) +{ int i; /* analyse all graphs */ for (i = get_irp_n_irgs() - 1; i >= 0; --i) { @@ -815,7 +797,8 @@ static void callee_ana(void) { /*--------------------------------------------------------------------------*/ /** Frees intermediate data structures. */ -static void sel_methods_dispose(void) { +static void sel_methods_dispose(void) +{ ir_entity * ent; assert(entities); for (ent = eset_first(entities); ent; ent = eset_next(entities)) { @@ -833,7 +816,8 @@ static void sel_methods_dispose(void) { /* Freeing the callee arrays. */ /*--------------------------------------------------------------------------*/ -static void destruct_walker(ir_node * node, void * env) { +static void destruct_walker(ir_node * node, void * env) +{ (void) env; if (is_Call(node)) { remove_Call_callee_arr(node); @@ -844,7 +828,8 @@ static void destruct_walker(ir_node * node, void * env) { /* Main drivers. */ /*--------------------------------------------------------------------------*/ -void cgana(int *length, ir_entity ***free_methods) { +void cgana(int *length, ir_entity ***free_methods) +{ /* Optimize Sel/SymConst nodes and compute all methods that implement an entity. */ sel_methods_init(); *free_methods = get_free_methods(length); @@ -852,12 +837,14 @@ void cgana(int *length, ir_entity ***free_methods) { sel_methods_dispose(); } -void free_callee_info(ir_graph *irg) { +void free_callee_info(ir_graph *irg) +{ irg_walk_graph(irg, destruct_walker, NULL, NULL); set_irg_callee_info_state(irg, irg_callee_info_none); } -void free_irp_callee_info(void) { +void free_irp_callee_info(void) +{ int i; for (i = get_irp_n_irgs() - 1; i >= 0; --i) { free_callee_info(get_irp_irg(i)); @@ -878,7 +865,8 @@ void free_irp_callee_info(void) { * by Const nodes referring to the entity that implements the method in * the type given by the Alloc node. */ -void opt_call_addrs(void) { +void opt_call_addrs(void) +{ sel_methods_init(); sel_methods_dispose(); } diff --git a/ir/ana/irmemory.c b/ir/ana/irmemory.c index 876688236..3f059095a 100644 --- a/ir/ana/irmemory.c +++ b/ir/ana/irmemory.c @@ -949,8 +949,9 @@ static void analyse_irg_entity_usage(ir_graph *irg) { /* methods can only be analyzed globally */ if (! is_method_entity(ent)) { - ir_entity_usage flags = - get_entity_stickyness(ent) == stickyness_sticky ? ir_usage_unknown : 0; + ir_entity_usage flags = 0; + if (get_entity_linkage(ent) & IR_LINKAGE_HIDDEN_USER) + flags = ir_usage_unknown; set_entity_usage(ent, flags); } } @@ -982,10 +983,11 @@ static void analyse_irg_entity_usage(ir_graph *irg) { if (! is_method_entity(ent)) continue; - if (get_entity_peculiarity(ent) == peculiarity_description) - continue; inner_irg = get_entity_irg(ent); + if (inner_irg == NULL) + continue; + assure_irg_outs(inner_irg); args = get_irg_args(inner_irg); for (j = get_irn_n_outs(args) - 1; j >= 0; --j) { @@ -1025,7 +1027,8 @@ void set_irg_entity_usage_state(ir_graph *irg, ir_entity_usage_computed_state st irg->entity_usage_state = state; } -void assure_irg_entity_usage_computed(ir_graph *irg) { +void assure_irg_entity_usage_computed(ir_graph *irg) +{ if (irg->entity_usage_state != ir_entity_usage_not_computed) return; @@ -1036,18 +1039,16 @@ void assure_irg_entity_usage_computed(ir_graph *irg) { /** * Initialize the entity_usage flag for a global type like type. */ -static void init_entity_usage(ir_type *tp) { +static void init_entity_usage(ir_type *tp) +{ int i; /* We have to be conservative: All external visible entities are unknown */ for (i = get_compound_n_members(tp) - 1; i >= 0; --i) { ir_entity *ent = get_compound_member(tp, i); ir_entity_usage flags = ir_usage_none; - ir_visibility vis = get_entity_visibility(ent); - if (vis == visibility_external_visible || - vis == visibility_external_allocated || - get_entity_stickyness(ent) == stickyness_sticky) { + if (! (get_entity_linkage(ent) & IR_LINKAGE_LOCAL)) { flags |= ir_usage_unknown; } set_entity_usage(ent, flags); @@ -1093,29 +1094,21 @@ static void check_initializer_nodes(ir_initializer_t *initializer) * * @param ent the entity */ -static void check_initializer(ir_entity *ent) { +static void check_initializer(ir_entity *ent) +{ ir_node *n; int i; - /* do not check uninitialized values */ - if (get_entity_variability(ent) == variability_uninitialized) - return; - /* Beware: Methods are always initialized with "themself". This does not - count as a taken address. */ + * count as a taken address. + * TODO: this initialisation with "themself" is wrong and should be removed + */ if (is_Method_type(get_entity_type(ent))) return; - if (ent->has_initializer) { - check_initializer_nodes(ent->attr.initializer); - } else if (is_atomic_entity(ent)) { - /* let's check if it's an address */ - n = get_atomic_ent_value(ent); - if (is_Global(n)) { - ir_entity *ent = get_Global_entity(n); - set_entity_usage(ent, ir_usage_unknown); - } - } else { + if (ent->initializer != NULL) { + check_initializer_nodes(ent->initializer); + } else if (entity_has_compound_ent_values(ent)) { for (i = get_compound_ent_n_values(ent) - 1; i >= 0; --i) { n = get_compound_ent_value(ent, i); @@ -1126,7 +1119,7 @@ static void check_initializer(ir_entity *ent) { } } } -} /* check_initializer */ +} /** @@ -1303,7 +1296,8 @@ static void update_calls_to_private(ir_node *call, void *env) { } /* update_calls_to_private */ /* Mark all private methods, i.e. those of which all call sites are known. */ -void mark_private_methods(void) { +void mark_private_methods(void) +{ int i; int changed = 0; @@ -1316,12 +1310,11 @@ void mark_private_methods(void) { ir_graph *irg = get_irp_irg(i); ir_entity *ent = get_irg_entity(irg); ir_entity_usage flags = get_entity_usage(ent); + ir_linkage linkage = get_entity_linkage(ent); - /* If an entity is sticky, it might be called from external - places (like inline assembler), so do NOT mark it as private. */ - if (get_entity_visibility(ent) == visibility_local && - !(flags & ir_usage_address_taken) && - get_entity_stickyness(ent) != stickyness_sticky) { + if ((linkage & IR_LINKAGE_LOCAL) && + !(linkage & IR_LINKAGE_HIDDEN_USER) && + !(flags & ir_usage_address_taken)) { ir_type *mtp = get_entity_type(ent); set_entity_additional_property(ent, mtp_property_private); diff --git a/ir/ana/rta.c b/ir/ana/rta.c index 4ddb4df46..48f54affa 100644 --- a/ir/ana/rta.c +++ b/ir/ana/rta.c @@ -56,19 +56,6 @@ static eset *_live_classes = NULL; /* cache computed results */ static eset *_live_graphs = NULL; -/** - * Given a method, find the firm graph that implements that method. - */ -static ir_graph *get_implementing_graph(ir_entity *method) -{ - ir_graph *graph = NULL; - - if (get_entity_peculiarity(method) != peculiarity_description) - graph = get_entity_irg(get_SymConst_entity(get_atomic_ent_value(method))); - - return graph; -} - /** * Add a graph to the set of live graphs. * @@ -120,7 +107,7 @@ static int add_implementing_graphs(ir_entity *method) int change = FALSE; if (NULL == graph) - graph = get_implementing_graph(method); + graph = get_entity_irg(method); DB((dbg, LEVEL_2, "RTA: new call to %+F\n", method)); @@ -223,9 +210,10 @@ static int rta_fill_incremental(void) for (i = get_irp_n_irgs() - 1; i >= 0; --i) { ir_graph *graph = get_irp_irg(i); ir_entity *ent = get_irg_entity(graph); + ir_linkage linkage = get_entity_linkage(ent); - if ((visibility_external_visible == get_entity_visibility(ent)) || - (stickyness_sticky == get_entity_stickyness(ent))) { + if (!(linkage & IR_LINKAGE_LOCAL) + || (linkage & IR_LINKAGE_HIDDEN_USER)) { eset_insert(_live_graphs, graph); } } @@ -374,16 +362,16 @@ void rta_init(void) * Changes the peculiarity of entities that represents * dead graphs to peculiarity_description. */ -static void make_entity_to_description(type_or_ent tore, void *env) { +static void make_entity_to_description(type_or_ent tore, void *env) +{ (void) env; if (is_entity(tore.ent)) { ir_entity *ent = tore.ent; - if ((is_Method_type(get_entity_type(ent))) && - (get_entity_peculiarity(ent) != peculiarity_description) && - (get_entity_visibility(ent) != visibility_external_allocated) ) { - ir_graph *irg = get_entity_irg(get_SymConst_entity(get_atomic_ent_value(ent))); - if (! eset_contains(_live_graphs, irg)) { + if ((is_Method_type(get_entity_type(ent))) && + !entity_is_externally_visible(ent)) { + ir_graph *irg = get_entity_irg(ent); + if (irg != NULL && ! eset_contains(_live_graphs, irg)) { set_entity_peculiarity(ent, peculiarity_description); set_entity_irg(ent, NULL); } @@ -410,10 +398,6 @@ void rta_delete_dead_graphs(void) irg = get_irp_irg(i); if (! rta_is_alive_graph(irg)) { -#ifndef NDEBUG - ir_entity *ent = get_irg_entity(irg); - assert(visibility_external_visible != get_entity_visibility(ent)); -#endif set_irg_link(irg, dead_irgs); dead_irgs = irg; ++n_dead_irgs; diff --git a/ir/be/arm/bearch_arm.c b/ir/be/arm/bearch_arm.c index bce4373bb..ae5b384d8 100644 --- a/ir/be/arm/bearch_arm.c +++ b/ir/be/arm/bearch_arm.c @@ -534,7 +534,8 @@ static void *arm_cg_init(be_irg_t *birg) { * and map all instructions the backend did not support * to runtime calls. */ -static void arm_handle_intrinsics(void) { +static void arm_handle_intrinsics(void) +{ ir_type *tp, *int_tp, *uint_tp; i_record records[8]; int n_records = 0; @@ -565,7 +566,7 @@ static void arm_handle_intrinsics(void) { rt_iDiv.exc_mem_proj_nr = pn_Div_M; rt_iDiv.res_proj_nr = pn_Div_res; - set_entity_visibility(rt_iDiv.ent, visibility_external_allocated); + set_entity_linkage(rt_iDiv.ent, IR_LINKAGE_EXTERN | IR_LINKAGE_CONSTANT); map_Div->kind = INTRINSIC_INSTR; map_Div->op = op_Div; @@ -591,7 +592,7 @@ static void arm_handle_intrinsics(void) { rt_uDiv.exc_mem_proj_nr = pn_Div_M; rt_uDiv.res_proj_nr = pn_Div_res; - set_entity_visibility(rt_uDiv.ent, visibility_external_allocated); + set_entity_linkage(rt_uDiv.ent, IR_LINKAGE_EXTERN); map_Div->kind = INTRINSIC_INSTR; map_Div->op = op_Div; @@ -617,7 +618,7 @@ static void arm_handle_intrinsics(void) { rt_iMod.exc_mem_proj_nr = pn_Mod_M; rt_iMod.res_proj_nr = pn_Mod_res; - set_entity_visibility(rt_iMod.ent, visibility_external_allocated); + set_entity_linkage(rt_iMod.ent, IR_LINKAGE_EXTERN); map_Mod->kind = INTRINSIC_INSTR; map_Mod->op = op_Mod; @@ -643,7 +644,7 @@ static void arm_handle_intrinsics(void) { rt_uMod.exc_mem_proj_nr = pn_Mod_M; rt_uMod.res_proj_nr = pn_Mod_res; - set_entity_visibility(rt_uMod.ent, visibility_external_allocated); + set_entity_linkage(rt_uMod.ent, IR_LINKAGE_EXTERN); map_Mod->kind = INTRINSIC_INSTR; map_Mod->op = op_Mod; diff --git a/ir/be/be_dbgout.h b/ir/be/be_dbgout.h index a5d7acc3b..114d7e79e 100644 --- a/ir/be/be_dbgout.h +++ b/ir/be/be_dbgout.h @@ -42,7 +42,7 @@ void be_dbg_so(const char *filename); void be_dbg_main_program(void); /** debug for a method begin */ -void be_dbg_method_begin(ir_entity *ent, const be_stack_layout_t *layout); +void be_dbg_method_begin(const ir_entity *ent, const be_stack_layout_t *layout); /** debug for a method end */ void be_dbg_method_end(void); @@ -51,7 +51,7 @@ void be_dbg_method_end(void); void be_dbg_types(void); /** dump a variable in the global type */ -void be_dbg_variable(ir_entity *ent); +void be_dbg_variable(const ir_entity *ent); void be_dbg_set_dbg_info(dbg_info *dbgi); diff --git a/ir/be/beabi.c b/ir/be/beabi.c index 0c887e212..e24bedf09 100644 --- a/ir/be/beabi.c +++ b/ir/be/beabi.c @@ -1233,8 +1233,6 @@ static ir_type *compute_arg_type(be_abi_irg_t *env, be_abi_call_t *call, arg->stack_ent = copy_entity_own(val_ent, res); set_entity_link(val_ent, arg->stack_ent); set_entity_link(arg->stack_ent, NULL); - /* must be automatic to set a fixed layout */ - set_entity_allocation(arg->stack_ent, allocation_automatic); } else { /* create a new entity */ snprintf(buf, sizeof(buf), "param_%d", i); @@ -1507,7 +1505,6 @@ static ir_entity *get_argument_entity(ir_entity *ent, lower_frame_sels_env_t *ct argument_ent = copy_entity_own(ent, frame_tp); /* must be automatic to set a fixed layout */ - set_entity_allocation(argument_ent, allocation_automatic); set_entity_offset(argument_ent, offset); offset += get_type_size_bytes(tp); @@ -1667,7 +1664,6 @@ static void fix_address_of_parameter_access(be_abi_irg_t *env, ent_pos_pair *val set_entity_owner(ent, frame_tp); add_class_member(frame_tp, ent); /* must be automatic to set a fixed layout */ - set_entity_allocation(ent, allocation_automatic); set_entity_offset(ent, offset); offset += get_type_size_bytes(tp); } @@ -1759,7 +1755,9 @@ static void fix_outer_variable_access(be_abi_irg_t *env, if (! is_method_entity(ent)) continue; - if (get_entity_peculiarity(ent) == peculiarity_description) + + irg = get_entity_irg(ent); + if (irg == NULL) continue; /* @@ -1768,7 +1766,6 @@ static void fix_outer_variable_access(be_abi_irg_t *env, */ ctx->static_link_pos = 0; - irg = get_entity_irg(ent); irg_walk_graph(irg, NULL, update_outer_frame_sels, ctx); } } @@ -2114,8 +2111,7 @@ static ir_entity *create_trampoline(be_main_env_t *be, ir_entity *method) ir_type *parent = be->pic_trampolines_type; ir_entity *ent = new_entity(parent, old_id, type); set_entity_ld_ident(ent, id); - set_entity_visibility(ent, visibility_local); - set_entity_variability(ent, variability_uninitialized); + set_entity_linkage(ent, IR_LINKAGE_LOCAL); return ent; } @@ -2143,8 +2139,7 @@ static ir_entity *create_pic_symbol(be_main_env_t *be, ir_entity *entity) ir_type *parent = be->pic_symbols_type; ir_entity *ent = new_entity(parent, old_id, type); set_entity_ld_ident(ent, id); - set_entity_visibility(ent, visibility_local); - set_entity_variability(ent, variability_uninitialized); + set_entity_linkage(ent, IR_LINKAGE_LOCAL); return ent; } @@ -2167,7 +2162,7 @@ static ir_entity *get_pic_symbol(be_main_env_t *env, ir_entity *entity) */ static int can_address_relative(ir_entity *entity) { - return get_entity_visibility(entity) != visibility_external_allocated; + return !(get_entity_linkage(entity) & IR_LINKAGE_EXTERN); } /** patches SymConsts to work in position independent code */ @@ -2631,10 +2626,9 @@ void be_abi_fix_stack_bias(be_abi_irg_t *env) frame_tp = get_irg_frame_type(irg); for (i = get_class_n_members(frame_tp) - 1; i >= 0; --i) { ir_entity *ent = get_class_member(frame_tp, i); + ir_graph *irg = get_entity_irg(ent); - if (is_method_entity(ent) && get_entity_peculiarity(ent) != peculiarity_description) { - ir_graph *irg = get_entity_irg(ent); - + if (irg != NULL) { irg_walk_graph(irg, NULL, lower_outer_frame_sels, env); } } diff --git a/ir/be/begnuas.c b/ir/be/begnuas.c index be0d0ead8..f67f76366 100644 --- a/ir/be/begnuas.c +++ b/ir/be/begnuas.c @@ -46,9 +46,9 @@ #include "be_dbgout.h" /** by default, we generate assembler code for the Linux gas */ -be_gas_flavour_t be_gas_flavour = GAS_FLAVOUR_ELF; -char be_gas_elf_type_char = '@'; -bool be_gas_emit_types = true; +object_file_format_t be_gas_object_file_format = OBJECT_FILE_FORMAT_ELF; +bool be_gas_emit_types = true; +char be_gas_elf_type_char = '@'; static be_gas_section_t current_section = (be_gas_section_t) -1; @@ -60,9 +60,10 @@ static be_gas_section_t current_section = (be_gas_section_t) -1; * * @return the pseudo-instruction */ -static const char *get_section_name(be_gas_section_t section) { - static const char *text[GAS_FLAVOUR_LAST+1][GAS_SECTION_LAST+1] = { - { /* GAS_FLAVOUR_ELF */ +static const char *get_section_name(be_gas_section_t section) +{ + static const char *text[OBJECT_FILE_FORMAT_LAST+1][GAS_SECTION_LAST+1] = { + { /* OBJECT_FILE_FORMAT_ELF */ ".section\t.text", ".section\t.data", ".section\t.rodata", @@ -74,7 +75,7 @@ static const char *get_section_name(be_gas_section_t section) { NULL, NULL }, - { /* GAS_FLAVOUR_MINGW */ + { /* OBJECT_FILE_FORMAT_COFF */ ".section\t.text", ".section\t.data", ".section .rdata,\"dr\"", @@ -86,38 +87,28 @@ static const char *get_section_name(be_gas_section_t section) { NULL, NULL }, - { /* GAS_FLAVOUR_YASM */ - ".section\t.text", - ".section\t.data", - ".section\t.rodata", - ".section\t.bss", - ".section\t.tbss,\"awT\",@nobits", - ".section\t.ctors,\"aw\",@progbits", - ".section\t.dtors,\"aw\",@progbits", - NULL, - NULL, - NULL - }, - { /* GAS_FLAVOUR_MACH_O */ + { /* OBJECT_FILE_FORMAT_MACH_O */ ".text", ".data", ".const", ".data", NULL, /* TLS is not supported on Mach-O */ ".mod_init_func", - NULL, /* TODO: how is this called? */ + NULL, /* are there destructors on mach-o? */ ".cstring", ".section\t__IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5", ".section\t__IMPORT,__pointers,non_lazy_symbol_pointers" } }; - assert((int) be_gas_flavour >= 0 && be_gas_flavour <= GAS_FLAVOUR_LAST); + assert((int) be_gas_object_file_format >= 0 + && be_gas_object_file_format <= OBJECT_FILE_FORMAT_LAST); assert((int) section >= 0 && section <= GAS_SECTION_LAST); - return text[be_gas_flavour][section]; + return text[be_gas_object_file_format][section]; } -void be_gas_emit_switch_section(be_gas_section_t section) { +void be_gas_emit_switch_section(be_gas_section_t section) +{ if (current_section == section) return; @@ -128,41 +119,56 @@ void be_gas_emit_switch_section(be_gas_section_t section) { current_section = section; } +static void emit_entity_visibility(const ir_entity *entity) +{ + ir_linkage linkage = get_entity_linkage(entity); + + if (! (linkage & IR_LINKAGE_LOCAL)) { + be_emit_cstring(".globl "); + be_emit_ident(get_entity_ld_ident(entity)); + be_emit_char('\n'); + be_emit_write_line(); + } + if (linkage & IR_LINKAGE_WEAK) { + if (! (linkage & IR_LINKAGE_MERGE)) { + panic("Weak symbols only supported in combination with IR_LINKAGE_MERGE on this architecture"); + } + be_emit_cstring(".weak "); + be_emit_ident(get_entity_ld_ident(entity)); + be_emit_char('\n'); + be_emit_write_line(); + } +} + void be_gas_emit_function_prolog(ir_entity *entity, unsigned po2alignment) { const char *name = get_entity_ld_name(entity); - const char *fill_byte = ""; - unsigned maximum_skip; be_gas_emit_switch_section(GAS_SECTION_TEXT); - /* write the begin line (used by scripts processing the assembler... */ + /* write the begin line (makes the life easier for scripts parsing the + * assembler) */ be_emit_write_line(); be_emit_cstring("# -- Begin "); be_emit_string(name); be_emit_char('\n'); be_emit_write_line(); - /* gcc fills space between function with 0x90, no idea if this is needed */ - if (be_gas_flavour == GAS_FLAVOUR_MACH_O) { - fill_byte = "0x90"; - } - if (po2alignment > 0) { - maximum_skip = (1 << po2alignment) - 1; + const char *fill_byte = ""; + unsigned maximum_skip = (1 << po2alignment) - 1; + /* gcc fills space between function with 0x90... */ + if (be_gas_object_file_format == OBJECT_FILE_FORMAT_MACH_O) { + fill_byte = "0x90"; + } be_emit_cstring("\t.p2align "); be_emit_irprintf("%u,%s,%u\n", po2alignment, fill_byte, maximum_skip); be_emit_write_line(); } - if (get_entity_visibility(entity) == visibility_external_visible) { - be_emit_cstring(".globl "); - be_emit_string(name); - be_emit_char('\n'); - be_emit_write_line(); - } + emit_entity_visibility(entity); - switch (be_gas_flavour) { - case GAS_FLAVOUR_ELF: + switch (be_gas_object_file_format) { + case OBJECT_FILE_FORMAT_ELF: be_emit_cstring("\t.type\t"); be_emit_string(name); be_emit_cstring(", "); @@ -170,18 +176,19 @@ void be_gas_emit_function_prolog(ir_entity *entity, unsigned po2alignment) be_emit_cstring("function\n"); be_emit_write_line(); break; - case GAS_FLAVOUR_MINGW: + case OBJECT_FILE_FORMAT_COFF: be_emit_cstring("\t.def\t"); be_emit_string(name); - if (get_entity_visibility(entity) == visibility_external_visible) { - be_emit_cstring(";\t.scl\t2;\t.type\t32;\t.endef\n"); + be_emit_cstring(";"); + if (get_entity_linkage(entity) & IR_LINKAGE_LOCAL) { + be_emit_cstring("\t.scl\t3;"); } else { - be_emit_cstring(";\t.scl\t3;\t.type\t32;\t.endef\n"); + be_emit_cstring("\t.scl\t2;"); } + be_emit_cstring("\t.type\t32;\t.endef\n"); be_emit_write_line(); break; - case GAS_FLAVOUR_MACH_O: - case GAS_FLAVOUR_YASM: + case OBJECT_FILE_FORMAT_MACH_O: break; } be_emit_string(name); @@ -193,7 +200,7 @@ void be_gas_emit_function_epilog(ir_entity *entity) { const char *name = get_entity_ld_name(entity); - if (be_gas_flavour == GAS_FLAVOUR_ELF) { + if (be_gas_object_file_format == OBJECT_FILE_FORMAT_ELF) { be_emit_cstring("\t.size\t"); be_emit_string(name); be_emit_cstring(", .-"); @@ -217,6 +224,7 @@ void be_gas_emit_function_epilog(ir_entity *entity) typedef struct _be_gas_decl_env { be_gas_section_t section; waitq *worklist; /**< A worklist we use to place not yet handled entities on. */ + const be_main_env_t *main_env; } be_gas_decl_env_t; /************************************************************************/ @@ -286,14 +294,16 @@ static void dump_arith_tarval(tarval *tv, int bytes) /** * Return the label prefix for labeled blocks. */ -const char *be_gas_block_label_prefix(void) { +const char *be_gas_block_label_prefix(void) +{ return ".LG"; } /** * Return the label prefix for labeled instructions. */ -const char *be_gas_insn_label_prefix(void) { +const char *be_gas_insn_label_prefix(void) +{ return ".LE"; } @@ -565,12 +575,11 @@ static int initializer_is_string_const(const ir_initializer_t *initializer) * @param ent The entity * @return 1 if it is a string constant, 0 otherwise */ -static int ent_is_string_const(ir_entity *ent) +static int ent_is_string_const(const ir_entity *ent) { ir_type *type, *element_type; ir_mode *mode; int i, c, n; - int found_printable = 0; type = get_entity_type(ent); @@ -590,10 +599,10 @@ static int ent_is_string_const(ir_entity *ent) if (!mode_is_int(mode) || get_mode_size_bits(mode) != 8) return 0; - if (ent->has_initializer) { - /* TODO */ - return 0; - } else { + if (ent->initializer != NULL) { + return initializer_is_string_const(ent->initializer); + } else if (entity_has_compound_ent_values(ent)) { + int found_printable = 0; /* if it contains only printable chars and a 0 at the end */ n = get_compound_ent_n_values(ent); for (i = 0; i < n; ++i) { @@ -611,10 +620,10 @@ static int ent_is_string_const(ir_entity *ent) if (i == n - 1 && c != '\0') return 0; } + return found_printable; } - /* then we can emit it as a string constant */ - return found_printable; + return 0; } /** @@ -623,7 +632,7 @@ static int ent_is_string_const(ir_entity *ent) * * @param ent The entity to dump. */ -static void dump_string_cst(ir_entity *ent) +static void dump_string_cst(const ir_entity *ent) { int i, len; int output_len; @@ -633,7 +642,7 @@ static void dump_string_cst(ir_entity *ent) len = get_compound_ent_n_values(ent); output_len = len; - if (be_gas_flavour == GAS_FLAVOUR_MACH_O) { + if (be_gas_object_file_format == OBJECT_FILE_FORMAT_MACH_O) { be_emit_cstring("\t.ascii \""); } else { be_emit_cstring("\t.string \""); @@ -678,7 +687,7 @@ static void dump_string_initializer(const ir_initializer_t *initializer) size_t i, len; len = initializer->compound.n_initializers; - if (be_gas_flavour == GAS_FLAVOUR_MACH_O) { + if (be_gas_object_file_format == OBJECT_FILE_FORMAT_MACH_O) { be_emit_cstring("\t.ascii \""); } else { be_emit_cstring("\t.string \""); @@ -921,9 +930,9 @@ static void dump_ir_initializer(normal_or_bitfield *vals, panic("invalid ir_initializer kind found"); } -static void dump_initializer(be_gas_decl_env_t *env, ir_entity *entity) +static void dump_initializer(be_gas_decl_env_t *env, const ir_entity *entity) { - const ir_initializer_t *initializer = entity->attr.initializer; + const ir_initializer_t *initializer = entity->initializer; ir_type *type; normal_or_bitfield *vals; size_t size; @@ -996,17 +1005,15 @@ static void dump_initializer(be_gas_decl_env_t *env, ir_entity *entity) xfree(vals); } -/** - * Dump an initializer for a compound entity. - */ -static void dump_compound_init(be_gas_decl_env_t *env, ir_entity *ent) +static void dump_compound_graph_init(be_gas_decl_env_t *env, + const ir_entity *ent) { normal_or_bitfield *vals; int i, j, n; unsigned k, last_ofs; - if (ent->has_initializer) { - dump_initializer(env, ent); + if (ent_is_string_const(ent)) { + dump_string_cst(ent); return; } @@ -1045,12 +1052,12 @@ static void dump_compound_init(be_gas_decl_env_t *env, ir_entity *ent) assert(offset_bits >= 0); if (offset_bits != 0 || - (value_len != 8 && value_len != 16 && value_len != 32 && value_len != 64)) { + (value_len != 8 && value_len != 16 && value_len != 32 && value_len != 64)) { tarval *tv = get_atomic_init_tv(value); unsigned char curr_bits, last_bits = 0; if (tv == NULL) { panic("Couldn't get numeric value for bitfield initializer '%s'", - get_entity_ld_name(ent)); + get_entity_ld_name(ent)); } /* normalize offset */ offset += offset_bits >> 3; @@ -1084,9 +1091,9 @@ static void dump_compound_init(be_gas_decl_env_t *env, ir_entity *ent) if (vals[k].v.value != NULL) { dump_atomic_init(env, vals[k].v.value); skip = get_mode_size_bytes(get_irn_mode(vals[k].v.value)) - 1; - } else { - space = 1; - } + } else { + space = 1; + } } else { assert(vals[k].kind == BITFIELD); be_emit_irprintf("\t.byte\t%d\n", vals[k].v.bf_val); @@ -1115,7 +1122,7 @@ static void emit_align(unsigned p2alignment) be_emit_write_line(); } -static unsigned get_effective_entity_alignment(ir_entity *entity) +static unsigned get_effective_entity_alignment(const ir_entity *entity) { unsigned alignment = get_entity_alignment(entity); if (alignment == 0) { @@ -1125,78 +1132,111 @@ static unsigned get_effective_entity_alignment(ir_entity *entity) return alignment; } +static be_gas_section_t determine_section(be_gas_decl_env_t *env, + const ir_entity *entity) +{ + ir_type *owner = get_entity_owner(entity); + + if (owner == get_segment_type(IR_SEGMENT_GLOBAL)) { + ir_linkage linkage = get_entity_linkage(entity); + if (linkage & IR_LINKAGE_CONSTANT) { + /* mach-o is the only one with a cstring section */ + if (be_gas_object_file_format == OBJECT_FILE_FORMAT_MACH_O + && ent_is_string_const(entity)) + return GAS_SECTION_CSTRING; + + return GAS_SECTION_RODATA; + } + if (!entity_has_definition(entity)) + return GAS_SECTION_BSS; + + return GAS_SECTION_DATA; + + } else if (owner == env->main_env->pic_symbols_type) { + return GAS_SECTION_PIC_SYMBOLS; + } else if (owner == env->main_env->pic_trampolines_type) { + return GAS_SECTION_PIC_TRAMPOLINES; + } else if (owner == get_segment_type(IR_SEGMENT_CONSTRUCTORS)) { + return GAS_SECTION_CONSTRUCTORS; + } else if (owner == get_segment_type(IR_SEGMENT_DESTRUCTORS)) { + return GAS_SECTION_DESTRUCTORS; + } else if (owner == get_segment_type(IR_SEGMENT_THREAD_LOCAL)) { + return GAS_SECTION_TLS; + } + + panic("Couldn't determine section for %+F?!?", entity); +} + +static void emit_common(const ir_entity *ent) +{ + const char *name = get_entity_ld_name(ent); + unsigned size = get_type_size_bytes(get_entity_type(ent)); + unsigned alignment = get_effective_entity_alignment(ent); + + switch (be_gas_object_file_format) { + case OBJECT_FILE_FORMAT_MACH_O: + be_emit_irprintf("\t.comm %s,%u,%u\n", name, size, + log2_floor(alignment)); + be_emit_write_line(); + return; + case OBJECT_FILE_FORMAT_ELF: + be_emit_irprintf("\t.comm %s,%u,%u\n", name, size, alignment); + be_emit_write_line(); + return; + case OBJECT_FILE_FORMAT_COFF: + be_emit_irprintf("\t.comm %s,%u # %u\n", name, size, alignment); + be_emit_write_line(); + return; + } + panic("invalid object file format"); +} /** * Dump a global entity. * - * @param env the gas output environment - * @param ent the entity to be dumped + * @param env the gas output environment + * @param ent the entity to be dumped */ -static void dump_global(be_gas_decl_env_t *env, ir_entity *ent) +static void dump_global(be_gas_decl_env_t *env, const ir_entity *ent) { ir_type *type = get_entity_type(ent); ident *ld_ident = get_entity_ld_ident(ent); unsigned alignment = get_effective_entity_alignment(ent); - int emit_as_common = 0; - be_gas_section_t section = env->section; - ir_variability variability = get_entity_variability(ent); - ir_visibility visibility = get_entity_visibility(ent); + be_gas_section_t section = determine_section(env, ent); + ir_linkage linkage = get_entity_linkage(ent); + /* we already emitted all methods. Except for the trampolines which + * the assembler/linker generates */ if (is_Method_type(type) && section != GAS_SECTION_PIC_TRAMPOLINES) { return; } - if (type == firm_code_type) { + /* block labels are already emittet in the code */ + if (type == firm_code_type) return; - } - - if (section != (be_gas_section_t) -1) { - emit_as_common = 0; - } else if (variability == variability_constant) { - /* a constant entity, put it on the rdata */ - section = GAS_SECTION_RODATA; - if (be_gas_flavour == GAS_FLAVOUR_MACH_O - && ent_is_string_const(ent)) { - section = GAS_SECTION_CSTRING; - } - } else if (variability == variability_uninitialized) { - /* uninitialized entity put it in bss segment */ - section = GAS_SECTION_COMMON; - if (visibility != visibility_local) - emit_as_common = 1; - } else { - section = GAS_SECTION_DATA; - } - - if (!emit_as_common) { - be_gas_emit_switch_section(section); - } be_dbg_variable(ent); - /* global or not global */ - if (visibility == visibility_external_visible && !emit_as_common) { - be_emit_cstring(".globl\t"); - be_emit_ident(ld_ident); - be_emit_char('\n'); - be_emit_write_line(); - } else if (visibility == visibility_external_allocated) { - be_emit_cstring(".globl\t"); - be_emit_ident(ld_ident); - be_emit_char('\n'); - be_emit_write_line(); - /* we can return now... */ + /* nothing to do for externally defined values */ + if (linkage & IR_LINKAGE_EXTERN) return; - } + if (!is_po2(alignment)) panic("alignment not a power of 2"); + + if (section == GAS_SECTION_BSS && + (get_entity_linkage(ent) & IR_LINKAGE_MERGE)) { + emit_common(ent); + return; + } + + be_gas_emit_switch_section(section); + /* alignment */ - if (alignment > 1 && !emit_as_common && section != GAS_SECTION_PIC_TRAMPOLINES - && section != GAS_SECTION_PIC_SYMBOLS) { + if (alignment > 1) { emit_align(alignment); } - - if (visibility != visibility_external_allocated && !emit_as_common - && be_gas_flavour == GAS_FLAVOUR_ELF + emit_entity_visibility(ent); + if (be_gas_object_file_format == OBJECT_FILE_FORMAT_ELF && be_gas_emit_types) { be_emit_cstring("\t.type\t"); be_emit_ident(ld_ident); @@ -1206,77 +1246,18 @@ static void dump_global(be_gas_decl_env_t *env, ir_entity *ent) be_emit_ident(ld_ident); be_emit_irprintf(", %u\n", get_type_size_bytes(type)); } + be_emit_ident(ld_ident); + be_emit_cstring(":\n"); + be_emit_write_line(); - if (!emit_as_common) { - be_emit_ident(ld_ident); - be_emit_cstring(":\n"); - be_emit_write_line(); - } - - if (variability == variability_uninitialized) { - if (emit_as_common) { - switch (be_gas_flavour) { - case GAS_FLAVOUR_MACH_O: - be_emit_irprintf("\t.comm %s,%u,%u\n", - get_id_str(ld_ident), get_type_size_bytes(type), - log2_floor(alignment)); - break; - case GAS_FLAVOUR_ELF: - case GAS_FLAVOUR_YASM: - be_emit_irprintf("\t.comm %s,%u,%u\n", - get_id_str(ld_ident), get_type_size_bytes(type), alignment); - be_emit_write_line(); - break; - case GAS_FLAVOUR_MINGW: - be_emit_irprintf("\t.comm %s,%u # %u\n", - get_id_str(ld_ident), get_type_size_bytes(type), alignment); - be_emit_write_line(); - break; - } - } else if (section == GAS_SECTION_PIC_TRAMPOLINES - || section == GAS_SECTION_PIC_SYMBOLS) { - if (be_gas_flavour == GAS_FLAVOUR_MACH_O) { - be_emit_cstring("\t.indirect_symbol "); - be_emit_ident(get_entity_ident(ent)); - be_emit_char('\n'); - be_emit_write_line(); - if (section == GAS_SECTION_PIC_TRAMPOLINES) { - be_emit_cstring("\thlt ; hlt ; hlt ; hlt ; hlt\n"); - be_emit_write_line(); - } else { - assert(section == GAS_SECTION_PIC_SYMBOLS); - be_emit_cstring("\t.long 0\n"); - be_emit_write_line(); - } - } else { - panic("PIC trampolines not yet supported in this gas mode"); - } - } else { - be_emit_irprintf("\t.space %u\n", get_type_size_bytes(type)); - be_emit_write_line(); - } + if (ent->initializer != NULL) { + dump_initializer(env, ent); + } else if(entity_has_compound_ent_values(ent)) { + dump_compound_graph_init(env, ent); } else { - if (is_atomic_entity(ent)) { - dump_atomic_init(env, get_atomic_ent_value(ent)); - } else { - /* sort_compound_ent_values(ent); */ - - switch (get_type_tpop_code(get_entity_type(ent))) { - case tpo_array: - if (ent_is_string_const(ent)) - dump_string_cst(ent); - else - dump_compound_init(env, ent); - break; - case tpo_struct: - case tpo_class: - case tpo_union: - dump_compound_init(env, ent); - break; - default: - panic("Unimplemented type kind in dump_global()"); - } - } + /* uninitialized */ + be_emit_irprintf("\t.space %u\n", get_type_size_bytes(type)); + be_emit_write_line(); } } @@ -1297,8 +1278,7 @@ static void be_gas_dump_globals(ir_type *gt, be_gas_decl_env_t *env, if (only_emit_marked) { for (i = 0; i < n; i++) { ir_entity *ent = get_compound_member(gt, i); - if (is_entity_backend_marked(ent) || - get_entity_visibility(ent) != visibility_external_allocated) { + if (is_entity_backend_marked(ent) || entity_has_definition(ent)) { waitq_put(worklist, ent); set_entity_backend_marked(ent, 1); } @@ -1333,28 +1313,29 @@ void be_gas_emit_decls(const be_main_env_t *main_env, memset(&env, 0, sizeof(env)); /* dump global type */ - env.section = (be_gas_section_t) -1; + env.main_env = main_env; + env.section = (be_gas_section_t) -1; + be_gas_dump_globals(get_glob_type(), &env, only_emit_marked_entities); - env.section = GAS_SECTION_TLS; be_gas_dump_globals(get_tls_type(), &env, only_emit_marked_entities); - env.section = GAS_SECTION_CONSTRUCTORS; be_gas_dump_globals(get_segment_type(IR_SEGMENT_CONSTRUCTORS), &env, only_emit_marked_entities); - env.section = GAS_SECTION_DESTRUCTORS; be_gas_dump_globals(get_segment_type(IR_SEGMENT_DESTRUCTORS), &env, only_emit_marked_entities); - - env.section = GAS_SECTION_PIC_SYMBOLS; be_gas_dump_globals(main_env->pic_symbols_type, &env, only_emit_marked_entities); - - if (get_compound_n_members(main_env->pic_trampolines_type) > 0) { - env.section = GAS_SECTION_PIC_TRAMPOLINES; - be_gas_dump_globals(main_env->pic_trampolines_type, &env, - only_emit_marked_entities); - if (be_gas_flavour == GAS_FLAVOUR_MACH_O) { - be_emit_cstring("\t.subsections_via_symbols\n"); - be_emit_write_line(); - } + be_gas_dump_globals(main_env->pic_trampolines_type, &env, + only_emit_marked_entities); + + /** + * ".subsections_via_symbols marks object files which are OK to divide + * their section contents into individual blocks". + * From my understanding this means no label points in the middle of an + * object which we want to address as a whole. Firm code should be fine + * with this. + */ + if (be_gas_object_file_format == OBJECT_FILE_FORMAT_MACH_O) { + be_emit_cstring("\t.subsections_via_symbols\n"); + be_emit_write_line(); } } diff --git a/ir/be/begnuas.h b/ir/be/begnuas.h index 708d8ec78..97660fe5c 100644 --- a/ir/be/begnuas.h +++ b/ir/be/begnuas.h @@ -31,14 +31,11 @@ #include "be.h" #include "beemitter.h" -/** - * Sections. - */ typedef enum section_t { - GAS_SECTION_TEXT, /**< text section */ - GAS_SECTION_DATA, /**< data section */ - GAS_SECTION_RODATA, /**< rodata section */ - GAS_SECTION_COMMON, /**< common section */ + GAS_SECTION_TEXT, /**< text section - contains program code */ + GAS_SECTION_DATA, /**< data section - contains arbitrary data */ + GAS_SECTION_RODATA, /**< rodata section - contains read-only data */ + GAS_SECTION_BSS, /**< bss section - contains uninitialized data */ GAS_SECTION_TLS, /**< thread local storage section */ GAS_SECTION_CONSTRUCTORS, /**< ctors section */ GAS_SECTION_DESTRUCTORS, /**< dtors section */ @@ -48,20 +45,16 @@ typedef enum section_t { GAS_SECTION_LAST = GAS_SECTION_PIC_SYMBOLS } be_gas_section_t; -/** - * Support for some GAS "dialects". - */ -typedef enum asm_flavour_t { - GAS_FLAVOUR_ELF, /**< ELF variant */ - GAS_FLAVOUR_MINGW, /**< MinGW variant (no-ELF) */ - GAS_FLAVOUR_YASM, /**< YASM GNU parser */ - GAS_FLAVOUR_MACH_O, /**< Mach-O variant (as found on darwin, OS/X) */ - GAS_FLAVOUR_LAST = GAS_FLAVOUR_MACH_O -} be_gas_flavour_t; +typedef enum object_file_format_t { + OBJECT_FILE_FORMAT_ELF, /**< Executable and Linkable Format (unixes) */ + OBJECT_FILE_FORMAT_COFF, /**< Common Object File Format (Windows) */ + OBJECT_FILE_FORMAT_MACH_O, /**< Mach Object File Format (OS/X) */ + OBJECT_FILE_FORMAT_LAST = OBJECT_FILE_FORMAT_MACH_O +} object_file_format_t; /** The variable where the GAS dialect is stored. */ -extern be_gas_flavour_t be_gas_flavour; -extern bool be_gas_emit_types; +extern object_file_format_t be_gas_object_file_format; +extern bool be_gas_emit_types; /** * the .type directive needs to specify @function, #function or %function * depending on the target architecture (yay) diff --git a/ir/be/bestabs.c b/ir/be/bestabs.c index 6872902c2..6b5fe3cf5 100644 --- a/ir/be/bestabs.c +++ b/ir/be/bestabs.c @@ -661,7 +661,8 @@ static void stabs_set_dbg_info(dbg_handle *h, dbg_info *dbgi) /** * dump the stabs for a method begin */ -static void stabs_method_begin(dbg_handle *handle, ir_entity *ent, const be_stack_layout_t *layout) { +static void stabs_method_begin(dbg_handle *handle, ir_entity *ent, const be_stack_layout_t *layout) +{ stabs_handle *h = (stabs_handle *)handle; ir_type *mtp, *rtp; unsigned type_num; @@ -681,7 +682,7 @@ static void stabs_method_begin(dbg_handle *handle, ir_entity *ent, const be_stac type_num = get_type_number(h, rtp); be_emit_irprintf("\t.stabs\t\"%s:%c%u\",%u,0,0,%s\n", get_entity_name(ent), - get_entity_visibility(ent) == visibility_external_visible ? 'F' : 'f', + entity_is_externally_visible(ent) ? 'F' : 'f', type_num, N_FUN, get_entity_ld_name(ent)); @@ -793,17 +794,16 @@ static void stabs_variable(dbg_handle *handle, ir_entity *ent) { unsigned tp_num = get_type_number(h, get_entity_type(ent)); char buf[1024]; - if (get_entity_visibility(ent) == visibility_external_visible) { + if (entity_is_externally_visible(ent)) { /* a global variable */ snprintf(buf, sizeof(buf), "\t.stabs\t\"%s:G%u\",%d,0,0,0\n", get_entity_name(ent), tp_num, N_GSYM); - } else { /* some kind of local */ - ir_variability variability = get_entity_variability(ent); + } else { + /* some kind of local */ + ir_linkage linkage = get_entity_linkage(ent); int kind = N_STSYM; - if (variability == variability_uninitialized) - kind = N_LCSYM; - else if (variability == variability_constant) + if (linkage & IR_LINKAGE_CONSTANT) kind = N_ROSYM; snprintf(buf, sizeof(buf), "\t.stabs\t\"%s:S%u\",%d,0,0,%s\n", get_entity_name(ent), tp_num, kind, get_entity_ld_name(ent)); diff --git a/ir/be/ia32/bearch_ia32.c b/ir/be/ia32/bearch_ia32.c index 965d2bf7a..b68105eb9 100644 --- a/ir/be/ia32/bearch_ia32.c +++ b/ir/be/ia32/bearch_ia32.c @@ -865,13 +865,14 @@ static void ia32_before_abi(void *self) ir_lower_mode_b(cg->irg, &lower_mode_b_config); if (cg->dump) be_dump(cg->irg, "-lower_modeb", dump_ir_block_graph_sched); + if (cg->gprof) { if (mcount == NULL) { ir_type *tp = new_type_method(0, 0); mcount = new_entity(get_glob_type(), ID("mcount"), tp); /* FIXME: enter the right ld_ident here */ set_entity_ld_ident(mcount, get_entity_ident(mcount)); - set_entity_visibility(mcount, visibility_external_allocated); + set_entity_linkage(mcount, IR_LINKAGE_EXTERN); } instrument_initcall(cg->irg, mcount); } @@ -2180,7 +2181,8 @@ static bool mux_is_abs(ir_node *sel, ir_node *mux_true, ir_node *mux_false) /** * Check if Mux(sel, mux_true, mux_false) would represent a Max or Min operation */ -static bool mux_is_float_min_max(ir_node *sel, ir_node *mux_true, ir_node *mux_false) +static bool mux_is_float_min_max(ir_node *sel, ir_node *mux_true, + ir_node *mux_false) { ir_node *cmp_l; ir_node *cmp_r; @@ -2244,7 +2246,8 @@ static bool mux_is_set(ir_node *sel, ir_node *mux_true, ir_node *mux_false) (void) sel; ir_mode *mode = get_irn_mode(mux_true); - if (!mode_is_int(mode) && !mode_is_reference(mode)) + if (!mode_is_int(mode) && !mode_is_reference(mode) + && mode != mode_b) return false; if (is_Const(mux_true) && is_Const_one(mux_true) @@ -2259,7 +2262,8 @@ static bool mux_is_set(ir_node *sel, ir_node *mux_true, ir_node *mux_false) return false; } -static bool mux_is_float_const_const(ir_node *sel, ir_node *mux_true, ir_node *mux_false) +static bool mux_is_float_const_const(ir_node *sel, ir_node *mux_true, + ir_node *mux_false) { (void) sel; @@ -2284,18 +2288,21 @@ static bool mux_is_doz(ir_node *sel, ir_node *mux_true, ir_node *mux_false) if (!is_Cmp(cmp)) return false; + mode = get_irn_mode(mux_true); + if (mode_is_signed(mode) || mode_is_float(mode)) + return false; + + pn = get_Proj_proj(sel); cmp_left = get_Cmp_left(cmp); cmp_right = get_Cmp_right(cmp); - mode = get_irn_mode(mux_true); - pn = get_Proj_proj(sel); - if ((pn & pn_Cmp_Gt) && !mode_is_signed(mode) && + if ((pn & pn_Cmp_Gt) && is_Const(mux_false) && is_Const_null(mux_false) && is_Sub(mux_true) && get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) { /* Mux(a >=u b, a - b, 0) unsigned Doz */ return true; } - if ((pn & pn_Cmp_Lt) && !mode_is_signed(mode) && + if ((pn & pn_Cmp_Lt) && is_Const(mux_true) && is_Const_null(mux_true) && is_Sub(mux_false) && get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) { @@ -2452,15 +2459,14 @@ static const backend_params *ia32_get_libfirm_params(void) } static const lc_opt_enum_int_items_t gas_items[] = { - { "elf", GAS_FLAVOUR_ELF }, - { "mingw", GAS_FLAVOUR_MINGW }, - { "yasm", GAS_FLAVOUR_YASM }, - { "macho", GAS_FLAVOUR_MACH_O }, - { NULL, 0 } + { "elf", OBJECT_FILE_FORMAT_ELF }, + { "mingw", OBJECT_FILE_FORMAT_COFF }, + { "macho", OBJECT_FILE_FORMAT_MACH_O }, + { NULL, 0 } }; static lc_opt_enum_int_var_t gas_var = { - (int*) &be_gas_flavour, gas_items + (int*) &be_gas_object_file_format, gas_items }; #ifdef FIRM_GRGEN_BE diff --git a/ir/be/ia32/ia32_common_transform.c b/ir/be/ia32/ia32_common_transform.c index fee06180a..44f69e03b 100644 --- a/ir/be/ia32/ia32_common_transform.c +++ b/ir/be/ia32/ia32_common_transform.c @@ -143,9 +143,7 @@ ir_entity *create_float_const_entity(ir_node *cnst) res = new_entity(get_glob_type(), ia32_unique_id(".LC%u"), tp); set_entity_ld_ident(res, get_entity_ident(res)); - set_entity_visibility(res, visibility_local); - set_entity_variability(res, variability_constant); - set_entity_allocation(res, allocation_static); + set_entity_linkage(res, IR_LINKAGE_LOCAL | IR_LINKAGE_CONSTANT); /* we create a new entity here: It's initialization must resist on the const code irg */ diff --git a/ir/be/ia32/ia32_emitter.c b/ir/be/ia32/ia32_emitter.c index 162fe545f..e149ab4c1 100644 --- a/ir/be/ia32/ia32_emitter.c +++ b/ir/be/ia32/ia32_emitter.c @@ -286,7 +286,7 @@ static void ia32_emit_entity(ir_entity *entity, int no_pic_adjust) be_gas_emit_entity(entity); if (get_entity_owner(entity) == get_tls_type()) { - if (get_entity_visibility(entity) == visibility_external_allocated) { + if (get_entity_linkage(entity) & IR_LINKAGE_EXTERN) { be_emit_cstring("@INDNTPOFF"); } else { be_emit_cstring("@NTPOFF"); @@ -2419,7 +2419,7 @@ static void bemit_entity(ir_entity *entity, bool entity_sign, int offset, be_gas_emit_entity(entity); if (get_entity_owner(entity) == get_tls_type()) { - if (get_entity_visibility(entity) == visibility_external_allocated) { + if (get_entity_linkage(entity) & IR_LINKAGE_EXTERN) { be_emit_cstring("@INDNTPOFF"); } else { be_emit_cstring("@NTPOFF"); diff --git a/ir/be/ia32/ia32_fpu.c b/ir/be/ia32/ia32_fpu.c index bb6aee7f1..330267a97 100644 --- a/ir/be/ia32/ia32_fpu.c +++ b/ir/be/ia32/ia32_fpu.c @@ -68,9 +68,7 @@ static ir_entity *create_ent(int value, const char *name) tv = new_tarval_from_long(value, mode); ent = new_entity(glob, new_id_from_str(name), type); set_entity_ld_ident(ent, get_entity_ident(ent)); - set_entity_visibility(ent, visibility_local); - set_entity_variability(ent, variability_constant); - set_entity_allocation(ent, allocation_static); + set_entity_linkage(ent, IR_LINKAGE_LOCAL | IR_LINKAGE_CONSTANT); cnst_irg = get_const_code_irg(); cnst = new_r_Const(cnst_irg, tv); diff --git a/ir/be/ia32/ia32_intrinsics.c b/ir/be/ia32/ia32_intrinsics.c index 21db02f50..5835636a1 100644 --- a/ir/be/ia32/ia32_intrinsics.c +++ b/ir/be/ia32/ia32_intrinsics.c @@ -667,7 +667,8 @@ static int map_Abs(ir_node *call, void *ctx) { /** * Maps a Div. Change into a library call. */ -static int map_Div(ir_node *call, void *ctx) { +static int map_Div(ir_node *call, void *ctx) +{ ia32_intrinsic_env_t *env = ctx; ir_type *method = get_Call_type(call); ir_mode *h_mode = get_type_mode(get_method_res_type(method, 1)); @@ -682,7 +683,7 @@ static int map_Div(ir_node *call, void *ctx) { if (ent == NULL) { /* create library entity */ ent = env->divdi3 = new_entity(get_glob_type(), ID("__divdi3"), method); - set_entity_visibility(ent, visibility_external_allocated); + set_entity_linkage(ent, IR_LINKAGE_EXTERN); set_entity_ld_ident(ent, ID("__divdi3")); } } else { @@ -691,7 +692,7 @@ static int map_Div(ir_node *call, void *ctx) { if (ent == NULL) { /* create library entity */ ent = env->udivdi3 = new_entity(get_glob_type(), ID("__udivdi3"), method); - set_entity_visibility(ent, visibility_external_allocated); + set_entity_linkage(ent, IR_LINKAGE_EXTERN); set_entity_ld_ident(ent, ID("__udivdi3")); } } @@ -722,7 +723,7 @@ static int map_Mod(ir_node *call, void *ctx) { if (ent == NULL) { /* create library entity */ ent = env->moddi3 = new_entity(get_glob_type(), ID("__moddi3"), method); - set_entity_visibility(ent, visibility_external_allocated); + set_entity_linkage(ent, IR_LINKAGE_EXTERN); set_entity_ld_ident(ent, ID("__moddi3")); } } else { @@ -731,7 +732,7 @@ static int map_Mod(ir_node *call, void *ctx) { if (ent == NULL) { /* create library entity */ ent = env->umoddi3 = new_entity(get_glob_type(), ID("__umoddi3"), method); - set_entity_visibility(ent, visibility_external_allocated); + set_entity_linkage(ent, IR_LINKAGE_EXTERN); set_entity_ld_ident(ent, ID("__umoddi3")); } } diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index a8cd00476..615a69c04 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -509,9 +509,7 @@ ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct) ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp); set_entity_ld_ident(ent, get_entity_ident(ent)); - set_entity_visibility(ent, visibility_local); - set_entity_variability(ent, variability_constant); - set_entity_allocation(ent, allocation_static); + set_entity_linkage(ent, IR_LINKAGE_LOCAL | IR_LINKAGE_CONSTANT); if (kct == ia32_ULLBIAS) { ir_initializer_t *initializer = create_initializer_compound(2); @@ -3103,9 +3101,7 @@ static ir_entity *ia32_create_const_array(ir_node *c0, ir_node *c1, ir_mode **ne ent = new_entity(get_glob_type(), ia32_unique_id(".LC%u"), tp); set_entity_ld_ident(ent, get_entity_ident(ent)); - set_entity_visibility(ent, visibility_local); - set_entity_variability(ent, variability_constant); - set_entity_allocation(ent, allocation_static); + set_entity_linkage(ent, IR_LINKAGE_LOCAL | IR_LINKAGE_CONSTANT); initializer = create_initializer_compound(2); diff --git a/ir/be/ppc32/bearch_ppc32.c b/ir/be/ppc32/bearch_ppc32.c index 6268c71e1..f4e7747ce 100644 --- a/ir/be/ppc32/bearch_ppc32.c +++ b/ir/be/ppc32/bearch_ppc32.c @@ -505,8 +505,7 @@ static void ppc32_collect_symconsts_walk(ir_node *node, void *env) { if (is_SymConst(node)) { ir_entity *ent = get_SymConst_entity(node); set_entity_backend_marked(ent, 1); - if (! is_direct_entity(ent)) - pset_insert_ptr(symbol_set, ent); + pset_insert_ptr(symbol_set, ent); } } @@ -621,8 +620,7 @@ static void ppc32_get_call_abi(const void *self, ir_type *method_type, be_abi_ca be_abi_call_flags_t call_flags = { { 0, 0, 1, 0, 0, 0, 1 } }; (void) self; - if(get_type_visibility(method_type)!=visibility_external_allocated) - call_flags.bits.call_has_imm = 1; + call_flags.bits.call_has_imm = 1; /* set stack parameter passing style */ be_abi_call_set_flags(abi, call_flags, &ppc32_abi_callbacks); diff --git a/ir/be/ppc32/ppc32_transform.c b/ir/be/ppc32/ppc32_transform.c index ca0d27402..789988fd8 100644 --- a/ir/be/ppc32/ppc32_transform.c +++ b/ir/be/ppc32/ppc32_transform.c @@ -50,8 +50,6 @@ extern ir_op *get_op_Mulh(void); -int is_direct_entity(ir_entity *ent); - ir_mode* ppc32_mode_Cond = NULL; /** @@ -953,12 +951,14 @@ static ir_node *ldst_insert_const(ir_node *ptr, tarval **ptv, ident **pid, ppc32 } else if(is_ppc32_SymConst(ptr)) { +#if 0 ir_entity *ent = get_ppc32_frame_entity(ptr); if(is_direct_entity(ent)) { id_symconst = get_entity_ident(ent); ptr = new_bd_ppc32_Addis_zero(env->dbg, env->block, mode_P, ppc32_ao_Ha16, NULL, id_symconst); } +#endif } *ptv = tv_const; *pid = id_symconst; @@ -1383,7 +1383,9 @@ static int cmp_tv_ent(const void *a, const void *b, size_t len) { } /** Generates a SymConst node for a known FP const */ -static ir_node *gen_fp_known_symconst(ppc32_transform_env_t *env, tarval *known_const) { +static ir_node *gen_fp_known_symconst(ppc32_transform_env_t *env, + tarval *known_const) +{ static set *const_set = NULL; static ir_type *tp = NULL; struct tv_ent key; @@ -1408,9 +1410,7 @@ static ir_node *gen_fp_known_symconst(ppc32_transform_env_t *env, tarval *known_ ent = new_entity(get_glob_type(), new_id_from_str(buf), tp); set_entity_ld_ident(ent, get_entity_ident(ent)); - set_entity_visibility(ent, visibility_local); - set_entity_variability(ent, variability_constant); - set_entity_allocation(ent, allocation_static); + set_entity_linkage(ent, IR_LINKAGE_CONSTANT|IR_LINKAGE_LOCAL); /* we create a new entity here: It's initialization must resist on the const code irg */ @@ -1532,6 +1532,7 @@ static ir_node *gen_ppc32_fConst(ppc32_transform_env_t *env) { env->irn = gen_fp_known_symconst(env, tv_const); env->mode = mode_P; ent = get_ppc32_frame_entity(env->irn); +#if 0 if(is_direct_entity(ent)) { ident *id_symconst = get_entity_ident(ent); @@ -1547,12 +1548,15 @@ static ir_node *gen_ppc32_fConst(ppc32_transform_env_t *env) { } else { +#endif addr = gen_ppc32_SymConst (env); if(mode==mode_D) load = new_bd_ppc32_Lfd(env->dbg, env->block, addr, new_NoMem()); else // mode_F load = new_bd_ppc32_Lfs(env->dbg, env->block, addr, new_NoMem()); +#if 0 } +#endif return new_rd_Proj(env->dbg, env->block, load, mode, pn_Load_res); } @@ -1561,24 +1565,6 @@ static ir_node *gen_ppc32_fConst(ppc32_transform_env_t *env) { } } - -/** - * Returns true, if the entity can be accessed directly, - * or false, if the address must be loaded first - */ -int is_direct_entity(ir_entity *ent) { - return get_entity_visibility(ent) != visibility_external_allocated; -/* visibility vis = get_entity_visibility(ent); - if(is_Method_type(get_entity_type(ent))) - { - return (vis!=visibility_external_allocated); - } - else - { - return (vis==visibility_local); - }*/ -} - /** * Transforms a SymConst. * @@ -1595,12 +1581,15 @@ static ir_node *gen_ppc32_SymConst(ppc32_transform_env_t *env) { switch(get_nice_modecode(env->mode)){ case irm_P: { + /* if (is_direct_entity(ent)) { + */ ir_node *node_addis = new_bd_ppc32_Addis_zero(env->dbg, env->block, env->mode, ppc32_ao_Hi16, NULL, id_symconst); node = new_bd_ppc32_Ori(env->dbg, env->block, node_addis, env->mode); set_ppc32_symconst_ident(node, id_symconst); set_ppc32_offset_mode(node, ppc32_ao_Lo16); +#if 0 } else { @@ -1610,6 +1599,7 @@ static ir_node *gen_ppc32_SymConst(ppc32_transform_env_t *env) { set_ppc32_offset_mode(node, ppc32_ao_Lo16); node = new_rd_Proj(env->dbg, env->block, node, env->mode, pn_Load_res); } +#endif break; } diff --git a/ir/be/sparc/bearch_sparc.c b/ir/be/sparc/bearch_sparc.c index ea14c88d3..5d27934bb 100644 --- a/ir/be/sparc/bearch_sparc.c +++ b/ir/be/sparc/bearch_sparc.c @@ -332,8 +332,6 @@ static void *sparc_cg_init(be_irg_t *birg) //cg->unknown_fpa = NULL; cg->dump = (birg->main_env->options->dump_flags & DUMP_BE) ? 1 : 0; - FIRM_DBG_REGISTER(cg->mod, "firm.be.sparc.cg"); - /* enter the current code generator */ isa->cg = cg; diff --git a/ir/be/sparc/bearch_sparc_t.h b/ir/be/sparc/bearch_sparc_t.h index ef28b1a9d..c1da87e22 100644 --- a/ir/be/sparc/bearch_sparc_t.h +++ b/ir/be/sparc/bearch_sparc_t.h @@ -41,7 +41,6 @@ typedef struct _sparc_code_gen_t { sparc_isa_t *isa; /**< the isa instance */ be_irg_t *birg; /**< The be-irg (contains additional information about the irg) */ char dump; /**< set to 1 if graphs should be dumped */ - firm_dbg_module_t *mod; /**< debugging module */ } sparc_code_gen_t; diff --git a/ir/ir/irdump.c b/ir/ir/irdump.c index 462f062a3..e3581ec0c 100644 --- a/ir/ir/irdump.c +++ b/ir/ir/irdump.c @@ -1947,10 +1947,7 @@ static void print_typespecific_info(FILE *F, ir_type *tp) { static void print_typespecific_vcgattr(FILE *F, ir_type *tp) { switch (get_type_tpop_code(tp)) { case tpo_class: - if (peculiarity_existent == get_class_peculiarity(tp)) - fprintf(F, " " TYPE_CLASS_NODE_ATTR); - else - fprintf(F, " " TYPE_DESCRIPTION_NODE_ATTR); + fprintf(F, " " TYPE_CLASS_NODE_ATTR); break; case tpo_struct: fprintf(F, " " TYPE_METH_NODE_ATTR); @@ -1972,7 +1969,6 @@ static void print_typespecific_vcgattr(FILE *F, ir_type *tp) { } /* switch type */ } - int dump_type_node(FILE *F, ir_type *tp) { int bad = 0; @@ -2059,33 +2055,23 @@ static void dump_type_info(type_or_ent tore, void *env) { print_ent_ent_edge(F,ent, get_entity_overwrites(ent, i), 0, -1, ENT_OVERWRITES_EDGE_ATTR); } /* attached subgraphs */ - if (const_entities && (get_entity_variability(ent) != variability_uninitialized)) { - if (is_atomic_entity(ent)) { - value = get_atomic_ent_value(ent); - if (value) { - print_ent_node_edge(F, ent, value, ENT_VALUE_EDGE_ATTR, i); - /* DDMN(value); $$$ */ - dump_const_expression(F, value); - } - } - if (is_compound_entity(ent)) { - if (has_entity_initializer(ent)) { - /* new style initializers */ - dump_entity_initializer(F, ent); - } else { - /* old style compound entity values */ - for (i = get_compound_ent_n_values(ent) - 1; i >= 0; --i) { - value = get_compound_ent_value(ent, i); - if (value) { - print_ent_node_edge(F, ent, value, ENT_VALUE_EDGE_ATTR, i); - dump_const_expression(F, value); - print_ent_ent_edge(F, ent, get_compound_ent_value_member(ent, i), 0, -1, ENT_CORR_EDGE_ATTR, i); - /* - fprintf(F, "edge: { sourcename: \"%p\" targetname: \"%p\" " - ENT_CORR_EDGE_ATTR "}\n", GET_ENTID(ent), - get_compound_ent_value_member(ent, i), i); - */ - } + if (const_entities) { + if (ent->initializer != NULL) { + /* new style initializers */ + dump_entity_initializer(F, ent); + } else if (entity_has_compound_ent_values(ent)) { + /* old style compound entity values */ + for (i = get_compound_ent_n_values(ent) - 1; i >= 0; --i) { + value = get_compound_ent_value(ent, i); + if (value) { + print_ent_node_edge(F, ent, value, ENT_VALUE_EDGE_ATTR, i); + dump_const_expression(F, value); + print_ent_ent_edge(F, ent, get_compound_ent_value_member(ent, i), 0, -1, ENT_CORR_EDGE_ATTR, i); + /* + fprintf(F, "edge: { sourcename: \"%p\" targetname: \"%p\" " + ENT_CORR_EDGE_ATTR "}\n", GET_ENTID(ent), + get_compound_ent_value_member(ent, i), i); + */ } } } diff --git a/ir/ir/irdumptxt.c b/ir/ir/irdumptxt.c index 7d90a662a..e36235260 100644 --- a/ir/ir/irdumptxt.c +++ b/ir/ir/irdumptxt.c @@ -613,6 +613,25 @@ static void dump_ir_initializers_to_file(FILE *F, const char *prefix, need_nl = 1; } +static void dump_entity_linkage(FILE *F, const ir_entity *entity) +{ + ir_linkage linkage = get_entity_linkage(entity); + + if (linkage & IR_LINKAGE_CONSTANT) + fprintf(F, " constant"); + if (linkage & IR_LINKAGE_WEAK) + fprintf(F, " weak"); + if (linkage & IR_LINKAGE_LOCAL) + fprintf(F, " local"); + if (linkage & IR_LINKAGE_EXTERN) + fprintf(F, " extern"); + if (linkage & IR_LINKAGE_GARBAGE_COLLECT) + fprintf(F, " garbage_collect"); + if (linkage & IR_LINKAGE_MERGE) + fprintf(F, " merge"); + if (linkage & IR_LINKAGE_HIDDEN_USER) + fprintf(F, " hidden_user"); +} void dump_entity_to_file_prefix(FILE *F, ir_entity *ent, char *prefix, unsigned verbosity) { int i, j; @@ -674,9 +693,8 @@ void dump_entity_to_file_prefix(FILE *F, ir_entity *ent, char *prefix, unsigned } } - fprintf(F, "%s allocation: %s", prefix, get_allocation_name(get_entity_allocation(ent))); - fprintf(F, "\n%s visibility: %s", prefix, get_visibility_name(get_entity_visibility(ent))); - fprintf(F, "\n%s variability: %s", prefix, get_variability_name(get_entity_variability(ent))); + fprintf(F, "%s linkage:", prefix); + dump_entity_linkage(F, ent); if (is_Method_type(get_entity_type(ent))) { unsigned mask = get_entity_additional_properties(ent); @@ -729,54 +747,45 @@ void dump_entity_to_file_prefix(FILE *F, ir_entity *ent, char *prefix, unsigned if (is_Method_type(get_entity_type(ent))) fputs("(...)", F); if (verbosity & dump_verbosity_accessStats) { - if (get_entity_allocation(ent) == allocation_static) fputs(" (stat)", F); - if (get_entity_peculiarity(ent) == peculiarity_description) fputs(" (desc)", F); - if (get_entity_peculiarity(ent) == peculiarity_inherited) fputs(" (inh)", F); + dump_entity_linkage(F, ent); } fputc('\n', F); } if (verbosity & dump_verbosity_entconsts) { - if (get_entity_variability(ent) != variability_uninitialized) { - if (ent->has_initializer) { - const ir_initializer_t *initializer = get_entity_initializer(ent); - fprintf(F, "\n%s Initializers:", prefix); - need_nl = 1; - dump_ir_initializers_to_file(F, prefix, initializer, get_entity_type(ent)); - } else { - /* old compound_graph_path based initializers */ - if (is_atomic_entity(ent)) { - fprintf(F, "%s atomic value: ", prefix); - dump_node_opcode(F, get_atomic_ent_value(ent)); - } else { - fprintf(F, "%s compound values:", prefix); - for (i = 0; i < get_compound_ent_n_values(ent); ++i) { - compound_graph_path *path = get_compound_ent_value_path(ent, i); - ir_entity *ent0 = get_compound_graph_path_node(path, 0); - fprintf(F, "\n%s %3d:%u ", prefix, get_entity_offset(ent0), get_entity_offset_bits_remainder(ent0)); - if (get_type_state(type) == layout_fixed) - fprintf(F, "(%3u:%u) ", get_compound_ent_value_offset_bytes(ent, i), get_compound_ent_value_offset_bit_remainder(ent, i)); - fprintf(F, "%s", get_entity_name(ent)); - for (j = 0; j < get_compound_graph_path_length(path); ++j) { - ir_entity *node = get_compound_graph_path_node(path, j); - fprintf(F, ".%s", get_entity_name(node)); - if (is_Array_type(get_entity_owner(node))) - fprintf(F, "[%d]", get_compound_graph_path_array_index(path, j)); - } - fprintf(F, "\t = "); - dump_node_opcode(F, get_compound_ent_value(ent, i)); - } + if (ent->initializer != NULL) { + const ir_initializer_t *initializer = get_entity_initializer(ent); + fprintf(F, "\n%s Initializers:", prefix); + need_nl = 1; + dump_ir_initializers_to_file(F, prefix, initializer, get_entity_type(ent)); + } else if (entity_has_compound_ent_values(ent)) { + fprintf(F, "%s compound values:", prefix); + for (i = 0; i < get_compound_ent_n_values(ent); ++i) { + compound_graph_path *path = get_compound_ent_value_path(ent, i); + ir_entity *ent0 = get_compound_graph_path_node(path, 0); + fprintf(F, "\n%s %3d:%u ", prefix, get_entity_offset(ent0), get_entity_offset_bits_remainder(ent0)); + if (get_type_state(type) == layout_fixed) + fprintf(F, "(%3u:%u) ", get_compound_ent_value_offset_bytes(ent, i), get_compound_ent_value_offset_bit_remainder(ent, i)); + fprintf(F, "%s", get_entity_name(ent)); + for (j = 0; j < get_compound_graph_path_length(path); ++j) { + ir_entity *node = get_compound_graph_path_node(path, j); + fprintf(F, ".%s", get_entity_name(node)); + if (is_Array_type(get_entity_owner(node))) + fprintf(F, "[%d]", get_compound_graph_path_array_index(path, j)); } + fprintf(F, "\t = "); + dump_node_opcode(F, get_compound_ent_value(ent, i)); } fputc('\n', F); } } if (verbosity & dump_verbosity_entattrs) { + fprintf(F, "%s linkage:", prefix); + dump_entity_linkage(F, ent); fprintf(F, "%s volatility: %s", prefix, get_volatility_name(get_entity_volatility(ent))); fprintf(F, "\n%s aligned: %s", prefix, get_align_name(get_entity_aligned(ent))); fprintf(F, "\n%s alignment: %u", prefix, get_entity_alignment(ent)); - fprintf(F, "\n%s peculiarity: %s", prefix, get_peculiarity_name(get_entity_peculiarity(ent))); fprintf(F, "\n%s ld_name: %s", prefix, ent->ld_name ? get_entity_ld_name(ent) : "no yet set"); fprintf(F, "\n%s offset: %d bytes, %d rem bits", prefix, get_entity_offset(ent), get_entity_offset_bits_remainder(ent)); if (is_Method_type(get_entity_type(ent))) { @@ -929,207 +938,6 @@ void dump_entity(ir_entity *ent) { dump_entity_to_file(stdout, ent, dump_verbosity_max); } -void dump_entitycsv_to_file_prefix(FILE *F, ir_entity *ent, char *prefix, - unsigned verbosity, int *max_disp, - int disp[], const char *comma) -{ - (void) verbosity; - (void) max_disp; - (void) disp; - (void) comma; -#if 0 /* Outputs loop depth of all occurrences. */ - int n_acc = get_entity_n_accesses(ent); - int max_L_freq = -1; - int max_S_freq = -1; - int max_LA_freq = -1; - int max_SA_freq = -1; - int *L_freq; - int *S_freq; - int *LA_freq; - int *SA_freq; - int i, max_depth = 0; - - /* Find maximal depth */ - for (i = 0; i < n_acc; ++i) { - ir_node *acc = get_entity_access(ent, i); - int depth = get_weighted_loop_depth(acc); - max_depth = (depth > max_depth) ? depth : max_depth ; - } - - L_freq = XMALLOCNZ(int, 4 * (max_depth + 1)); - - S_freq = L_freq + 1*max_depth; - LA_freq = L_freq + 2*max_depth; - SA_freq = L_freq + 3*max_depth; - - for (i = 0; i < n_acc; ++i) { - ir_node *acc = get_entity_access(ent, i); - int depth = get_weighted_loop_depth(acc); - assert(depth <= max_depth); - if (is_Load(acc) || is_Call(acc)) { - L_freq[depth]++; - max_L_freq = (depth > max_L_freq) ? depth : max_L_freq; - if (addr_is_alloc(acc)) { - LA_freq[depth]++; - max_LA_freq = (depth > max_LA_freq) ? depth : max_LA_freq; - } - if (get_entity_allocation(ent) == allocation_static) { - disp[depth]++; - *max_disp = (depth > *max_disp) ? depth : *max_disp; - } - } else if (is_Store(acc)) { - S_freq[depth]++; - max_S_freq = (depth > max_S_freq) ? depth : max_S_freq; - if (addr_is_alloc(acc)) { - SA_freq[depth]++; - max_SA_freq = (depth > max_SA_freq) ? depth : max_SA_freq; - } - if (get_entity_allocation(ent) == allocation_static) { - assert(0); - } - } else { - assert(0); - } - } - - if (get_entity_allocation(ent) != allocation_static) { - - ir_fprintf(F, "%+F_%s", get_entity_owner(ent), get_entity_name(ent)); - - if (max_L_freq >= 0) { - fprintf(F, "%s Load", comma); - for (i = 0; i <= max_L_freq; ++i) { - fprintf(F, "%s %d", comma, L_freq[i]); - } - } - if (max_S_freq >= 0) { - if (max_L_freq >= 0) { - ir_fprintf(F, "\n%+F_%s", get_entity_owner(ent), - get_entity_name(ent)); - } - fprintf(F, "%s Store", comma); - for (i = 0; i <= max_S_freq; ++i) { - fprintf(F, "%s %d", comma, S_freq[i]); - } - } - fprintf(F, "\n"); - } - free(L_freq); -#endif - - if (get_entity_allocation(ent) != allocation_static) { - if (is_Method_type(get_entity_type(ent))) return; - - /* Output the entity name. */ - fprintf(F, "%s%-40s ", prefix, get_entity_ld_name(ent)); - -#ifdef INTERPROCEDURAL_VIEW - if (get_trouts_state() != outs_none) { - if (is_Method_type(get_entity_type(ent))) { - //fprintf(F, "%s Estimated #Calls: %lf\n", prefix, get_entity_estimated_n_calls(ent)); - //fprintf(F, "%s Estimated #dynCalls: %lf\n", prefix, get_entity_estimated_n_calls(ent)); - } else { - fprintf(F, "%6.2lf ", get_entity_estimated_n_loads(ent)); - fprintf(F, "%6.2lf", get_entity_estimated_n_stores(ent)); - } - } -#endif - - fprintf(F, "\n"); - } -} - -#ifdef INTERPROCEDURAL_VIEW -/* A fast hack to dump a CSV-file. */ -void dump_typecsv_to_file(FILE *F, ir_type *tp, dump_verbosity verbosity, const char *comma) { - int i; - char buf[1024]; - (void) comma; - - if (!is_Class_type(tp)) return; // we also want array types. Stupid, these are classes in java. - - if (verbosity & dump_verbosity_accessStats) { - -#if 0 - /* Outputs loop depth of all occurrences. */ - int max_freq = -1; - int max_disp = -1; - int *freq, *disp; /* Accumulated accesses to static members: dispatch table. */ - int n_all = get_type_n_allocs(tp); - int max_depth = 0; - /* Find maximal depth */ - for (i = 0; i < n_all; ++i) { - ir_node *all = get_type_alloc(tp, i); - int depth = get_weighted_loop_depth(all); - max_depth = (depth > max_depth) ? depth : max_depth ; - } - - freq = XMALLOCNZ(int, 2 * (max_depth + 1)); - - disp = freq + max_depth; - - for (i = 0; i < n_all; ++i) { - ir_node *all = get_type_alloc(tp, i); - int depth = get_weighted_loop_depth(all); - assert(depth <= max_depth); - freq[depth]++; - max_freq = (depth > max_freq) ? depth : max_freq; - assert(is_Alloc(all)); - } - - ir_fprintf(F, "%+F ", tp); - fprintf(F, "%s Alloc ", comma); - - if (max_freq >= 0) { - for (i = 0; i <= max_freq; ++i) { - fprintf(F, "%s %d", comma, freq[i]); - } - } - fprintf(F, "\n"); - - for (i = 0; i < get_class_n_members(tp); ++i) { - ir_entity *mem = get_class_member(tp, i); - if (((verbosity & dump_verbosity_methods) && is_Method_type(get_entity_type(mem))) || - ((verbosity & dump_verbosity_fields) && !is_Method_type(get_entity_type(mem))) ) { - if (!((verbosity & dump_verbosity_nostatic) && (get_entity_allocation(mem) == allocation_static))) { - dump_entitycsv_to_file_prefix(F, mem, " ", verbosity, &max_disp, disp, comma); - } - } - } - - if (max_disp >= 0) { - ir_fprintf(F, "%+F__disp_tab%s Load", tp, comma); - for (i = 0; i <= max_disp; ++i) { - fprintf(F, "%s %d", comma, disp[i]); - } - fprintf(F, "\n"); - } - - /* free allocated space */ - free(freq); -#endif - -#define DISP_TAB_SUFFIX "__disp_tab" - if (get_trouts_state() != outs_none) { - ir_fprintf(F, "%+F %6.2lf -1.00\n", tp, - get_type_estimated_n_instances(tp)); - ir_snprintf(buf, sizeof(buf), "%+F%s", tp, DISP_TAB_SUFFIX); - fprintf(F, "%-44s %6.2lf 0.00\n", buf, get_class_estimated_n_dyncalls(tp)); - } - - for (i = 0; i < get_class_n_members(tp); ++i) { - ir_entity *mem = get_class_member(tp, i); - if (((verbosity & dump_verbosity_methods) && is_Method_type(get_entity_type(mem))) || - ((verbosity & dump_verbosity_fields) && !is_Method_type(get_entity_type(mem))) ) { - if (!((verbosity & dump_verbosity_nostatic) && (get_entity_allocation(mem) == allocation_static))) { - dump_entitycsv_to_file_prefix(F, mem, " ", verbosity, NULL, 0, 0); - } - } - } - } -} -#endif - void dump_type_to_file(FILE *F, ir_type *tp, dump_verbosity verbosity) { int i; @@ -1155,7 +963,7 @@ void dump_type_to_file(FILE *F, ir_type *tp, dump_verbosity verbosity) { ir_entity *mem = get_class_member(tp, i); if (((verbosity & dump_verbosity_methods) && is_Method_type(get_entity_type(mem))) || ((verbosity & dump_verbosity_fields) && !is_Method_type(get_entity_type(mem))) ) { - if (!((verbosity & dump_verbosity_nostatic) && (get_entity_allocation(mem) == allocation_static))) { + if (!(verbosity & dump_verbosity_nostatic)) { dump_entity_to_file_prefix(F, mem, " ", verbosity); } } @@ -1188,7 +996,6 @@ void dump_type_to_file(FILE *F, ir_type *tp, dump_verbosity verbosity) { } } - fprintf(F, "\n peculiarity: %s\n", get_peculiarity_name(get_class_peculiarity(tp))); fprintf(F, "\n flags: "); if (is_class_final(tp)) fprintf(F, "final, "); @@ -1304,7 +1111,6 @@ void dump_type_to_file(FILE *F, ir_type *tp, dump_verbosity verbosity) { } } - fprintf(F, " visibility: %s,\n", get_visibility_name(get_type_visibility(tp))); fprintf(F, " state: %s,\n", get_type_state_name(get_type_state(tp))); fprintf(F, " size: %2u Bytes,\n", get_type_size_bytes(tp)); fprintf(F, " alignment: %2u Bytes,\n", get_type_alignment_bytes(tp)); @@ -1380,61 +1186,39 @@ void dump_type(ir_type *tp) { dump_type_to_file (stdout, tp, dump_verbosity_max); } - void dump_types_as_text(unsigned verbosity, const char *suffix) { const char *basename; - FILE *F, *CSV = NULL; + FILE *F; int i, n_types = get_irp_n_types(); basename = irp_prog_name_is_set() ? get_irp_name() : "TextTypes"; F = text_open(basename, suffix, "-types", ".txt"); - if (verbosity & dump_verbosity_csv) { - CSV = text_open(basename, suffix, "-types", ".csv"); - //fprintf(CSV, "Class, Field, Operation, L0, L1, L2, L3\n"); - } - for (i = 0; i < n_types; ++i) { ir_type *t = get_irp_type(i); //if (is_jack_rts_class(t)) continue; dump_type_to_file(F, t, verbosity); -#ifdef INTERPROCEDURAL_VIEW - if (CSV) { - dump_typecsv_to_file(CSV, t, verbosity, ""); - } -#endif } fclose(F); - if (CSV) fclose(CSV); } - void dump_globals_as_text(unsigned verbosity, const char *suffix) { const char *basename; - FILE *F, *CSV = NULL; + FILE *F; ir_type *g = get_glob_type(); int i, n_mems = get_class_n_members(g); basename = irp_prog_name_is_set() ? get_irp_name() : "TextGlobals"; F = text_open (basename, suffix, "-globals", ".txt"); - if (verbosity & dump_verbosity_csv) { - CSV = text_open (basename, suffix, "-types", ".csv"); - //fprintf(CSV, "Class, Field, Operation, L0, L1, L2, L3\n"); - } - for (i = 0; i < n_mems; ++i) { ir_entity *e = get_class_member(g, i); dump_entity_to_file(F, e, verbosity); - if (CSV) { - //dump_entitycsv_to_file_prefix(CSV, e, "", verbosity, ""???); - } } fclose (F); - if (CSV) fclose (CSV); } diff --git a/ir/ir/irgraph.c b/ir/ir/irgraph.c index 58cfe0513..e73cbaeb3 100644 --- a/ir/ir/irgraph.c +++ b/ir/ir/irgraph.c @@ -527,7 +527,8 @@ ir_graph *create_irg_copy(ir_graph *irg) { inefficient search, call remove_irp_irg by hand). Does not free types, entities or modes that are used only by this graph, nor the entity standing for this graph. */ -void free_ir_graph(ir_graph *irg) { +void free_ir_graph(ir_graph *irg) +{ assert(is_ir_graph(irg)); edges_deactivate(irg); @@ -540,10 +541,7 @@ void free_ir_graph(ir_graph *irg) { if (irg->value_table) del_identities(irg->value_table); if (irg->ent) { - ir_peculiarity pec = get_entity_peculiarity (irg->ent); - set_entity_peculiarity (irg->ent, peculiarity_description); set_entity_irg(irg->ent, NULL); /* not set in const code irg */ - set_entity_peculiarity (irg->ent, pec); } free_End(get_irg_end(irg)); diff --git a/ir/ir/irgwalk.c b/ir/ir/irgwalk.c index 80545fd7f..a7ca5ff57 100644 --- a/ir/ir/irgwalk.c +++ b/ir/ir/irgwalk.c @@ -698,17 +698,13 @@ static void walk_entity(ir_entity *ent, void *env) { walk_env *my_env = (walk_env *)env; - if (get_entity_variability(ent) != variability_uninitialized) { - if (ent->has_initializer) { - walk_initializer(ent->attr.initializer, my_env); - } else if (is_atomic_entity(ent)) { - irg_walk(get_atomic_ent_value(ent), my_env->pre, my_env->post, my_env->env); - } else { - int i, n_vals = get_compound_ent_n_values(ent); - - for (i = 0; i < n_vals; i++) - irg_walk(get_compound_ent_value(ent, i), my_env->pre, my_env->post, my_env->env); - } + if (ent->initializer != NULL) { + walk_initializer(ent->initializer, my_env); + } else if (entity_has_compound_ent_values(ent)) { + int i, n_vals = get_compound_ent_n_values(ent); + + for (i = 0; i < n_vals; i++) + irg_walk(get_compound_ent_value(ent, i), my_env->pre, my_env->post, my_env->env); } } diff --git a/ir/ir/irio.c b/ir/ir/irio.c index f10c74c39..1a9893c41 100644 --- a/ir/ir/irio.c +++ b/ir/ir/irio.c @@ -71,13 +71,11 @@ typedef enum typetag_t tt_keyword, tt_mode_sort, tt_mode_arithmetic, - tt_peculiarity, tt_pin_state, tt_tpo, tt_type_state, - tt_variability, - tt_visibility, tt_volatility, + tt_linkage, tt_segment } typetag_t; @@ -193,6 +191,14 @@ static void symtbl_init(void) INSERT(tt_segment, "constructors", IR_SEGMENT_CONSTRUCTORS); INSERT(tt_segment, "destructors", IR_SEGMENT_DESTRUCTORS); + INSERT(tt_linkage, "constant", IR_LINKAGE_CONSTANT); + INSERT(tt_linkage, "weak", IR_LINKAGE_WEAK); + INSERT(tt_linkage, "local", IR_LINKAGE_LOCAL); + INSERT(tt_linkage, "extern", IR_LINKAGE_EXTERN); + INSERT(tt_linkage, "garbage_collect", IR_LINKAGE_GARBAGE_COLLECT); + INSERT(tt_linkage, "merge", IR_LINKAGE_MERGE); + INSERT(tt_linkage, "hidden_user", IR_LINKAGE_HIDDEN_USER); + INSERTKEYWORD(constirg); INSERTKEYWORD(entity); INSERTKEYWORD(irg); @@ -208,11 +214,6 @@ static void symtbl_init(void) INSERTENUM(tt_align, align_non_aligned); INSERTENUM(tt_align, align_is_aligned); - INSERTENUM(tt_allocation, allocation_automatic); - INSERTENUM(tt_allocation, allocation_parameter); - INSERTENUM(tt_allocation, allocation_dynamic); - INSERTENUM(tt_allocation, allocation_static); - INSERTENUM(tt_builtin, ir_bk_trap); INSERTENUM(tt_builtin, ir_bk_debugbreak); INSERTENUM(tt_builtin, ir_bk_return_address); @@ -245,10 +246,6 @@ static void symtbl_init(void) INSERTENUM(tt_mode_arithmetic, irma_ieee754); INSERTENUM(tt_mode_arithmetic, irma_float_BCD); - INSERTENUM(tt_peculiarity, peculiarity_description); - INSERTENUM(tt_peculiarity, peculiarity_inherited); - INSERTENUM(tt_peculiarity, peculiarity_existent); - INSERTENUM(tt_pin_state, op_pin_state_floats); INSERTENUM(tt_pin_state, op_pin_state_pinned); INSERTENUM(tt_pin_state, op_pin_state_exc_pinned); @@ -257,15 +254,6 @@ static void symtbl_init(void) INSERTENUM(tt_type_state, layout_undefined); INSERTENUM(tt_type_state, layout_fixed); - INSERTENUM(tt_variability, variability_uninitialized); - INSERTENUM(tt_variability, variability_initialized); - INSERTENUM(tt_variability, variability_part_constant); - INSERTENUM(tt_variability, variability_constant); - - INSERTENUM(tt_visibility, visibility_local); - INSERTENUM(tt_visibility, visibility_external_visible); - INSERTENUM(tt_visibility, visibility_external_allocated); - INSERTENUM(tt_volatility, volatility_non_volatile); INSERTENUM(tt_volatility, volatility_is_volatile); @@ -412,13 +400,12 @@ static void write_volatility(io_env_t *env, ir_node *irn) static void export_type_common(io_env_t *env, ir_type *tp) { - fprintf(env->file, "\ttype %ld %s %u %u %s %s %d ", + fprintf(env->file, "\ttype %ld %s %u %u %s %d ", get_type_nr(tp), get_type_tpop_name(tp), get_type_size_bytes(tp), get_type_alignment_bytes(tp), get_type_state_name(get_type_state(tp)), - get_visibility_name(get_type_visibility(tp)), tp->flags); } @@ -573,43 +560,32 @@ static void export_entity(io_env_t *env, ir_entity *ent) fprintf(env->file, "NULL "); } - fprintf(env->file, "%ld %ld %d %u %d %s %s %s %s %s ", + fprintf(env->file, "%ld %ld %d %u %d %s ", get_type_nr(get_entity_type(ent)), get_type_nr(owner), get_entity_offset(ent), (unsigned) get_entity_offset_bits_remainder(ent), is_entity_compiler_generated(ent), - get_allocation_name(get_entity_allocation(ent)), - get_visibility_name(get_entity_visibility(ent)), - get_variability_name(get_entity_variability(ent)), - get_peculiarity_name(get_entity_peculiarity(ent)), get_volatility_name(get_entity_volatility(ent))); /* TODO: inheritance stuff for class entities not supported yet */ if (is_Class_type(owner) && owner != get_glob_type()) fprintf(stderr, "Inheritance of class entities not supported yet!\n"); - if (get_entity_variability(ent) != variability_uninitialized && - get_entity_visibility(ent) != visibility_external_allocated) - { - if (is_compound_entity(ent)) { - if (has_entity_initializer(ent)) { - fputs("initializer ", env->file); - write_initializer(env, get_entity_initializer(ent)); - } else { - int i, n = get_compound_ent_n_values(ent); - fputs("noninitializer ", env->file); - fprintf(env->file, "%d ", n); - for (i = 0; i < n; i++) { - ir_entity *member = get_compound_ent_value_member(ent, i); - ir_node *irn = get_compound_ent_value(ent, i); - fprintf(env->file, "%ld %ld ", get_entity_nr(member), get_irn_node_nr(irn)); - } - } - } else { - ir_node *irn = get_atomic_ent_value(ent); - fprintf(env->file, "%ld ", get_irn_node_nr(irn)); + if (ent->initializer != NULL) { + fputs("initializer ", env->file); + write_initializer(env, get_entity_initializer(ent)); + } else if (entity_has_compound_ent_values(ent)) { + int i, n = get_compound_ent_n_values(ent); + fputs("compoundgraph ", env->file); + fprintf(env->file, "%d ", n); + for (i = 0; i < n; i++) { + ir_entity *member = get_compound_ent_value_member(ent, i); + ir_node *irn = get_compound_ent_value(ent, i); + fprintf(env->file, "%ld %ld ", get_entity_nr(member), get_irn_node_nr(irn)); } + } else { + fputs("none", env->file); } fputc('\n', env->file); @@ -1088,20 +1064,18 @@ static const char *get_typetag_name(typetag_t typetag) case tt_align: return "align"; case tt_allocation: return "allocation"; case tt_builtin: return "builtin kind"; + case tt_cond_jmp_predicate: return "cond_jmp_predicate"; case tt_initializer: return "initializer kind"; case tt_iro: return "opcode"; - case tt_peculiarity: return "peculiarity"; + case tt_keyword: return "keyword"; + case tt_linkage: return "linkage"; + case tt_mode_arithmetic: return "mode_arithmetic"; + case tt_mode_sort: return "mode_sort"; case tt_pin_state: return "pin state"; + case tt_segment: return "segment"; case tt_tpo: return "type"; case tt_type_state: return "type state"; - case tt_variability: return "variability"; - case tt_visibility: return "visibility"; case tt_volatility: return "volatility"; - case tt_cond_jmp_predicate: return "cond_jmp_predicate"; - case tt_keyword: return "keyword"; - case tt_mode_sort: return "mode_sort"; - case tt_mode_arithmetic: return "mode_arithmetic"; - case tt_segment: return "segment"; } return ""; } @@ -1133,7 +1107,6 @@ static unsigned read_enum(io_env_t *env, typetag_t typetag) #define read_pin_state(env) ((op_pin_state) read_enum(env, tt_pin_state)) #define read_type_state(env) ((ir_type_state) read_enum(env, tt_type_state)) #define read_variability(env) ((ir_variability) read_enum(env, tt_variability)) -#define read_visibility(env) ((ir_visibility) read_enum(env, tt_visibility)) #define read_volatility(env) ((ir_volatility) read_enum(env, tt_volatility)) static ir_cons_flags get_cons_flags(io_env_t *env) @@ -1209,7 +1182,6 @@ static void import_type(io_env_t *env) unsigned size = (unsigned) read_long(env); unsigned align = (unsigned) read_long(env); ir_type_state state = read_type_state(env); - ir_visibility vis = read_visibility(env); unsigned flags = (unsigned) read_long(env); switch (tpop) { @@ -1325,7 +1297,6 @@ static void import_type(io_env_t *env) } set_type_alignment_bytes(type, align); - set_type_visibility(type, vis); type->flags = flags; if (state == layout_fixed) @@ -1342,6 +1313,7 @@ static void import_entity(io_env_t *env) ident *ld_name = read_ident_null(env); long typenr = read_long(env); long ownertypenr = read_long(env); + const char *str; ir_type *type = get_type(env, typenr); ir_type *ownertype = !ownertypenr ? get_glob_type() : get_type(env, ownertypenr); @@ -1352,35 +1324,25 @@ static void import_entity(io_env_t *env) set_entity_offset (entity, (int) read_long(env)); set_entity_offset_bits_remainder(entity, (unsigned char) read_long(env)); set_entity_compiler_generated(entity, (int) read_long(env)); - set_entity_allocation (entity, read_allocation(env)); - set_entity_visibility (entity, read_visibility(env)); - set_entity_variability(entity, read_variability(env)); - set_entity_peculiarity(entity, read_peculiarity(env)); set_entity_volatility (entity, read_volatility(env)); - - if (get_entity_variability(entity) != variability_uninitialized && - get_entity_visibility(entity) != visibility_external_allocated) { - - if (is_compound_entity(entity)) { - char *str = read_word(env); - if (strcmp(str, "initializer") == 0) { - set_entity_initializer(entity, read_initializer(env)); - } else if (strcmp(str, "noninitializer") == 0) { - int n = (int) read_long(env); - int i; - for (i = 0; i < n; i++) { - ir_entity *member = get_entity(env, read_long(env)); - ir_node *irn = get_node_or_dummy(env, read_long(env)); - add_compound_ent_value(entity, irn, member); - } - } else { - parse_error(env, "expected 'initializer' or 'noninitializer', got '%s'\n", str); - exit(1); - } - } else { - ir_node *irn = get_node_or_dummy(env, read_long(env)); - set_atomic_ent_value(entity, irn); + /* TODO: read/write linkage */ + + str = read_word(env); + if (strcmp(str, "initializer") == 0) { + set_entity_initializer(entity, read_initializer(env)); + } else if (strcmp(str, "compoundgraph") == 0) { + int n = (int) read_long(env); + int i; + for (i = 0; i < n; i++) { + ir_entity *member = get_entity(env, read_long(env)); + ir_node *irn = get_node_or_dummy(env, read_long(env)); + add_compound_ent_value(entity, irn, member); } + } else if (strcmp(str, "none") == 0) { + /* do nothing */ + } else { + parse_error(env, "expected 'initializer', 'compoundgraph' or 'none' got '%s'\n", str); + exit(1); } set_id(env, entnr, entity); diff --git a/ir/ir/irnode.c b/ir/ir/irnode.c index 854664b5f..7f320c3bd 100644 --- a/ir/ir/irnode.c +++ b/ir/ir/irnode.c @@ -818,10 +818,10 @@ ir_entity *create_Block_entity(ir_node *block) { glob = get_glob_type(); entity = new_entity(glob, id_unique("block_%u"), get_code_type()); + set_entity_linkage(entity, IR_LINKAGE_LOCAL|IR_LINKAGE_CONSTANT); nr = get_irp_next_label_nr(); set_entity_label(entity, nr); set_entity_compiler_generated(entity, 1); - set_entity_allocation(entity, allocation_static); block->attr.block.entity = entity; } diff --git a/ir/ir/irprofile.c b/ir/ir/irprofile.c index d6a9ab6df..913267d22 100644 --- a/ir/ir/irprofile.c +++ b/ir/ir/irprofile.c @@ -182,7 +182,7 @@ static void add_constructor(ir_entity *method) method, NULL); set_entity_compiler_generated(ptr, 1); - set_entity_variability(ptr, variability_constant); + set_entity_linkage(ptr, IR_LINKAGE_CONSTANT); set_atomic_ent_value(ptr, val); } @@ -290,7 +290,7 @@ static void create_location_data(dbg_info *dbg, block_id_walker_data_t *wd) for (i = 0; i < len; ++i) { tarval_string[i] = new_tarval_from_long(fname[i], mode_Bs); } - set_entity_variability(ent, variability_constant); + set_entity_linkage(ent, IR_LINKAGE_CONSTANT); set_array_entity_values(ent, tarval_string, len); } else { ent = entry->value; @@ -385,12 +385,10 @@ ir_profile_instrument(const char *filename, unsigned flags) cur_ident = IDENT("__FIRMPROF__BLOCK_IDS"); bblock_id = new_entity(gtp, cur_ident, array_type); set_entity_ld_ident(bblock_id, cur_ident); - set_entity_variability(bblock_id, variability_initialized); cur_ident = IDENT("__FIRMPROF__BLOCK_COUNTS"); bblock_counts = new_entity(gtp, cur_ident, array_type); set_entity_ld_ident(bblock_counts, cur_ident); - set_entity_variability(bblock_counts, variability_initialized); cur_ident = IDENT("__FIRMPROF__FILE_NAME"); ent_filename = new_entity(gtp, cur_ident, string_type); @@ -438,7 +436,7 @@ ir_profile_instrument(const char *filename, unsigned flags) for (i = 0; i < filename_len; ++i) { tarval_string[i] = new_tarval_from_long(filename[i], mode_Bs); } - set_entity_variability(ent_filename, variability_constant); + set_entity_linkage(ent_filename, IR_LINKAGE_CONSTANT); set_array_entity_values(ent_filename, tarval_string, filename_len); /* initialize block id array and instrument blocks */ @@ -500,7 +498,7 @@ ir_profile_instrument(const char *filename, unsigned flags) rem = current_ir_graph; current_ir_graph = get_const_code_irg(); ent = get_array_element_entity(loc_type); - set_entity_variability(ent_locations, variability_constant); + set_entity_linkage(ent_locations, IR_LINKAGE_CONSTANT); for (i = 0; i < n_blocks; ++i) { compound_graph_path *path; tarval *tv; diff --git a/ir/ir/irvrfy.c b/ir/ir/irvrfy.c index 751a01c0c..65d2d81f2 100644 --- a/ir/ir/irvrfy.c +++ b/ir/ir/irvrfy.c @@ -1073,20 +1073,11 @@ static int verify_node_Const(ir_node *n, ir_graph *irg) { /** * verify a SymConst node */ -static int verify_node_SymConst(ir_node *n, ir_graph *irg) { +static int verify_node_SymConst(ir_node *n, ir_graph *irg) +{ ir_mode *mymode = get_irn_mode(n); (void) irg; - if (get_SymConst_kind(n) == symconst_addr_ent) { - ir_entity *ent = get_SymConst_entity(n); - if (is_Method_type(get_entity_type(ent)) && - get_irn_irg(n) != get_const_code_irg()) { -#if 1 - ASSERT_AND_RET((get_entity_peculiarity(ent) != peculiarity_description), - "A constant must address an existing method.", 0); -#endif - } - } ASSERT_AND_RET( /* SymConst: BB --> int*/ (mode_is_int(mymode) || diff --git a/ir/lower/lower_dw.c b/ir/lower/lower_dw.c index f75110800..84bc4144e 100644 --- a/ir/lower/lower_dw.c +++ b/ir/lower/lower_dw.c @@ -2653,6 +2653,5 @@ ir_entity *def_create_intrinsic_fkt(ir_type *method, const ir_op *op, ent = new_entity(get_glob_type(), id, method); set_entity_ld_ident(ent, get_entity_ident(ent)); - set_entity_visibility(ent, visibility_external_allocated); return ent; } /* def_create_intrinsic_fkt */ diff --git a/ir/lower/lower_hl.c b/ir/lower/lower_hl.c index b59794d35..16ecbff5a 100644 --- a/ir/lower/lower_hl.c +++ b/ir/lower/lower_hl.c @@ -218,8 +218,6 @@ static void lower_sel(ir_node *sel) { int offset; /* replace Sel by add(obj, const(ent.offset)) */ - assert(!(get_entity_allocation(ent) == allocation_static && - (get_entity_n_overwrites(ent) == 0 && get_entity_n_overwrittenby(ent) == 0))); newn = get_Sel_ptr(sel); offset = get_entity_offset(ent); if (offset != 0) { diff --git a/ir/lower/lower_intrinsics.c b/ir/lower/lower_intrinsics.c index 6155c9f4b..5638e1f2b 100644 --- a/ir/lower/lower_intrinsics.c +++ b/ir/lower/lower_intrinsics.c @@ -553,12 +553,12 @@ int i_mapper_tanh(ir_node *call, void *ctx) { * * @param ptr the pointer */ -static ir_entity *get_const_entity(ir_node *ptr) { - /* FIXME: this cannot handle constant strings inside struct initializers yet */ +static ir_entity *get_const_entity(ir_node *ptr) +{ if (is_Global(ptr)) { ir_entity *ent = get_Global_entity(ptr); - if (get_entity_variability(ent) == variability_constant) { + if (get_entity_linkage(ent) & IR_LINKAGE_CONSTANT) { /* a constant entity */ return ent; } diff --git a/ir/opt/ircgopt.c b/ir/opt/ircgopt.c index 2b28f563f..c1a24956f 100644 --- a/ir/opt/ircgopt.c +++ b/ir/opt/ircgopt.c @@ -59,27 +59,9 @@ static void collect_call(ir_node *node, void *env) { } } -/** - * Type walker, set the peculiarity of entities which graphs - * gets removed to peculiarity_description. - */ -static void make_entity_to_description(type_or_ent tore, void *env) { - if (is_entity(tore.ent)) { - ir_entity *ent = tore.ent; - - if ((is_Method_type(get_entity_type(ent))) && - (get_entity_peculiarity(ent) != peculiarity_description) && - (get_entity_visibility(ent) != visibility_external_allocated) ) { - ir_entity *impl = get_SymConst_entity(get_atomic_ent_value(ent)); - if (get_entity_link(impl) != env) { - set_entity_peculiarity(ent, peculiarity_description); - } - } - } -} - /* garbage collect methods: mark and remove */ -void gc_irgs(int n_keep, ir_entity ** keep_arr) { +void gc_irgs(int n_keep, ir_entity ** keep_arr) +{ void * MARK = &MARK; /* @@@ gefaehrlich!!! Aber wir markieren hoechstens zu viele ... */ int i; @@ -102,55 +84,52 @@ void gc_irgs(int n_keep, ir_entity ** keep_arr) { } for (i = 0; i < ARR_LEN(marked); ++i) { - /* check for extern methods, these don't have an IRG */ - if (get_entity_visibility(marked[i]) != visibility_external_allocated) { - ir_graph *irg = get_entity_irg(marked[i]); - ir_node *node = get_irg_end(irg); - - /* collect calls */ - ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK); - irg_walk_graph(irg, firm_clear_link, collect_call, node); - - /* iterate calls */ - for (node = get_irn_link(node); node; node = get_irn_link(node)) { - int i; - assert(is_Call(node)); - - for (i = get_Call_n_callees(node) - 1; i >= 0; --i) { - ir_entity *ent = get_Call_callee(node, i); - - if (get_entity_irg(ent) && get_entity_link(ent) != MARK) { - set_entity_link(ent, MARK); - ARR_APP1(ir_entity *, marked, ent); - - DB((dbg, LEVEL_1, " method %+F can be called from Call %+F: kept alive.\n", - ent, node)); - } + ir_graph *irg = get_entity_irg(marked[i]); + ir_node *node; + + if (irg == NULL) + continue; + + node = get_irg_end(irg); + + /* collect calls */ + ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK); + irg_walk_graph(irg, firm_clear_link, collect_call, node); + + /* iterate calls */ + for (node = get_irn_link(node); node; node = get_irn_link(node)) { + int i; + assert(is_Call(node)); + + for (i = get_Call_n_callees(node) - 1; i >= 0; --i) { + ir_entity *ent = get_Call_callee(node, i); + + if (get_entity_irg(ent) && get_entity_link(ent) != MARK) { + set_entity_link(ent, MARK); + ARR_APP1(ir_entity *, marked, ent); + + DB((dbg, LEVEL_1, " method %+F can be called from Call %+F: kept alive.\n", + ent, node)); } } - ir_free_resources(irg, IR_RESOURCE_IRN_LINK); } + ir_free_resources(irg, IR_RESOURCE_IRN_LINK); } DEL_ARR_F(marked); } /* clean */ - type_walk(make_entity_to_description, NULL, MARK); for (i = get_irp_n_irgs() - 1; i >= 0; --i) { ir_graph *irg = get_irp_irg(i); ir_entity *ent = get_irg_entity(irg); - /* Removing any graph invalidates all interprocedural loop trees. */ - if (get_irg_loopinfo_state(irg) == loopinfo_ip_consistent || - get_irg_loopinfo_state(irg) == loopinfo_ip_inconsistent) { - free_loop_information(irg); - } - if ((get_entity_visibility(ent) == visibility_local) && (get_entity_link(ent) != MARK)) { - DB((dbg, LEVEL_1, " freeing method %+F\n", ent)); - remove_irp_irg(irg); - set_entity_peculiarity(ent, peculiarity_description); - } - set_entity_link(ent, NULL); + if (get_entity_link(ent) == MARK) + continue; + + DB((dbg, LEVEL_1, " freeing method %+F\n", ent)); + remove_irp_irg(irg); + + remove_class_member(get_entity_owner(ent), ent); } } diff --git a/ir/opt/ldstopt.c b/ir/opt/ldstopt.c index dd0231e2d..4c63e0cb9 100644 --- a/ir/opt/ldstopt.c +++ b/ir/opt/ldstopt.c @@ -295,7 +295,7 @@ static ir_entity *find_constant_entity(ir_node *ptr) } } - if (variability_constant == get_entity_variability(ent)) + if (get_entity_linkage(ent) & IR_LINKAGE_CONSTANT) return ent; /* try next */ @@ -1146,9 +1146,7 @@ static unsigned optimize_load(ir_node *load) value = NULL; /* check if we can determine the entity that will be loaded */ ent = find_constant_entity(ptr); - if (ent != NULL && - allocation_static == get_entity_allocation(ent) && - visibility_external_allocated != get_entity_visibility(ent)) { + if (ent != NULL && !(get_entity_linkage(ent) & IR_LINKAGE_EXTERN)) { /* a static allocation that is not external: there should be NO exception * when loading even if we cannot replace the load itself. */ @@ -1164,17 +1162,11 @@ static unsigned optimize_load(ir_node *load) res |= CF_CHANGED; } - if (variability_constant == get_entity_variability(ent)) { - if (is_atomic_entity(ent)) { - /* Might not be atomic after lowering of Sels. In this case we - * could also load, but it's more complicated. */ - /* more simpler case: we load the content of a constant value: - * replace it by the constant itself */ - value = get_atomic_ent_value(ent); - } else if (ent->has_initializer) { + if (get_entity_linkage(ent) & IR_LINKAGE_CONSTANT) { + if (ent->initializer != NULL) { /* new style initializer */ value = find_compound_ent_value(ptr); - } else { + } else if (entity_has_compound_ent_values(ent)) { /* old style initializer */ compound_graph_path *path = get_accessed_path(ptr); diff --git a/ir/opt/opt_inline.c b/ir/opt/opt_inline.c index a829ccce4..a86020d65 100644 --- a/ir/opt/opt_inline.c +++ b/ir/opt/opt_inline.c @@ -2048,7 +2048,7 @@ static int calc_inline_benefice(call_entry *entry, ir_graph *callee) callee_env = get_irg_link(callee); if (callee_env->n_callers == 1 && callee != current_ir_graph && - get_entity_visibility(ent) == visibility_local) { + (get_entity_linkage(ent) & IR_LINKAGE_LOCAL)) { weight += 700; } diff --git a/ir/opt/opt_ldst.c b/ir/opt/opt_ldst.c index aba92eec2..e9dce0fd1 100644 --- a/ir/opt/opt_ldst.c +++ b/ir/opt/opt_ldst.c @@ -568,7 +568,7 @@ static ir_entity *find_constant_entity(ir_node *ptr) { } } - if (variability_constant == get_entity_variability(ent)) + if (get_entity_linkage(ent) == IR_LINKAGE_CONSTANT) return ent; /* try next */ @@ -1026,9 +1026,7 @@ static void update_Load_memop(memop_t *m) { /* check if we can determine the entity that will be loaded */ ent = find_constant_entity(ptr); - if (ent != NULL && - allocation_static == get_entity_allocation(ent) && - visibility_external_allocated != get_entity_visibility(ent)) { + if (ent != NULL && !(get_entity_linkage(ent) & IR_LINKAGE_EXTERN)) { /* a static allocation that is not external: there should be NO exception * when loading even if we cannot replace the load itself. */ ir_node *value = NULL; @@ -1046,17 +1044,11 @@ static void update_Load_memop(memop_t *m) { env.changed = 1; } - if (variability_constant == get_entity_variability(ent)) { - if (is_atomic_entity(ent)) { - /* Might not be atomic after lowering of Sels. In this case we - * could also load, but it's more complicated. */ - /* more simpler case: we load the content of a constant value: - * replace it by the constant itself */ - value = get_atomic_ent_value(ent); - } else if (ent->has_initializer) { + if (get_entity_linkage(ent) & IR_LINKAGE_CONSTANT) { + if (ent->initializer) { /* new style initializer */ value = find_compound_ent_value(ptr); - } else { + } else if (entity_has_compound_ent_values(ent)) { /* old style initializer */ compound_graph_path *path = get_accessed_path(ptr); diff --git a/ir/opt/opt_polymorphy.c b/ir/opt/opt_polymorphy.c index c8cb79645..a0902b706 100644 --- a/ir/opt/opt_polymorphy.c +++ b/ir/opt/opt_polymorphy.c @@ -98,7 +98,8 @@ static ir_type *get_dynamic_type(ir_node *ptr) { /** * Check, if an entity is final, i.e. is not anymore overridden. */ -static int is_final_ent(ir_entity *ent) { +static int is_final_ent(ir_entity *ent) +{ if (is_entity_final(ent)) { /* not possible to override this entity. */ return 1; @@ -155,8 +156,6 @@ ir_node *transform_node_Sel(ir_node *node) { /* We know which method will be called, no dispatch necessary. */ called_ent = resolve_ent_polymorphy(dyn_tp, ent); - /* called_ent may not be description: has no Address/Const to Call! */ - assert(get_entity_peculiarity(called_ent) != peculiarity_description); rem_block = get_cur_block(); set_cur_block(get_nodes_block(node)); @@ -192,8 +191,7 @@ ir_node *transform_polymorph_Load(ir_node *load) { if (! is_Sel(field_ptr)) return load; ent = get_Sel_entity(field_ptr); - if ((get_entity_allocation(ent) != allocation_static) || - (get_entity_variability(ent) != variability_constant) ) + if ( !(get_entity_linkage(ent) & IR_LINKAGE_CONSTANT) ) return load; /* If the entity is a leave in the inheritance tree, @@ -210,8 +208,6 @@ ir_node *transform_polymorph_Load(ir_node *load) { /* We know which method will be called, no dispatch necessary. */ loaded_ent = resolve_ent_polymorphy(dyn_tp, ent); - /* called_ent may not be description: has no Address/Const to Call! */ - assert(get_entity_peculiarity(loaded_ent) != peculiarity_description); new_node = get_atomic_ent_value(loaded_ent); } } diff --git a/ir/opt/proc_cloning.c b/ir/opt/proc_cloning.c index a86bfde5a..ff0cf07d7 100644 --- a/ir/opt/proc_cloning.c +++ b/ir/opt/proc_cloning.c @@ -188,7 +188,7 @@ static void collect_irg_calls(ir_node *call, void *env) { callee = get_Global_entity(call_ptr); /* we can only clone calls to existing entities */ - if (get_entity_visibility(callee) == visibility_external_allocated) + if (get_entity_irg(callee) == NULL) return; /* we cannot clone calls to weak functions */ @@ -403,10 +403,10 @@ static void change_entity_type(quadruple_t *q, ir_entity *ent) { * * @param q Contains information for the method to clone. */ -static ir_entity *clone_method(quadruple_t *q) { +static ir_entity *clone_method(quadruple_t *q) +{ ir_entity *new_entity; ident *clone_ident; - ir_graph *rem; symconst_symbol sym; /* A counter for the clones.*/ static unsigned nr = 0; @@ -417,7 +417,7 @@ static ir_entity *clone_method(quadruple_t *q) { new_entity = copy_entity_name(q->ent, clone_ident); /* a cloned entity is always local */ - set_entity_visibility(new_entity, visibility_local); + add_entity_linkage(new_entity, IR_LINKAGE_LOCAL); /* set a ld name here: Should we mangle this ? */ set_entity_ld_ident(new_entity, get_entity_ident(new_entity)); @@ -430,10 +430,6 @@ static ir_entity *clone_method(quadruple_t *q) { /* We must set the atomic value of our "new_entity". */ sym.entity_p = new_entity; - rem = current_ir_graph; - current_ir_graph = get_const_code_irg(); - new_entity->value = new_SymConst(mode_P_code, sym, symconst_addr_ent); - current_ir_graph = rem; /* The "new_entity" don't have this information. */ new_entity->attr.mtd_attr.param_access = NULL; diff --git a/ir/tr/compound_path.c b/ir/tr/compound_path.c index e842e7a58..50e014291 100644 --- a/ir/tr/compound_path.c +++ b/ir/tr/compound_path.c @@ -132,8 +132,13 @@ ir_type *get_compound_graph_path_type(const compound_graph_path *gr) void add_compound_ent_value_w_path(ir_entity *ent, ir_node *val, compound_graph_path *path) { - assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized)); + assert(is_compound_entity(ent)); assert(is_compound_graph_path(path)); + if (ent->attr.cmpd_attr.values == NULL) { + ent->attr.cmpd_attr.values = NEW_ARR_F(ir_node*, 0); + assert(ent->attr.cmpd_attr.val_paths == NULL); + ent->attr.cmpd_attr.val_paths = NEW_ARR_F(compound_graph_path*, 0); + } ARR_APP1(ir_node *, ent->attr.cmpd_attr.values, val); ARR_APP1(compound_graph_path *, ent->attr.cmpd_attr.val_paths, path); } @@ -141,17 +146,17 @@ void add_compound_ent_value_w_path(ir_entity *ent, ir_node *val, void set_compound_ent_value_w_path(ir_entity *ent, ir_node *val, compound_graph_path *path, int pos) { - assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized)); + assert(is_compound_entity(ent)); 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; } -compound_graph_path *get_compound_ent_value_path(ir_entity *ent, int pos) +compound_graph_path *get_compound_ent_value_path(const ir_entity *ent, int pos) { - assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized)); - assert(!ent->has_initializer); + assert(is_compound_entity(ent)); + assert(ent->initializer == NULL); assert(0 <= pos && pos < ARR_LEN(ent->attr.cmpd_attr.val_paths)); return ent->attr.cmpd_attr.val_paths[pos]; } @@ -196,7 +201,7 @@ static int equal_paths(compound_graph_path *path1, compound_graph_path *path2) * and should be replaced when the new tree oriented * value representation is finally implemented. */ -static int get_compound_ent_pos_by_path(ir_entity *ent, +static int get_compound_ent_pos_by_path(const ir_entity *ent, compound_graph_path *path) { int i, n_paths = get_compound_ent_n_values(ent); @@ -209,7 +214,7 @@ static int get_compound_ent_pos_by_path(ir_entity *ent, return -1; } -ir_node *get_compound_ent_value_by_path(ir_entity *ent, +ir_node *get_compound_ent_value_by_path(const ir_entity *ent, compound_graph_path *path) { int pos = get_compound_ent_pos_by_path(ent, path); @@ -221,7 +226,7 @@ ir_node *get_compound_ent_value_by_path(ir_entity *ent, void remove_compound_ent_value(ir_entity *ent, ir_entity *value_ent) { int i, n; - assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized)); + assert(is_compound_entity(ent)); n = ARR_LEN(ent->attr.cmpd_attr.val_paths); for (i = 0; i < n; ++i) { @@ -242,7 +247,7 @@ void add_compound_ent_value(ir_entity *ent, ir_node *val, ir_entity *member) { compound_graph_path *path; ir_type *owner_tp = get_entity_owner(member); - assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized)); + assert(is_compound_entity(ent)); path = new_compound_graph_path(get_entity_type(ent), 1); path->list[0].node = member; if (is_Array_type(owner_tp)) { @@ -262,10 +267,10 @@ void add_compound_ent_value(ir_entity *ent, ir_node *val, ir_entity *member) add_compound_ent_value_w_path(ent, val, path); } -ir_entity *get_compound_ent_value_member(ir_entity *ent, int pos) +ir_entity *get_compound_ent_value_member(const ir_entity *ent, int pos) { compound_graph_path *path; - assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized)); + assert(is_compound_entity(ent)); path = get_compound_ent_value_path(ent, pos); return get_compound_graph_path_node(path, get_compound_graph_path_length(path)-1); @@ -275,7 +280,7 @@ void set_compound_ent_value(ir_entity *ent, ir_node *val, ir_entity *member, int pos) { compound_graph_path *path; - assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized)); + assert(is_compound_entity(ent)); path = get_compound_ent_value_path(ent, pos); set_compound_graph_path_node(path, 0, member); set_compound_ent_value_w_path(ent, val, path, pos); @@ -294,7 +299,6 @@ void set_array_entity_values(ir_entity *ent, tarval **values, int num_vals) /* One bound is sufficient, the number of constant fields makes the size. */ assert(get_array_lower_bound (arrtp, 0) || get_array_upper_bound (arrtp, 0)); - assert(get_entity_variability(ent) != variability_uninitialized); current_ir_graph = get_const_code_irg(); for (i = 0; i < num_vals; i++) { @@ -305,7 +309,7 @@ void set_array_entity_values(ir_entity *ent, tarval **values, int num_vals) current_ir_graph = rem; } -unsigned get_compound_ent_value_offset_bytes(ir_entity *ent, int pos) +unsigned get_compound_ent_value_offset_bytes(const ir_entity *ent, int pos) { compound_graph_path *path; int path_len, i; @@ -343,7 +347,8 @@ unsigned get_compound_ent_value_offset_bytes(ir_entity *ent, int pos) return offset; } -unsigned get_compound_ent_value_offset_bit_remainder(ir_entity *ent, int pos) +unsigned get_compound_ent_value_offset_bit_remainder(const ir_entity *ent, + int pos) { compound_graph_path *path; int path_len; @@ -361,17 +366,25 @@ unsigned get_compound_ent_value_offset_bit_remainder(ir_entity *ent, int pos) return get_entity_offset_bits_remainder(last_node); } -int get_compound_ent_n_values(ir_entity *ent) +int get_compound_ent_n_values(const ir_entity *ent) { - assert(!ent->has_initializer); - assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized)); + assert(ent->initializer == NULL); + assert(is_compound_entity(ent)); return ARR_LEN(ent->attr.cmpd_attr.values); } -ir_node *get_compound_ent_value(ir_entity *ent, int pos) +ir_node *get_compound_ent_value(const ir_entity *ent, int pos) { - assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized)); - assert(!ent->has_initializer); + assert(is_compound_entity(ent)); + assert(ent->initializer == NULL); assert(0 <= pos && pos < ARR_LEN(ent->attr.cmpd_attr.values)); return skip_Id(ent->attr.cmpd_attr.values[pos]); } + +int entity_has_compound_ent_values(const ir_entity *entity) +{ + if (!is_compound_entity(entity)) + return 0; + + return entity->attr.cmpd_attr.values != NULL; +} diff --git a/ir/tr/entity.c b/ir/tr/entity.c index 5e0b13a1c..9fb13a1b6 100644 --- a/ir/tr/entity.c +++ b/ir/tr/entity.c @@ -43,6 +43,7 @@ #include "irgraph_t.h" #include "callgraph.h" #include "error.h" +#include "compound_path.h" /*-----------------------------------------------------------------*/ /** general **/ @@ -108,14 +109,9 @@ new_rd_entity(dbg_info *db, ir_type *owner, ident *name, ir_type *type) res->type = type; res->owner = owner; - res->allocation = allocation_automatic; - res->visibility = visibility_local; res->volatility = volatility_non_volatile; res->aligned = align_is_aligned; - res->stickyness = stickyness_unsticky; - res->peculiarity = peculiarity_existent; res->usage = ir_usage_unknown; - res->final = 0; res->compiler_gen = 0; res->backend_marked = 0; res->offset = -1; @@ -130,25 +126,19 @@ new_rd_entity(dbg_info *db, ir_type *owner, ident *name, ir_type *type) sym.entity_p = res; rem = current_ir_graph; current_ir_graph = get_const_code_irg(); - res->value = new_SymConst(mode, sym, symconst_addr_ent); + set_atomic_ent_value(res, new_SymConst(mode, sym, symconst_addr_ent)); current_ir_graph = rem; - res->allocation = allocation_static; - res->variability = variability_constant; + res->linkage = IR_LINKAGE_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 if (is_code_type(type)) { res->attr.code_attr.label = (ir_label_t) -1; - } else { - res->variability = variability_uninitialized; - res->value = NULL; } if (is_Class_type(owner)) { @@ -192,7 +182,8 @@ new_entity(ir_type *owner, ident *name, ir_type *type) { * * @param ent the entity */ -static void free_entity_attrs(ir_entity *ent) { +static void free_entity_attrs(ir_entity *ent) +{ int i; if (get_type_tpop(get_entity_owner(ent)) == type_class) { DEL_ARR_F(ent->overwrites); ent->overwrites = NULL; @@ -201,24 +192,24 @@ static void free_entity_attrs(ir_entity *ent) { assert(ent->overwrites == NULL); assert(ent->overwrittenby == NULL); } + if (ent->initializer != NULL) { + /* TODO: free initializers */ + } else if (entity_has_compound_ent_values(ent)) { + 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. */ + /* DEL_ARR_F(ent->attr.cmpd_attr.val_paths); */ + } + ent->attr.cmpd_attr.val_paths = NULL; + } + } if (is_compound_entity(ent)) { - 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. */ - /* DEL_ARR_F(ent->attr.cmpd_attr.val_paths); */ - } - ent->attr.cmpd_attr.val_paths = NULL; - } - if (ent->attr.cmpd_attr.values) { - /*DEL_ARR_F(ent->attr.cmpd_attr.values)*/; - } - ent->attr.cmpd_attr.values = NULL; + if (ent->attr.cmpd_attr.values) { + /*DEL_ARR_F(ent->attr.cmpd_attr.values)*/; } + ent->attr.cmpd_attr.values = NULL; } else if (is_method_entity(ent)) { if (ent->attr.mtd_attr.param_access) { DEL_ARR_F(ent->attr.mtd_attr.param_access); @@ -239,19 +230,17 @@ static ir_entity *deep_entity_copy(ir_entity *old) ir_entity *newe = XMALLOC(ir_entity); *newe = *old; - 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); - } + if (old->initializer != NULL) { + /* FIXME: the initializers are NOT copied */ + } else if (entity_has_compound_ent_values(old)) { + 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; @@ -331,164 +320,64 @@ get_entity_nr(const ir_entity *ent) { const char * (get_entity_name)(const ir_entity *ent) { return _get_entity_name(ent); -} /* get_entity_name */ +} ident * (get_entity_ident)(const ir_entity *ent) { return _get_entity_ident(ent); -} /* get_entity_ident */ +} void (set_entity_ident)(ir_entity *ent, ident *id) { _set_entity_ident(ent, id); -} /* set_entity_ident */ +} ir_type * -(get_entity_owner)(ir_entity *ent) { +(get_entity_owner)(const ir_entity *ent) { return _get_entity_owner(ent); -} /* get_entity_owner */ +} void set_entity_owner(ir_entity *ent, ir_type *owner) { assert(is_entity(ent)); assert(is_compound_type(owner)); ent->owner = owner; -} /* set_entity_owner */ +} -ident * -(get_entity_ld_ident)(ir_entity *ent) { +ident *(get_entity_ld_ident)(const ir_entity *ent) +{ return _get_entity_ld_ident(ent); -} /* get_entity_ld_ident */ +} void (set_entity_ld_ident)(ir_entity *ent, ident *ld_ident) { _set_entity_ld_ident(ent, ld_ident); -} /* set_entity_ld_ident */ +} -const char * -(get_entity_ld_name)(ir_entity *ent) { +const char *(get_entity_ld_name)(const ir_entity *ent) +{ return _get_entity_ld_name(ent); -} /* get_entity_ld_name */ +} ir_type * -(get_entity_type)(ir_entity *ent) { +(get_entity_type)(const ir_entity *ent) { return _get_entity_type(ent); -} /* get_entity_type */ +} void (set_entity_type)(ir_entity *ent, ir_type *type) { _set_entity_type(ent, type); -} /* set_entity_type */ - -ir_allocation -(get_entity_allocation)(const ir_entity *ent) { - return _get_entity_allocation(ent); -} /* get_entity_allocation */ - -void -(set_entity_allocation)(ir_entity *ent, ir_allocation al) { - _set_entity_allocation(ent, al); -} /* set_entity_allocation */ - -/* return the name of the visibility */ -const char *get_allocation_name(ir_allocation al) -{ -#define X(a) case a: return #a - switch (al) { - X(allocation_automatic); - X(allocation_parameter); - X(allocation_dynamic); - X(allocation_static); - default: return "BAD VALUE"; - } -#undef X -} /* get_allocation_name */ - -ir_visibility -(get_entity_visibility)(const ir_entity *ent) { - return _get_entity_visibility(ent); -} /* get_entity_visibility */ - -void -set_entity_visibility(ir_entity *ent, ir_visibility vis) { - 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 */ - -/* return the name of the visibility */ -const char *get_visibility_name(ir_visibility vis) -{ -#define X(a) case a: return #a - switch (vis) { - X(visibility_local); - X(visibility_external_visible); - X(visibility_external_allocated); - default: return "BAD VALUE"; - } -#undef X -} /* get_visibility_name */ - -ir_variability -(get_entity_variability)(const ir_entity *ent) { - return _get_entity_variability(ent); -} /* get_entity_variability */ - -void -set_entity_variability(ir_entity *ent, ir_variability var) -{ - 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_r_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 */ - -/* return the name of the variability */ -const char *get_variability_name(ir_variability var) -{ -#define X(a) case a: return #a - switch (var) { - X(variability_uninitialized); - X(variability_initialized); - X(variability_part_constant); - X(variability_constant); - default: return "BAD VALUE"; - } -#undef X -} /* get_variability_name */ +} ir_volatility (get_entity_volatility)(const ir_entity *ent) { return _get_entity_volatility(ent); -} /* get_entity_volatility */ +} void (set_entity_volatility)(ir_entity *ent, ir_volatility vol) { _set_entity_volatility(ent, vol); -} /* set_entity_volatility */ +} /* Return the name of the volatility. */ const char *get_volatility_name(ir_volatility var) @@ -545,25 +434,37 @@ ir_label_t get_entity_label(const ir_entity *ent) return ent->attr.code_attr.label; } -ir_peculiarity -(get_entity_peculiarity)(const ir_entity *ent) { - return _get_entity_peculiarity(ent); -} /* get_entity_peculiarity */ +static void verify_linkage(ir_entity *entity) +{ + ir_linkage linkage = entity->linkage; + /* local and extern are mutually exclusive */ + (void) linkage; + assert(! ((linkage & IR_LINKAGE_EXTERN) && (linkage & IR_LINKAGE_LOCAL))); + assert(! (linkage & IR_LINKAGE_EXTERN) || !entity_has_definition(entity)); +} -void -(set_entity_peculiarity)(ir_entity *ent, ir_peculiarity pec) { - _set_entity_peculiarity(ent, pec); -} /* set_entity_peculiarity */ +void set_entity_linkage(ir_entity *entity, ir_linkage linkage) +{ + entity->linkage = linkage; + verify_linkage(entity); +} + +ir_linkage (get_entity_linkage)(const ir_entity *entity) +{ + return get_entity_linkage(entity); +} -/* Checks if an entity cannot be overridden anymore. */ -int (is_entity_final)(const ir_entity *ent) { - return _is_entity_final(ent); -} /* is_entity_final */ +void add_entity_linkage(ir_entity *entity, ir_linkage linkage) +{ + entity->linkage |= linkage; + verify_linkage(entity); +} -/* Sets/resets the final flag of an entity. */ -void (set_entity_final)(ir_entity *ent, int final) { - _set_entity_final(ent, final); -} /* set_entity_final */ +void remove_entity_linkage(ir_entity *entity, ir_linkage linkage) +{ + entity->linkage &= ~linkage; + verify_linkage(entity); +} /* Checks if an entity is compiler generated */ int (is_entity_compiler_generated)(const ir_entity *ent) { @@ -593,35 +494,47 @@ void (set_entity_usage)(ir_entity *ent, ir_entity_usage flags) { _set_entity_usage(ent, flags); } -/* Get the entity's stickyness */ -ir_stickyness -(get_entity_stickyness)(const ir_entity *ent) { - return _get_entity_stickyness(ent); -} /* get_entity_stickyness */ +/* Set has no effect for existent entities of type method. */ +ir_node *get_atomic_ent_value(ir_entity *entity) +{ + ir_initializer_t *initializer = get_entity_initializer(entity); -/* Set the entity's stickyness */ -void -(set_entity_stickyness)(ir_entity *ent, ir_stickyness stickyness) { - _set_entity_stickyness(ent, stickyness); -} /* set_entity_stickyness */ + assert(entity && is_atomic_entity(entity)); + if (initializer == NULL) { + ir_type *type = get_entity_type(entity); + return new_r_Unknown(get_const_code_irg(), get_type_mode(type)); + } -/* Set has no effect for existent entities of type method. */ -ir_node * -get_atomic_ent_value(ir_entity *ent) + switch (get_initializer_kind(initializer)) { + case IR_INITIALIZER_NULL: { + ir_type *type = get_entity_type(entity); + ir_mode *mode = get_type_mode(type); + return new_r_Const(get_const_code_irg(), get_mode_null(mode)); + } + case IR_INITIALIZER_TARVAL: { + tarval *tv = get_initializer_tarval_value(initializer); + return new_r_Const(get_const_code_irg(), tv); + } + case IR_INITIALIZER_CONST: + return get_initializer_const_value(initializer); + case IR_INITIALIZER_COMPOUND: + panic("compound initializer in atomic entity not allowed (%+F)", entity); + } + + panic("invalid initializer kind in get_atomic_ent_value(%+F)", entity); +} + +void set_atomic_ent_value(ir_entity *entity, ir_node *val) { - assert(ent && is_atomic_entity(ent)); - assert(ent->variability != variability_uninitialized); - return skip_Id(ent->value); -} /* get_atomic_ent_value */ + ir_initializer_t *initializer; -void -set_atomic_ent_value(ir_entity *ent, ir_node *val) { - assert(is_atomic_entity(ent) && (ent->variability != variability_uninitialized)); - if (is_Method_type(ent->type) && (ent->peculiarity == peculiarity_existent)) - return; - assert(is_Dummy(val) || get_irn_mode(val) == get_type_mode(ent->type)); - ent->value = val; -} /* set_atomic_ent_value */ + assert(is_atomic_entity(entity)); + assert(get_entity_peculiarity(entity) != peculiarity_description); + + assert(is_Dummy(val) || get_irn_mode(val) == get_type_mode(entity->type)); + initializer = create_initializer_const(val); + entity->initializer = initializer; +} /* Returns true if the the node is representable as code on * const_code_irg. */ @@ -808,26 +721,36 @@ ir_initializer_kind_t get_initializer_kind(const ir_initializer_t *initializer) static void check_entity_initializer(ir_entity *entity) { - /* TODO */ - (void) entity; +#ifndef NDEBUG + ir_initializer_t *initializer = entity->initializer; + switch (initializer->kind) { + case IR_INITIALIZER_COMPOUND: + assert(is_compound_entity(entity)); + break; + case IR_INITIALIZER_CONST: + case IR_INITIALIZER_TARVAL: + assert(is_atomic_entity(entity)); + break; + case IR_INITIALIZER_NULL: + break; + } +#endif } void set_entity_initializer(ir_entity *entity, ir_initializer_t *initializer) { - entity->attr.initializer = initializer; - entity->has_initializer = 1; + entity->initializer = initializer; check_entity_initializer(entity); } int has_entity_initializer(const ir_entity *entity) { - return entity->has_initializer; + return entity->initializer != NULL; } ir_initializer_t *get_entity_initializer(const ir_entity *entity) { - assert(entity->has_initializer); - return entity->attr.initializer; + return entity->initializer; } int (get_entity_offset)(const ir_entity *ent) @@ -863,13 +786,13 @@ void add_entity_overwrites(ir_entity *ent, ir_entity *overwritten) ARR_APP1(ir_entity *, overwritten->overwrittenby, ent); } -int get_entity_n_overwrites(ir_entity *ent) +int get_entity_n_overwrites(const ir_entity *ent) { assert(is_Class_type(get_entity_owner(ent))); return (ARR_LEN(ent->overwrites)); } -int get_entity_overwrites_index(ir_entity *ent, ir_entity *overwritten) +int get_entity_overwrites_index(const ir_entity *ent, ir_entity *overwritten) { int i, n; assert(is_Class_type(get_entity_owner(ent))); @@ -881,7 +804,7 @@ int get_entity_overwrites_index(ir_entity *ent, ir_entity *overwritten) return -1; } -ir_entity *get_entity_overwrites(ir_entity *ent, int pos) +ir_entity *get_entity_overwrites(const ir_entity *ent, int pos) { assert(is_Class_type(get_entity_owner(ent))); assert(pos < get_entity_n_overwrites(ent)); @@ -915,13 +838,13 @@ void add_entity_overwrittenby(ir_entity *ent, ir_entity *overwrites) add_entity_overwrites(overwrites, ent); } -int get_entity_n_overwrittenby(ir_entity *ent) +int get_entity_n_overwrittenby(const ir_entity *ent) { assert(is_Class_type(get_entity_owner(ent))); return ARR_LEN(ent->overwrittenby); } -int get_entity_overwrittenby_index(ir_entity *ent, ir_entity *overwrites) +int get_entity_overwrittenby_index(const ir_entity *ent, ir_entity *overwrites) { int i, n; assert(is_Class_type(get_entity_owner(ent))); @@ -933,7 +856,7 @@ int get_entity_overwrittenby_index(ir_entity *ent, ir_entity *overwrites) return -1; } -ir_entity *get_entity_overwrittenby(ir_entity *ent, int pos) +ir_entity *get_entity_overwrittenby(const ir_entity *ent, int pos) { assert(is_Class_type(get_entity_owner(ent))); assert(pos < get_entity_n_overwrittenby(ent)); @@ -981,16 +904,7 @@ ir_graph *(get_entity_irg)(const ir_entity *ent) void set_entity_irg(ir_entity *ent, ir_graph *irg) { assert(is_method_entity(ent)); - /* Wie kann man die Referenz auf einen IRG löschen, z.B. wenn die - * Methode selbst nicht mehr aufgerufen werden kann, die Entität - * aber erhalten bleiben soll? Wandle die Entitaet in description oder - * inherited um! */ - /* assert(irg); */ - assert((irg && ent->peculiarity == peculiarity_existent) || - (!irg && (ent->peculiarity == peculiarity_existent) - && (ent -> visibility == visibility_external_allocated)) || - (!irg && ent->peculiarity == peculiarity_description) || - (!irg && ent->peculiarity == peculiarity_inherited)); + assert(get_entity_peculiarity(ent) == peculiarity_existent); ent->attr.mtd_attr.irg = irg; } @@ -1011,7 +925,7 @@ int (is_entity)(const void *thing) return _is_entity(thing); } -int is_atomic_entity(ir_entity *ent) +int is_atomic_entity(const ir_entity *ent) { ir_type *t = get_entity_type(ent); const tp_op *op = get_type_tpop(t); @@ -1019,7 +933,7 @@ int is_atomic_entity(ir_entity *ent) op == type_enumeration || op == type_method); } -int is_compound_entity(ir_entity *ent) +int is_compound_entity(const ir_entity *ent) { ir_type *t = get_entity_type(ent); const tp_op *op = get_type_tpop(t); @@ -1027,13 +941,13 @@ int is_compound_entity(ir_entity *ent) op == type_array || op == type_union); } -int is_method_entity(ir_entity *ent) +int is_method_entity(const ir_entity *ent) { ir_type *t = get_entity_type(ent); return is_Method_type(t); } -ir_visited_t (get_entity_visited)(ir_entity *ent) +ir_visited_t (get_entity_visited)(const ir_entity *ent) { return _get_entity_visited(ent); } @@ -1048,17 +962,17 @@ void (mark_entity_visited)(ir_entity *ent) _mark_entity_visited(ent); } -int (entity_visited)(ir_entity *ent) +int (entity_visited)(const ir_entity *ent) { return _entity_visited(ent); } -int (entity_not_visited)(ir_entity *ent) +int (entity_not_visited)(const ir_entity *ent) { return _entity_not_visited(ent); } -unsigned get_entity_additional_properties(ir_entity *ent) +unsigned get_entity_additional_properties(const ir_entity *ent) { ir_graph *irg; @@ -1132,6 +1046,18 @@ void (set_entity_dbg_info)(ir_entity *ent, dbg_info *db) _set_entity_dbg_info(ent, db); } +int entity_is_externally_visible(const ir_entity *entity) +{ + return (get_entity_linkage(entity) & IR_LINKAGE_LOCAL) == 0; +} + +int entity_has_definition(const ir_entity *entity) +{ + return entity->initializer != NULL + || get_entity_irg(entity) != NULL + || entity_has_compound_ent_values(entity); +} + void firm_init_entity(void) { symconst_symbol sym; @@ -1140,11 +1066,40 @@ void firm_init_entity(void) assert(!unknown_entity && "Call firm_init_entity() only once!"); unknown_entity = new_rd_entity(NULL, firm_unknown_type, new_id_from_str(UNKNOWN_ENTITY_NAME), firm_unknown_type); - set_entity_visibility(unknown_entity, visibility_external_allocated); + set_entity_linkage(unknown_entity, IR_LINKAGE_EXTERN); + set_entity_ld_ident(unknown_entity, get_entity_ident(unknown_entity)); - current_ir_graph = get_const_code_irg(); - sym.entity_p = unknown_entity; - /* TODO: we need two unknown_entities here, one for code and one for data */ - unknown_entity->value = new_SymConst(mode_P_data, sym, symconst_addr_ent); + current_ir_graph = get_const_code_irg(); + sym.entity_p = unknown_entity; +} + +ir_allocation get_entity_allocation(const ir_entity *entity) +{ + return entity->allocation; +} + +void set_entity_allocation(ir_entity *entity, ir_allocation allocation) +{ + entity->allocation = allocation; +} + +ir_peculiarity get_entity_peculiarity(const ir_entity *entity) +{ + return entity->peculiarity; +} + +void set_entity_peculiarity(ir_entity *entity, ir_peculiarity peculiarity) +{ + entity->peculiarity = peculiarity; +} + +void set_entity_final(ir_entity *entity, int final) +{ + entity->final = final; +} + +int is_entity_final(const ir_entity *entity) +{ + return entity->final; } diff --git a/ir/tr/entity_t.h b/ir/tr/entity_t.h index a3f46ca88..d0c61f4d2 100644 --- a/ir/tr/entity_t.h +++ b/ir/tr/entity_t.h @@ -71,19 +71,11 @@ union ir_initializer_t { ir_initializer_tarval_t tarval; }; -/** The attributes for atomic entities. */ -typedef struct atomic_ent_attr { - ir_node *value; /**< value if entity is not of variability uninitialized. - Only for atomic entities. */ -} atomic_ent_attr; - /** The attributes for compound entities. */ typedef struct compound_ent_attr { - ir_node **values; /**< constant values of compound entities. Only available if - variability not uninitialized. Must be set for variability constant. */ + ir_node **values; /**< constant values of compound entities. */ compound_graph_path **val_paths; - /**< paths corresponding to constant values. Only available if - variability not uninitialized. Must be set for variability constant. */ + /**< paths corresponding to constant values. */ } compound_ent_attr; /** A reserved value for "not yet set". */ @@ -127,39 +119,43 @@ struct ir_entity { ir_type *type; /**< The type of this entity, e.g., a method type, a basic type of the language or a class itself. */ ir_type *owner; /**< The compound type (e.g. class type) this entity belongs to. */ - unsigned allocation:3; /**< Distinguishes static and dynamically allocated - entities and some further cases. */ - unsigned visibility:3; /**< Specifies visibility to external program fragments. */ - unsigned variability:3; /**< Specifies variability of entities content. */ - unsigned volatility:1; /**< Specifies volatility of entities content. */ - unsigned aligned:1; /**< Specifies alignment of entities content. */ - unsigned stickyness:2; /**< Specifies whether this entity is sticky. */ - unsigned peculiarity:3; /**< The peculiarity of this entity. */ - unsigned usage:4; /**< flag indicating usage types of this entity, see ir_entity_usage. */ - unsigned final:1; /**< If set, this entity cannot be overridden. */ - unsigned compiler_gen:1; /**< If set, this entity was compiler generated. */ - unsigned backend_marked:1; /**< If set, this entity was marked by the backend for emission. */ - unsigned has_initializer:1; /**< if set, this entity is initialized by new style initializers. */ - int offset; /**< Offset in bytes for this entity. Fixed when layout - of owner is determined. */ - unsigned alignment; /**< entity alignment in bytes */ + unsigned linkage:10; /**< Specifies linkage type */ + unsigned volatility:1; /**< Specifies volatility of entities content.*/ + unsigned aligned:1; /**< Specifies alignment of entities content. */ + unsigned usage:4; /**< flag indicating usage types of this entity, + see ir_entity_usage. */ + unsigned compiler_gen:1; /**< If set, this entity was compiler generated. + */ + unsigned backend_marked:1; /**< If set, this entity was marked by the + backend for emission. */ + unsigned visibility:3; /**< @deprecated */ + unsigned allocation:3; /**< @deprecated */ + unsigned peculiarity:3; /**< @deprecated */ + unsigned final:1; /**< @deprecated */ + int offset; /**< Offset in bytes for this entity. Fixed + when layout of owner is determined. */ + unsigned alignment; /**< entity alignment in bytes */ unsigned char offset_bit_remainder; - /**< If the entity is a bit field, this is the offset of - the start of the bit field within the byte specified - by offset. */ - 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_type *repr_class; /**< If this entity represents a class info, the associated class. */ + /**< If the entity is a bit field, this is the + offset of the start of the bit field + within the byte specified by offset. */ + 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_type *repr_class; /**< If this entity represents a class info, the + associated class. */ /* ------------- fields for entities owned by a class type ---------------*/ - ir_entity **overwrites; /**< A list of entities this entity overwrites. */ - ir_entity **overwrittenby; /**< A list of entities that overwrite this entity. */ + ir_entity **overwrites; /**< A list of entities this entity overwrites. + */ + ir_entity **overwrittenby; /**< A list of entities that overwrite this + entity. */ /* ------------- fields for atomic entities --------------- */ - ir_node *value; /**< value if entity is not of variability uninitialized. - Only for atomic entities. */ + ir_initializer_t *initializer; /**< entity initializer */ union { /* ------------- fields for compound entities -------------- */ compound_ent_attr cmpd_attr; @@ -167,21 +163,19 @@ struct ir_entity { method_ent_attr mtd_attr; /* fields for code entities */ code_ent_attr code_attr; - /* entity initializer */ - ir_initializer_t *initializer; } attr; /**< type specific attributes */ /* ------------- fields for analyses ---------------*/ #ifdef DEBUG_libfirm - long nr; /**< A unique node number for each node to make output readable. */ -# endif /* DEBUG_libfirm */ + long nr; /**< A unique node number for each node to make output + readable. */ +#endif }; /** Initialize the entity module. */ void firm_init_entity(void); - /* ----------------------- inline functions ------------------------ */ static inline int _is_entity(const void *thing) { @@ -207,17 +201,17 @@ _set_entity_ident(ir_entity *ent, ident *id) { } static inline ir_type * -_get_entity_owner(ir_entity *ent) { +_get_entity_owner(const ir_entity *ent) { assert(ent && ent->kind == k_entity); return ent->owner; } static inline ident * -_get_entity_ld_ident(ir_entity *ent) +_get_entity_ld_ident(const ir_entity *ent) { assert(ent && ent->kind == k_entity); if (ent->ld_name == NULL) - ent->ld_name = id_mangle_entity(ent); + return ent->name; return ent->ld_name; } @@ -228,13 +222,13 @@ _set_entity_ld_ident(ir_entity *ent, ident *ld_ident) { } static inline const char * -_get_entity_ld_name(ir_entity *ent) { +_get_entity_ld_name(const ir_entity *ent) { assert(ent && ent->kind == k_entity); return get_id_str(get_entity_ld_ident(ent)); } static inline ir_type * -_get_entity_type(ir_entity *ent) { +_get_entity_type(const ir_entity *ent) { assert(ent && ent->kind == k_entity); return ent->type; } @@ -245,28 +239,10 @@ _set_entity_type(ir_entity *ent, ir_type *type) { ent->type = type; } -static inline ir_allocation -_get_entity_allocation(const ir_entity *ent) { +static inline ir_linkage +_get_entity_linkage(const ir_entity *ent) { assert(ent && ent->kind == k_entity); - return ent->allocation; -} - -static inline void -_set_entity_allocation(ir_entity *ent, ir_allocation al) { - assert(ent && ent->kind == k_entity); - ent->allocation = al; -} - -static inline ir_visibility -_get_entity_visibility(const ir_entity *ent) { - assert(ent && ent->kind == k_entity); - return ent->visibility; -} - -static inline ir_variability -_get_entity_variability(const ir_entity *ent) { - assert(ent && ent->kind == k_entity); - return ent->variability; + return ent->linkage; } static inline ir_volatility @@ -305,52 +281,6 @@ _set_entity_aligned(ir_entity *ent, ir_align a) { ent->aligned = a; } -static inline ir_peculiarity -_get_entity_peculiarity(const ir_entity *ent) { - assert(ent && ent->kind == k_entity); - return ent->peculiarity; -} - -/** - * @todo Why peculiarity only for methods? - * Good question. Originally, there were only description and - * existent. The thought was, what sense does it make to - * describe a field? With inherited the situation changed. So - * I removed the assertion. GL, 28.2.05 - */ -static inline void -_set_entity_peculiarity(ir_entity *ent, ir_peculiarity pec) { - assert(ent && ent->kind == k_entity); - /* @@@ why peculiarity only for methods? */ - //assert(is_Method_type(ent->type)); - - ent->peculiarity = pec; -} - -static inline ir_stickyness -_get_entity_stickyness(const ir_entity *ent) { - assert(ent && ent->kind == k_entity); - return ent->stickyness; -} - -static inline void -_set_entity_stickyness(ir_entity *ent, ir_stickyness stickyness) { - assert(ent && ent->kind == k_entity); - ent->stickyness = stickyness; -} - -static inline int -_is_entity_final(const ir_entity *ent) { - assert(ent && ent->kind == k_entity); - return (int)ent->final; -} - -static inline void -_set_entity_final(ir_entity *ent, int final) { - assert(ent && ent->kind == k_entity); - ent->final = final ? 1 : 0; -} - static inline int _is_entity_compiler_generated(const ir_entity *ent) { assert(ent && ent->kind == k_entity); @@ -437,50 +367,51 @@ _get_entity_irg(const ir_entity *ent) { return irg; } -static inline ir_visited_t -_get_entity_visited(ir_entity *ent) { +static inline ir_visited_t _get_entity_visited(const ir_entity *ent) +{ assert(ent && ent->kind == k_entity); return ent->visit; } -static inline void -_set_entity_visited(ir_entity *ent, ir_visited_t num) { +static inline void _set_entity_visited(ir_entity *ent, ir_visited_t num) +{ assert(ent && ent->kind == k_entity); ent->visit = num; } -static inline void -_mark_entity_visited(ir_entity *ent) { +static inline void _mark_entity_visited(ir_entity *ent) +{ assert(ent && ent->kind == k_entity); ent->visit = firm_type_visited; } -static inline int -_entity_visited(ir_entity *ent) { +static inline int _entity_visited(const ir_entity *ent) +{ return _get_entity_visited(ent) >= firm_type_visited; } -static inline int -_entity_not_visited(ir_entity *ent) { +static inline int _entity_not_visited(const ir_entity *ent) +{ return _get_entity_visited(ent) < firm_type_visited; } -static inline ir_type * -_get_entity_repr_class(const ir_entity *ent) { +static inline ir_type *_get_entity_repr_class(const ir_entity *ent) +{ assert(ent && ent->kind == k_entity); return ent->repr_class; } -static inline dbg_info * -_get_entity_dbg_info(const ir_entity *ent) { +static inline dbg_info *_get_entity_dbg_info(const ir_entity *ent) +{ return ent->dbi; } -static inline void -_set_entity_dbg_info(ir_entity *ent, dbg_info *db) { +static inline void _set_entity_dbg_info(ir_entity *ent, dbg_info *db) +{ ent->dbi = db; } +int is_entity_final(const ir_entity *entity); #define is_entity(thing) _is_entity(thing) #define get_entity_name(ent) _get_entity_name(ent) @@ -492,22 +423,13 @@ _set_entity_dbg_info(ir_entity *ent, dbg_info *db) { #define get_entity_ld_name(ent) _get_entity_ld_name(ent) #define get_entity_type(ent) _get_entity_type(ent) #define set_entity_type(ent, type) _set_entity_type(ent, type) -#define get_entity_allocation(ent) _get_entity_allocation(ent) -#define set_entity_allocation(ent, al) _set_entity_allocation(ent, al) -#define get_entity_visibility(ent) _get_entity_visibility(ent) -#define get_entity_variability(ent) _get_entity_variability(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 get_entity_peculiarity(ent) _get_entity_peculiarity(ent) -#define set_entity_peculiarity(ent, pec) _set_entity_peculiarity(ent, pec) -#define get_entity_stickyness(ent) _get_entity_stickyness(ent) -#define set_entity_stickyness(ent, stickyness) _set_entity_stickyness(ent, stickyness) -#define is_entity_final(ent) _is_entity_final(ent) -#define set_entity_final(ent, final) _set_entity_final(ent, final) #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 is_entity_backend_marked(ent) _is_entity_backend_marked(ent) @@ -530,5 +452,4 @@ _set_entity_dbg_info(ir_entity *ent, dbg_info *db) { #define get_entity_dbg_info(ent) _get_entity_dbg_info(ent) #define set_entity_dbg_info(ent, db) _set_entity_dbg_info(ent, db) - -#endif /* FIRM_TR_ENTITY_T_H */ +#endif diff --git a/ir/tr/tr_inheritance.c b/ir/tr/tr_inheritance.c index 009d48f50..cba4fdce2 100644 --- a/ir/tr/tr_inheritance.c +++ b/ir/tr/tr_inheritance.c @@ -80,10 +80,10 @@ static void copy_entities_from_superclass(ir_type *clss, void *env) if (get_entity_peculiarity(inhent) == peculiarity_existent) set_entity_peculiarity(thisent, peculiarity_inherited); set_entity_ld_ident(thisent, mfunc(inhent, clss)); - if (get_entity_variability(inhent) == variability_constant) { + if (get_entity_linkage(inhent) & IR_LINKAGE_CONSTANT) { assert(is_atomic_entity(inhent) && /* @@@ */ "Inheritance of constant, compound entities not implemented"); - set_entity_variability(thisent, variability_constant); + add_entity_linkage(thisent, IR_LINKAGE_CONSTANT); set_atomic_ent_value(thisent, get_atomic_ent_value(inhent)); } } diff --git a/ir/tr/trvrfy.c b/ir/tr/trvrfy.c index aac293587..8bf75694c 100644 --- a/ir/tr/trvrfy.c +++ b/ir/tr/trvrfy.c @@ -30,7 +30,8 @@ #include "irflag_t.h" #include "irprintf.h" #include "irgwalk.h" - +#include "error.h" +#include "tv.h" #ifdef NDEBUG /* @@ -137,15 +138,6 @@ static void show_ent_overwrite_cnt(ir_entity *ent) { } } -/** - * Shows a wrong entity allocation - */ -static void show_ent_alloc_error(ir_entity *ent) { - ir_fprintf(stderr, "%+e owner %t has allocation %s\n", - ent, get_entity_type(ent), - get_allocation_name(get_entity_allocation(ent))); -} - #endif /* #ifndef NDEBUG */ /** @@ -288,7 +280,8 @@ static void on_irg_storage(ir_node *n, void *env) { * checks whether a given constant IR node is NOT on the * constant IR graph. */ -static int constant_on_wrong_irg(ir_node *n) { +static int constant_on_wrong_irg(ir_node *n) +{ struct myenv env; env.res = 1; /* on right obstack */ @@ -298,35 +291,45 @@ static int constant_on_wrong_irg(ir_node *n) { return ! env.res; } +static int initializer_constant_on_wrong_irg(ir_initializer_t *initializer) +{ + switch (get_initializer_kind(initializer)) { + case IR_INITIALIZER_NULL: + return 0; + case IR_INITIALIZER_TARVAL: + return 0; + case IR_INITIALIZER_CONST: + return constant_on_wrong_irg(get_initializer_const_value(initializer)); + case IR_INITIALIZER_COMPOUND: { + int n = get_initializer_compound_n_entries(initializer); + int i; + for (i = 0; i < n; ++i) { + ir_initializer_t *sub + = get_initializer_compound_value(initializer, i); + if (initializer_constant_on_wrong_irg(sub)) + return 1; + } + return 0; + } + } + panic("invalid initializer in initializer_on_wrong_irg"); +} + /** * Check if constants node are NOT on the constant IR graph. * * @return NON-zero if an entity initializer constant is NOT on * the current_ir_graph's obstack. */ -static int constants_on_wrong_irg(ir_entity *ent) { - if (get_entity_variability(ent) == variability_uninitialized) return 0; - - if (is_compound_entity(ent)) { - if(!ent->has_initializer) { - int i; - for (i = get_compound_ent_n_values(ent) - 1; i >= 0; --i) { - if (constant_on_wrong_irg(get_compound_ent_value(ent, i))) - return 1; - } - } - } else { - /* Might not be set if entity belongs to a description or is external allocated. */ - if (get_atomic_ent_value(ent)) - return constant_on_wrong_irg(get_atomic_ent_value(ent)); - else if (get_entity_visibility(ent) != visibility_external_allocated) { - ASSERT_AND_RET_DBG( - is_Class_type(get_entity_owner(ent)) && - get_class_peculiarity(get_entity_owner(ent)) == peculiarity_description, - "Value in constant atomic entity not set.", - 0, - ir_fprintf(stderr, "%+e, owner %+F\n", ent, get_entity_owner(ent)) - ); +static int constants_on_wrong_irg(ir_entity *ent) +{ + if (ent->initializer != NULL) { + return initializer_constant_on_wrong_irg(ent->initializer); + } else if (entity_has_compound_ent_values(ent)) { + int i; + for (i = get_compound_ent_n_values(ent) - 1; i >= 0; --i) { + if (constant_on_wrong_irg(get_compound_ent_value(ent, i))) + return 1; } } return 0; @@ -340,10 +343,9 @@ static int constants_on_wrong_irg(ir_entity *ent) { * 0 if no error encountered * != 0 a trvrfy_error_codes code */ -int check_entity(ir_entity *ent) { - int rem_vpi; +int check_entity(ir_entity *ent) +{ ir_type *tp = get_entity_type(ent); - ir_type *owner = get_entity_owner(ent); current_ir_graph = get_const_code_irg(); ASSERT_AND_RET_DBG( @@ -353,60 +355,42 @@ int check_entity(ir_entity *ent) { ir_fprintf(stderr, "%+e not on %+F\n", ent, current_ir_graph) ); - rem_vpi = get_visit_pseudo_irgs(); - set_visit_pseudo_irgs(1); - if ((get_entity_peculiarity(ent) == peculiarity_existent) && - (get_entity_visibility(ent) != visibility_external_allocated) && - (is_Method_type(get_entity_type(ent))) && - (!get_entity_irg(ent) || !(is_ir_graph(get_entity_irg(ent))))) { - ASSERT_AND_RET_DBG( - 0, - "Method ents with pec_exist must have an irg", - error_existent_entity_without_irg, - ir_fprintf(stderr, "%+e\n", ent) - ); - } - set_visit_pseudo_irgs(rem_vpi); - /* Originally, this test assumed, that only method entities have - pecularity_inherited. As I changed this, I have to test for method type before - doing the test. */ - if (get_entity_peculiarity(ent) == peculiarity_inherited) { - if (is_Method_type(get_entity_type(ent))) { - ir_entity *impl = get_SymConst_entity(get_atomic_ent_value(ent)); - ASSERT_AND_RET_DBG( - get_entity_peculiarity(impl) == peculiarity_existent, - "inherited method entities must have constant pointing to existent entity.", - error_inherited_ent_without_const, - ir_fprintf(stderr, "%+e points to %+e\n", ent, impl) - ); - } - } + pecularity_inherited. As I changed this, I have to test for method type + before doing the test. */ + if (get_entity_peculiarity(ent) == peculiarity_existent + && is_method_entity(ent)) { - /* Entities in global type are not dynamic or automatic allocated. */ - if (owner == get_glob_type()) { + ir_entity *impl = get_SymConst_entity(get_atomic_ent_value(ent)); ASSERT_AND_RET_DBG( - get_entity_allocation(ent) != allocation_dynamic && - get_entity_allocation(ent) != allocation_automatic, - "Entities in global type are not allowed to by dynamic or automatic allocated", - error_glob_ent_allocation, - show_ent_alloc_error(ent) + impl != NULL, + "inherited method entities must have constant pointing to existent entity.", + error_inherited_ent_without_const, + ir_fprintf(stderr, "%+e points to %+e\n", ent, impl) ); } - if (get_entity_variability(ent) != variability_uninitialized) { - if (is_atomic_type(tp)) { - ir_node *val = get_atomic_ent_value(ent); - if (val) { - ASSERT_AND_RET_DBG( - get_irn_mode(val) == get_type_mode(tp), - "Mode of constant in entity must match type.", - error_ent_const_mode, - ir_fprintf(stderr, "%+e const %+F, type %+F(%+F)\n", - ent, val, tp, get_type_mode(tp)) - ); - } + if (is_atomic_entity(ent) && ent->initializer != NULL) { + ir_mode *mode = NULL; + ir_initializer_t *initializer = ent->initializer; + switch (initializer->kind) { + case IR_INITIALIZER_CONST: + mode = get_irn_mode(get_initializer_const_value(initializer)); + break; + case IR_INITIALIZER_TARVAL: + mode = get_tarval_mode(get_initializer_tarval_value(initializer)); + break; + case IR_INITIALIZER_NULL: + case IR_INITIALIZER_COMPOUND: + break; } + ASSERT_AND_RET_DBG( + mode == NULL || mode == get_type_mode(tp), + "Mode of constant in entity must match type.", + error_ent_const_mode, + ir_fprintf(stderr, "%+e, type %+F(%+F)\n", + ent, tp, get_type_mode(tp)) + ); } return no_error; } diff --git a/ir/tr/type.c b/ir/tr/type.c index 1dc9724eb..0c29b4ede 100644 --- a/ir/tr/type.c +++ b/ir/tr/type.c @@ -971,18 +971,6 @@ void set_class_type_info(ir_type *clss, ir_entity *ent) ent->repr_class = clss; } -const char *get_peculiarity_name(ir_peculiarity p) -{ -#define X(a) case a: return #a - switch (p) { - X(peculiarity_description); - X(peculiarity_inherited); - X(peculiarity_existent); - } -#undef X - return "invalid peculiarity"; -} - ir_peculiarity get_class_peculiarity(const ir_type *clss) { assert(clss && (clss->type_op == type_class)); diff --git a/ir/tr/type_t.h b/ir/tr/type_t.h index 46c7028df..1f1752bbd 100644 --- a/ir/tr/type_t.h +++ b/ir/tr/type_t.h @@ -169,7 +169,6 @@ enum type_flags { * - type_op: A tp_op specifying the kind of the type. * - name: An identifier specifying the name of the type. To be * set by the frontend. - * - visibility: The visibility of this type. * - size: The size of the type, i.e. an entity of this type will * occupy size bits in memory. In several cases this is * determined when fixing the layout of this type (class, diff --git a/ir/tr/typewalk.c b/ir/tr/typewalk.c index 4620e85ac..3a545b6fb 100644 --- a/ir/tr/typewalk.c +++ b/ir/tr/typewalk.c @@ -126,19 +126,14 @@ static void do_type_walk(type_or_ent tore, cont.typ = get_entity_type(ent); do_type_walk(cont, pre, post, env); - if (get_entity_variability(ent) != variability_uninitialized) { - /* walk over the value types */ - if (ent->has_initializer) { - walk_initializer(ent->attr.initializer, pre, post, env); - } else if (is_atomic_entity(ent)) { - n = get_atomic_ent_value(ent); + /* walk over the value types */ + if (ent->initializer != NULL) { + walk_initializer(ent->initializer, pre, post, env); + } else if (entity_has_compound_ent_values(ent)) { + n_mem = get_compound_ent_n_values(ent); + for (i = 0; i < n_mem; ++i) { + n = get_compound_ent_value(ent, i); irn_type_walker(n, pre, post, env); - } else { - n_mem = get_compound_ent_n_values(ent); - for (i = 0; i < n_mem; ++i) { - n = get_compound_ent_value(ent, i); - irn_type_walker(n, pre, post, env); - } } } break;