This is an internal change to documentation, and the interface
to one function in the compiler. No functional effect, so no
test needed.
Tested on x86_64-pc-linux-gnu, committed on trunk
2014-01-21 Robert Dewar <[email protected]>
* sem_eval.adb (Compile_Time_Known_Value): Add Ignore_CRT
parameter.
* sem_eval.ads (Compile_Time_Known_Value): Add Ignore_CRT
parameter, completely rewrite spec.
Index: sem_eval.adb
===================================================================
--- sem_eval.adb (revision 206841)
+++ sem_eval.adb (working copy)
@@ -1287,7 +1287,10 @@
-- Compile_Time_Known_Value --
------------------------------
- function Compile_Time_Known_Value (Op : Node_Id) return Boolean is
+ function Compile_Time_Known_Value
+ (Op : Node_Id;
+ Ignore_CRT : Boolean := False) return Boolean
+ is
K : constant Node_Kind := Nkind (Op);
CV_Ent : CV_Entry renames CV_Cache (Nat (Op) mod CV_Cache_Size);
@@ -1311,9 +1314,9 @@
-- time. This avoids anomalies where whether something is allowed with a
-- given configurable run-time library depends on how good the compiler
-- is at optimizing and knowing that things are constant when they are
- -- nonstatic.
+ -- nonstatic. This check is suppressed if Ignore_CRT is True
- if Configurable_Run_Time_Mode
+ if (Configurable_Run_Time_Mode and not Ignore_CRT)
and then K /= N_Null
and then not Is_Static_Expression (Op)
then
@@ -1326,7 +1329,6 @@
and then Etype (Entity (Op)) = Standard_Boolean
then
null;
-
else
return False;
end if;
Index: sem_eval.ads
===================================================================
--- sem_eval.ads (revision 206804)
+++ sem_eval.ads (working copy)
@@ -85,14 +85,14 @@
-- does not raise constraint error. In fact for certain legality checks not
-- only do we need to ascertain that the expression is static, but we must
-- also ensure that it does not raise constraint error.
- --
+
-- Neither of Is_Static_Expression and Is_OK_Static_Expression should be
-- used for compile time evaluation purposes. In fact certain expression
- -- whose value is known at compile time are not static in the RM 4.9 sense.
- -- A typical example is:
- --
+ -- whose value may be known at compile time are not static in the RM 4.9
+ -- sense. A typical example is:
+
-- C : constant Integer := Record_Type'Size;
- --
+
-- The expression 'C' is not static in the technical RM sense, but for many
-- simple record types, the size is in fact known at compile time. When we
-- are trying to perform compile time constant folding (for instance for
@@ -100,8 +100,8 @@
-- are not the right functions to test if folding is possible. Instead, we
-- use Compile_Time_Known_Value. All static expressions that do not raise
-- constraint error (i.e. those for which Is_OK_Static_Expression is true)
- -- are known at compile time, but as shown by the above example, there are
- -- cases of non-static expressions which are known at compile time.
+ -- are known at compile time, but as shown by the above example, there may
+ -- be cases of non-static expressions which are known at compile time.
-----------------
-- Subprograms --
@@ -224,15 +224,60 @@
-- Determine whether two types T1, T2, which have the same base type,
-- are statically matching subtypes (RM 4.9.1(1-2)).
- function Compile_Time_Known_Value (Op : Node_Id) return Boolean;
+ function Compile_Time_Known_Value
+ (Op : Node_Id;
+ Ignore_CRT : Boolean := False) return Boolean;
-- Returns true if Op is an expression not raising Constraint_Error whose
- -- value is known at compile time. This is true if Op is a static
+ -- value is known at compile time and for which a call to Expr_Value can
+ -- be used to determine this value. This is always true if Op is a static
-- expression, but can also be true for expressions which are technically
- -- non-static but which are in fact known at compile time, such as the
- -- static lower bound of a non-static range or the value of a constant
- -- object whose initial value is static. Note that this routine is defended
- -- against unanalyzed expressions. Such expressions will not cause a
- -- blowup, they may cause pessimistic (i.e. False) results to be returned.
+ -- non-static but which are in fact known at compile time. Some possible
+ -- examples of such expressions might be the static lower bound of a
+ -- non-static range or the value of a constant object whose initial
+ -- value is itself compile time known in the sense of this routine. Note
+ -- that this routine is defended against unanalyzed expressions. Such
+ -- expressions will not cause a blowup, they may cause pessimistic (i.e.
+ -- False) results to be returned. In general we take a pessimistic view.
+ -- False does not mean the value could not be known at compile time, but
+ -- True means that absolutely definition it is known at compile time and
+ -- it is safe to call Expr_Value on the expression Op.
+ --
+ -- Note that we don't define precisely the set of expressions that return
+ -- True. Callers should not make any assumptions regarding the value that
+ -- is returned for non-static expressions. Functional behavior should never
+ -- be affected by whether a given non-static expression returns True or
+ -- False when this function is called. In other words this is purely for
+ -- efficiency optimization purposes. The code generated can often be more
+ -- efficient with compile time known values, e.g. range analysis for the
+ -- purpose of removing checks is more effective if we know precise bounds.
+ --
+ -- The Ignore_CRT parameter has to do with the special case of configurable
+ -- runtime mode. Consider the following example:
+ --
+ -- X := B ** C;
+ --
+ -- Now if C is compile time known, and has the value 4, then inline code
+ -- can be generated at compile time, instead of calling a run-time routine.
+ -- That's fine in the normal case, but when we have a configurable run-time
+ -- the run-time routine may not be available. This means that the program
+ -- will be rejected if C is not known at compile time. We don't want the
+ -- legality of a program to depend on how clever the implementation of this
+ -- function is. If the run-time in use lacks the exponentiation routine,
+ -- then what we say is that exponentiation is permitted if the exponent is
+ -- officially static and has a value in the range 0 .. 4.
+ --
+ -- However, in the normal case, we want efficient code in the case where
+ -- a non-static exponent is known at compile time. To take care of this,
+ -- the normal default behavior is that in configurable run-time mode most
+ -- expressions are considered known at compile time ONLY in the case where
+ -- they are officially static. An exception is boolean objects which may
+ -- be considered known at compile time even in configurable run-time mode.
+ --
+ -- That loses optimization opportunities, and it would be better to look
+ -- case by case at each use of Compile_Time_Known_Value to see if this
+ -- configurable run-time mode special processing is needed. The Ignore_CRT
+ -- parameter can be set to True to ignore this special handling in cases
+ -- where it is known to be safe to do so.
function Compile_Time_Known_Value_Or_Aggr (Op : Node_Id) return Boolean;
-- Similar to Compile_Time_Known_Value, but also returns True if the value