summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJonas Haag <jonas@lophus.org>2015-10-03 11:57:59 +0200
committerPhilipp Serrer <philipp@serrer.de>2018-01-18 17:53:14 +0100
commit927ca6881f5f48e74f1b54918ba0635c11bff51e (patch)
tree7aa8c350afdea36747fc9fd257e0d310807b2ab0
parentbf9182f495551d399703bcf50f314278557905b0 (diff)
Introduce X_regular and X_except outs on Calls
-rw-r--r--ir/be/bespillutil.c4
-rw-r--r--ir/be/ia32/ia32_spec.pl4
-rw-r--r--ir/be/ia32/ia32_transform.c8
-rw-r--r--ir/opt/funccall.c2
4 files changed, 15 insertions, 3 deletions
diff --git a/ir/be/bespillutil.c b/ir/be/bespillutil.c
index 9e7cdf9..832a666 100644
--- a/ir/be/bespillutil.c
+++ b/ir/be/bespillutil.c
@@ -1088,6 +1088,10 @@ static void add_missing_keep_walker(ir_node *node, void *data)
/* are keeps missing? */
unsigned n_to_keep = 0;
for (unsigned i = 0; i < n_outs; ++i) {
+ if (is_fragile_op(node) && (i == node->op->pn_x_regular || i == node->op->pn_x_except)) {
+ /* Ignore control-flow outs */
+ continue;
+ }
arch_register_req_t const *const req = arch_get_irn_register_req_out(node, i);
arch_register_class_t const *const cls = req->cls;
if (!cls->manual_ra) {
diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl
index 563a427..6bbe395 100644
--- a/ir/be/ia32/ia32_spec.pl
+++ b/ir/be/ia32/ia32_spec.pl
@@ -1243,13 +1243,13 @@ Return => {
},
Call => {
- op_flags => [ "uses_memory" ],
+ op_flags => [ "uses_memory", "fragile" ],
irn_flags => [ "modify_flags" ],
state => "exc_pinned",
in_reqs => "...",
out_reqs => "...",
ins => [ "base", "index", "mem", "callee", "stack", "first_argument" ],
- outs => [ "mem", "stack", "first_result" ],
+ outs => [ "mem", "stack", "X_regular", "X_except", "first_result" ],
fixed => "x86_insn_size_t const size = X86_SIZE_32;",
emit => "call %*AS3",
attr_type => "ia32_call_attr_t",
diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c
index e60f551..0ec5953 100644
--- a/ir/be/ia32/ia32_transform.c
+++ b/ir/be/ia32/ia32_transform.c
@@ -4860,6 +4860,8 @@ static ir_node *gen_Call(ir_node *node)
ir_node *const call = new_bd_ia32_Call(dbgi, block, in_arity, in, in_req,
n_out, cconv->sp_delta,
n_reg_results);
+ int throws_exception = ir_throws_exception(node);
+ ir_set_throws_exception(call, throws_exception);
arch_set_additional_pressure(call, &ia32_reg_classes[CLASS_ia32_gp],
add_pressure);
@@ -4871,8 +4873,9 @@ static ir_node *gen_Call(ir_node *node)
/* Construct outputs. */
arch_set_irn_register_req_out(call, pn_ia32_Call_mem, arch_memory_req);
-
arch_copy_irn_out_info(call, pn_ia32_Call_stack, callframe);
+ arch_set_irn_register_req_out(call, pn_ia32_Call_X_regular, arch_exec_req);
+ arch_set_irn_register_req_out(call, pn_ia32_Call_X_except, arch_exec_req);
unsigned const n_ress = get_method_n_ress(type);
for (unsigned r = 0; r < n_ress; ++r) {
@@ -4913,11 +4916,14 @@ static ir_node *gen_Proj_Call(ir_node *node)
unsigned pn = get_Proj_num(node);
ir_node *call = get_Proj_pred(node);
ir_node *new_call = be_transform_node(call);
+
switch ((pn_Call)pn) {
case pn_Call_M:
return be_new_Proj(new_call, pn_ia32_Call_mem);
case pn_Call_X_regular:
+ return be_new_Proj(new_call, pn_ia32_Call_X_regular);
case pn_Call_X_except:
+ return be_new_Proj(new_call, pn_ia32_Call_X_except);
case pn_Call_T_result:
break;
}
diff --git a/ir/opt/funccall.c b/ir/opt/funccall.c
index a7334a7..7e1ad59 100644
--- a/ir/opt/funccall.c
+++ b/ir/opt/funccall.c
@@ -469,6 +469,8 @@ static mtp_additional_properties analyze_irg(ir_graph *irg)
foreach_irn_in(endbl, i, pred) {
if (is_Bad(pred))
continue;
+ if (is_x_except_Proj(pred))
+ continue;
if (is_Return(pred)) {
ir_node *mem = get_Return_mem(pred);
max_prop &= follow_mem(mem, min_prop, max_prop);