From: Matthias Braun Date: Fri, 16 Jul 2010 16:25:31 +0000 (+0000) Subject: avoid code duplication: use be_add_missing_keeps in ia32 backend also X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=d7925741c820983f9613b519ab215133765a3cb2;p=libfirm avoid code duplication: use be_add_missing_keeps in ia32 backend also [r27754] --- diff --git a/ir/be/beabihelper.c b/ir/be/beabihelper.c index fcfe8686a..7deb48928 100644 --- a/ir/be/beabihelper.c +++ b/ir/be/beabihelper.c @@ -423,7 +423,7 @@ static void add_missing_keep_walker(ir_node *node, void *data) req = arch_get_out_register_req(node, i); cls = req->cls; - if (cls == NULL) { + if (cls == NULL || (cls->flags & arch_register_class_flag_manual_ra)) { continue; } diff --git a/ir/be/bearch.h b/ir/be/bearch.h index a17dc39e7..bfa1de888 100644 --- a/ir/be/bearch.h +++ b/ir/be/bearch.h @@ -43,7 +43,7 @@ typedef enum arch_register_class_flags_t { arch_register_class_flag_none = 0, /** don't do automatic register allocation for this class */ - arch_register_class_flag_manual_ra = 1U << 0, + arch_register_class_flag_manual_ra = 1U << 0, /** the register models an abstract state (example: fpu rounding mode) */ arch_register_class_flag_state = 1U << 1 } arch_register_class_flags_t; @@ -75,7 +75,7 @@ typedef enum arch_register_type_t { */ typedef enum arch_register_req_type_t { /** No register requirement. */ - arch_register_req_type_none = 0, + arch_register_req_type_none = 0, /** All registers in the class are allowed. */ arch_register_req_type_normal = 1U << 0, /** Only a real subset of the class is allowed. */ @@ -380,7 +380,7 @@ struct arch_inverse_t { struct arch_irn_ops_t { /** - * Get the register requirements for a given operand. + * Get the register requirements for a given operand. * @param irn The node. * @param pos The operand's position * @return The register requirements for the selected operand. diff --git a/ir/be/ia32/bearch_ia32.c b/ir/be/ia32/bearch_ia32.c index 3be7fe6f4..4b00da247 100644 --- a/ir/be/ia32/bearch_ia32.c +++ b/ir/be/ia32/bearch_ia32.c @@ -71,6 +71,7 @@ #include "../beflags.h" #include "../betranshlp.h" #include "../belistsched.h" +#include "../beabihelper.h" #include "bearch_ia32_t.h" @@ -999,7 +1000,7 @@ static void ia32_before_ra(void *self) be_sched_fix_flags(cg->irg, &ia32_reg_classes[CLASS_ia32_flags], &flags_remat); - ia32_add_missing_keeps(cg); + be_add_missing_keeps(cg->irg); } diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index b6c1828fc..bba8f65ba 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -5779,90 +5779,6 @@ static void ia32_pretransform_node(void) get_fpcw(); } -/** - * Walker, checks if all ia32 nodes producing more than one result have their - * Projs, otherwise creates new Projs and keeps them using a be_Keep node. - */ -static void add_missing_keep_walker(ir_node *node, void *data) -{ - int n_outs, i; - unsigned found_projs = 0; - const ir_edge_t *edge; - ir_mode *mode = get_irn_mode(node); - ir_node *last_keep; - (void) data; - if (mode != mode_T) - return; - if (!is_ia32_irn(node)) - return; - - n_outs = arch_irn_get_n_outs(node); - if (n_outs <= 0) - return; - if (is_ia32_SwitchJmp(node)) - return; - - assert(n_outs < (int) sizeof(unsigned) * 8); - foreach_out_edge(node, edge) { - ir_node *proj = get_edge_src_irn(edge); - int pn; - - /* The node could be kept */ - if (is_End(proj)) - continue; - - if (get_irn_mode(proj) == mode_M) - continue; - - pn = get_Proj_proj(proj); - assert(pn < n_outs); - found_projs |= 1 << pn; - } - - - /* are keeps missing? */ - last_keep = NULL; - for (i = 0; i < n_outs; ++i) { - ir_node *block; - ir_node *in[1]; - const arch_register_req_t *req; - const arch_register_class_t *cls; - - if (found_projs & (1 << i)) { - continue; - } - - req = arch_get_out_register_req(node, i); - cls = req->cls; - if (cls == NULL) { - continue; - } - if (cls == &ia32_reg_classes[CLASS_ia32_flags]) { - continue; - } - - block = get_nodes_block(node); - in[0] = new_r_Proj(node, arch_register_class_mode(cls), i); - if (last_keep != NULL) { - be_Keep_add_node(last_keep, cls, in[0]); - } else { - last_keep = be_new_Keep(block, 1, in); - if (sched_is_scheduled(node)) { - sched_add_after(node, last_keep); - } - } - } -} - -/** - * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs - * and keeps them. - */ -void ia32_add_missing_keeps(ia32_code_gen_t *cg) -{ - irg_walk_graph(cg->irg, add_missing_keep_walker, NULL, NULL); -} - /** * Post-process all calls if we are in SSE mode. * The ABI requires that the results are in st0, copy them diff --git a/ir/be/ia32/ia32_transform.h b/ir/be/ia32/ia32_transform.h index 624dbf921..bd8dd2e2b 100644 --- a/ir/be/ia32/ia32_transform.h +++ b/ir/be/ia32/ia32_transform.h @@ -52,8 +52,6 @@ typedef enum { */ ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct); -void ia32_add_missing_keeps(ia32_code_gen_t *cg); - /** * Skip all Down-Conv's on a given node and return the resulting node. */ @@ -62,4 +60,4 @@ ir_node *ia32_skip_downconv(ir_node *node); /** Initialize the ia32 instruction selector. */ void ia32_init_transform(void); -#endif /* FIRM_BE_IA32_IA32_TRANSFORM_H */ +#endif