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> 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 * exp_ch5.adb (Expand_Iterator_Loop_Over_Array): Code cleanup. Required
to avoid generating an ill-formed tree that confuses gnatprove causing to avoid generating an ill-formed tree that confuses gnatprove causing
it to blowup. it to blowup.
......
...@@ -1085,33 +1085,9 @@ package body Inline is ...@@ -1085,33 +1085,9 @@ package body Inline is
Cannot_Inline ("cannot inline & (multiple returns)?", N, Spec_Id); Cannot_Inline ("cannot inline & (multiple returns)?", N, Spec_Id);
return; return;
-- Functions that return unconstrained composite types require -- Functions that return controlled types cannot currently be inlined
-- secondary stack handling, and cannot currently be inlined, unless -- because they require secondary stack handling; controlled actions
-- all return statements return a local variable that is the first -- may also interfere in complex ways with inlining.
-- 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.
elsif Ekind (Spec_Id) = E_Function elsif Ekind (Spec_Id) = E_Function
and then Needs_Finalization (Etype (Spec_Id)) and then Needs_Finalization (Etype (Spec_Id))
...@@ -1234,10 +1210,37 @@ package body Inline is ...@@ -1234,10 +1210,37 @@ package body Inline is
Restore_Env; Restore_Env;
end if; 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 -- If secondary stack is used, there is no point in inlining. We have
-- already issued the warning in this case, so nothing to do. -- 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; return;
end if; end if;
...@@ -3904,17 +3907,23 @@ package body Inline is ...@@ -3904,17 +3907,23 @@ package body Inline is
if Present (Expression (N)) if Present (Expression (N))
and then Is_Entity_Name (Expression (N)) and then Is_Entity_Name (Expression (N))
then then
pragma Assert (Present (Entity (Expression (N))));
if No (Return_Statement) then if No (Return_Statement) then
Return_Statement := N; Return_Statement := N;
return OK; return OK;
elsif Chars (Expression (N)) =
Chars (Expression (Return_Statement))
then
return OK;
else 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; end if;
-- A return statement within an extended return is a noop -- A return statement within an extended return is a noop
...@@ -3963,8 +3972,8 @@ package body Inline is ...@@ -3963,8 +3972,8 @@ package body Inline is
else else
return Present (Declarations (N)) return Present (Declarations (N))
and then Present (First (Declarations (N))) and then Present (First (Declarations (N)))
and then Chars (Expression (Return_Statement)) = and then Entity (Expression (Return_Statement)) =
Chars (Defining_Identifier (First (Declarations (N)))); Defining_Identifier (First (Declarations (N)));
end if; end if;
end Has_Single_Return; 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