Commit 1dda364d authored by Matthias Braun's avatar Matthias Braun
Browse files

generalize support for segments

[r20827]
parent 7006f996
......@@ -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);
......
......@@ -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);
......
......@@ -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 */
......
......@@ -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();
......
......@@ -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);
......
......@@ -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()
......
......@@ -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. */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment