Commit d7925741 authored by Matthias Braun's avatar Matthias Braun
Browse files

avoid code duplication: use be_add_missing_keeps in ia32 backend also

[r27754]
parent 2b3e33ed
......@@ -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;
}
......
......@@ -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.
......
......@@ -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);
}
......
......@@ -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
......
......@@ -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
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