Commit 3ac5f7de by Javier Miranda Committed by Pierre-Marie de Rodat

[Ada] Code cleanup on functions inlining

This patch is preventive: it improves checks on inline functions that
return unconstrained type. It does not change the functionality of
the compiler.

2018-07-16  Javier Miranda  <miranda@adacore.com>

gcc/ada/

	* inline.adb (Build_Body_To_Inline): Minor code reorganization that
	ensures that calls to function Has_Single_Return() pass a decorated
	tree.
	(Has_Single_Return.Check_Return): Peform checks on entities (instead on
	relying on their characters).

From-SVN: r262708
parent a3b7645b
2018-07-16 Javier Miranda <miranda@adacore.com>
* inline.adb (Build_Body_To_Inline): Minor code reorganization that
ensures that calls to function Has_Single_Return() pass a decorated
tree.
(Has_Single_Return.Check_Return): Peform checks on entities (instead on
relying on their characters).
2018-07-16 Javier Miranda <miranda@adacore.com>
* exp_ch5.adb (Expand_Iterator_Loop_Over_Array): Code cleanup. Required
to avoid generating an ill-formed tree that confuses gnatprove causing
it to blowup.
......
......@@ -1085,33 +1085,9 @@ package body Inline is
Cannot_Inline ("cannot inline & (multiple returns)?", N, Spec_Id);
return;
-- Functions that return unconstrained composite types require
-- secondary stack handling, and cannot currently be inlined, unless
-- all return statements return a local variable that is the first
-- local declaration in the body.
elsif Ekind (Spec_Id) = E_Function
and then not Is_Scalar_Type (Etype (Spec_Id))
and then not Is_Access_Type (Etype (Spec_Id))
and then not Is_Constrained (Etype (Spec_Id))
then
if not Has_Single_Return (N)
-- Skip inlining if the function returns an unconstrained type
-- using an extended return statement, since this part of the
-- new inlining model is not yet supported by the current
-- implementation. ???
or else (Returns_Unconstrained_Type (Spec_Id)
and then Has_Extended_Return)
then
Cannot_Inline
("cannot inline & (unconstrained return type)?", N, Spec_Id);
return;
end if;
-- Ditto for functions that return controlled types, where controlled
-- actions interfere in complex ways with inlining.
-- Functions that return controlled types cannot currently be inlined
-- because they require secondary stack handling; controlled actions
-- may also interfere in complex ways with inlining.
elsif Ekind (Spec_Id) = E_Function
and then Needs_Finalization (Etype (Spec_Id))
......@@ -1234,10 +1210,37 @@ package body Inline is
Restore_Env;
end if;
-- Functions that return unconstrained composite types require
-- secondary stack handling, and cannot currently be inlined, unless
-- all return statements return a local variable that is the first
-- local declaration in the body. We had to delay this check until
-- the body of the function is analyzed since Has_Single_Return()
-- requires a minimum decoration.
if Ekind (Spec_Id) = E_Function
and then not Is_Scalar_Type (Etype (Spec_Id))
and then not Is_Access_Type (Etype (Spec_Id))
and then not Is_Constrained (Etype (Spec_Id))
then
if not Has_Single_Return (Body_To_Analyze)
-- Skip inlining if the function returns an unconstrained type
-- using an extended return statement, since this part of the
-- new inlining model is not yet supported by the current
-- implementation. ???
or else (Returns_Unconstrained_Type (Spec_Id)
and then Has_Extended_Return)
then
Cannot_Inline
("cannot inline & (unconstrained return type)?", N, Spec_Id);
return;
end if;
-- If secondary stack is used, there is no point in inlining. We have
-- already issued the warning in this case, so nothing to do.
if Uses_Secondary_Stack (Body_To_Analyze) then
elsif Uses_Secondary_Stack (Body_To_Analyze) then
return;
end if;
......@@ -3904,17 +3907,23 @@ package body Inline is
if Present (Expression (N))
and then Is_Entity_Name (Expression (N))
then
pragma Assert (Present (Entity (Expression (N))));
if No (Return_Statement) then
Return_Statement := N;
return OK;
elsif Chars (Expression (N)) =
Chars (Expression (Return_Statement))
then
return OK;
else
return Abandon;
pragma Assert
(Present (Entity (Expression (Return_Statement))));
if Entity (Expression (N)) =
Entity (Expression (Return_Statement))
then
return OK;
else
return Abandon;
end if;
end if;
-- A return statement within an extended return is a noop
......@@ -3963,8 +3972,8 @@ package body Inline is
else
return Present (Declarations (N))
and then Present (First (Declarations (N)))
and then Chars (Expression (Return_Statement)) =
Chars (Defining_Identifier (First (Declarations (N))));
and then Entity (Expression (Return_Statement)) =
Defining_Identifier (First (Declarations (N)));
end if;
end Has_Single_Return;
......
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