From 9331f39078c520d761ee4ee7efd295098b84f914 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Christian=20W=C3=BCrdig?= Date: Mon, 4 Sep 2006 12:10:22 +0000 Subject: [PATCH] added ctor section support --- ir/be/ia32/bearch_ia32.c | 2 +- ir/be/ia32/ia32_emitter.c | 6 ++- ir/be/ia32/ia32_emitter.h | 3 +- ir/be/ia32/ia32_gen_decls.c | 97 ++++++++++++++++++++++++++++--------- ir/be/ia32/ia32_gen_decls.h | 4 +- 5 files changed, 85 insertions(+), 27 deletions(-) diff --git a/ir/be/ia32/bearch_ia32.c b/ir/be/ia32/bearch_ia32.c index 5d09e3a93..b7d3872cf 100644 --- a/ir/be/ia32/bearch_ia32.c +++ b/ir/be/ia32/bearch_ia32.c @@ -1491,7 +1491,7 @@ static void ia32_done(void *self) { ia32_isa_t *isa = self; /* emit now all global declarations */ - ia32_gen_decls(isa->out); + ia32_gen_decls(isa->out, isa->cg); pmap_destroy(isa->regs_16bit); pmap_destroy(isa->regs_8bit); diff --git a/ir/be/ia32/ia32_emitter.c b/ir/be/ia32/ia32_emitter.c index 67effda78..c9bed250b 100644 --- a/ir/be/ia32/ia32_emitter.c +++ b/ir/be/ia32/ia32_emitter.c @@ -53,14 +53,16 @@ void ia32_switch_section(FILE *F, section_t sec) { ".section\t.data", ".section\t.rodata", ".section\t.text", - ".section\t.tbss,\"awT\",@nobits" + ".section\t.tbss,\"awT\",@nobits", + ".section\t.ctors,\"aw\",@progbits" }, { ".section\t.text", ".section\t.data", ".section .rdata,\"dr\"", ".section\t.text", - ".section\t.tbss,\"awT\",@nobits" + ".section\t.tbss,\"awT\",@nobits", + ".section\t.ctors,\"aw\",@progbits" } }; diff --git a/ir/be/ia32/ia32_emitter.h b/ir/be/ia32/ia32_emitter.h index 3f640050f..40860d3a4 100644 --- a/ir/be/ia32/ia32_emitter.h +++ b/ir/be/ia32/ia32_emitter.h @@ -47,7 +47,8 @@ typedef enum section_t { SECTION_RODATA = 2, /**< rodata section */ SECTION_COMMON = 3, /**< common section */ SECTION_TLS = 4, /**< thread local storage section */ - SECTION_MAX = 5 + SECTION_CTOR = 5, /**< ctor section for instrumentation code init */ + SECTION_MAX = 6 } section_t; /** diff --git a/ir/be/ia32/ia32_gen_decls.c b/ir/be/ia32/ia32_gen_decls.c index 6fa5d88ff..8decc1ffb 100644 --- a/ir/be/ia32/ia32_gen_decls.c +++ b/ir/be/ia32/ia32_gen_decls.c @@ -16,9 +16,21 @@ #include "entity.h" #include "irprog.h" +#include "../bearch.h" + #include "ia32_emitter.h" #include "ia32_gen_decls.h" +typedef struct obstack obstack_t; + +typedef struct _ia32_decl_env { + obstack_t *rodata_obst; + obstack_t *data_obst; + obstack_t *comm_obst; + obstack_t *ctor_obst; + ia32_code_gen_t *cg; +} ia32_decl_env_t; + /************************************************************************/ /* @@ -54,7 +66,7 @@ static unsigned highest_bit(unsigned v) return res; } -static void ia32_dump_comm(struct obstack *obst, const char *name, visibility vis, int size, int align) { +static void ia32_dump_comm(obstack_t *obst, const char *name, visibility vis, int size, int align) { switch (asm_flavour) { case ASM_LINUX_GAS: if (vis == visibility_local) @@ -73,7 +85,7 @@ static void ia32_dump_comm(struct obstack *obst, const char *name, visibility vi /** * output the alignment to an obstack */ -static void ia32_dump_align(struct obstack *obst, int align) +static void ia32_dump_align(obstack_t *obst, int align) { int h = highest_bit(align); @@ -103,7 +115,7 @@ static void ia32_dump_align_f(FILE *f, int align) /** * output a tarval */ -static void dump_arith_tarval(struct obstack *obst, tarval *tv, int bytes) +static void dump_arith_tarval(obstack_t *obst, tarval *tv, int bytes) { switch (bytes) { @@ -139,7 +151,7 @@ static void dump_arith_tarval(struct obstack *obst, tarval *tv, int bytes) /* * dump an atomic value */ -static void do_dump_atomic_init(struct obstack *obst, ir_node *init) +static void do_dump_atomic_init(obstack_t *obst, ir_node *init) { ir_mode *mode = get_irn_mode(init); int bytes = get_mode_size_bytes(mode); @@ -217,14 +229,10 @@ static void do_dump_atomic_init(struct obstack *obst, ir_node *init) } /* - * dump an atomic value + * dumps the type for given size (.byte, .long, ...) */ -static void dump_atomic_init(struct obstack *obst, ir_node *init) -{ - ir_mode *mode = get_irn_mode(init); - int bytes = get_mode_size_bytes(mode); - - switch (bytes) { +static void dump_size_type(obstack_t *obst, int size) { + switch (size) { case 1: obstack_printf(obst, "\t.byte\t"); @@ -248,10 +256,20 @@ static void dump_atomic_init(struct obstack *obst, ir_node *init) break; default: - fprintf(stderr, "Try to dump an tarval with %d bytes\n", bytes); + fprintf(stderr, "Try to dump a type with %d bytes\n", size); assert(0); } +} + +/* + * dump an atomic value + */ +static void dump_atomic_init(obstack_t *obst, ir_node *init) +{ + ir_mode *mode = get_irn_mode(init); + int bytes = get_mode_size_bytes(mode); + dump_size_type(obst, bytes); do_dump_atomic_init(obst, init); obstack_printf(obst, "\n"); } @@ -316,7 +334,7 @@ static int ent_is_string_const(entity *ent) * @param obst The obst to dump on. * @param ent The entity to dump. */ -static void dump_string_cst(struct obstack *obst, entity *ent) +static void dump_string_cst(obstack_t *obst, entity *ent) { int i, n; @@ -356,7 +374,7 @@ struct arr_info { /** * Dump the size of an object */ -static void dump_object_size(struct obstack *obst, const char *name, int size) { +static void dump_object_size(obstack_t *obst, const char *name, int size) { switch (asm_flavour) { case ASM_LINUX_GAS: obstack_printf(obst, "\t.type\t%s,@object\n", name); @@ -369,12 +387,15 @@ static void dump_object_size(struct obstack *obst, const char *name, int size) { * Dumps the initialization of global variables that are not * "uninitialized". */ -static void dump_global(struct obstack *rdata_obstack, struct obstack *data_obstack, struct obstack *comm_obstack, entity *ent) +static void dump_global(const arch_env_t *arch_env, + obstack_t *rdata_obstack, obstack_t *data_obstack, + obstack_t *comm_obstack, obstack_t *ctor_obstack, + entity *ent) { ir_type *ty = get_entity_type(ent); const char *ld_name = get_entity_ld_name(ent); + obstack_t *obst = data_obstack; int align, h; - struct obstack *obst = data_obstack; /* * FIXME: did NOT work for partly constant values @@ -562,24 +583,31 @@ static void dump_global(struct obstack *rdata_obstack, struct obstack *data_obst obstack_printf(comm_obstack, "%s:\n\t.zero %d\n", ld_name, get_type_size_bytes(ty)); } } + } /* ! is method type */ + else if (ctor_obstack && arch_ent_is_constructor(arch_env, ent)) { + ia32_dump_align(ctor_obstack, get_type_alignment_bytes(ty)); + dump_size_type(ctor_obstack, get_type_alignment_bytes(ty)); + obstack_printf(ctor_obstack, "%s\n", ld_name); } } /** * Dumps declarations of global variables and the initialization code. */ -static void ia32_dump_globals(ir_type *gt, struct obstack *rdata_obstack, struct obstack *data_obstack, struct obstack *comm_obstack) +static void ia32_dump_globals(ir_type *gt, ia32_decl_env_t *env) { int i, n = get_compound_n_members(gt); for (i = 0; i < n; i++) - dump_global(rdata_obstack, data_obstack, comm_obstack, get_compound_member(gt, i)); + dump_global(env->cg->arch_env, env->rodata_obst, env->data_obst, env->comm_obst, env->ctor_obst, + get_compound_member(gt, i)); } /************************************************************************/ -void ia32_gen_decls(FILE *out) { - struct obstack rodata, data, comm; +void ia32_gen_decls(FILE *out, ia32_code_gen_t *cg) { + ia32_decl_env_t env; + obstack_t rodata, data, comm, ctor; int size; char *cp; @@ -588,7 +616,15 @@ void ia32_gen_decls(FILE *out) { obstack_init(&data); obstack_init(&comm); - ia32_dump_globals(get_glob_type(), &rodata, &data, &comm); + if (cg->birg->main_env->options->opt_profile) + obstack_init(&ctor); + + env.rodata_obst = &rodata; + env.data_obst = &data; + env.comm_obst = &comm; + env.ctor_obst = cg->birg->main_env->options->opt_profile ? &ctor : NULL; + + ia32_dump_globals(get_glob_type(), &env); size = obstack_object_size(&data); cp = obstack_finish(&data); @@ -611,13 +647,29 @@ void ia32_gen_decls(FILE *out) { fwrite(cp, 1, size, out); } + if (cg->birg->main_env->options->opt_profile) { + size = obstack_object_size(&ctor); + cp = obstack_finish(&ctor); + if (size > 0) { + ia32_switch_section(out, SECTION_CTOR); + fwrite(cp, 1, size, out); + } + obstack_free(&ctor, NULL); + } + obstack_free(&rodata, NULL); obstack_free(&data, NULL); obstack_free(&comm, NULL); /* dump the Thread Local Storage */ obstack_init(&data); - ia32_dump_globals(get_tls_type(), &data, &data, &data); + + env.rodata_obst = &data; + env.data_obst = &data; + env.comm_obst = &data; + env.ctor_obst = NULL; + + ia32_dump_globals(get_tls_type(), &env); size = obstack_object_size(&data); cp = obstack_finish(&data); @@ -627,4 +679,5 @@ void ia32_gen_decls(FILE *out) { fwrite(cp, 1, size, out); } + obstack_free(&data, NULL); } diff --git a/ir/be/ia32/ia32_gen_decls.h b/ir/be/ia32/ia32_gen_decls.h index 51230aefc..2946492a3 100644 --- a/ir/be/ia32/ia32_gen_decls.h +++ b/ir/be/ia32/ia32_gen_decls.h @@ -7,9 +7,11 @@ #ifndef _IA32_GEN_DECLS_H_ #define _IA32_GEN_DECLS_H_ +#include "bearch_ia32_t.h" + /** * Generate all entities. */ -void ia32_gen_decls(FILE *out); +void ia32_gen_decls(FILE *out, ia32_code_gen_t *cg); #endif /* _IA32_GEN_DECLS_H_ */ -- 2.20.1