Sun WorkShop Compiler C 5.0 User's Guide

Keywords

asm Keyword

The _asm keyword is a synonym for the asm keyword. asm is available under all compilation modes, although a warning is issued when it is used under the -Xc mode.

The asm statement has the form:


asm("string"):

where string is a valid assembly language statement.

For example:


main()
{
	int i;

	/* i = 10 */
	asm("mov 10,%l0");
	asm("st  %l0,[%fp-8]");

	printf("i = %d\n",i);
}
% cc foo.c
% a.out
i = 10
%

asm statements must appear within function bodies.

_Restrict Keyword

For a compiler to effectively perform parallel execution of a loop, it needs to determine if certain lvalues designate distinct regions of storage. Aliases are lvalues whose regions of storage are not distinct. Determining if two pointers to objects are aliases is a difficult and time-consuming process because it could require analysis of the entire program.

Example: the function vsq()


void vsq(int n, double * a, double * b)
{
	int i;
	for (i=0; i<n; i++) b[i] = a[i] * a[i];
}

The compiler can parallelize the execution of the different iterations of the loops if it knows that pointers a and b access different objects. If there is an overlap in objects accessed through pointers a and b then it would be unsafe for the compiler to execute the loops in parallel. At compile time, the compiler does not know if the objects accessed by a and b overlap by simply analyzing the function vsq(); the compiler may need to analyze the whole program to get this information.

Restricted pointers are used to specify pointers which designate distinct objects so that the compiler can perform pointer alias analysis. To support restricted pointers, the keyword _Restrict is recognized by the Sun ANSI/ISO C compiler as an extension. Below is an example of declaring function parameters of vsq() as restricted pointers:


void vsq(int n, double * _Restrict a, double * _Restrict b)

Pointers a and b are declared as restricted pointers, so the compiler knows that the regions of storage pointed to by a and b are distinct. With this alias information, the compiler is able to parallelize the loop.

The _Restrict keyword is a type qualifier, like volatile, and it qualifies pointer types only. _Restrict is recognized as a keyword only for compilation modes -Xa (default) and -Xt. For these two modes, the compiler defines the macro __RESTRICT to enable users write portable code with restricted pointers.

The compiler defines the macro __RESTRICT to enable users to write portable code with restricted pointers. For example, the following code works on the Sun ANSI/ISO C compiler in all compilation modes, and should work on other compilers which do not support restricted pointers:


#ifdef __RESTRICT
#define restrict _Restrict
#else
#define restrict
#endif

void vsq(int n, double * restrict a, double * restrict b)
{
	int i;
	for (i=0; i<n; i++) b[i] = a[i] * a[i];
}

If restricted pointers become a part of the ANSI/ISO C Standard, it is likely that "restrict" will be the keyword. Users may want to write code with restricted pointers using:


#define restrict _Restrict

as in vsq() because this way there will be minimal changes should "restrict" become a keyword in the ANSI/ISO C Standard. The Sun ANSI/ISO C compiler uses _Restrict as the keyword because it is in the implementor's name space, so there is no conflict with identifiers in the user's name space.

There are situations where a user may not want to change the source code. One can specify pointer-valued function parameters to be treated as restricted pointers with the command-line option -xrestrict; refer to "-xrestrict=f" for details.

If a function list is specified, pointer parameters in the specified functions are treated as restricted; otherwise, all pointer parameters in the entire C file are treated as restricted. For example, -xrestrict=vsq would qualify the pointers a and b given in the example with the keyword _Restrict.

It is critical that _Restrict be used correctly. If pointers qualified as restricted pointers point to objects which are not distinct, loops may be incorrectly parallelized, resulting in undefined behavior. For example, assume that pointers a and b of function vsq() point to objects which overlap, such that b[i] and a[i+1] are the same object. If a and b are not declared as restricted pointers, the loops will be executed serially. If a and b are incorrectly qualified as restricted pointers, the compiler may parallelize the execution of the loops; this is not safe, because b[i+1] should only be computed after b[i] has been computed.