%%% section
\section{\code{ref}, \code{val}, \code{uval} Modifiers for \code{linear} Clause}
\label{sec:linear_modifier}

When generating vector functions from \code{declare}~\code{simd} directives, it is important for a compiler to know the proper types of function arguments in
order to generate efficient codes.
This is especially true for C++ reference types and Fortran arguments.

In the following example, the function \plc{add\_one2} has a C++ reference
parameter (or Fortran argument) \plc{p}.  Variable \plc{p} gets incremented by 1 in the function.
The caller loop \plc{i} in the main program passes 
a variable \plc{k} as a reference to the function \plc{add\_one2} call.   
The \code{ref} modifier for the \code{linear} clause on the 
\code{declare}~\code{simd} directive is used to annotate the 
reference-type parameter \plc{p} to match the property of the variable 
\plc{k} in the loop.  
This use of reference type is equivalent to the second call to 
\plc{add\_one2} with a direct passing of the array element \plc{a[i]}.  
In the example, the preferred vector 
length 8 is specified for both the caller loop and the callee function.

When \code{linear(ref(p))} is applied to an argument passed by reference, 
it tells the compiler that the addresses in its vector argument are consecutive,
and so the compiler can generate a single vector load or store instead of 
a gather or scatter. This allows more efficient SIMD code to be generated with 
less source changes.

\cppexample[4.5]{linear_modifier}{1}
\ffreeexample[4.5]{linear_modifier}{1}
\clearpage

 
The following example is a variant of the above example. The function \plc{add\_one2} in the C++ code includes an additional C++ reference parameter \plc{i}. 
The loop index \plc{i} of the caller loop \plc{i} in the main program 
is passed as a reference to the function \plc{add\_one2} call.   
The loop index \plc{i} has a uniform address with
linear value of step 1 across SIMD lanes. 
Thus, the \code{uval} modifier is used for the \code{linear} clause 
to annotate the C++ reference-type parameter \plc{i} to match 
the property of loop index \plc{i}.

In the correponding Fortran code the arguments \plc{p} and
\plc{i} in the routine \plc{add\_on2} are passed by references. 
Similar modifiers are used for these variables in the \code{linear} clauses
to match with the property at the caller loop in the main program.

When \code{linear(uval(i))} is applied to an argument passed by reference, it 
tells the compiler that its addresses in the vector argument are uniform 
so that the compiler can generate a scalar load or scalar store and create 
linear values. This allows more efficient SIMD code to be generated with 
less source changes.

\cppexample[4.5]{linear_modifier}{2}
\ffreeexample[4.5]{linear_modifier}{2}

In the following example, the function \plc{func} takes arrays \plc{x} and \plc{y} as arguments, and accesses the array elements referenced by 
the index \plc{i}.
The caller loop \plc{i} in the main program passes a linear copy of
the variable \plc{k} to the function \plc{func}.
The \code{val} modifier is used for the \code{linear} clause 
in the \code{declare}~\code{simd} directive for the function
\plc{func} to annotate argument \plc{i} to match the property of 
the actual argument \plc{k} passed in the SIMD loop.
Arrays \plc{x} and \plc{y} have uniform addresses across SIMD lanes.

When \code{linear(val(i):1)} is applied to an argument, 
it tells the compiler that its addresses in the vector argument may not be 
consecutive, however, their values are linear (with stride 1 here). When the value of \plc{i} is used 
in subscript of array references (e.g., \plc{x[i]}), the compiler can generate 
a vector load or store instead of a gather or scatter. This allows more 
efficient SIMD code to be generated with less source changes.

\cexample[4.5]{linear_modifier}{3}
\ffreeexample[4.5]{linear_modifier}{3}


