Commit 4e36e86b authored by Manuel Mohr's avatar Manuel Mohr
Browse files

Do not coalesce spillslots if graph contains a call that returns twice.

This works around a problem with modeling control flow for calls to
setjmp and similar functions.
parent 60a4728c
......@@ -186,7 +186,7 @@ static void amd64_finish_graph(ir_graph *irg)
/* create and coalesce frame entities */
irg_walk_graph(irg, NULL, amd64_collect_frame_entity_nodes, fec_env);
be_assign_entities(fec_env, amd64_set_frame_entity, at_begin);
be_assign_entities(fec_env, amd64_set_frame_entity, at_begin, true);
be_free_frame_entity_coalescer(fec_env);
irg_block_walk_graph(irg, NULL, amd64_after_ra_walker, NULL);
......
......@@ -220,7 +220,7 @@ static void arm_emit(ir_graph *irg)
be_fec_env_t *fec_env = be_new_frame_entity_coalescer(irg);
irg_walk_graph(irg, NULL, arm_collect_frame_entity_nodes, fec_env);
be_assign_entities(fec_env, arm_set_frame_entity, at_begin);
be_assign_entities(fec_env, arm_set_frame_entity, at_begin, true);
be_free_frame_entity_coalescer(fec_env);
irg_block_walk_graph(irg, NULL, arm_after_ra_walker, NULL);
......
......@@ -675,7 +675,8 @@ void be_free_frame_entity_coalescer(be_fec_env_t *env)
void be_assign_entities(be_fec_env_t *env,
set_frame_entity_func set_frame_entity,
bool alloc_entities_at_begin)
bool alloc_entities_at_begin,
bool coalescing_allowed)
{
env->set_frame_entity = set_frame_entity;
env->at_begin = alloc_entities_at_begin;
......@@ -684,7 +685,7 @@ void be_assign_entities(be_fec_env_t *env,
stat_ev_dbl("spillslots", ARR_LEN(env->spills));
}
if (be_coalesce_spill_slots) {
if (be_coalesce_spill_slots && coalescing_allowed) {
do_greedy_coalescing(env);
}
......
......@@ -46,6 +46,6 @@ typedef void (*set_frame_entity_func)(ir_node *node, ir_entity *entity);
* Adds memory perms where needed.
*/
void be_assign_entities(be_fec_env_t *env, set_frame_entity_func set_frame,
bool alloc_entities_at_begin);
bool alloc_entities_at_begin, bool coalescing_allowed);
#endif
......@@ -56,6 +56,7 @@
#include "bearch_ia32_t.h"
#include "ia32_new_nodes.h"
#include "ia32_nodes_attr.h"
#include "gen_ia32_regalloc_if.h"
#include "ia32_common_transform.h"
#include "ia32_transform.h"
......@@ -872,6 +873,20 @@ need_stackent:
be_node_needs_frame_entity(env, node, mode, align);
}
static void ia32_check_coal_allowed(ir_node *irn, void *data)
{
bool *allowed = (bool*)data;
if (!*allowed || !is_ia32_Call(irn))
return;
const ia32_call_attr_t *attrs = get_ia32_call_attr_const(irn);
const ir_type *type = attrs->call_tp;
mtp_additional_properties mtp = get_method_additional_properties(type);
if (mtp & mtp_property_returns_twice)
*allowed = false;
}
static int determine_ebp_input(ir_node *ret)
{
const arch_register_t *bp = &ia32_registers[REG_EBP];
......@@ -1020,11 +1035,13 @@ static void ia32_emit(ir_graph *irg)
ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
be_stack_layout_t *stack_layout = be_get_irg_stack_layout(irg);
bool at_begin = stack_layout->sp_relative ? true : false;
bool coal_allowed = true;
be_fec_env_t *fec_env = be_new_frame_entity_coalescer(irg);
/* create and coalesce frame entities */
irg_walk_graph(irg, NULL, ia32_collect_frame_entity_nodes, fec_env);
be_assign_entities(fec_env, ia32_set_frame_entity, at_begin);
irg_walk_graph(irg, NULL, ia32_check_coal_allowed, &coal_allowed);
be_assign_entities(fec_env, ia32_set_frame_entity, at_begin, coal_allowed);
be_free_frame_entity_coalescer(fec_env);
irg_block_walk_graph(irg, NULL, ia32_after_ra_walker, NULL);
......
......@@ -738,14 +738,30 @@ static void fix_constraints_walker(ir_node *block, void *env)
}
}
static void sparc_check_coal_allowed(ir_node *irn, void *data)
{
bool *allowed = (bool*)data;
if (!*allowed || !is_sparc_Call(irn))
return;
const sparc_call_attr_t *attrs = get_sparc_call_attr_const(irn);
const ir_type *type = attrs->call_type;
mtp_additional_properties mtp = get_method_additional_properties(type);
if (mtp & mtp_property_returns_twice)
*allowed = false;
}
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;
bool coal_allowed = true;
be_fec_env_t *fec_env = be_new_frame_entity_coalescer(irg);
irg_walk_graph(irg, NULL, sparc_collect_frame_entity_nodes, fec_env);
be_assign_entities(fec_env, sparc_set_frame_entity, at_begin);
irg_walk_graph(irg, NULL, sparc_check_coal_allowed, &coal_allowed);
be_assign_entities(fec_env, sparc_set_frame_entity, at_begin, coal_allowed);
be_free_frame_entity_coalescer(fec_env);
sparc_adjust_stack_entity_offsets(irg);
......
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