#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
*
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);
*/
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);
".section\t.bss",
".section\t.tbss,\"awT\",@nobits",
".section\t.ctors,\"aw\",@progbits",
+ ".section\t.dtors,\"aw\",@progbits",
NULL, /* no cstring section */
NULL,
NULL
".section\t.bss",
".section\t.tbss,\"awT\",@nobits",
".section\t.ctors,\"aw\",@progbits",
+ ".section\t.dtors,\"aw\",@progbits",
NULL,
NULL,
NULL
".section\t.bss",
".section\t.tbss,\"awT\",@nobits",
".section\t.ctors,\"aw\",@progbits",
+ ".section\t.dtors,\"aw\",@progbits",
NULL,
NULL,
NULL
".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"
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);
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 */
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();
#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"
/** 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();
/* 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);
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();
}
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);
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
#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()
#include "execution_frequency.h"
#include "irmemory.h"
#include "callgraph.h"
+#include "irprog.h"
#include "field_temperature.h"
#include "irphases_t.h"
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. */