remove img_section stuff and create a new constructors_type
authorMatthias Braun <matze@braunis.de>
Thu, 3 Apr 2008 18:56:41 +0000 (18:56 +0000)
committerMatthias Braun <matze@braunis.de>
Thu, 3 Apr 2008 18:56:41 +0000 (18:56 +0000)
[r19098]

include/libfirm/irprog.h
include/libfirm/typerep.h
ir/be/begnuas.c
ir/ir/irprofile.c
ir/ir/irprog.c
ir/ir/irprog_t.h
ir/ir/irtypes.h
ir/tr/entity.c
ir/tr/entity_t.h

index 394df4d..da1da06 100644 (file)
@@ -152,6 +152,13 @@ ir_type *get_glob_type(void);
  */
 ir_type *get_tls_type(void);
 
+/**
+ * returns the constructors type containing entities that should be put in
+ * the constructos section. (The constructors section contains pointers to
+ * module constructor functions)
+ */
+ir_type *get_constructors_type(void);
+
 /** Adds type to the list of types in irp. */
 void add_irp_type(ir_type *typ);
 
index 0a614af..6c01a9d 100644 (file)
@@ -745,22 +745,6 @@ typedef enum acc_bits {
 #define IS_WRITTEN(a)  ((a) & ptr_access_write)
 #define IS_STORED(a)   ((a) & ptr_access_store)
 
-/**
- * Supported image sections.
- * Currently only methods can be placed in different sections.
- */
-typedef enum {
-       section_text,           /**< The code segment. This is the default for methods. */
-       section_constructors    /**< The constructor section. */
-} ir_img_section;
-
-/** Returns the section of a method. */
-ir_img_section get_method_img_section(const ir_entity *method);
-
-/** Sets the section of a method. */
-void set_method_img_section(ir_entity *method, ir_img_section section);
-
-
 /**
  * @page tyop  type operations
  *  This module specifies the kinds of types available in firm.
index 03057df..b79ba28 100644 (file)
@@ -197,8 +197,8 @@ void be_gas_emit_function_epilog(ir_entity *entity)
  */
 typedef struct _be_gas_decl_env {
        const be_main_env_t *main_env; /**< The main backend environment, used for it's debug handle. */
-       int                  dump_tls;
-       waitq     *worklist;           /**< A worklist we use to place not yet handled entities on. */
+       be_gas_section_t     section;
+       waitq               *worklist;           /**< A worklist we use to place not yet handled entities on. */
 } be_gas_decl_env_t;
 
 /************************************************************************/
@@ -1088,37 +1088,18 @@ static void emit_align(unsigned alignment)
  *
  * @param env           the gas output environment
  * @param ent           the entity to be dumped
- * @param emit_commons  if non-zero, emit commons (non-local uninitialized entities)
  */
-static void dump_global(be_gas_decl_env_t *env, ir_entity *ent, int emit_commons)
+static void dump_global(be_gas_decl_env_t *env, ir_entity *ent)
 {
        ir_type          *type           = get_entity_type(ent);
        ident            *ld_ident       = get_entity_ld_ident(ent);
        unsigned          align          = get_type_alignment_bytes(type);
        int               emit_as_common = 0;
-       be_gas_section_t  section;
-       ir_variability    variability;
-       ir_visibility     visibility;
-
-       if (is_Method_type(type)) {
-               if (be_gas_flavour != GAS_FLAVOUR_MACH_O
-                               && get_method_img_section(ent) == section_constructors) {
-                       be_gas_emit_switch_section(GAS_SECTION_CTOR);
-                       emit_align(align);
-                       dump_size_type(align);
-                       be_emit_ident(ld_ident);
-                       be_emit_char('\n');
-                       be_emit_write_line();
-               }
+       be_gas_section_t  section        = env->section;
+       ir_variability    variability    = get_entity_variability(ent);
+       ir_visibility     visibility     = get_entity_visibility(ent);
 
-               return;
-       }
-
-       variability = get_entity_variability(ent);
-       visibility  = get_entity_visibility(ent);
-       section     = GAS_SECTION_DATA;
-       if (env->dump_tls) {
-               section = GAS_SECTION_TLS;
+       if (section != (be_gas_section_t) -1) {
                emit_as_common = 0;
        } else if (variability == variability_constant) {
                /* a constant entity, put it on the rdata */
@@ -1130,7 +1111,7 @@ static void dump_global(be_gas_decl_env_t *env, ir_entity *ent, int emit_commons
        } else if (variability == variability_uninitialized) {
                /* uninitialized entity put it in bss segment */
                section = GAS_SECTION_COMMON;
-               if (emit_commons && visibility != visibility_local)
+               if (visibility != visibility_local)
                        emit_as_common = 1;
        }
 
@@ -1215,12 +1196,11 @@ static void dump_global(be_gas_decl_env_t *env, ir_entity *ent, int emit_commons
  *
  * @param gt                a global like type, either the global or the TLS one
  * @param env               an environment
- * @param emit_commons      if non-zero, emit commons (non-local uninitialized entities)
  * @param only_emit_marked  if non-zero, external allocated entities that do not have
  *                          its visited flag set are ignored
  */
 static void be_gas_dump_globals(ir_type *gt, be_gas_decl_env_t *env,
-                              int emit_commons, int only_emit_marked)
+                                int only_emit_marked)
 {
        int i, n = get_compound_n_members(gt);
        waitq *worklist = new_waitq();
@@ -1247,7 +1227,7 @@ static void be_gas_dump_globals(ir_type *gt, be_gas_decl_env_t *env,
        while (!waitq_empty(worklist)) {
                ir_entity *ent = waitq_get(worklist);
 
-               dump_global(env, ent, emit_commons);
+               dump_global(env, ent);
        }
 
        del_waitq(worklist);
@@ -1266,10 +1246,11 @@ void be_gas_emit_decls(const be_main_env_t *main_env,
        env.main_env = main_env;
 
        /* dump global type */
-       be_gas_dump_globals(get_glob_type(), &env, 1, only_emit_marked_entities);
-
-       /* dump the Thread Local Storage */
-       env.dump_tls = 1;
-       be_gas_dump_globals(get_tls_type(), &env, 0, only_emit_marked_entities);
-       env.dump_tls = 0;
+       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_CTOR;
+       be_gas_dump_globals(get_constructors_type(), &env,
+                           only_emit_marked_entities);
 }
index 1609687..7ff8805 100644 (file)
@@ -172,6 +172,22 @@ fix_ssa(ir_node * bb, void * data)
        set_Load_mem(get_irn_link(get_irn_link(bb)), mem);
 }
 
+static void add_constructor(ir_entity *method)
+{
+    ir_type   *method_type  = get_entity_type(method);
+    ident     *id           = id_unique("constructor_ptrt.%u");
+    ir_type   *ptr_type     = new_type_pointer(id, method_type, mode_P_code);
+
+    ir_type   *constructors = get_constructors_type();
+    ident     *ide          = id_unique("constructor_ptr.%u");
+    ir_entity *ptr          = new_entity(constructors, ide, ptr_type);
+       ir_graph  *irg          = get_const_code_irg();
+    ir_node   *val          = new_rd_SymConst_addr_ent(NULL, irg, mode_P_code,
+                                                          method, NULL);
+
+    set_entity_compiler_generated(ptr, 1);
+    set_atomic_ent_value(ptr, val);
+}
 
 /**
  * Generates a new irg which calls the initializer
@@ -239,6 +255,8 @@ gen_initializer_irg(ir_entity * ent_filename, ir_entity * bblock_id, ir_entity *
 
        irg_finalize_cons(irg);
 
+       add_constructor(ent);
+
        return irg;
 }
 
index 6fce2af..3ff3542 100644 (file)
@@ -44,6 +44,8 @@
 #define GLOBAL_TYPE_NAME "GlobalType"
 /** The name of the Thread Local Storage type. */
 #define TLS_TYPE_NAME "TLS"
+/** The name of the constructors type. */
+#define CONSTRUCTORS_TYPE_NAME "Constructors"
 /** The initial name of the irp program. */
 #define INITAL_PROG_NAME "no_name_set"
 
@@ -81,13 +83,15 @@ static ir_prog *new_incomplete_ir_prog(void) {
 static ir_prog *complete_ir_prog(ir_prog *irp) {
 #define IDENT(s) new_id_from_chars(s, sizeof(s)-1)
 
-       irp->name      = IDENT(INITAL_PROG_NAME);
-       irp->glob_type = new_type_class(IDENT(GLOBAL_TYPE_NAME));
-       irp->tls_type  = new_type_struct(IDENT(TLS_TYPE_NAME));
+       irp->name              = IDENT(INITAL_PROG_NAME);
+       irp->glob_type         = new_type_class(IDENT(GLOBAL_TYPE_NAME));
+       irp->tls_type          = new_type_struct(IDENT(TLS_TYPE_NAME));
+       irp->constructors_type = new_type_struct(IDENT(CONSTRUCTORS_TYPE_NAME));
        /* Remove these types from type list.  Must be treated differently than
           other types. */
        remove_irp_type(irp->glob_type);
        remove_irp_type(irp->tls_type);
+       remove_irp_type(irp->constructors_type);
 
        /* Set these flags for debugging. */
        irp->glob_type->flags |= tf_global_type;
@@ -129,10 +133,9 @@ ir_prog *new_ir_prog (void) {
 /* frees all memory used by irp.  Types in type list, irgs in irg
    list and entities in global type must be freed by hand before. */
 void free_ir_prog(void) {
-       if (irp->glob_type)
-               free_type(irp->glob_type);
-       if (irp->tls_type)
-               free_type(irp->tls_type);
+       free_type(irp->glob_type);
+       free_type(irp->tls_type);
+       free_type(irp->constructors_type);
 
        /* @@@ * free_ir_graph(irp->const_code_irg); * ?? End has no in?? */
        DEL_ARR_F(irp->graphs);
@@ -168,6 +171,10 @@ ir_type *(get_tls_type)(void) {
        return _get_tls_type();
 }
 
+ir_type *(get_constructors_type)(void) {
+       return _get_constructors_type();
+}
+
 /* Adds irg to the list of ir graphs in irp. */
 void add_irp_irg(ir_graph *irg) {
        assert(irg != NULL);
index 9478fbf..e23b213 100644 (file)
@@ -59,6 +59,12 @@ _get_tls_type(void) {
        return irp->tls_type = skip_tid(irp->tls_type);
 }
 
+static INLINE ir_type *
+_get_constructors_type(void) {
+       assert(irp);
+       return irp->constructors_type = skip_tid(irp->constructors_type);
+}
+
 static INLINE int
 _get_irp_n_irgs(void) {
        assert (irp && irp->graphs);
@@ -166,6 +172,7 @@ void init_irprog_2(void);
 #define get_const_code_irg()      _get_const_code_irg()
 #define get_glob_type()           _get_glob_type()
 #define get_tls_type()            _get_tls_type()
+#define get_constructors_type()   _get_constructors_type()
 #define get_irp_next_region_nr()  _get_irp_next_region_nr()
 #define get_irp_next_label_nr()   _get_irp_next_label_nr()
 
index 585dd8d..8bd8c03 100644 (file)
@@ -526,6 +526,8 @@ struct ir_prog {
                                             have fields and procedures.  */
        ir_type   *tls_type;            /**< The thread local storage type.  Must be a struct as it can
                                             only have fields.  */
+       ir_type   *constructors_type;   /**< contains links to module constructor
+                                            functions. Must be a struct */
        ir_type  **types;               /**< A list of all types in the ir. */
        ir_mode  **modes;               /**< A list of all modes in the ir. */
        ir_op    **opcodes;             /**< A list of all opcodes in the ir. */
index 541fd26..b3f5808 100644 (file)
@@ -170,7 +170,6 @@ new_rd_entity(dbg_info *db, ir_type *owner, ident *name, ir_type *type)
                res->attr.mtd_attr.param_access       = NULL;
                res->attr.mtd_attr.param_weight       = NULL;
                res->attr.mtd_attr.irg                = NULL;
-               res->attr.mtd_attr.section            = section_text;
        } else if (is_compound_type(type)) {
                res->variability = variability_uninitialized;
                res->value       = NULL;
@@ -1331,18 +1330,6 @@ void set_entity_vtable_number(ir_entity *ent, unsigned vtable_number) {
        ent->attr.mtd_attr.vtable_number = vtable_number;
 }  /* set_entity_vtable_number */
 
-/* Returns the section of a method. */
-ir_img_section get_method_img_section(const ir_entity *ent) {
-       assert(is_method_entity((ir_entity *)ent));
-       return ent->attr.mtd_attr.section;
-}  /* get_method_img_section */
-
-/* Sets the section of a method. */
-void set_method_img_section(ir_entity *ent, ir_img_section section) {
-       assert(is_method_entity(ent));
-       ent->attr.mtd_attr.section = section;
-}  /* set_method_img_section */
-
 int
 (is_entity)(const void *thing) {
        return _is_entity(thing);
index 0f306b1..e779523 100644 (file)
@@ -107,7 +107,6 @@ typedef struct method_ent_attr {
        ptr_access_kind *param_access; /**< the parameter access */
        float *param_weight;           /**< The weight of method's parameters. Parameters
                                            with a high weight are good for procedure cloning. */
-       ir_img_section section;        /**< The code section where this method should be placed */
 } method_ent_attr;