In section 5.3 we gave a handful of special rules
for distributed array element access. One example is that in
Proving that an arbitrary expression is invariant throughout
a particular block of code can be a very hard problem for a compiler.
The block of code (our overall construct) may, for example, contain
method invocations. If the expression we are analysing involves fields
or array elements, it is not generally possible to be prove that the method
invocation does not change the value of the expression as a side-effect.
On the other hand, if one failed to prove that expressions like
above were invariant, the loss of efficiency in the translated code
might be quite spectacular.
For these reasons the translator imposes the following, fairly sweeping, restrictions [Actually these aren't implemented in the current translator--neither are the run-time checks that should be associated with subscripting multiarrays and distributed arrays.]:
Note that Java (and HPJava) support an idea of blank final variables. A blank final variable is a variable that is declared with the final attribute, meaning it is essentially constant, but its value is not initialized in its declaration. Instead it is initialized in a later assignment. Thus a blank final variable is a kind of single-assignment variable. A blank final instance variable, for example, can (and in fact must) be initialized in a constructor of the class to which it belongs. Restricting distributed array variables to be final variables is thus not as limiting as it may sound, because these array variables may be blank finals. On the other hand this restriction allows accesses to the special arrays of HPJava to be analysed with at least some of the simplicity of earlier, more static, languages like Fortran, and this is a very important advantage. Moreover we suspect that this limitation will rarely be noticed by the programmer--it mainly enforces practices that are likely to be commonplace anyway.
This identifier can refer to a local variable or a field of the current class (or of a superclass or lexically enclosing class). Again the actual inconvenience to the programmer due to this restriction is fairly minor. It seems only to enforce common practices. If, however, code in one object really does need to subscript a distributed-array-valued field in another object (say), the array reference just needs to be copied to a distributed-array-valued local variable prior to subscripting.
We can now very cleanly enforce the original requirements on subscripting
in overall and at constructs, by applying a simple static
check that if a distributed index i
appears in a subscript of a
distributed array a, the variable a should have been declared
outside the scope of i, and (if it is a blank final)
should not be assigned inside the scope of i.
The Java constraints on assignments to blank final make the latter
check easy.