make opcode list global
authorMatthias Braun <matze@braunis.de>
Thu, 15 Dec 2011 16:13:45 +0000 (17:13 +0100)
committerMatthias Braun <matze@braunis.de>
Mon, 19 Dec 2011 16:34:40 +0000 (17:34 +0100)
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().

35 files changed:
include/libfirm/irop.h
include/libfirm/irprog.h
ir/be/TEMPLATE/TEMPLATE_emitter.c
ir/be/TEMPLATE/bearch_TEMPLATE.c
ir/be/amd64/amd64_emitter.c
ir/be/amd64/bearch_amd64.c
ir/be/arm/arm_emitter.c
ir/be/arm/arm_optimize.c
ir/be/arm/bearch_arm.c
ir/be/bearch.h
ir/be/bemain.c
ir/be/benode.c
ir/be/benode.h
ir/be/betranshlp.c
ir/be/ia32/bearch_ia32.c
ir/be/ia32/ia32_emitter.c
ir/be/ia32/ia32_optimize.c
ir/be/ia32/ia32_x87.c
ir/be/scripts/generate_new_opcodes.pl
ir/be/sparc/bearch_sparc.c
ir/be/sparc/bearch_sparc_t.h
ir/be/sparc/sparc_emitter.c
ir/be/sparc/sparc_finish.c
ir/common/firm.c
ir/ir/irio.c
ir/ir/irop.c
ir/ir/irop_t.h
ir/ir/irprog.c
ir/ir/irprog_t.h
ir/ir/irtypes.h
ir/lower/lower_dw.c
ir/lower/lower_intrinsics.c
ir/lower/lower_softfloat.c
ir/opt/combo.c
scripts/gen_ir.py

index 0b06304..4eaed6a 100644 (file)
@@ -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
  */
index 144465b..540fd90 100644 (file)
@@ -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
index 61c19f3..752d348 100644 (file)
@@ -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();
index 58811e3..2fc2f99 100644 (file)
@@ -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,
index 3a541eb..bb9dc32 100644 (file)
@@ -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();
index e1528cb..2e31788 100644 (file)
@@ -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,
index e77ffcd..8c35f7a 100644 (file)
@@ -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();
index 9168d2b..c26921b 100644 (file)
@@ -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);
index 8e3a3af..a92f56c 100644 (file)
@@ -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,
index 62326be..e14d3c5 100644 (file)
@@ -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
index ddf438b..918e887 100644 (file)
@@ -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");
index af54ed2..fa2c136 100644 (file)
@@ -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;
+}
index 3b639af..e12fbd4 100644 (file)
@@ -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.
  */
index 434e7ce..8b8e2ca 100644 (file)
@@ -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);
index 5f0be45..ede1091 100644 (file)
@@ -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 */
 };
 
index d63111f..b265442 100644 (file)
@@ -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);
index be4ec75..c46bdc8 100644 (file)
@@ -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);
index 70a5694..71795a1 100644 (file)
@@ -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);
index 649ca5b..7ff3637 100755 (executable)
@@ -116,6 +116,7 @@ my @obst_opvar;       # stack for the "ir_op *op_<arch>_<op-name> = NULL;" state
 my @obst_get_opvar;   # stack for the get_op_<arch>_<op-name>() 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 <arch>_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<<ENDOFMAIN;
 
-       if (run_once)
-               return;
-       run_once = 1;
-
        cur_opcode = get_next_ir_opcodes(iro_$arch\_last);
 
        $arch\_opcode_start = cur_opcode;
@@ -848,7 +848,18 @@ print OUT "\t$arch\_register_additional_opcodes(cur_opcode);\n" if (defined($add
 print OUT "\t$arch\_opcode_end = cur_opcode + iro_$arch\_last";
 print OUT " + $additional_opcodes" if (defined($additional_opcodes));
 print OUT ";\n";
-print OUT "}\n";
+print OUT <<ENDOFMAIN;
+}
+
+void $arch\_free_opcodes(void)
+{
+ENDOFMAIN
+
+print OUT @obst_free_irop;
+
+print OUT <<ENDOFMAIN;
+}
+ENDOFMAIN
 
 close(OUT);
 
index cd2ee21..cfd45bb 100644 (file)
@@ -347,6 +347,11 @@ static void sparc_init(void)
        sparc_cconv_init();
 }
 
+static void sparc_finish(void)
+{
+       sparc_free_opcodes();
+}
+
 static arch_env_t *sparc_begin_codegeneration(const be_main_env_t *env)
 {
        sparc_isa_t *isa = XMALLOC(sparc_isa_t);
@@ -541,6 +546,7 @@ static ir_node *sparc_new_reload(ir_node *value, ir_node *spill,
 
 const arch_isa_if_t sparc_isa_if = {
        sparc_init,
+       sparc_finish,
        sparc_get_backend_params,
        sparc_lower_for_target,
        sparc_parse_asm_constraint,
@@ -560,7 +566,7 @@ const arch_isa_if_t sparc_isa_if = {
        NULL,                /* before_abi */
        sparc_prepare_graph,
        sparc_before_ra,
-       sparc_finish,
+       sparc_finish_graph,
        sparc_emit_routine,
 };
 
index cf9777a..d5cc225 100644 (file)
@@ -75,7 +75,7 @@ static inline bool sparc_is_value_imm_encodeable(int32_t value)
        return SPARC_IMMEDIATE_MIN <= value && value <= SPARC_IMMEDIATE_MAX;
 }
 
-void sparc_finish(ir_graph *irg);
+void sparc_finish_graph(ir_graph *irg);
 
 void sparc_introduce_prolog_epilog(ir_graph *irg);
 
index 50f6e70..b60a227 100644 (file)
@@ -1209,7 +1209,7 @@ static inline void set_emitter(ir_op *op, emit_func sparc_emit_node)
 static void sparc_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 */
        sparc_register_spec_emitters();
 
index 22cb231..7695934 100644 (file)
@@ -628,7 +628,7 @@ static void sparc_set_frame_entity(ir_node *node, ir_entity *entity)
        }
 }
 
-void sparc_finish(ir_graph *irg)
+void sparc_finish_graph(ir_graph *irg)
 {
        be_stack_layout_t *stack_layout = be_get_irg_stack_layout(irg);
        bool               at_begin     = stack_layout->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);
index a6bdfbf..1095594 100644 (file)
@@ -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)
index fab04b5..a0dd036 100644 (file)
@@ -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);
index d714bd9..23ed46e 100644 (file)
@@ -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"
index a2fc0ec..54a2d51 100644 (file)
 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.
index 74dae2b..d6a7306 100644 (file)
@@ -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;
index bc50824..9f2f484 100644 (file)
@@ -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_()
index 07317f4..8f55b77 100644 (file)
@@ -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 -- */
index 58f75f1..7251c99 100644 (file)
@@ -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);
index 4b34720..cf03933 100644 (file)
@@ -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;
index 9455f6b..036dde8 100644 (file)
@@ -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);
index fa98e2b..a56ec0a 100644 (file)
@@ -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;
        }
 
index c9a478b..fe3d4db 100755 (executable)
@@ -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 %}
 }