From 6bb28287b0f135a4dda410e2caa974997a5c6a21 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Thu, 15 Dec 2011 17:13:45 +0100 Subject: [PATCH] make opcode list global The opcode list was a member of irprog before which wasn't really handled consistently. Also make sure opcodes are properly freed at ir_finish(). --- include/libfirm/irop.h | 14 +++++++ include/libfirm/irprog.h | 16 ------- ir/be/TEMPLATE/TEMPLATE_emitter.c | 2 +- ir/be/TEMPLATE/bearch_TEMPLATE.c | 6 +++ ir/be/amd64/amd64_emitter.c | 2 +- ir/be/amd64/bearch_amd64.c | 6 +++ ir/be/arm/arm_emitter.c | 2 +- ir/be/arm/arm_optimize.c | 2 +- ir/be/arm/bearch_arm.c | 6 +++ ir/be/bearch.h | 7 +++- ir/be/bemain.c | 14 ++++++- ir/be/benode.c | 22 +++++++++- ir/be/benode.h | 2 + ir/be/betranshlp.c | 2 +- ir/be/ia32/bearch_ia32.c | 18 ++++---- ir/be/ia32/ia32_emitter.c | 4 +- ir/be/ia32/ia32_optimize.c | 4 +- ir/be/ia32/ia32_x87.c | 2 +- ir/be/scripts/generate_new_opcodes.pl | 25 +++++++---- ir/be/sparc/bearch_sparc.c | 8 +++- ir/be/sparc/bearch_sparc_t.h | 2 +- ir/be/sparc/sparc_emitter.c | 2 +- ir/be/sparc/sparc_finish.c | 6 +-- ir/common/firm.c | 10 ++--- ir/ir/irio.c | 2 +- ir/ir/irop.c | 60 +++++++++++++++++++++++++-- ir/ir/irop_t.h | 6 +-- ir/ir/irprog.c | 53 ++++------------------- ir/ir/irprog_t.h | 14 ------- ir/ir/irtypes.h | 1 - ir/lower/lower_dw.c | 2 +- ir/lower/lower_intrinsics.c | 2 +- ir/lower/lower_softfloat.c | 4 +- ir/opt/combo.c | 4 +- scripts/gen_ir.py | 10 ++--- 35 files changed, 206 insertions(+), 136 deletions(-) diff --git a/include/libfirm/irop.h b/include/libfirm/irop.h index 0b0630432..4eaed6a25 100644 --- a/include/libfirm/irop.h +++ b/include/libfirm/irop.h @@ -283,6 +283,20 @@ FIRM_API ir_op *new_ir_op(unsigned code, const char *name, op_pin_state p, unsigned flags, op_arity opar, int op_index, size_t attr_size, const ir_op_ops *ops); +/** Returns one more than the highest opcode code in use. */ +FIRM_API unsigned ir_get_n_opcodes(void); + +/** + * Returns the opcode with code @p code. + * + * @p code has to be smaller than get_irp_n_opcode(), returns NULL if + * no opcode with the code exists. + */ +FIRM_API ir_op *ir_get_opcode(unsigned code); + +/** Sets the generic function pointer of all opcodes to NULL */ +FIRM_API void ir_clear_opcodes_generic_func(void); + /** * Sets memory input of operation using memory */ diff --git a/include/libfirm/irprog.h b/include/libfirm/irprog.h index 144465bc3..540fd9036 100644 --- a/include/libfirm/irprog.h +++ b/include/libfirm/irprog.h @@ -236,22 +236,6 @@ FIRM_API size_t get_irp_n_modes(void); /** Returns the mode at position pos in the irp. */ FIRM_API ir_mode *get_irp_mode(size_t pos); -/** Adds opcode to the list of opcodes in irp. */ -FIRM_API void add_irp_opcode(ir_op *opcode); - -/** Removes opcode from the list of opcodes, deallocates it and - shrinks the list by one. */ -FIRM_API void remove_irp_opcode(ir_op *opcode); - -/** Returns the number of all opcodes in the irp. */ -FIRM_API size_t get_irp_n_opcodes(void); - -/** Returns the opcode at position pos in the irp. */ -FIRM_API ir_op *get_irp_opcode(size_t pos); - -/** Sets the generic function pointer of all opcodes to NULL */ -FIRM_API void clear_irp_opcodes_generic_func(void); - /** Returns the graph for global constants of the current irp. * * Returns an irgraph that only contains constant expressions for diff --git a/ir/be/TEMPLATE/TEMPLATE_emitter.c b/ir/be/TEMPLATE/TEMPLATE_emitter.c index 61c19f358..752d348b8 100644 --- a/ir/be/TEMPLATE/TEMPLATE_emitter.c +++ b/ir/be/TEMPLATE/TEMPLATE_emitter.c @@ -175,7 +175,7 @@ static inline void set_emitter(ir_op *op, emit_func func) static void TEMPLATE_register_emitters(void) { /* first clear the generic function pointer for all ops */ - clear_irp_opcodes_generic_func(); + ir_clear_opcodes_generic_func(); /* register all emitter functions defined in spec */ TEMPLATE_register_spec_emitters(); diff --git a/ir/be/TEMPLATE/bearch_TEMPLATE.c b/ir/be/TEMPLATE/bearch_TEMPLATE.c index 58811e3a3..2fc2f99b3 100644 --- a/ir/be/TEMPLATE/bearch_TEMPLATE.c +++ b/ir/be/TEMPLATE/bearch_TEMPLATE.c @@ -154,6 +154,11 @@ static void TEMPLATE_init(void) TEMPLATE_create_opcodes(&TEMPLATE_irn_ops); } +static void TEMPLATE_finish(void) +{ + TEMPLATE_free_opcodes(); +} + static arch_env_t *TEMPLATE_begin_codegeneration(const be_main_env_t *env) { TEMPLATE_isa_t *isa = XMALLOC(TEMPLATE_isa_t); @@ -356,6 +361,7 @@ static int TEMPLATE_register_saved_by(const arch_register_t *reg, int callee) const arch_isa_if_t TEMPLATE_isa_if = { TEMPLATE_init, + TEMPLATE_finish, TEMPLATE_get_backend_params, TEMPLATE_lower_for_target, TEMPLATE_parse_asm_constraint, diff --git a/ir/be/amd64/amd64_emitter.c b/ir/be/amd64/amd64_emitter.c index 3a541eb03..bb9dc3266 100644 --- a/ir/be/amd64/amd64_emitter.c +++ b/ir/be/amd64/amd64_emitter.c @@ -486,7 +486,7 @@ static inline void set_emitter(ir_op *op, emit_func arm_emit_node) static void amd64_register_emitters(void) { /* first clear the generic function pointer for all ops */ - clear_irp_opcodes_generic_func(); + ir_clear_opcodes_generic_func(); /* register all emitter functions defined in spec */ amd64_register_spec_emitters(); diff --git a/ir/be/amd64/bearch_amd64.c b/ir/be/amd64/bearch_amd64.c index e1528cb61..2e3178804 100644 --- a/ir/be/amd64/bearch_amd64.c +++ b/ir/be/amd64/bearch_amd64.c @@ -301,6 +301,11 @@ static void amd64_init(void) amd64_create_opcodes(&amd64_irn_ops); } +static void amd64_finish(void) +{ + amd64_free_opcodes(); +} + static arch_env_t *amd64_begin_codegeneration(const be_main_env_t *env) { amd64_isa_t *isa = XMALLOC(amd64_isa_t); @@ -536,6 +541,7 @@ static int amd64_register_saved_by(const arch_register_t *reg, int callee) const arch_isa_if_t amd64_isa_if = { amd64_init, + amd64_finish, amd64_get_backend_params, amd64_lower_for_target, amd64_parse_asm_constraint, diff --git a/ir/be/arm/arm_emitter.c b/ir/be/arm/arm_emitter.c index e77ffcd47..8c35f7acb 100644 --- a/ir/be/arm/arm_emitter.c +++ b/ir/be/arm/arm_emitter.c @@ -794,7 +794,7 @@ static inline void set_emitter(ir_op *op, emit_func arm_emit_node) static void arm_register_emitters(void) { /* first clear the generic function pointer for all ops */ - clear_irp_opcodes_generic_func(); + ir_clear_opcodes_generic_func(); /* register all emitter functions defined in spec */ arm_register_spec_emitters(); diff --git a/ir/be/arm/arm_optimize.c b/ir/be/arm/arm_optimize.c index 9168d2b8f..c26921b1f 100644 --- a/ir/be/arm/arm_optimize.c +++ b/ir/be/arm/arm_optimize.c @@ -267,7 +267,7 @@ static void register_peephole_optimisation(ir_op *op, peephole_opt_func func) void arm_peephole_optimization(ir_graph *irg) { /* register peephole optimizations */ - clear_irp_opcodes_generic_func(); + ir_clear_opcodes_generic_func(); register_peephole_optimisation(op_be_IncSP, peephole_be_IncSP); register_peephole_optimisation(op_arm_Str, peephole_arm_Str_Ldr); register_peephole_optimisation(op_arm_Ldr, peephole_arm_Str_Ldr); diff --git a/ir/be/arm/bearch_arm.c b/ir/be/arm/bearch_arm.c index 8e3a3afd9..a92f56c57 100644 --- a/ir/be/arm/bearch_arm.c +++ b/ir/be/arm/bearch_arm.c @@ -433,6 +433,11 @@ static void arm_init(void) arm_create_opcodes(&arm_irn_ops); } +static void arm_finish(void) +{ + arm_free_opcodes(); +} + static arch_env_t *arm_begin_codegeneration(const be_main_env_t *env) { arm_isa_t *isa = XMALLOC(arm_isa_t); @@ -564,6 +569,7 @@ static const lc_opt_table_entry_t arm_options[] = { const arch_isa_if_t arm_isa_if = { arm_init, + arm_finish, arm_get_libfirm_params, arm_lower_for_target, arm_parse_asm_constraint, diff --git a/ir/be/bearch.h b/ir/be/bearch.h index 62326befb..e14d3c5b9 100644 --- a/ir/be/bearch.h +++ b/ir/be/bearch.h @@ -437,6 +437,11 @@ struct arch_isa_if_t { */ void (*init)(void); + /** + * Fress resources allocated by this isa interface. + */ + void (*finish)(void); + /** * Returns the frontend settings needed for this backend. */ @@ -547,7 +552,7 @@ struct arch_isa_if_t { * Called directly before done is called. This should be the last place * where the irg is modified. */ - void (*finish)(ir_graph *irg); + void (*finish_graph)(ir_graph *irg); /** * Called after everything happened. This call should emit the final diff --git a/ir/be/bemain.c b/ir/be/bemain.c index ddf438bb6..918e88777 100644 --- a/ir/be/bemain.c +++ b/ir/be/bemain.c @@ -151,6 +151,15 @@ static void initialize_isa(void) if (isa_initialized) return; isa_if->init(); + isa_initialized = true; +} + +static void finish_isa(void) +{ + if (isa_initialized) { + isa_if->finish(); + isa_initialized = false; + } } void be_init_default_asm_constraint_flags(void) @@ -341,6 +350,7 @@ void firm_be_init(void) /* Finalize the Firm backend. */ void firm_be_finish(void) { + finish_isa(); be_quit_modules(); } @@ -720,8 +730,8 @@ static void be_main_loop(FILE *file_handle, const char *cup_name) dump(DUMP_RA, irg, "ra"); be_timer_push(T_FINISH); - if (arch_env->impl->finish != NULL) - arch_env->impl->finish(irg); + if (arch_env->impl->finish_graph != NULL) + arch_env->impl->finish_graph(irg); be_timer_pop(T_FINISH); dump(DUMP_FINAL, irg, "finish"); diff --git a/ir/be/benode.c b/ir/be/benode.c index af54ed299..fa2c136ae 100644 --- a/ir/be/benode.c +++ b/ir/be/benode.c @@ -1334,6 +1334,8 @@ void be_init_op(void) { unsigned opc; + assert(op_be_Spill == NULL); + /* Acquire all needed opcodes. */ op_be_Spill = new_ir_op(beo_Spill, "be_Spill", op_pin_state_exc_pinned, irop_flag_none, oparity_unary, 0, sizeof(be_frame_attr_t), &be_node_op_ops); op_be_Reload = new_ir_op(beo_Reload, "be_Reload", op_pin_state_exc_pinned, irop_flag_none, oparity_zero, 0, sizeof(be_frame_attr_t), &be_node_op_ops); @@ -1369,10 +1371,28 @@ void be_init_op(void) /* attach out dummy_ops to middle end nodes */ for (opc = iro_First; opc <= iro_Last; ++opc) { - ir_op *op = get_irp_opcode(opc); + ir_op *op = ir_get_opcode(opc); assert(op->ops.be_ops == NULL); op->ops.be_ops = &dummy_be_irn_ops; } op_Phi->ops.be_ops = &phi_irn_ops; } + +void be_finish_op(void) +{ + free_ir_op(op_be_Spill); op_be_Spill = NULL; + free_ir_op(op_be_Reload); op_be_Reload = NULL; + free_ir_op(op_be_Perm); op_be_Perm = NULL; + free_ir_op(op_be_MemPerm); op_be_MemPerm = NULL; + free_ir_op(op_be_Copy); op_be_Copy = NULL; + free_ir_op(op_be_Keep); op_be_Keep = NULL; + free_ir_op(op_be_CopyKeep); op_be_CopyKeep = NULL; + free_ir_op(op_be_Call); op_be_Call = NULL; + free_ir_op(op_be_Return); op_be_Return = NULL; + free_ir_op(op_be_IncSP); op_be_IncSP = NULL; + free_ir_op(op_be_AddSP); op_be_AddSP = NULL; + free_ir_op(op_be_SubSP); op_be_SubSP = NULL; + free_ir_op(op_be_Start); op_be_Start = NULL; + free_ir_op(op_be_FrameAddr); op_be_FrameAddr = NULL; +} diff --git a/ir/be/benode.h b/ir/be/benode.h index 3b639afbb..e12fbd458 100644 --- a/ir/be/benode.h +++ b/ir/be/benode.h @@ -63,6 +63,8 @@ int is_be_node(const ir_node *irn); */ void be_init_op(void); +void be_finish_op(void); + /** * Position numbers for the be_Spill inputs. */ diff --git a/ir/be/betranshlp.c b/ir/be/betranshlp.c index 434e7cea7..8b8e2ca90 100644 --- a/ir/be/betranshlp.c +++ b/ir/be/betranshlp.c @@ -149,7 +149,7 @@ static ir_node *transform_end(ir_node *node) void be_start_transform_setup(void) { - clear_irp_opcodes_generic_func(); + ir_clear_opcodes_generic_func(); be_set_transform_function(op_Bad, be_duplicate_node); be_set_transform_function(op_be_Copy, be_duplicate_node); diff --git a/ir/be/ia32/bearch_ia32.c b/ir/be/ia32/bearch_ia32.c index 5f0be4587..ede109199 100644 --- a/ir/be/ia32/bearch_ia32.c +++ b/ir/be/ia32/bearch_ia32.c @@ -1310,7 +1310,7 @@ static void introduce_prolog_epilog(ir_graph *irg) * virtual with real x87 instructions, creating a block schedule and peephole * optimisations. */ -static void ia32_finish(ir_graph *irg) +static void ia32_finish_graph(ir_graph *irg) { ia32_irg_data_t *irg_data = ia32_get_irg_data(irg); be_stack_layout_t *stack_layout = be_get_irg_stack_layout(irg); @@ -1736,9 +1736,6 @@ static void ia32_init(void) init_asm_constraints(); - ia32_register_init(); - ia32_create_opcodes(&ia32_irn_ops); - ia32_mode_fpcw = new_int_mode("Fpcw", irma_twos_complement, 16, 0, 0); /* note mantissa is 64bit but with explicitely encoded 1 so the really @@ -1764,6 +1761,14 @@ static void ia32_init(void) ia32_backend_params.mode_float_arithmetic = ia32_mode_E; ia32_backend_params.type_long_double = ia32_type_E; } + + ia32_register_init(); + ia32_create_opcodes(&ia32_irn_ops); +} + +static void ia32_finish(void) +{ + ia32_free_opcodes(); } /** @@ -2042,8 +2047,6 @@ static void ia32_lower_for_target(void) &intrinsic_env, }; - ia32_create_opcodes(&ia32_irn_ops); - /* lower compound param handling * Note: we lower compound arguments ourself, since on ia32 we don't * have hidden parameters but know where to find the structs on the stack. @@ -2163,6 +2166,7 @@ static const lc_opt_table_entry_t ia32_options[] = { const arch_isa_if_t ia32_isa_if = { ia32_init, + ia32_finish, ia32_get_libfirm_params, ia32_lower_for_target, ia32_parse_asm_constraint, @@ -2182,7 +2186,7 @@ const arch_isa_if_t ia32_isa_if = { ia32_before_abi, /* before abi introduce hook */ ia32_prepare_graph, ia32_before_ra, /* before register allocation hook */ - ia32_finish, /* called before codegen */ + ia32_finish_graph, /* called before codegen */ ia32_emit, /* emit && done */ }; diff --git a/ir/be/ia32/ia32_emitter.c b/ir/be/ia32/ia32_emitter.c index d63111fc8..b26544221 100644 --- a/ir/be/ia32/ia32_emitter.c +++ b/ir/be/ia32/ia32_emitter.c @@ -1560,7 +1560,7 @@ static void ia32_register_emitters(void) #define BE_IGN(a) op_be_##a->ops.generic = (op_func)emit_Nothing /* first clear the generic function pointer for all ops */ - clear_irp_opcodes_generic_func(); + ir_clear_opcodes_generic_func(); /* register all emitter functions defined in spec */ ia32_register_spec_emitters(); @@ -3668,7 +3668,7 @@ static void register_emitter(ir_op *op, emit_func func) static void ia32_register_binary_emitters(void) { /* first clear the generic function pointer for all ops */ - clear_irp_opcodes_generic_func(); + ir_clear_opcodes_generic_func(); /* benode emitter */ register_emitter(op_be_Copy, bemit_copy); diff --git a/ir/be/ia32/ia32_optimize.c b/ir/be/ia32/ia32_optimize.c index be4ec7582..c46bdc8cb 100644 --- a/ir/be/ia32/ia32_optimize.c +++ b/ir/be/ia32/ia32_optimize.c @@ -1278,7 +1278,7 @@ void ia32_peephole_optimization(ir_graph *irg) */ /* pass 1 */ - clear_irp_opcodes_generic_func(); + ir_clear_opcodes_generic_func(); register_peephole_optimisation(op_ia32_Cmp, peephole_ia32_Cmp); register_peephole_optimisation(op_ia32_Cmp8Bit, peephole_ia32_Cmp); register_peephole_optimisation(op_ia32_Lea, peephole_ia32_Lea); @@ -1291,7 +1291,7 @@ void ia32_peephole_optimization(ir_graph *irg) be_peephole_opt(irg); /* pass 2 */ - clear_irp_opcodes_generic_func(); + ir_clear_opcodes_generic_func(); register_peephole_optimisation(op_ia32_Const, peephole_ia32_Const); register_peephole_optimisation(op_be_IncSP, peephole_be_IncSP); register_peephole_optimisation(op_ia32_Test, peephole_ia32_Test); diff --git a/ir/be/ia32/ia32_x87.c b/ir/be/ia32/ia32_x87.c index 70a56945c..71795a1f1 100644 --- a/ir/be/ia32/ia32_x87.c +++ b/ir/be/ia32/ia32_x87.c @@ -2208,7 +2208,7 @@ static void x87_init_simulator(x87_simulator *sim, ir_graph *irg) "x87 Simulator started for %+F\n", irg)); /* set the generic function pointer of instruction we must simulate */ - clear_irp_opcodes_generic_func(); + ir_clear_opcodes_generic_func(); register_sim(op_ia32_Call, sim_Call); register_sim(op_ia32_vfld, sim_fld); diff --git a/ir/be/scripts/generate_new_opcodes.pl b/ir/be/scripts/generate_new_opcodes.pl index 649ca5b11..7ff3637f9 100755 --- a/ir/be/scripts/generate_new_opcodes.pl +++ b/ir/be/scripts/generate_new_opcodes.pl @@ -116,6 +116,7 @@ my @obst_opvar; # stack for the "ir_op *op__ = NULL;" state my @obst_get_opvar; # stack for the get_op__() functions my $obst_constructor; # stack for node constructor functions my @obst_new_irop; # stack for the new_ir_op calls +my @obst_free_irop; # stack for free_ir_op calls my @obst_enum_op; # stack for creating the _opcode enum my $obst_header; # stack for function prototypes my @obst_is_archirn; # stack for the is_$arch_irn() function @@ -159,6 +160,7 @@ foreach my $class_name (keys(%reg_classes)) { $n_opcodes += $additional_opcodes if (defined($additional_opcodes)); $obst_header .= "void ${arch}_create_opcodes(const arch_irn_ops_t *be_ops);\n"; +$obst_header .= "void ${arch}_free_opcodes(void);\n"; sub create_constructor { my $op = shift; @@ -712,6 +714,8 @@ EOF push(@obst_new_irop, "\tset_op_attr(op_$op, attr);\n"); } + push(@obst_free_irop, "\tfree_ir_op(op_$op); op_$op = NULL;\n"); + push(@obst_enum_op, "\tiro_$op,\n"); $obst_header .= "\n"; @@ -817,10 +821,10 @@ $obst_constructor * Creates the $arch specific Firm machine operations * needed for the assembler irgs. */ -void $arch\_create_opcodes(const arch_irn_ops_t *be_ops) { +void $arch\_create_opcodes(const arch_irn_ops_t *be_ops) +{ ir_op_ops ops; int cur_opcode; - static int run_once = 0; ENDOFMAIN if (defined($default_op_attr_type)) { @@ -829,10 +833,6 @@ ENDOFMAIN print OUT<sp_relative ? true : false; @@ -647,7 +647,7 @@ void sparc_finish(ir_graph *irg) heights = heights_new(irg); /* perform peephole optimizations */ - clear_irp_opcodes_generic_func(); + ir_clear_opcodes_generic_func(); register_peephole_optimisation(op_be_IncSP, peephole_be_IncSP); register_peephole_optimisation(op_sparc_FrameAddr, peephole_sparc_FrameAddr); register_peephole_optimisation(op_sparc_RestoreZero, @@ -655,7 +655,7 @@ void sparc_finish(ir_graph *irg) be_peephole_opt(irg); /* perform legalizations (mostly fix nodes with too big immediates) */ - clear_irp_opcodes_generic_func(); + ir_clear_opcodes_generic_func(); register_peephole_optimisation(op_be_IncSP, finish_be_IncSP); register_peephole_optimisation(op_sparc_FrameAddr, finish_sparc_FrameAddr); register_peephole_optimisation(op_sparc_Ld, finish_sparc_Ld); diff --git a/ir/common/firm.c b/ir/common/firm.c index a6bdfbf6f..1095594f9 100644 --- a/ir/common/firm.c +++ b/ir/common/firm.c @@ -85,12 +85,12 @@ void ir_init(void) init_mode(); /* initialize tarvals, and floating point arithmetic */ init_tarval_2(); + /* initialize node opcodes */ + firm_init_op(); /* init graph construction */ firm_init_irgraph(); /* kind of obstack initialization */ firm_init_mangle(); - /* initialize all op codes an irnode can consist of */ - init_op(); /* initialize reassociation */ firm_init_reassociation(); /* initialize function call optimization */ @@ -124,15 +124,15 @@ void ir_finish(void) #ifdef DEBUG_libfirm firm_finish_debugger(); #endif - free_ir_prog(); + firm_be_finish(); + free_ir_prog(); + firm_finish_op(); finish_tarval(); finish_mode(); finish_tpop(); firm_finish_mangle(); finish_ident(); - - firm_be_finish(); } unsigned ir_get_version_major(void) diff --git a/ir/ir/irio.c b/ir/ir/irio.c index fab04b5b0..a0dd0363a 100644 --- a/ir/ir/irio.c +++ b/ir/ir/irio.c @@ -980,7 +980,7 @@ static void register_node_writer(ir_op *op, write_node_func func) static void writers_init(void) { - clear_irp_opcodes_generic_func(); + ir_clear_opcodes_generic_func(); register_node_writer(op_Anchor, write_Anchor); register_node_writer(op_ASM, write_ASM); register_node_writer(op_Block, write_Block); diff --git a/ir/ir/irop.c b/ir/ir/irop.c index d714bd970..23ed46ea9 100644 --- a/ir/ir/irop.c +++ b/ir/ir/irop.c @@ -36,9 +36,9 @@ #include "reassoc_t.h" #include "xmalloc.h" +#include "benode.h" -void be_init_op(void); - +static ir_op **opcodes; /** the available next opcode */ static unsigned next_iro = iro_MaxOpcode; @@ -182,7 +182,16 @@ ir_op *new_ir_op(unsigned code, const char *name, op_pin_state p, set_default_operations(code, &res->ops); - add_irp_opcode(res); + { + size_t len = ARR_LEN(opcodes); + if ((size_t)code >= len) { + ARR_RESIZE(ir_op*, opcodes, (size_t)code+1); + memset(&opcodes[len], 0, (code-len+1) * sizeof(opcodes[0])); + } + if (opcodes[code] != NULL) + panic("opcode registered twice"); + opcodes[code] = res; + } hook_new_ir_op(res); return res; @@ -192,10 +201,35 @@ void free_ir_op(ir_op *code) { hook_free_ir_op(code); - remove_irp_opcode(code); + assert(opcodes[code->code] == code); + opcodes[code->code] = NULL; + free(code); } +unsigned ir_get_n_opcodes(void) +{ + return ARR_LEN(opcodes); +} + +ir_op *ir_get_opcode(unsigned code) +{ + assert((size_t)code < ARR_LEN(opcodes)); + return opcodes[code]; +} + +void ir_clear_opcodes_generic_func(void) +{ + size_t n = ir_get_n_opcodes(); + size_t i; + + for (i = 0; i < n; ++i) { + ir_op *op = ir_get_opcode(i); + if (op != NULL) + op->ops.generic = (op_func)NULL; + } +} + void ir_op_set_memory_index(ir_op *op, int memory_index) { assert(op->flags & irop_flag_uses_memory); @@ -280,4 +314,22 @@ irop_flags get_op_flags(const ir_op *op) return (irop_flags)op->flags; } +static void generated_init_op(void); +static void generated_finish_op(void); + +void firm_init_op(void) +{ + opcodes = NEW_ARR_F(ir_op*, 0); + generated_init_op(); + be_init_op(); +} + +void firm_finish_op(void) +{ + be_finish_op(); + generated_finish_op(); + DEL_ARR_F(opcodes); + opcodes = NULL; +} + #include "gen_irop.c.inl" diff --git a/ir/ir/irop_t.h b/ir/ir/irop_t.h index a2fc0eca0..54a2d5171 100644 --- a/ir/ir/irop_t.h +++ b/ir/ir/irop_t.h @@ -38,10 +38,10 @@ void free_ir_op(ir_op *code); /** Initialize the irop module. */ -void init_op(void); +void firm_init_op(void); -/** Free memory used by irop module. */ -void finish_op(void); +/** frees memory allocated by irop module */ +void firm_finish_op(void); /** * Copies simply all attributes stored in the old node to the new node. diff --git a/ir/ir/irprog.c b/ir/ir/irprog.c index 74dae2b1f..d6a730669 100644 --- a/ir/ir/irprog.c +++ b/ir/ir/irprog.c @@ -58,7 +58,6 @@ static ir_prog *new_incomplete_ir_prog(void) res->graphs = NEW_ARR_F(ir_graph *, 0); res->types = NEW_ARR_F(ir_type *, 0); res->modes = NEW_ARR_F(ir_mode *, 0); - res->opcodes = NEW_ARR_F(ir_op *, 0); res->global_asms = NEW_ARR_F(ident *, 0); res->last_label_nr = 1; /* 0 is reserved as non-label */ res->max_irg_idx = 0; @@ -138,21 +137,26 @@ void free_ir_prog(void) for (i = get_irp_n_types(); i > 0;) free_type_entities(get_irp_type(--i)); + ir_finish_entity(irp); + for (i = get_irp_n_types(); i > 0;) free_type(get_irp_type(--i)); free_ir_graph(irp->const_code_irg); + + ir_finish_type(irp); + DEL_ARR_F(irp->graphs); DEL_ARR_F(irp->types); DEL_ARR_F(irp->modes); - finish_op(); - DEL_ARR_F(irp->opcodes); DEL_ARR_F(irp->global_asms); irp->name = NULL; irp->const_code_irg = NULL; irp->kind = k_BAD; + free(irp); + irp = NULL; } ir_graph *get_irp_main_irg(void) @@ -298,49 +302,6 @@ void add_irp_mode(ir_mode *mode) ARR_APP1(ir_mode *, irp->modes, mode); } -void add_irp_opcode(ir_op *opcode) -{ - size_t len; - size_t code; - assert(opcode != NULL); - assert(irp); - len = ARR_LEN(irp->opcodes); - code = opcode->code; - if (code >= len) { - ARR_RESIZE(ir_op*, irp->opcodes, code+1); - memset(&irp->opcodes[len], 0, (code-len+1) * sizeof(irp->opcodes[0])); - } - - assert(irp->opcodes[code] == NULL && "opcode registered twice"); - irp->opcodes[code] = opcode; -} - -void remove_irp_opcode(ir_op *opcode) -{ - assert(opcode->code < ARR_LEN(irp->opcodes)); - irp->opcodes[opcode->code] = NULL; -} - -size_t (get_irp_n_opcodes)(void) -{ - return get_irp_n_opcodes_(); -} - -ir_op *(get_irp_opcode)(size_t pos) -{ - return get_irp_opcode_(pos); -} - -void clear_irp_opcodes_generic_func(void) -{ - size_t i, n; - - for (i = 0, n = get_irp_n_opcodes(); i < n; ++i) { - ir_op *op = get_irp_opcode(i); - op->ops.generic = (op_func)NULL; - } -} - void set_irp_prog_name(ident *name) { irp->name = name; diff --git a/ir/ir/irprog_t.h b/ir/ir/irprog_t.h index bc50824b4..9f2f4844c 100644 --- a/ir/ir/irprog_t.h +++ b/ir/ir/irprog_t.h @@ -93,18 +93,6 @@ static inline ir_mode *get_irp_mode_(size_t pos) return irp->modes[pos]; } -static inline size_t get_irp_n_opcodes_(void) -{ - assert(irp && irp->opcodes); - return ARR_LEN(irp->opcodes); -} - -static inline ir_op *get_irp_opcode_(size_t pos) -{ - assert(irp && irp->opcodes); - return irp->opcodes[pos]; -} - /** Returns a new, unique number to number nodes or the like. */ static inline long get_irp_new_node_nr(void) { @@ -167,8 +155,6 @@ void remove_irp_type(ir_type *typ); #define get_irp_type(pos) get_irp_type_(pos) #define get_irp_n_modes() get_irp_n_modes_() #define get_irp_mode(pos) get_irp_mode_(pos) -#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_() diff --git a/ir/ir/irtypes.h b/ir/ir/irtypes.h index 07317f418..8f55b77b4 100644 --- a/ir/ir/irtypes.h +++ b/ir/ir/irtypes.h @@ -629,7 +629,6 @@ struct ir_prog { ir_type *code_type; /**< unique 'code'-type */ ir_type *unknown_type; /**< unique 'unknown'-type */ ir_mode **modes; /**< A list of all modes in the ir. */ - ir_op **opcodes; /**< A list of all opcodes in the ir. */ ident **global_asms; /**< An array of global ASM insertions. */ /* -- states of and access to generated information -- */ diff --git a/ir/lower/lower_dw.c b/ir/lower/lower_dw.c index 58f75f160..7251c9943 100644 --- a/ir/lower/lower_dw.c +++ b/ir/lower/lower_dw.c @@ -2931,7 +2931,7 @@ void ir_prepare_dw_lowering(const lwrdw_param_t *new_param) param = new_param; - clear_irp_opcodes_generic_func(); + ir_clear_opcodes_generic_func(); ir_register_dw_lower_function(op_ASM, lower_ASM); ir_register_dw_lower_function(op_Add, lower_binop); ir_register_dw_lower_function(op_And, lower_And); diff --git a/ir/lower/lower_intrinsics.c b/ir/lower/lower_intrinsics.c index 4b34720fb..cf03933d4 100644 --- a/ir/lower/lower_intrinsics.c +++ b/ir/lower/lower_intrinsics.c @@ -93,7 +93,7 @@ static void call_mapper(ir_node *node, void *env) size_t lower_intrinsics(i_record *list, size_t length, int part_block_used) { size_t i, n; - size_t n_ops = get_irp_n_opcodes(); + size_t n_ops = ir_get_n_opcodes(); ir_graph *irg; pmap *c_map = pmap_create_ex(length); i_instr_record **i_map; diff --git a/ir/lower/lower_softfloat.c b/ir/lower/lower_softfloat.c index 9455f6b78..036dde855 100644 --- a/ir/lower/lower_softfloat.c +++ b/ir/lower/lower_softfloat.c @@ -1061,7 +1061,7 @@ void lower_floating_point(void) ir_prepare_softfloat_lowering(); - clear_irp_opcodes_generic_func(); + ir_clear_opcodes_generic_func(); ir_register_softloat_lower_function(op_Add, lower_Add); ir_register_softloat_lower_function(op_Cmp, lower_Cmp); ir_register_softloat_lower_function(op_Conv, lower_Conv); @@ -1085,7 +1085,7 @@ void lower_floating_point(void) ir_nodeset_destroy(&created_mux_nodes); } - clear_irp_opcodes_generic_func(); + ir_clear_opcodes_generic_func(); ir_register_softloat_lower_function(op_Call, lower_Call); ir_register_softloat_lower_function(op_Const, lower_Const); ir_register_softloat_lower_function(op_Div, lower_Div_mode); diff --git a/ir/opt/combo.c b/ir/opt/combo.c index fa98e2b14..a56ec0aa0 100644 --- a/ir/opt/combo.c +++ b/ir/opt/combo.c @@ -3463,8 +3463,8 @@ static void set_compute_functions(void) size_t i, n; /* set the default compute function */ - for (i = 0, n = get_irp_n_opcodes(); i < n; ++i) { - ir_op *op = get_irp_opcode(i); + for (i = 0, n = ir_get_n_opcodes(); i < n; ++i) { + ir_op *op = ir_get_opcode(i); op->ops.generic = (op_func)default_compute; } diff --git a/scripts/gen_ir.py b/scripts/gen_ir.py index c9a478bb0..fe3d4db4e 100755 --- a/scripts/gen_ir.py +++ b/scripts/gen_ir.py @@ -468,9 +468,9 @@ irop_template = env.from_string( ir_op *op_{{node.name}}; ir_op *get_op_{{node.name}}(void) { return op_{{node.name}}; } {%- endfor %} -void init_op(void) +static void generated_init_op(void) { - {% for node in nodes %} + {%- for node in nodes %} op_{{node.name}} = new_ir_op( {%- filter arguments %} iro_{{node.name}} @@ -489,13 +489,11 @@ void init_op(void) ir_op_set_fragile_indices(op_{{node.name}}, pn_{{node.name}}_X_regular, pn_{{node.name}}_X_except); {%- endif -%} {%- endfor %} - - be_init_op(); } -void finish_op(void) +static void generated_finish_op(void) { - {% for node in nodes %} + {%- for node in nodes %} free_ir_op(op_{{node.name}}); op_{{node.name}} = NULL; {%- endfor %} } -- 2.20.1