* @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);
/**
* @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
* @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
* @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
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. */
*
* - 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)
* - 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.
* @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.
* 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);
* 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. */
/** 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);
/* -- 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);
/** 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 */
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);
*
* @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
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);
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.
* 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);
* - 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
*/
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.
* - 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
*
* - 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
#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);
* @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.
*
*/
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.
*/
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
*/
#include "config.h"
-# include <string.h>
+#include <string.h>
#include "cgana.h"
#include "rta.h"
/* 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".
* @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);
}
*
* @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;
* @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;
}
} 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)
* 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)) {
* 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);
* 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). */
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);
}
}
*
* @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);
*
* @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];
/* 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 */
* @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)
/**
* 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;
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);
* 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.
*/
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);
}
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 */
* @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));
* 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();
/**
* 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;
* 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) {
/*--------------------------------------------------------------------------*/
/** 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)) {
/* 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);
/* 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);
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));
* 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();
}
/* 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);
}
}
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) {
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;
/**
* 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);
*
* @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);
}
}
}
-} /* check_initializer */
+}
/**
} /* 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;
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);
/* 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.
*
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));
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);
}
}
* 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);
}
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;
* 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;
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;
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;
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;
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;
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);
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);
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);
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);
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);
}
if (! is_method_entity(ent))
continue;
- if (get_entity_peculiarity(ent) == peculiarity_description)
+
+ irg = get_entity_irg(ent);
+ if (irg == NULL)
continue;
/*
*/
ctx->static_link_pos = 0;
- irg = get_entity_irg(ent);
irg_walk_graph(irg, NULL, update_outer_frame_sels, ctx);
}
}
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;
}
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;
}
*/
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 */
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);
}
}
#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;
*
* @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",
NULL,
NULL
},
- { /* GAS_FLAVOUR_MINGW */
+ { /* OBJECT_FILE_FORMAT_COFF */
".section\t.text",
".section\t.data",
".section .rdata,\"dr\"",
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;
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(", ");
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);
{
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(", .-");
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;
/************************************************************************/
/**
* 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";
}
* @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);
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) {
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;
}
/**
*
* @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;
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 \"");
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 \"");
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;
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;
}
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;
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);
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) {
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);
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();
}
}
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);
}
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();
}
}
#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 */
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)
/**
* 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;
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));
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));
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);
}
/**
* 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;
(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)
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;
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) {
}
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
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 */
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");
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");
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);
/**
* 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));
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 {
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"));
}
}
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 {
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"));
}
}
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);
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);
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);
}
}
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);
extern ir_op *get_op_Mulh(void);
-int is_direct_entity(ir_entity *ent);
-
ir_mode* ppc32_mode_Cond = NULL;
/**
}
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;
}
/** 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;
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 */
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);
}
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);
}
}
}
-
-/**
- * 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.
*
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
{
set_ppc32_offset_mode(node, ppc32_ao_Lo16);
node = new_rd_Proj(env->dbg, env->block, node, env->mode, pn_Load_res);
}
+#endif
break;
}
//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;
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;
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);
} /* switch type */
}
-
int dump_type_node(FILE *F, ir_type *tp)
{
int bad = 0;
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);
+ */
}
}
}
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;
}
}
- 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);
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))) {
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;
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);
}
}
}
}
- 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, ");
}
}
- 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));
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);
}
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);
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));
{
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);
}
}
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;
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);
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);
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);
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);
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);
}
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);
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 "<UNKNOWN>";
}
#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)
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) {
}
set_type_alignment_bytes(type, align);
- set_type_visibility(type, vis);
type->flags = flags;
if (state == layout_fixed)
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);
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);
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;
}
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);
}
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;
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);
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 */
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;
/**
* 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) ||
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 */
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) {
*
* @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;
}
}
}
-/**
- * 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;
}
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);
}
}
}
}
- if (variability_constant == get_entity_variability(ent))
+ if (get_entity_linkage(ent) & IR_LINKAGE_CONSTANT)
return ent;
/* try next */
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. */
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);
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;
}
}
}
- if (variability_constant == get_entity_variability(ent))
+ if (get_entity_linkage(ent) == IR_LINKAGE_CONSTANT)
return ent;
/* try next */
/* 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;
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);
/**
* 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;
/* 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));
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,
/* 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);
}
}
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 */
*
* @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;
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));
/* 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;
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);
}
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];
}
* 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);
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);
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) {
{
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)) {
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);
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);
/* 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++) {
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;
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;
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;
+}
#include "irgraph_t.h"
#include "callgraph.h"
#include "error.h"
+#include "compound_path.h"
/*-----------------------------------------------------------------*/
/** general **/
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;
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)) {
*
* @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;
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);
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;
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)
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) {
_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. */
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)
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)));
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));
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)));
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));
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;
}
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);
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);
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);
}
_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;
_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;
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;
}
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". */
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;
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) {
}
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;
}
}
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;
}
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
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);
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)
#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)
#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
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));
}
}
#include "irflag_t.h"
#include "irprintf.h"
#include "irgwalk.h"
-
+#include "error.h"
+#include "tv.h"
#ifdef NDEBUG
/*
}
}
-/**
- * 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 */
/**
* 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 */
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;
* 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(
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;
}
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));
* - 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,
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;