Commit 6bb28287 authored by Matthias Braun's avatar Matthias Braun
Browse files

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().
parent dc0ab1c4
......@@ -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);
......
......@@ -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();
......
......@@ -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);
......
......@@ -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)
......
......@@ -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);
......
......@@ -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"
......@@ -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.
......
......@@ -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;
......
......@@ -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_()
......
......@@ -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 -- */
......
......@@ -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);
......
......@@ -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;
......
......@@ -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);
......
......@@ -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;
}
......
......@@ -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 %}
}
......
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