generalize support for segments
authorMatthias Braun <matze@braunis.de>
Thu, 31 Jul 2008 09:17:10 +0000 (09:17 +0000)
committerMatthias Braun <matze@braunis.de>
Thu, 31 Jul 2008 09:17:10 +0000 (09:17 +0000)
[r20827]

include/libfirm/irprog.h
ir/be/begnuas.c
ir/be/begnuas.h
ir/ir/irprofile.c
ir/ir/irprog.c
ir/ir/irprog_t.h
ir/ir/irtypes.h

index da1da06..3f4f6ea 100644 (file)
 #include "firm_types.h"
 #include "irgraph.h"
 
+typedef enum ir_segment_t {
+       /** "normal" global data */
+       IR_SEGMENT_GLOBAL,
+       /** thread local storage segment */
+       IR_SEGMENT_THREAD_LOCAL,
+       /**
+        * the constructors segment. Contains pointers to functions which are
+        * executed on module initialization (program start or when a library is
+        * dynamically loaded)
+        */
+       IR_SEGMENT_CONSTRUCTORS,
+       /** like constructors, but functions are executed on module exit */
+       IR_SEGMENT_DESTRUCTORS,
+
+       IR_SEGMENT_COUNT
+} ir_segment_t;
+
 /**
  * Datastructure that holds central information about a program
  *
@@ -140,9 +157,15 @@ int get_irp_n_allirgs(void);
  pseudo graphs).  Visits first graphs, then pseudo graphs. */
 ir_graph *get_irp_allirg(int pos);
 
+/**
+ * returns the type containing the entities for a segment
+ */
+ir_type *get_segment_type(ir_segment_t segment);
+
 /**
  * Returns the "global" type of the irp.
  * Upon creation this is an empty class type.
+ * This is a convenience function for get_segment_type(IR_SEGMENT_GLOBAL)
  */
 ir_type *get_glob_type(void);
 
