+2014-02-06 Sergey Rybin <rybin@adacore.com frybin>
+
+ * gnat_ugn.texi, vms_data.ads: Add documentation of -j option for
+ gnatelim.
+
+2014-02-06 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat_rm.texi (Pragma Optimize_Alignment): Document the effect
+ of the pragma on individual objects.
+
+2014-02-06 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * einfo.adb Node29 is now used as BIP_Initialization_Call.
+ (BIP_Initialization_Call): New routine.
+ (Set_BIP_Initialization_Call): New routine.
+ (Write_Field29_Name): Add an entry for constants and variables.
+ * einfo.ads Add new attribute BIP_Initialization_Call and update
+ its usage in nodes.
+ (BIP_Initialization_Call): New routine along with pragma Inline.
+ (Set_BIP_Initialization_Call): New routine along with pragma Inline.
+ * exp_ch6.adb (Make_Build_In_Place_Call_In_Object_Declaration):
+ Add local declaration Res_Decl. Capture the build-in-place
+ initialization call when the related object declaration has
+ created a transient block.
+ * exp_ch7.adb (Process_Transient_Objects): Add local variable
+ Fin_Insrt. Recognize a scenario where an object declaration acts
+ as a transient context and is initialized by a build-in-place
+ function call.
+
2014-02-06 Pascal Obry <obry@adacore.com>
* prj-util.adb (For_Interface_Sources): Fix handling of required
-- Initialization_Statements Node28
-- Underlying_Record_View Node28
+ -- BIP_Initialization_Call Node29
-- Subprograms_For_Type Node29
-- Corresponding_Equality Node30
return Elist16 (Id);
end Body_References;
+ function BIP_Initialization_Call (Id : E) return N is
+ begin
+ pragma Assert (Ekind_In (Id, E_Constant, E_Variable));
+ return Node29 (Id);
+ end BIP_Initialization_Call;
+
function C_Pass_By_Copy (Id : E) return B is
begin
pragma Assert (Is_Record_Type (Id));
Set_Elist16 (Id, V);
end Set_Body_References;
+ procedure Set_BIP_Initialization_Call (Id : E; V : N) is
+ begin
+ pragma Assert (Ekind_In (Id, E_Constant, E_Variable));
+ Set_Node29 (Id, V);
+ end Set_BIP_Initialization_Call;
+
procedure Set_C_Pass_By_Copy (Id : E; V : B := True) is
begin
pragma Assert (Is_Record_Type (Id) and then Is_Base_Type (Id));
procedure Write_Field29_Name (Id : Entity_Id) is
begin
case Ekind (Id) is
+ when E_Constant |
+ E_Variable =>
+ Write_Str ("BIP_Initialization_Call");
+
when Type_Kind =>
Write_Str ("Subprograms_For_Type");
-- defines the related state. If the body refines the said state, all
-- references on this list are illegal due to the visible refinement.
+-- BIP_Initialization_Call (Node29)
+-- Defined in constants and variables whose corresponding declaration
+-- is wrapped in a transient block and the inital value is provided by
+-- a build-in-place function call. Contains the relocated build-in-place
+-- call after the expansion has decoupled the call from the object. This
+-- attribute is used by the finalization machinery to insert cleanup code
+-- for all additional transient variables found in the transient block.
+
-- C_Pass_By_Copy (Flag125) [implementation base type only]
-- Defined in record types. Set if a pragma Convention for the record
-- type specifies convention C_Pass_By_Copy. This convention name is
-- Interface_Name (Node21) (constants only)
-- Related_Type (Node27) (constants only)
-- Initialization_Statements (Node28)
+ -- BIP_Initialization_Call (Node29)
-- Linker_Section_Pragma (Node33)
-- Has_Alignment_Clause (Flag46)
-- Has_Atomic_Components (Flag86)
-- Last_Assignment (Node26)
-- Related_Type (Node27)
-- Initialization_Statements (Node28)
+ -- BIP_Initialization_Call (Node29)
-- Linker_Section_Pragma (Node33)
-- Contract (Node34)
-- Has_Alignment_Clause (Flag46)
function Body_Entity (Id : E) return E;
function Body_Needed_For_SAL (Id : E) return B;
function Body_References (Id : E) return L;
+ function BIP_Initialization_Call (Id : E) return N;
function CR_Discriminant (Id : E) return E;
function C_Pass_By_Copy (Id : E) return B;
function Can_Never_Be_Null (Id : E) return B;
procedure Set_Body_Entity (Id : E; V : E);
procedure Set_Body_Needed_For_SAL (Id : E; V : B := True);
procedure Set_Body_References (Id : E; V : L);
+ procedure Set_BIP_Initialization_Call (Id : E; V : N);
procedure Set_CR_Discriminant (Id : E; V : E);
procedure Set_C_Pass_By_Copy (Id : E; V : B := True);
procedure Set_Can_Never_Be_Null (Id : E; V : B := True);
pragma Inline (Body_Entity);
pragma Inline (Body_Needed_For_SAL);
pragma Inline (Body_References);
+ pragma Inline (BIP_Initialization_Call);
pragma Inline (CR_Discriminant);
pragma Inline (C_Pass_By_Copy);
pragma Inline (Can_Never_Be_Null);
pragma Inline (Set_Body_Entity);
pragma Inline (Set_Body_Needed_For_SAL);
pragma Inline (Set_Body_References);
+ pragma Inline (Set_BIP_Initialization_Call);
pragma Inline (Set_CR_Discriminant);
pragma Inline (Set_C_Pass_By_Copy);
pragma Inline (Set_Can_Never_Be_Null);
Pass_Caller_Acc : Boolean := False;
New_Expr : Node_Id;
Ref_Type : Entity_Id;
+ Res_Decl : Node_Id;
Result_Subt : Entity_Id;
begin
Set_Etype (Def_Id, Ref_Type);
Set_Is_Known_Non_Null (Def_Id);
- Insert_After_And_Analyze (Ptr_Typ_Decl,
+ Res_Decl :=
Make_Object_Declaration (Loc,
Defining_Identifier => Def_Id,
Object_Definition => New_Reference_To (Ref_Type, Loc),
- Expression => New_Expr));
+ Expression => New_Expr);
+ Insert_After_And_Analyze (Ptr_Typ_Decl, Res_Decl);
-- If the result subtype of the called function is constrained and
-- is not itself the return expression of an enclosing BIP function,
if Is_Constrained (Underlying_Type (Result_Subt))
and then not Is_Return_Object (Defining_Identifier (Object_Decl))
then
+ -- The related object declaration is encased in a transient block
+ -- because the build-in-place function call contains at least one
+ -- nested function call that produces a controlled transient
+ -- temporary:
+
+ -- Obj : ... := BIP_Func_Call (Ctrl_Func_Call);
+
+ -- Since the build-in-place expansion decouples the call from the
+ -- object declaration, the finalization machinery lacks the context
+ -- which prompted the generation of the transient block. To resolve
+ -- this scenario, store the build-in-place call.
+
+ if Scope_Is_Transient
+ and then Node_To_Be_Wrapped = Object_Decl
+ then
+ Set_BIP_Initialization_Call (Obj_Def_Id, Res_Decl);
+ end if;
+
Set_Expression (Object_Decl, Empty);
Set_No_Initialization (Object_Decl);
begin
pragma Assert (Nkind (Allocator) = N_Allocator
- and then Nkind (Function_Call) = N_Function_Call);
+ and then Nkind (Function_Call) = N_Function_Call);
pragma Assert (Convention (Function_Id) = Convention_CPP
- and then Is_Constructor (Function_Id));
+ and then Is_Constructor (Function_Id));
pragma Assert (Is_Constrained (Underlying_Type (Result_Subt)));
-- Replace the initialized allocator of form "new T'(Func (...))" with
Fin_Block : Node_Id;
Fin_Data : Finalization_Exception_Data;
Fin_Decls : List_Id;
+ Fin_Insrt : Node_Id;
Last_Fin : Node_Id := Empty;
Loc : Source_Ptr;
Obj_Id : Entity_Id;
-- Start of processing for Process_Transient_Objects
begin
+ -- Recognize a scenario where the transient context is an object
+ -- declaration initialized by a build-in-place function call:
+
+ -- Obj : ... := BIP_Function_Call (Ctrl_Func_Call);
+
+ -- The rough expansion of the above is:
+
+ -- Temp : ... := Ctrl_Func_Call;
+ -- Obj : ...;
+ -- Res : ... := BIP_Func_Call (..., Obj, ...);
+
+ -- The finalization of any controlled transient must happen after
+ -- the build-in-place function call is executed.
+
+ if Nkind (N) = N_Object_Declaration
+ and then Present (BIP_Initialization_Call (Defining_Identifier (N)))
+ then
+ Must_Hook := True;
+ Fin_Insrt := BIP_Initialization_Call (Defining_Identifier (N));
+
-- Search the context for at least one subprogram call. If found, the
-- machinery exports all transient objects to the enclosing finalizer
-- due to the possibility of abnormal call termination.
- Detect_Subprogram_Call (N);
+ else
+ Detect_Subprogram_Call (N);
+ Fin_Insrt := Last_Object;
+ end if;
-- Examine all objects in the list First_Object .. Last_Object
if Present (Prev_Fin) then
Insert_Before_And_Analyze (Prev_Fin, Fin_Block);
else
- Insert_After_And_Analyze (Last_Object,
+ Insert_After_And_Analyze (Fin_Insrt,
Make_Block_Statement (Loc,
Declarations => Fin_Decls,
Handled_Statement_Sequence =>
-- Raise_From_Controlled_Operation (E);
-- end if;
- if Built
- and then Present (Last_Fin)
- then
+ if Built and then Present (Last_Fin) then
Insert_After_And_Analyze (Last_Fin,
Build_Raise_Statement (Fin_Data));
end if;
@noindent
This is a configuration pragma which affects the choice of default alignments
-for types where no alignment is explicitly specified. There is a time/space
-trade-off in the selection of these values. Large alignments result in more
-efficient code, at the expense of larger data space, since sizes have to be
-increased to match these alignments. Smaller alignments save space, but the
-access code is slower. The normal choice of default alignments (which is what
-you get if you do not use this pragma, or if you use an argument of OFF),
-tries to balance these two requirements.
+for types and objects where no alignment is explicitly specified. There is a
+time/space trade-off in the selection of these values. Large alignments result
+in more efficient code, at the expense of larger data space, since sizes have
+to be increased to match these alignments. Smaller alignments save space, but
+the access code is slower. The normal choice of default alignments for types
+and individual alignment promotions for objects (which is what you get if you
+do not use this pragma, or if you use an argument of OFF), tries to balance
+these two requirements.
Specifying SPACE causes smaller default alignments to be chosen in two cases.
First any packed record is given an alignment of 1. Second, if a size is given
in general possible to set the alignment of such a record to one, so the
pragma is ignored in this case (with a warning).
+Specifying SPACE also disables individual alignment promotions for objects,
+which occur when the compiler increases the alignment of a specific object
+without changing the alignment of its type.
+
Specifying TIME causes larger default alignments to be chosen in the case of
small types with sizes that are not a power of 2. For example, consider:
it is overridden. If this switch is not used, @command{gnatelim} outputs its results
into @file{stderr}
+@item ^-j^/PROCESSES=^@var{n}
+@cindex @option{^-j^/PROCESSES^} (@command{gnatelim})
+Use @var{n} processes to carry out the tree creations (internal representations
+of the argument sources). On a multiprocessor machine this speeds up processing
+of big sets of argument sources. If @var{n} is 0, then the maximum number of
+parallel tree creations is the number of core processors on the platform.
+
@item ^-q^/QUIET^
@cindex @option{^-q^/QUIET^} (@command{gnatelim})
Quiet mode: by default @code{gnatelim} outputs to the standard error
-- Do not generate pragmas for subprograms declared in the sources
-- listed in a specified file
+ S_Elim_Processes : aliased constant S := "/PROCESSES=#" &
+ "-j#";
+
+ -- /NOPROCESSES (D)
+ -- /PROCESSES=NNN
+ --
+ -- Use NNN processes to carry out the tree creations (internal
+ -- representations of the argument sources). On a multiprocessor machine
+ -- this speeds up processing of big sets of argument sources. If NNN is 0,
+ -- then the maximum number of parallel tree creations is the number of
+ -- core processors on the platform.
+
S_Elim_Project : aliased constant S := "/PROJECT_FILE=<" &
"-P>";
-- /PROJECT_FILE=filename
-- QUIET Some warning messages are suppressed
Elim_Switches : aliased constant Switches :=
- (S_Elim_Add 'Access,
- S_Elim_All 'Access,
- S_Elim_Bind 'Access,
- S_Elim_Comp 'Access,
- S_Elim_Config 'Access,
- S_Elim_Current 'Access,
- S_Elim_Ext 'Access,
- S_Elim_Files 'Access,
- S_Elim_Follow 'Access,
- S_Elim_GNATMAKE'Access,
- S_Elim_Log 'Access,
- S_Elim_Logfile 'Access,
- S_Elim_Main 'Access,
- S_Elim_Mess 'Access,
- S_Elim_Nodisp 'Access,
- S_Elim_Out 'Access,
- S_Elim_Project 'Access,
- S_Elim_Quiet 'Access,
- S_Elim_Search 'Access,
- S_Elim_Subdirs 'Access,
- S_Elim_Time 'Access,
- S_Elim_Verb 'Access,
- S_Elim_Warn 'Access);
+ (S_Elim_Add 'Access,
+ S_Elim_All 'Access,
+ S_Elim_Bind 'Access,
+ S_Elim_Comp 'Access,
+ S_Elim_Config 'Access,
+ S_Elim_Current 'Access,
+ S_Elim_Ext 'Access,
+ S_Elim_Files 'Access,
+ S_Elim_Follow 'Access,
+ S_Elim_GNATMAKE 'Access,
+ S_Elim_Log 'Access,
+ S_Elim_Logfile 'Access,
+ S_Elim_Main 'Access,
+ S_Elim_Mess 'Access,
+ S_Elim_Nodisp 'Access,
+ S_Elim_Out 'Access,
+ S_Elim_Processes'Access,
+ S_Elim_Project 'Access,
+ S_Elim_Quiet 'Access,
+ S_Elim_Search 'Access,
+ S_Elim_Subdirs 'Access,
+ S_Elim_Time 'Access,
+ S_Elim_Verb 'Access,
+ S_Elim_Warn 'Access);
----------------------------
-- Switches for GNAT FIND --