Commit 6625fbd0 by Robert Dewar Committed by Arnaud Charlet

exp_ch9.adb (Null_Statements): Moved to library level

2007-12-19  Robert Dewar  <dewar@adacore.com>

	* exp_ch9.adb (Null_Statements): Moved to library level
	(Trivial_Accept_OK): New function
	(Expand_Accept_Declaration): Use Trivial_Accept_OK
	(Expand_N_Accept_Statement): Use Trivial_Accept_OK

From-SVN: r131074
parent 5be0911d
...@@ -347,6 +347,12 @@ package body Exp_Ch9 is ...@@ -347,6 +347,12 @@ package body Exp_Ch9 is
Lo : Node_Id; Lo : Node_Id;
Hi : Node_Id) return Boolean; Hi : Node_Id) return Boolean;
function Null_Statements (Stats : List_Id) return Boolean;
-- Used to check DO-END sequence. Checks for equivalent of DO NULL; END.
-- Allows labels, and pragma Warnings/Unreferenced in the sequence as
-- well to still count as null. Returns True for a null sequence. The
-- argument is the list of statements from the DO-END sequence.
function Parameter_Block_Pack function Parameter_Block_Pack
(Loc : Source_Ptr; (Loc : Source_Ptr;
Blk_Typ : Entity_Id; Blk_Typ : Entity_Id;
...@@ -378,6 +384,16 @@ package body Exp_Ch9 is ...@@ -378,6 +384,16 @@ package body Exp_Ch9 is
-- ... -- ...
-- <actualN> := P.<formalN>; -- <actualN> := P.<formalN>;
function Trivial_Accept_OK return Boolean;
-- If there is no DO-END block for an accept, or if the DO-END block has
-- only null statements, then it is possible to do the Rendezvous with much
-- less overhead using the Accept_Trivial routine in the run-time library.
-- However, this is not always a valid optimization. Whether it is valid or
-- not depends on the Task_Dispatching_Policy. The issue is whether a full
-- rescheduling action is required or not. In FIFO_Within_Priorities, such
-- a rescheduling is required, so this optimization is not allowed. This
-- function returns True if the optimization is permitted.
procedure Update_Prival_Subtypes (N : Node_Id); procedure Update_Prival_Subtypes (N : Node_Id);
-- The actual subtypes of the privals will differ from the type of the -- The actual subtypes of the privals will differ from the type of the
-- private declaration in the original protected type, if the protected -- private declaration in the original protected type, if the protected
...@@ -3646,8 +3662,12 @@ package body Exp_Ch9 is ...@@ -3646,8 +3662,12 @@ package body Exp_Ch9 is
Formal : Entity_Id; Formal : Entity_Id;
begin begin
if Nkind (New_Res) = N_Access_Definition then -- If the result type is an access_to_subprogram, we must create
-- new entities for its spec.
if Nkind (New_Res) = N_Access_Definition
and then Present (Access_To_Subprogram_Definition (New_Res))
then
-- Provide new entities for the formals -- Provide new entities for the formals
Par_Spec := First (Parameter_Specifications Par_Spec := First (Parameter_Specifications
...@@ -4016,7 +4036,8 @@ package body Exp_Ch9 is ...@@ -4016,7 +4036,8 @@ package body Exp_Ch9 is
procedure Expand_Accept_Declarations (N : Node_Id; Ent : Entity_Id) is procedure Expand_Accept_Declarations (N : Node_Id; Ent : Entity_Id) is
Loc : constant Source_Ptr := Sloc (N); Loc : constant Source_Ptr := Sloc (N);
Ann : Entity_Id := Empty; Stats : constant Node_Id := Handled_Statement_Sequence (N);
Ann : Entity_Id := Empty;
Adecl : Node_Id; Adecl : Node_Id;
Lab_Id : Node_Id; Lab_Id : Node_Id;
Lab : Node_Id; Lab : Node_Id;
...@@ -4026,20 +4047,13 @@ package body Exp_Ch9 is ...@@ -4026,20 +4047,13 @@ package body Exp_Ch9 is
begin begin
if Expander_Active then if Expander_Active then
-- If we have no handled statement sequence, then build a dummy -- If we have no handled statement sequence, we may need to build
-- sequence consisting of a null statement. This is only done if -- a dummy sequence consisting of a null statement. This can be
-- pragma FIFO_Within_Priorities is specified. The issue here is -- skipped if the trivial accept optimization is permitted.
-- that even a null accept body has an effect on the called task
-- in terms of its position in the queue, so we cannot optimize if not Trivial_Accept_OK
-- the context switch away. However, if FIFO_Within_Priorities and then
-- is not active, the optimization is legitimate, since we can (No (Stats) or else Null_Statements (Statements (Stats)))
-- say that our dispatching policy (i.e. the default dispatching
-- policy) reorders the queue to be the same as just before the
-- call. In the absence of a specified dispatching policy, we are
-- allowed to modify queue orders for a given priority at will!
if Opt.Task_Dispatching_Policy = 'F' and then
No (Handled_Statement_Sequence (N))
then then
Set_Handled_Statement_Sequence (N, Set_Handled_Statement_Sequence (N,
Make_Handled_Sequence_Of_Statements (Loc, Make_Handled_Sequence_Of_Statements (Loc,
...@@ -4609,34 +4623,6 @@ package body Exp_Ch9 is ...@@ -4609,34 +4623,6 @@ package body Exp_Ch9 is
Call : Node_Id; Call : Node_Id;
Block : Node_Id; Block : Node_Id;
function Null_Statements (Stats : List_Id) return Boolean;
-- Used to check do-end sequence. Checks for equivalent of do null; end.
-- Allows labels, and pragma Warnings/Unreferenced in the sequence as
-- well to still count as null. Returns True for a null sequence.
---------------------
-- Null_Statements --
---------------------
function Null_Statements (Stats : List_Id) return Boolean is
Stmt : Node_Id;
begin
Stmt := First (Stats);
while Nkind (Stmt) /= N_Empty
and then (Nkind_In (Stmt, N_Null_Statement, N_Label)
or else
(Nkind (Stmt) = N_Pragma
and then (Chars (Stmt) = Name_Unreferenced
or else
Chars (Stmt) = Name_Warnings)))
loop
Next (Stmt);
end loop;
return Nkind (Stmt) = N_Empty;
end Null_Statements;
-- Start of processing for Expand_N_Accept_Statement -- Start of processing for Expand_N_Accept_Statement
begin begin
...@@ -4652,18 +4638,7 @@ package body Exp_Ch9 is ...@@ -4652,18 +4638,7 @@ package body Exp_Ch9 is
-- If the accept statement has declarations, then just insert them -- If the accept statement has declarations, then just insert them
-- before the procedure call. -- before the procedure call.
-- We avoid this optimization when FIFO_Within_Priorities or some other elsif Trivial_Accept_OK
-- specified dispatching policy is active, since this may not be not
-- correct according to annex D semantics. For example, in the case of
-- FIFO_Within_Priorities, the call is required to reorder the acceptors
-- position on its ready queue, even though there is nothing to be done.
-- However, if no policy is specified, then we decide that the default
-- dispatching policy always reorders the queue right after the RV to
-- look the way they were just before the RV. Since we are allowed to
-- freely reorder same-priority queues (this is part of what dispatching
-- policies are all about), the optimization is legitimate.
elsif Opt.Task_Dispatching_Policy = ' '
and then (No (Stats) or else Null_Statements (Statements (Stats))) and then (No (Stats) or else Null_Statements (Statements (Stats)))
then then
-- Remove declarations for renamings, because the parameter block -- Remove declarations for renamings, because the parameter block
...@@ -4877,7 +4852,7 @@ package body Exp_Ch9 is ...@@ -4877,7 +4852,7 @@ package body Exp_Ch9 is
-- begin -- begin
-- declare -- declare
-- -- Clean is added by Exp_Ch7.Expand_Cleanup_Actions. -- -- Clean is added by Exp_Ch7.Expand_Cleanup_Actions
-- procedure _clean is -- procedure _clean is
-- begin -- begin
...@@ -11485,6 +11460,29 @@ package body Exp_Ch9 is ...@@ -11485,6 +11460,29 @@ package body Exp_Ch9 is
return Next_Op; return Next_Op;
end Next_Protected_Operation; end Next_Protected_Operation;
---------------------
-- Null_Statements --
---------------------
function Null_Statements (Stats : List_Id) return Boolean is
Stmt : Node_Id;
begin
Stmt := First (Stats);
while Nkind (Stmt) /= N_Empty
and then (Nkind_In (Stmt, N_Null_Statement, N_Label)
or else
(Nkind (Stmt) = N_Pragma
and then (Chars (Stmt) = Name_Unreferenced
or else
Chars (Stmt) = Name_Warnings)))
loop
Next (Stmt);
end loop;
return Nkind (Stmt) = N_Empty;
end Null_Statements;
-------------------------- --------------------------
-- Parameter_Block_Pack -- -- Parameter_Block_Pack --
-------------------------- --------------------------
...@@ -11802,6 +11800,41 @@ package body Exp_Ch9 is ...@@ -11802,6 +11800,41 @@ package body Exp_Ch9 is
Set_Object_Ref (Body_Ent, Priv); Set_Object_Ref (Body_Ent, Priv);
end Set_Privals; end Set_Privals;
-----------------------
-- Trivial_Accept_OK --
-----------------------
function Trivial_Accept_OK return Boolean is
begin
case Opt.Task_Dispatching_Policy is
-- If we have the default task dispatching policy in effect, we can
-- definitely do the optimization (one way of looking at this is to
-- think of the formal definition of the default policy being allowed
-- to run any task it likes after a rendezvous, so even if notionally
-- a full rescheduling occurs, we can say that our dispatching policy
-- (i.e. the default dispatching policy) reorders the queue to be the
-- same as just before the call.
when ' ' =>
return True;
-- FIFO_Within_Priorities certainly certainly does not permit this
-- optimization since the Rendezvous is a scheduling action that may
-- require some other task to be run.
when 'F' =>
return False;
-- For now, disallow the optimization for all other policies. This
-- may be over-conservative, but it is certainly not incorrect.
when others =>
return False;
end case;
end Trivial_Accept_OK;
---------------------------- ----------------------------
-- Update_Prival_Subtypes -- -- Update_Prival_Subtypes --
---------------------------- ----------------------------
......
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