 |
» |
|
|
 |
By James Overman Computer Systems Division The HP31502A.05.04 release of Pascal/iX has changes for processing
of the $VOLATILE option results. The compiler will now flag as
errors certain uses of volatile references that are questionable
as to the user's desired meaning. The new error message will only
be produced if a $VOLATILE variable is used in a WITH statement.
A new option $VOLATILE_WITH has been created to allow users to
specify the compiler's processing of WITHs with volatile references.
Also, the $VOLATILE option has been expanded to be valid in a new
position within a type declaration. In previous versions of Pascal/iX, the volatility of a WITH
expression was not taken into consideration when generating alias
information for the optimizer. A WITH result pointer is actually
the address of the record referenced by the WITH expression. Although
there is no documentation about what should happen when volatile
pointers occur in WITH expressions, the previous situation is questionable
since at least some existing code assumes that the volatility is
transferred to the WITH result pointer. There is also the question
of how far down the WITH expression to look for volatility before
making the WITH result pointer volatile. Some users may want to
make the WITH volatile if either the record or pointer is volatile,
and some may not want the WITH volatile at all. Here are the details of the change: The compiler was enhanced to allow
users to specify that the pointed-to type is volatile. This was
done by adding a new place where $VOLATILE$ is legal:
<simple-type> = $VOLATILE$ <ident>
For example, the following code declares a volatile pointer:
ptr_mytype = ^ $VOLATILE$ mytype;
To change this into a declaration of a pointer to a volatile type:
ptr_mytype = ^ v_mytype;
v_mytype = $VOLATILE$ mytype; The user must now specify how they want volatility
handled in WITH statements if they use volatile records or pointers.
The "top type" of the WITH expression is checked for a volatile
record or pointer and an error is generated if the user has not
specified how it should be handled. A new compiler option
$VOLATILE_WITH has been added to allow the user to tell the
compiler what it should do in this situation:
$VOLATILE_WITH
0$ : do not make WITH temps volatile. This will generate the most
efficient code, but may not be "safe."
$VOLATILE_WITH
1$ : make the WITH temp volatile if the top level record type is volatile.
(This is provided for completeness, it is unclear how useful it
would be.)
$VOLATILE_WITH
2$ : make the WITH temp volatile if the top level record type or pointer
to the top level record type is volatile. This is the safest alternative,
at the cost of code efficiency. When a WITH statement is
seen, the $VOLATILE_WITH level currently in effect will be applied
to all WITH result pointers (temps) for that statement.
Only the "top type" is checked, because it is unlikely that a user
will want the temp volatility to be based on every level of the
whole expression. We go down one level to the first pointer because
the pointer/pointed-to-type misunderstanding may be commonplace,
given the previous ambiguity in volatile declarations.
If the "top type" in a WITH expression contains a volatile, you
will get the following error message:
VOLATILE RECORD OR POINTER IN WITH EXPRESSION; $VOLATILE_WITH REQUIRED
(895)
If you encounter this error, you should consider what you
want to be volatile, possibly change your type declarations if they
are incorrect, and add the appropriate $VOLATILE_WITH option.
For example, given the original code fragments:
ptr_type = ^ $extnaddr,VOLATILE$ mytype;
...
var l_dptr : ptr_type; {l_dptr is volatile}
...
with ..., l_dptr^ {l_dptr is volatile, l_dptr^
is not}
To generate the safest code, simply insert a $VOLATILE_WITH 2$ option
at some point before the WITH statement. This will cause the suspicious
WITH temp to be volatile; the compiler will generate code to always
reload the temp and all subsequent expressions based on the temp.
With this change, the WITH temp is reloaded on each reference,
and all loads and stores through that pointer are present in the
generated code.To
generate more efficient code, carefully examine the type declarations
to be sure you know what you want to be volatile. In this example,
the thing that the user really wants to be volatile is the record
type being pointed to, and the WITH temp (a pointer to that record
type) should not be volatile. This means that ptr_type should be
changed to a pointer to a volatile, and the $VOLATILE_WITH 0$ option
can be used.
For example:
ptr_type = ^ $extnaddr$ v_mytype;
v_mytype = $VOLATILE$ mytype;
...
var l_dptr : ptr_type; {l_dptr^ is volatile}
...
$VOLATILE_WITH 0$
with ..., l_dptr^
With these changes, the WITH temp is not reloaded on each reference,
but all loads and stores into the record are present in the generated
code since the pointed-to record is volatile.
Another alternative is to remove the suspicious WITH expression
from the WITH statement and expand all references in the WITH body.
Depending on the complexity of the expression and what parts are
volatile, the efficiency of the generated code might be the same
as using a WITH.
 |  |  |  |  | NOTE: An error will be generated when the compiler detects
a volatile WITH situation. This approach is taken in order to raise
its visibility. The user can simply add $VOLATILE_WITH 2$ to the
global compiler options if the utmost code efficiency is not a concern.The $VOLATILE_WITH option takes effect on a statement
basis, so it will affect the entire list of WITH expressions for
a WITH statement. If you have multiple expressions that require
different $VOLATILE_WITH levels, you will have to break the WITH
statement into multiple statements. |  |  |  |  |
|