+2017-01-13 Ed Schonberg <schonberg@adacore.com>
+
+ * einfo.ads: minor grammar fixes in comment of Normalized_Position_Max.
+ * scil_ll.adb: Minor style fix in comment.
+ * sem_ch8.adb (Analyze_Expanded_Name): Perform dimension analysis
+ even if entity is already set, because the node may be renalyzed
+ after inlining transformations.
+
+2017-01-13 Javier Miranda <miranda@adacore.com>
+
+ * sem_res.adb (Resolve_Call): Do not establish a transient scope
+ for a call to inlinable expression function (since the call will
+ be replaced by its returned object).
+ * exp_ch6.ads (Is_Inlinable_Expression_Function): New subprogram.
+ * exp_ch6.adb (Expression_Of_Expression_Function): New subprogram.
+ (Expand_Call): For inlinable expression function call replace the
+ call by its returned object.
+ (Is_Inlinable_Expression_Function): New subprogram.
+
2017-01-13 Gary Dismukes <dismukes@adacore.com>
* checks.adb: Minor typo fix and reformatting.
-- depends on discriminants. In this case, the Normalized_Position_Max
-- field represents the maximum possible value of Normalized_Position
-- assuming min/max values for discriminant subscripts in all fields.
--- This is used by Layout in front end layout mode to properly computed
--- the maximum size such records (needed for allocation purposes when
+-- This is used by Layout in front end layout mode to properly compute
+-- the maximum size of such records (needed for allocation purposes when
-- there are default discriminants, and also for the 'Size value).
-- Number_Dimensions (synthesized)
-- reference to the object itself, and the call becomes a call to the
-- corresponding protected subprogram.
+ function Expression_Of_Expression_Function
+ (Subp : Entity_Id) return Node_Id;
+ -- Return the expression of the expression function Subp
+
function Has_Unconstrained_Access_Discriminants
(Subtyp : Entity_Id) return Boolean;
-- Returns True if the given subtype is unconstrained and has one
if not Is_Inlined (Subp) then
null;
+ -- Frontend inlining of expression functions (performed also when
+ -- backend inlining is enabled)
+
+ elsif Is_Inlinable_Expression_Function (Subp) then
+ Rewrite (N, New_Copy (Expression_Of_Expression_Function (Subp)));
+ Analyze (N);
+ return;
+
-- Handle frontend inlining
elsif not Back_End_Inlining then
end if;
end Expand_Simple_Function_Return;
+ ---------------------------------------
+ -- Expression_Of_Expression_Function --
+ ---------------------------------------
+
+ function Expression_Of_Expression_Function
+ (Subp : Entity_Id) return Node_Id
+ is
+ Expr_Func : Node_Id;
+
+ begin
+ pragma Assert (Is_Expression_Function_Or_Completion (Subp));
+
+ if Nkind (Original_Node (Subprogram_Spec (Subp)))
+ = N_Expression_Function
+ then
+ Expr_Func := Original_Node (Subprogram_Spec (Subp));
+
+ elsif Nkind (Original_Node (Subprogram_Body (Subp)))
+ = N_Expression_Function
+ then
+ Expr_Func := Original_Node (Subprogram_Body (Subp));
+
+ else
+ pragma Assert (False);
+ null;
+ end if;
+
+ return Original_Node (Expression (Expr_Func));
+ end Expression_Of_Expression_Function;
+
--------------------------------------------
-- Has_Unconstrained_Access_Discriminants --
--------------------------------------------
end if;
end Freeze_Subprogram;
+ --------------------------------------
+ -- Is_Inlinable_Expression_Function --
+ --------------------------------------
+
+ function Is_Inlinable_Expression_Function (Subp : Entity_Id) return Boolean
+ is
+ Return_Expr : Node_Id;
+
+ begin
+ if Is_Expression_Function_Or_Completion (Subp)
+ and then Has_Pragma_Inline_Always (Subp)
+ and then Needs_No_Actuals (Subp)
+ and then No (Contract (Subp))
+ and then not Is_Dispatching_Operation (Subp)
+ and then Needs_Finalization (Etype (Subp))
+ and then not Is_Class_Wide_Type (Etype (Subp))
+ and then not (Has_Invariants (Etype (Subp)))
+ and then Present (Subprogram_Body (Subp))
+ and then Was_Expression_Function (Subprogram_Body (Subp))
+ then
+ Return_Expr := Expression_Of_Expression_Function (Subp);
+
+ -- The returned object must not have a qualified expression and its
+ -- nominal subtype must be statically compatible with the result
+ -- subtype of the expression function.
+
+ return Nkind (Return_Expr) = N_Identifier
+ and then Etype (Return_Expr) = Etype (Subp);
+ end if;
+
+ return False;
+ end Is_Inlinable_Expression_Function;
+
-----------------------
-- Is_Null_Procedure --
-----------------------
-- that requires handling as a build-in-place call or is a qualified
-- expression applied to such a call; otherwise returns False.
+ function Is_Inlinable_Expression_Function (Subp : Entity_Id) return Boolean;
+ -- Return True if Subp is an expression function that fulfills all the
+ -- following requirements for inlining:
+ -- 1. pragma/aspect Inline_Always
+ -- 2. No formals
+ -- 3. No contracts
+ -- 4. No dispatching primitive
+ -- 5. Result subtype controlled (or with controlled components)
+ -- 6. Result subtype not subject to type-invariant checks
+ -- 7. Result subtype not a class-wide type
+ -- 8. Return expression naming an object global to the function
+ -- 9. Nominal subtype of the returned object statically compatible
+ -- with the result subtype of the expression function.
+
function Is_Null_Procedure (Subp : Entity_Id) return Boolean;
-- Predicate to recognize stubbed procedures and null procedures, which
-- can be inlined unconditionally in all cases.
Key => Node_Id,
Hash => Hash,
Equal => "=");
- -- This table records the value of attribute SCIL_Node of tree nodes.
+ -- This table records the value of attribute SCIL_Node of tree nodes
--------------------
-- Copy_SCIL_Node --
Set_Etype (N, Etype (Entity (N)));
end if;
- return;
else
Find_Expanded_Name (N);
end if;
+ -- In either case, propagate dimension of entity to expanded name
+
Analyze_Dimension (N);
end Analyze_Expanded_Name;
-- within the specialized Exp_Ch6 procedures for expanding those
-- build-in-place calls.
- -- e) If the subprogram is marked Inline_Always, then even if it returns
+ -- e) Calls to inlinable expression functions do not use the secondary
+ -- stack (since the call will be replaced by its returned object).
+
+ -- f) If the subprogram is marked Inline_Always, then even if it returns
-- an unconstrained type the call does not require use of the secondary
-- stack. However, inlining will only take place if the body to inline
-- is already present. It may not be available if e.g. the subprogram is
elsif Ekind (Nam) = E_Enumeration_Literal
or else Is_Build_In_Place_Function (Nam)
or else Is_Intrinsic_Subprogram (Nam)
+ or else Is_Inlinable_Expression_Function (Nam)
then
null;