Commit ead0ba57 by Jan Hubicka Committed by Jan Hubicka

re PR ipa/63566 (i686 bootstrap fails: ICE RTL flag check: INSN_UID used with…

re PR ipa/63566 (i686 bootstrap fails: ICE RTL flag check: INSN_UID used with unexpected rtx code 'set' in INSN_UID, at rtl.h:1326)

	PR ipa/63566 
	* i386.c (ix86_function_regparm): Look through aliases to see if callee
	is local and optimized.
	(ix86_function_sseregparm): Likewise; also use target's SSE math
	settings; error out instead of silently generating wrong code
	on mismatches.
	(init_cumulative_args): Look through aliases.

From-SVN: r220520
parent 42685f72
2015-02-08 Jan Hubicka <hubicka@ucw.cz> 2015-02-08 Jan Hubicka <hubicka@ucw.cz>
PR ipa/63566 PR ipa/63566
* i386.c (ix86_function_regparm): Look through aliases to see if callee
is local and optimized.
(ix86_function_sseregparm): Likewise; also use target's SSE math
settings; error out instead of silently generating wrong code
on mismatches.
(init_cumulative_args): Look through aliases.
2015-02-08 Jan Hubicka <hubicka@ucw.cz>
PR ipa/63566
* ipa-split.c (execute_split_functions): Split if function has aliases. * ipa-split.c (execute_split_functions): Split if function has aliases.
2015-02-08 Jan Hubicka <hubicka@ucw.cz> 2015-02-08 Jan Hubicka <hubicka@ucw.cz>
......
...@@ -5767,49 +5767,55 @@ ix86_function_regparm (const_tree type, const_tree decl) ...@@ -5767,49 +5767,55 @@ ix86_function_regparm (const_tree type, const_tree decl)
/* Use register calling convention for local functions when possible. */ /* Use register calling convention for local functions when possible. */
if (decl if (decl
&& TREE_CODE (decl) == FUNCTION_DECL && TREE_CODE (decl) == FUNCTION_DECL)
{
cgraph_node *target = cgraph_node::get (decl);
if (target)
target = target->function_symbol ();
/* Caller and callee must agree on the calling convention, so /* Caller and callee must agree on the calling convention, so
checking here just optimize means that with checking here just optimize means that with
__attribute__((optimize (...))) caller could use regparm convention __attribute__((optimize (...))) caller could use regparm convention
and callee not, or vice versa. Instead look at whether the callee and callee not, or vice versa. Instead look at whether the callee
is optimized or not. */ is optimized or not. */
&& opt_for_fn (decl, optimize) if (target && opt_for_fn (target->decl, optimize)
&& !(profile_flag && !flag_fentry)) && !(profile_flag && !flag_fentry))
{
/* FIXME: remove this CONST_CAST when cgraph.[ch] is constified. */
cgraph_local_info *i = cgraph_node::local_info (CONST_CAST_TREE (decl));
if (i && i->local && i->can_change_signature)
{ {
int local_regparm, globals = 0, regno; cgraph_local_info *i = &target->local;
if (i && i->local && i->can_change_signature)
{
int local_regparm, globals = 0, regno;
/* Make sure no regparm register is taken by a /* Make sure no regparm register is taken by a
fixed register variable. */ fixed register variable. */
for (local_regparm = 0; local_regparm < REGPARM_MAX; local_regparm++) for (local_regparm = 0; local_regparm < REGPARM_MAX;
if (fixed_regs[local_regparm]) local_regparm++)
break; if (fixed_regs[local_regparm])
break;
/* We don't want to use regparm(3) for nested functions as /* We don't want to use regparm(3) for nested functions as
these use a static chain pointer in the third argument. */ these use a static chain pointer in the third argument. */
if (local_regparm == 3 && DECL_STATIC_CHAIN (decl)) if (local_regparm == 3 && DECL_STATIC_CHAIN (target->decl))
local_regparm = 2; local_regparm = 2;
/* In 32-bit mode save a register for the split stack. */ /* Save a register for the split stack. */
if (!TARGET_64BIT && local_regparm == 3 && flag_split_stack) if (local_regparm == 3 && flag_split_stack)
local_regparm = 2; local_regparm = 2;
/* Each fixed register usage increases register pressure, /* Each fixed register usage increases register pressure,
so less registers should be used for argument passing. so less registers should be used for argument passing.
This functionality can be overriden by an explicit This functionality can be overriden by an explicit
regparm value. */ regparm value. */
for (regno = AX_REG; regno <= DI_REG; regno++) for (regno = AX_REG; regno <= DI_REG; regno++)
if (fixed_regs[regno]) if (fixed_regs[regno])
globals++; globals++;
local_regparm local_regparm
= globals < local_regparm ? local_regparm - globals : 0; = globals < local_regparm ? local_regparm - globals : 0;
if (local_regparm > regparm) if (local_regparm > regparm)
regparm = local_regparm; regparm = local_regparm;
}
} }
} }
...@@ -5848,15 +5854,37 @@ ix86_function_sseregparm (const_tree type, const_tree decl, bool warn) ...@@ -5848,15 +5854,37 @@ ix86_function_sseregparm (const_tree type, const_tree decl, bool warn)
return 2; return 2;
} }
if (!decl)
return 0;
cgraph_node *target = cgraph_node::get (decl);
if (target)
target = target->function_symbol ();
/* For local functions, pass up to SSE_REGPARM_MAX SFmode /* For local functions, pass up to SSE_REGPARM_MAX SFmode
(and DFmode for SSE2) arguments in SSE registers. */ (and DFmode for SSE2) arguments in SSE registers. */
if (decl && TARGET_SSE_MATH && optimize if (target
/* TARGET_SSE_MATH */
&& (target_opts_for_fn (target->decl)->x_ix86_fpmath & FPMATH_SSE)
&& opt_for_fn (target->decl, optimize)
&& !(profile_flag && !flag_fentry)) && !(profile_flag && !flag_fentry))
{ {
/* FIXME: remove this CONST_CAST when cgraph.[ch] is constified. */ cgraph_local_info *i = &target->local;
cgraph_local_info *i = cgraph_node::local_info (CONST_CAST_TREE(decl));
if (i && i->local && i->can_change_signature) if (i && i->local && i->can_change_signature)
return TARGET_SSE2 ? 2 : 1; {
/* Refuse to produce wrong code when local function with SSE enabled
is called from SSE disabled function.
We may work hard to work out these scenarios but hopefully
it doesnot matter in practice. */
if (!TARGET_SSE && warn)
{
error ("calling %qD with SSE caling convention without "
"SSE/SSE2 enabled", decl);
return 0;
}
return TARGET_SSE2_P (target_opts_for_fn (target->decl)
->x_ix86_isa_flags) ? 2 : 1;
}
} }
return 0; return 0;
...@@ -6343,20 +6371,25 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */ ...@@ -6343,20 +6371,25 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */
tree fndecl, tree fndecl,
int caller) int caller)
{ {
struct cgraph_local_info *i; struct cgraph_local_info *i = NULL;
struct cgraph_node *target = NULL;
memset (cum, 0, sizeof (*cum)); memset (cum, 0, sizeof (*cum));
if (fndecl) if (fndecl)
{ {
i = cgraph_node::local_info (fndecl); target = cgraph_node::get (fndecl);
cum->call_abi = ix86_function_abi (fndecl); if (target)
{
target = target->function_symbol ();
i = cgraph_node::local_info (target->decl);
cum->call_abi = ix86_function_abi (target->decl);
}
else
cum->call_abi = ix86_function_abi (fndecl);
} }
else else
{ cum->call_abi = ix86_function_type_abi (fntype);
i = NULL;
cum->call_abi = ix86_function_type_abi (fntype);
}
cum->caller = caller; cum->caller = caller;
...@@ -6392,7 +6425,7 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */ ...@@ -6392,7 +6425,7 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */
helping K&R code. helping K&R code.
FIXME: once typesytem is fixed, we won't need this code anymore. */ FIXME: once typesytem is fixed, we won't need this code anymore. */
if (i && i->local && i->can_change_signature) if (i && i->local && i->can_change_signature)
fntype = TREE_TYPE (fndecl); fntype = TREE_TYPE (target->decl);
cum->stdarg = stdarg_p (fntype); cum->stdarg = stdarg_p (fntype);
cum->maybe_vaarg = (fntype cum->maybe_vaarg = (fntype
? (!prototype_p (fntype) || stdarg_p (fntype)) ? (!prototype_p (fntype) || stdarg_p (fntype))
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