@@ -152,13 +175,6 @@ 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 42d9e2a..6ff9698 100644 (file)
@@ -69,6 +69,7 @@ static const char *get_section_name(be_gas_section_t section) {
                        ".section\t.bss",
                        ".section\t.tbss,\"awT\",@nobits",
                        ".section\t.ctors,\"aw\",@progbits",
+                       ".section\t.dtors,\"aw\",@progbits",
                        NULL, /* no cstring section */
                        NULL,
                        NULL
@@ -80,6 +81,7 @@ static const char *get_section_name(be_gas_section_t section) {
                        ".section\t.bss",
                        ".section\t.tbss,\"awT\",@nobits",
                        ".section\t.ctors,\"aw\",@progbits",
+                       ".section\t.dtors,\"aw\",@progbits",
                        NULL,
                        NULL,
                        NULL
@@ -91,6 +93,7 @@ static const char *get_section_name(be_gas_section_t section) {
                        ".section\t.bss",
                        ".section\t.tbss,\"awT\",@nobits",
                        ".section\t.ctors,\"aw\",@progbits",
+                       ".section\t.dtors,\"aw\",@progbits",
                        NULL,
                        NULL,
                        NULL
@@ -102,6 +105,7 @@ static const char *get_section_name(be_gas_section_t section) {
                        ".data",
                        NULL,             /* TLS is not supported on Mach-O */
                        ".mod_init_func",
+                       NULL,             /* TODO: how is this called? */
                        ".cstring",
                        ".section\t__IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5",
                        ".section\t__IMPORT,__pointers,non_lazy_symbol_pointers"
@@ -1296,9 +1300,13 @@ void be_gas_emit_decls(const be_main_env_t *main_env,
        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,
+       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);
index 7ca65e6..edb75d0 100644 (file)
@@ -39,7 +39,8 @@ typedef enum section_t {
        GAS_SECTION_RODATA, /**< rodata section */
        GAS_SECTION_COMMON, /**< common section */
        GAS_SECTION_TLS,    /**< thread local storage section */
-       GAS_SECTION_CTOR,   /**< ctor section for instrumentation code init */
+       GAS_SECTION_CONSTRUCTORS,   /**< ctors section */
+       GAS_SECTION_DESTRUCTORS,    /**< dtors section */
        GAS_SECTION_CSTRING, /**< section for constant strings */
        GAS_SECTION_PIC_TRAMPOLINES, /**< trampolines for pic codes */
        GAS_SECTION_PIC_SYMBOLS,     /**< contains resolved pic symbols */
index e5e3255..f9e8fd1 100644 (file)
@@ -178,7 +178,7 @@ static void add_constructor(ir_entity *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();
+    ir_type   *constructors = get_segment_type(IR_SEGMENT_CONSTRUCTORS);
     ident     *ide          = id_unique("constructor_ptr.%u");
     ir_entity *ptr          = new_entity(constructors, ide, ptr_type);
        ir_graph  *irg          = get_const_code_irg();
index 3ff3542..5fad64a 100644 (file)
 #include "irop_t.h"
 #include "irmemory.h"
 
-/** The name of the Global type. */
-#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,25 +75,31 @@ static ir_prog *new_incomplete_ir_prog(void) {
 
 /** Completes an incomplete irprog. */
 static ir_prog *complete_ir_prog(ir_prog *irp) {
+       int i;
 #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->constructors_type = new_type_struct(IDENT(CONSTRUCTORS_TYPE_NAME));
+
+       irp->segment_types[IR_SEGMENT_GLOBAL] = new_type_class(IDENT("GlobalType"));
+       irp->segment_types[IR_SEGMENT_THREAD_LOCAL]
+               = new_type_struct(IDENT("ThreadLocal"));
+       irp->segment_types[IR_SEGMENT_CONSTRUCTORS]
+               = new_type_struct(IDENT("Constructors"));
+       irp->segment_types[IR_SEGMENT_DESTRUCTORS]
+               = new_type_struct(IDENT("Destructors"));
        /* 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);
+       for (i = 0; i < IR_SEGMENT_COUNT; ++i) {
+               remove_irp_type(irp->segment_types[i]);
+       }
 
        /* Set these flags for debugging. */
-       irp->glob_type->flags |= tf_global_type;
-       irp->tls_type->flags  |= tf_tls_type;
+       irp->segment_types[IR_SEGMENT_GLOBAL]->flags       |= tf_global_type;
+       irp->segment_types[IR_SEGMENT_THREAD_LOCAL]->flags |= tf_tls_type;
 
        /* The global type is a class, but we cannot derive from it, so set
           the final property to assist optimizations that checks for it. */
-       set_class_final(irp->glob_type, 1);
+       set_class_final(irp->segment_types[IR_SEGMENT_GLOBAL], 1);
 
        irp->const_code_irg   = new_const_code_irg();
 
@@ -133,9 +133,10 @@ 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) {
-       free_type(irp->glob_type);
-       free_type(irp->tls_type);
-       free_type(irp->constructors_type);
+       int i;
+       for (i = 0; i < IR_SEGMENT_COUNT; ++i) {
+               free_type(irp->segment_types[i]);
+       }
 
        /* @@@ * free_ir_graph(irp->const_code_irg); * ?? End has no in?? */
        DEL_ARR_F(irp->graphs);
@@ -163,6 +164,10 @@ void set_irp_main_irg(ir_graph *main_irg) {
        irp->main_irg = main_irg;
 }
 
+ir_type *(get_segment_type)(ir_segment_t segment) {
+       return _get_segment_type(segment);
+}
+
 ir_type *(get_glob_type)(void) {
        return _get_glob_type();
 }
@@ -171,10 +176,6 @@ 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 e23b213..0a0f08f 100644 (file)
 void  add_irp_mode(ir_mode *mode);
 
 /* INLINE functions */
-
 static INLINE ir_type *
-_get_glob_type(void) {
-       assert(irp);
-       return irp->glob_type = skip_tid(irp->glob_type);
+_get_segment_type(ir_segment_t segment)
+{
+       ir_type *type;
+
+       assert(segment < IR_SEGMENT_COUNT);
+       type                        = skip_tid(irp->segment_types[segment]);
+       irp->segment_types[segment] = type;
+       return type;
 }
 
 static INLINE ir_type *
-_get_tls_type(void) {
-       assert(irp);
-       return irp->tls_type = skip_tid(irp->tls_type);
+_get_glob_type(void) {
+       return _get_segment_type(IR_SEGMENT_GLOBAL);
 }
 
 static INLINE ir_type *
-_get_constructors_type(void) {
-       assert(irp);
-       return irp->constructors_type = skip_tid(irp->constructors_type);
+_get_tls_type(void) {
+       return _get_segment_type(IR_SEGMENT_THREAD_LOCAL);
 }
 
 static INLINE int
@@ -170,9 +172,9 @@ void init_irprog_2(void);
 #define get_irp_n_opcodes()       _get_irp_n_opcodes()
 #define get_irp_opcode(pos)       _get_irp_opcode(pos)
 #define get_const_code_irg()      _get_const_code_irg()
+#define get_segment_type(s)       _get_segment_type(s
 #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 823b403..6e3715e 100644 (file)
@@ -37,6 +37,7 @@
 #include "execution_frequency.h"
 #include "irmemory.h"
 #include "callgraph.h"
+#include "irprog.h"
 #include "field_temperature.h"
 #include "irphases_t.h"
 
@@ -528,12 +529,7 @@ struct ir_prog {
                                             to allocate nodes the represent values
                                             of constant entities. It is not meant as
                                             a procedure.  */
-       ir_type   *glob_type;           /**< The global type.  Must be a class as it can
-                                            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   *segment_types[IR_SEGMENT_COUNT];
        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. */