From: Matthias Braun Date: Thu, 31 Jul 2008 09:17:10 +0000 (+0000) Subject: generalize support for segments X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=1dda364d51a065159f1fa8f3b4a175a56dc78030;p=libfirm generalize support for segments [r20827] --- diff --git a/include/libfirm/irprog.h b/include/libfirm/irprog.h index da1da0683..3f4f6ea32 100644 --- a/include/libfirm/irprog.h +++ b/include/libfirm/irprog.h @@ -46,6 +46,23 @@ #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); diff --git a/ir/be/begnuas.c b/ir/be/begnuas.c index 42d9e2a67..6ff969862 100644 --- a/ir/be/begnuas.c +++ b/ir/be/begnuas.c @@ -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); diff --git a/ir/be/begnuas.h b/ir/be/begnuas.h index 7ca65e6e7..edb75d014 100644 --- a/ir/be/begnuas.h +++ b/ir/be/begnuas.h @@ -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 */ diff --git a/ir/ir/irprofile.c b/ir/ir/irprofile.c index e5e3255ea..f9e8fd156 100644 --- a/ir/ir/irprofile.c +++ b/ir/ir/irprofile.c @@ -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(); diff --git a/ir/ir/irprog.c b/ir/ir/irprog.c index 3ff354267..5fad64a6e 100644 --- a/ir/ir/irprog.c +++ b/ir/ir/irprog.c @@ -40,12 +40,6 @@ #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); diff --git a/ir/ir/irprog_t.h b/ir/ir/irprog_t.h index e23b2133e..0a0f08fab 100644 --- a/ir/ir/irprog_t.h +++ b/ir/ir/irprog_t.h @@ -46,23 +46,25 @@ 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() diff --git a/ir/ir/irtypes.h b/ir/ir/irtypes.h index 823b40397..6e3715e2b 100644 --- a/ir/ir/irtypes.h +++ b/ir/ir/irtypes.h @@ -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. */