Commit 7f971167 authored by Matthias Braun's avatar Matthias Braun Committed by Matthias Braun
Browse files

remove exception support for CopyB nodes

CopyB is normally used to transfer data on the stack or to enable compound
value calling conventions. Exceptions don't happen in these cases.
parent 4719c02b
......@@ -334,6 +334,7 @@ CopyB => {
attr_type => "arm_CopyB_attr_t",
reg_req => { in => [ "!sp", "!sp", "gp", "gp", "gp", "none" ], out => [ "none" ] },
outs => [ "M" ],
mode => "mode_M",
},
FrameAddr => {
......
......@@ -1124,12 +1124,9 @@ static ir_node *gen_CopyB(ir_node *node)
ir_node *mem = get_CopyB_mem(node);
ir_node *new_mem = be_transform_node(mem);
dbg_info *dbg = get_irn_dbg_info(node);
int size = get_type_size_bytes(get_CopyB_type(node));
ir_node *src_copy;
ir_node *dst_copy;
src_copy = be_new_Copy(block, new_src);
dst_copy = be_new_Copy(block, new_dst);
int size = get_type_size_bytes(get_CopyB_type(node));
ir_node *src_copy = be_new_Copy(block, new_src);
ir_node *dst_copy = be_new_Copy(block, new_dst);
return new_bd_arm_CopyB(dbg, block, dst_copy, src_copy,
new_bd_arm_EmptyReg(dbg, block),
......@@ -1249,25 +1246,6 @@ static ir_node *gen_Proj_Load(ir_node *node)
panic("Unsupported Proj from Load");
}
static ir_node *gen_Proj_CopyB(ir_node *node)
{
ir_node *pred = get_Proj_pred(node);
ir_node *new_pred = be_transform_node(pred);
dbg_info *dbgi = get_irn_dbg_info(node);
long proj = get_Proj_proj(node);
switch (proj) {
case pn_CopyB_M:
if (is_arm_CopyB(new_pred)) {
return new_rd_Proj(dbgi, new_pred, mode_M, pn_arm_CopyB_M);
}
break;
default:
break;
}
panic("Unsupported Proj from CopyB");
}
static ir_node *gen_Proj_Div(ir_node *node)
{
ir_node *pred = get_Proj_pred(node);
......@@ -1877,7 +1855,6 @@ static void arm_register_transformers(void)
be_set_transform_proj_function(op_Builtin, gen_Proj_Builtin);
be_set_transform_proj_function(op_Call, gen_Proj_Call);
be_set_transform_proj_function(op_Cond, be_duplicate_node);
be_set_transform_proj_function(op_CopyB, gen_Proj_CopyB);
be_set_transform_proj_function(op_Div, gen_Proj_Div);
be_set_transform_proj_function(op_Load, gen_Proj_Load);
be_set_transform_proj_function(op_Proj, gen_Proj_Proj);
......
......@@ -412,11 +412,8 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp)
mem = new_r_Proj(store, mode_M, pn_Store_M);
} else {
/* Make a mem copy for compound arguments. */
ir_node *copy;
assert(mode_is_reference(get_irn_mode(param)));
copy = new_rd_CopyB(dbgi, bl, curr_mem, addr, param, param_type);
mem = new_r_Proj(copy, mode_M, pn_CopyB_M);
mem = new_rd_CopyB(dbgi, bl, curr_mem, addr, param, param_type);
}
curr_ofs += param_size;
......
......@@ -642,33 +642,33 @@ ir_node *ia32_gen_CopyB(ir_node *node)
ir_node *new_dst = get_new_node(dst);
ir_node *mem = get_CopyB_mem(node);
ir_node *new_mem = get_new_node(mem);
ir_node *res = NULL;
dbg_info *dbgi = get_irn_dbg_info(node);
int size = get_type_size_bytes(get_CopyB_type(node));
int throws_exception = ir_throws_exception(node);
int rem;
/* If we have to copy more than 32 bytes, we use REP MOVSx and */
/* then we need the size explicitly in ECX. */
ir_node *projm;
if (size >= 32 * 4) {
rem = size & 0x3; /* size % 4 */
size >>= 2;
res = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, size);
res = new_bd_ia32_CopyB(dbgi, block, new_dst, new_src, res, new_mem, rem);
ir_node *cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, size);
ir_node *copyb = new_bd_ia32_CopyB(dbgi, block, new_dst, new_src, cnst,
new_mem, rem);
SET_IA32_ORIG_NODE(copyb, node);
projm = new_r_Proj(copyb, mode_M, pn_ia32_CopyB_M);
} else {
if (size == 0) {
ir_fprintf(stderr, "Optimization warning copyb %+F with size <4\n",
node);
}
res = new_bd_ia32_CopyB_i(dbgi, block, new_dst, new_src, new_mem, size);
ir_node *copyb = new_bd_ia32_CopyB_i(dbgi, block, new_dst, new_src,
new_mem, size);
SET_IA32_ORIG_NODE(copyb, node);
projm = new_r_Proj(copyb, mode_M, pn_ia32_CopyB_i_M);
}
ir_set_throws_exception(res, throws_exception);
SET_IA32_ORIG_NODE(res, node);
return res;
return projm;
}
ir_node *ia32_gen_Proj_tls(ir_node *node)
......
......@@ -1676,12 +1676,11 @@ l_FloattoLL => {
},
CopyB => {
op_flags => [ "uses_memory", "fragile" ],
state => "pinned",
op_flags => [ "uses_memory" ],
reg_req => { in => [ "edi", "esi", "ecx", "none" ],
out => [ "edi", "esi", "ecx", "none", "none", "none" ] },
out => [ "edi", "esi", "ecx", "none" ] },
ins => [ "dest", "source", "count", "mem" ],
outs => [ "dest", "source", "count", "M", "X_regular", "X_except" ],
outs => [ "dest", "source", "count", "M" ],
attr_type => "ia32_copyb_attr_t",
attr => "unsigned size",
latency => 250,
......@@ -1690,12 +1689,11 @@ CopyB => {
},
CopyB_i => {
op_flags => [ "uses_memory", "fragile" ],
state => "pinned",
op_flags => [ "uses_memory" ],
reg_req => { in => [ "edi", "esi", "none" ],
out => [ "edi", "esi", "none", "none", "none" ] },
out => [ "edi", "esi", "none" ] },
ins => [ "dest", "source", "mem" ],
outs => [ "dest", "source", "M", "X_regular", "X_except" ],
outs => [ "dest", "source", "M" ],
attr_type => "ia32_copyb_attr_t",
attr => "unsigned size",
latency => 3,
......
......@@ -4440,43 +4440,6 @@ static ir_node *gen_Proj_Mod(ir_node *node)
panic("No idea how to transform proj->Mod");
}
/**
* Transform and renumber the Projs from a CopyB.
*/
static ir_node *gen_Proj_CopyB(ir_node *node)
{
ir_node *pred = get_Proj_pred(node);
ir_node *new_pred = be_transform_node(pred);
dbg_info *dbgi = get_irn_dbg_info(node);
long proj = get_Proj_proj(node);
switch ((pn_CopyB)proj) {
case pn_CopyB_M:
if (is_ia32_CopyB_i(new_pred)) {
return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_i_M);
} else if (is_ia32_CopyB(new_pred)) {
return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_M);
}
break;
case pn_CopyB_X_regular:
if (is_ia32_CopyB_i(new_pred)) {
return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_CopyB_i_X_regular);
} else if (is_ia32_CopyB(new_pred)) {
return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_CopyB_X_regular);
}
break;
case pn_CopyB_X_except:
if (is_ia32_CopyB_i(new_pred)) {
return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_CopyB_i_X_except);
} else if (is_ia32_CopyB(new_pred)) {
return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_CopyB_X_except);
}
break;
}
panic("No idea how to transform proj->CopyB");
}
static ir_node *gen_be_Call(ir_node *node)
{
ir_node *const src_block = get_nodes_block(node);
......@@ -5373,7 +5336,6 @@ static void register_transformers(void)
be_set_transform_proj_function(op_be_Start, be_duplicate_node);
be_set_transform_proj_function(op_be_SubSP, gen_Proj_be_SubSP);
be_set_transform_proj_function(op_Builtin, gen_Proj_Builtin);
be_set_transform_proj_function(op_CopyB, gen_Proj_CopyB);
be_set_transform_proj_function(op_Div, gen_Proj_Div);
be_set_transform_proj_function(op_ia32_l_Adc, gen_Proj_default);
be_set_transform_proj_function(op_ia32_l_Add, gen_Proj_default);
......
......@@ -1163,23 +1163,14 @@ static ir_node *equivalent_node_Proj_Div(ir_node *proj)
/**
* Optimize CopyB(mem, x, x) into a Nop.
*/
static ir_node *equivalent_node_Proj_CopyB(ir_node *proj)
static ir_node *equivalent_node_CopyB(ir_node *copyb)
{
ir_node *oldn = proj;
ir_node *copyb = get_Proj_pred(proj);
ir_node *a = get_CopyB_dst(copyb);
ir_node *b = get_CopyB_src(copyb);
ir_node *a = get_CopyB_dst(copyb);
ir_node *b = get_CopyB_src(copyb);
if (a == b)
return get_CopyB_mem(copyb);
if (a == b) {
/* Turn CopyB into a tuple (mem, jmp, bad, bad) */
switch (get_Proj_proj(proj)) {
case pn_CopyB_M:
proj = get_CopyB_mem(copyb);
DBG_OPT_ALGSIM0(oldn, proj, FS_OPT_NOP);
break;
}
}
return proj;
return copyb;
}
/**
......@@ -4654,35 +4645,6 @@ is_bittest: {
return n;
}
/**
* Optimize CopyB(mem, x, x) into a Nop.
*/
static ir_node *transform_node_Proj_CopyB(ir_node *proj)
{
ir_node *copyb = get_Proj_pred(proj);
ir_node *a = get_CopyB_dst(copyb);
ir_node *b = get_CopyB_src(copyb);
if (a == b) {
switch (get_Proj_proj(proj)) {
case pn_CopyB_X_regular:
/* Turn CopyB into a tuple (mem, jmp, bad, bad) */
DBG_OPT_EXC_REM(proj);
proj = new_r_Jmp(get_nodes_block(copyb));
break;
case pn_CopyB_X_except: {
ir_graph *irg = get_irn_irg(proj);
DBG_OPT_EXC_REM(proj);
proj = new_r_Bad(irg, mode_X);
break;
}
default:
break;
}
}
return proj;
}
/**
* Does all optimizations on nodes that must be done on its Projs
* because of creating new nodes.
......@@ -6108,6 +6070,7 @@ void ir_register_opt_node_ops(void)
register_equivalent_node_func(op_And, equivalent_node_And);
register_equivalent_node_func(op_Confirm, equivalent_node_Confirm);
register_equivalent_node_func(op_Conv, equivalent_node_Conv);
register_equivalent_node_func(op_CopyB, equivalent_node_CopyB);
register_equivalent_node_func(op_Eor, equivalent_node_Eor);
register_equivalent_node_func(op_Id, equivalent_node_Id);
register_equivalent_node_func(op_Minus, equivalent_node_Minus);
......@@ -6121,7 +6084,6 @@ void ir_register_opt_node_ops(void)
register_equivalent_node_func(op_Shr, equivalent_node_left_zero);
register_equivalent_node_func(op_Shrs, equivalent_node_left_zero);
register_equivalent_node_func(op_Sub, equivalent_node_Sub);
register_equivalent_node_func_proj(op_CopyB, equivalent_node_Proj_CopyB);
register_equivalent_node_func_proj(op_Div, equivalent_node_Proj_Div);
register_equivalent_node_func_proj(op_Tuple, equivalent_node_Proj_Tuple);
......@@ -6151,7 +6113,6 @@ void ir_register_opt_node_ops(void)
register_transform_node_func(op_Sub, transform_node_Sub);
register_transform_node_func(op_Switch, transform_node_Switch);
register_transform_node_func(op_Sync, transform_node_Sync);
register_transform_node_func_proj(op_CopyB, transform_node_Proj_CopyB);
register_transform_node_func_proj(op_Div, transform_node_Proj_Div);
register_transform_node_func_proj(op_Load, transform_node_Proj_Load);
register_transform_node_func_proj(op_Mod, transform_node_Proj_Mod);
......
......@@ -321,7 +321,6 @@ typedef struct confirm_attr {
/** CopyB attribute. */
typedef struct copyb_attr {
except_attr exc; /**< The exception attribute. MUST be the first one. */
ir_type *type; /**< Type of the copied entity. */
} copyb_attr;
......
......@@ -572,35 +572,6 @@ static int verify_node_Proj_Tuple(const ir_node *p)
return 1;
}
/**
* verify a Proj(CopyB) node
*/
static int verify_node_Proj_CopyB(const ir_node *p)
{
ir_mode *mode = get_irn_mode(p);
ir_node *n = get_Proj_pred(p);
long proj = get_Proj_proj(p);
ASSERT_AND_RET_DBG(
(
(proj == pn_CopyB_M && mode == mode_M) ||
(proj == pn_CopyB_X_regular && mode == mode_X) ||
(proj == pn_CopyB_X_except && mode == mode_X)
),
"wrong Proj from CopyB", 0,
show_proj_failure(p);
);
if (proj == pn_CopyB_X_regular)
ASSERT_AND_RET(
get_irn_pinned(n) == op_pin_state_pinned,
"Regular Proj from unpinned CopyB", 0);
else if (proj == pn_CopyB_X_except)
ASSERT_AND_RET(
get_irn_pinned(n) == op_pin_state_pinned,
"Exception Proj from unpinned CopyB", 0);
return 1;
}
static int verify_node_Proj_fragile(const ir_node *node)
{
ir_node *pred = get_Proj_pred(node);
......@@ -1486,7 +1457,7 @@ static int verify_node_CopyB(const ir_node *n)
ir_type *t = get_CopyB_type(n);
/* CopyB: BB x M x ref x ref --> M x X */
ASSERT_AND_RET(mymode == mode_T && op1mode == mode_M, "CopyB node", 0);
ASSERT_AND_RET(mymode == mode_M && op1mode == mode_M, "CopyB node", 0);
if (!irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_BACKEND)) {
ASSERT_AND_RET(mode_is_reference(op2mode) && mode_is_reference(op3mode),
"CopyB node", 0 );
......@@ -1496,9 +1467,6 @@ static int verify_node_CopyB(const ir_node *n)
is_compound_type(t) || is_Array_type(t),
"CopyB node should copy compound types only", 0 );
/* NoMem nodes are only allowed as memory input if the CopyB is NOT pinned.
This should happen RARELY, as CopyB COPIES MEMORY */
ASSERT_AND_RET(verify_right_pinned(n), "CopyB node with wrong memory input", 0 );
return 1;
}
......@@ -2054,7 +2022,6 @@ void ir_register_verify_node_ops(void)
register_verify_node_func_proj(op_Alloc, verify_node_Proj_Alloc);
register_verify_node_func_proj(op_Call, verify_node_Proj_Call);
register_verify_node_func_proj(op_Cond, verify_node_Proj_Cond);
register_verify_node_func_proj(op_CopyB, verify_node_Proj_CopyB);
register_verify_node_func_proj(op_Div, verify_node_Proj_Div);
register_verify_node_func_proj(op_InstOf, verify_node_Proj_InstOf);
register_verify_node_func_proj(op_Load, verify_node_Proj_Load);
......
......@@ -518,28 +518,15 @@ static void add_hidden_param(ir_graph *irg, size_t n_com, ir_node **ins,
/* consider only the first CopyB */
if (ins[idx] == NULL) {
ir_node *block = get_nodes_block(p);
/* use the memory output of the call and not the input of the CopyB
* otherwise stuff breaks if the call was mtp_property_const, because
* then the copyb skips the call. But after lowering the call is not
* const anymore, and its memory has to be used */
* otherwise stuff breaks if the call was mtp_property_const,
* because then the copyb skips the call. But after lowering the
* call is not const anymore, and its memory has to be used */
ir_node *mem = new_r_Proj(entry->call, mode_M, pn_Call_M);
ins[idx] = get_CopyB_dst(p);
/* get rid of the CopyB */
if (ir_throws_exception(p)) {
ir_node *const in[] = {
[pn_CopyB_M] = mem,
[pn_CopyB_X_regular] = new_r_Jmp(block),
[pn_CopyB_X_except] = new_r_Bad(irg, mode_X),
};
turn_into_tuple(p, ARRAY_SIZE(in), in);
} else {
ir_node *const in[] = { mem };
turn_into_tuple(p, ARRAY_SIZE(in), in);
}
exchange(p, mem);
++n_args;
}
}
......@@ -620,7 +607,6 @@ static void fix_compound_params(cl_entry *entry, ir_type *ctp)
ir_node *block;
ir_node *arg;
ir_node *sel;
ir_node *copyb;
ir_entity *arg_entity;
if (!needs_lowering(type))
continue;
......@@ -629,8 +615,7 @@ static void fix_compound_params(cl_entry *entry, ir_type *ctp)
arg_entity = create_compound_arg_entity(irg, type);
block = get_nodes_block(call);
sel = new_rd_simpleSel(dbgi, block, nomem, frame, arg_entity);
copyb = new_rd_CopyB(dbgi, block, mem, sel, arg, type);
mem = new_r_Proj(copyb, mode_M, pn_CopyB_M);
mem = new_rd_CopyB(dbgi, block, mem, sel, arg, type);
set_Call_param(call, i, sel);
}
set_Call_mem(call, mem);
......@@ -673,7 +658,7 @@ static void transform_irg(compound_call_lowering_flags flags, ir_graph *irg)
ir_type *lowered_mtp, *tp, *ft;
size_t i, j, k;
size_t n_cr_opt;
ir_node **new_in, *ret, *endbl, *bl, *mem, *copy;
ir_node **new_in, *ret, *endbl, *bl, *mem;
cr_pair *cr_opt;
wlk_env env;
......@@ -787,15 +772,10 @@ static void transform_irg(compound_call_lowering_flags flags, ir_graph *irg)
cr_opt[n_cr_opt].ent = get_Sel_entity(pred);
cr_opt[n_cr_opt].arg = arg;
++n_cr_opt;
} else { /* copy-return optimization is impossible, do the copy. */
copy = new_r_CopyB(
bl,
mem,
arg,
pred,
tp
);
mem = new_r_Proj(copy, mode_M, pn_CopyB_M);
} else {
/* copy-return optimization is impossible, do the
* copy. */
mem = new_r_CopyB(bl, mem, arg, pred, tp);
}
}
if (flags & LF_RETURN_HIDDEN) {
......
......@@ -139,13 +139,7 @@ static void lower_small_copyb_node(ir_node *irn)
mode_bytes /= 2;
}
ir_node *const bad = new_r_Bad(irg, mode_X);
ir_node *const in[] = {
[pn_CopyB_M] = mem,
[pn_CopyB_X_regular] = bad,
[pn_CopyB_X_except] = bad,
};
turn_into_tuple(irn, ARRAY_SIZE(in), in);
exchange(irn, mem);
}
static ir_type *get_memcpy_methodtype(void)
......@@ -199,8 +193,7 @@ static void lower_large_copyb_node(ir_node *irn)
call = new_rd_Call(dbgi, block, mem, symconst, 3, in, call_tp);
call_mem = new_r_Proj(call, mode_M, pn_Call_M);
ir_node *const tuple_in[] = { call_mem };
turn_into_tuple(irn, ARRAY_SIZE(tuple_in), tuple_in);
exchange(irn, call_mem);
}
static void lower_copyb_node(ir_node *irn)
......@@ -227,17 +220,6 @@ static void find_copyb_nodes(ir_node *irn, void *ctx)
entry_t *entry;
bool medium_sized;
if (is_Proj(irn)) {
ir_node *pred = get_Proj_pred(irn);
if (is_CopyB(pred) && get_Proj_proj(irn) != pn_CopyB_M) {
/* found an exception Proj: remove it from the list again */
entry = (entry_t*)get_irn_link(pred);
list_del(&entry->list);
}
return;
}
if (! is_CopyB(irn))
return;
......
......@@ -317,8 +317,7 @@ static void copy_parameter_entities(ir_node *call, ir_graph *called_graph)
ir_node *new_mem;
if (is_compound_type(old_type) || is_Array_type(old_type)) {
/* Copy the compound parameter */
ir_node *copyb = new_rd_CopyB(dbgi, block, call_mem, sel, param, old_type);
new_mem = new_r_Proj(copyb, mode_M, pn_CopyB_M);
new_mem = new_rd_CopyB(dbgi, block, call_mem, sel, param, old_type);
set_Call_param(call, n_param_pos, sel);
if (have_copyb) {
ARR_APP1(ir_node*, sync_mem, new_mem);
......
......@@ -414,12 +414,8 @@ class CopyB:
("dst", "destination address"),
("src", "source address"),
]
outs = [
("M", "memory result"),
("X_regular", "control flow when no exception occurs"),
("X_except", "control flow when exception occured"),
]
flags = [ "fragile", "uses_memory" ]
mode = "mode_M"
flags = [ "uses_memory" ]
attrs = [
dict(
name = "type",
......@@ -428,9 +424,7 @@ class CopyB:
)
]
attr_struct = "copyb_attr"
pinned = "exception"
pinned_init = "op_pin_state_pinned"
throws_init = "false"
pinned = "no"
@op
class Div:
......
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