[sac-user] A Question about the Optimizations of Single Assignment C

Sven-Bodo Scholz S.Scholz at herts.ac.uk
Tue Nov 27 12:55:19 GMT 2007


On Mon, Nov 26, 2007 at 04:21:09PM +0000, Li Bin wrote:
> Dear Bodo,
> 
> When I checked the C files generated by using -simd option, I see 
> something like this:
> 
> I use a program as:
> 
> 1 use Structures:all;
> 2 use SimplePrint:all;
> 3 int main()
> 4 {
> 5   v1=genarray([10000],5);
> 6    v2=genarray([10000],5);
> 7   v1=with(iv)
> 8        (.<=iv<=[5000]):v1[iv]+v2[iv];
> 9        ([5001]<=iv<=[9000]):v1[iv]-v2[iv];
> 10       ([9001]<=iv<=.):v1[iv]+v2[iv];
> 11       modarray(v1);
> 12    res=print(v1);
> 13    return(res);
> 14   }
> 
> 
> The compiler only generates those "simd" C files corresponding to 
> initializing v1, and performing the addition operation on v1 and v2 
> (relative to line 8 and line 10 in original SAC code). And if I change 
> line 8 or line 10 to subtraction operation, it will also keep the same, 
> i.e. still only generate C file relative to the addition operation. So I 
> suppose that the substraction must have been optimized somewhere during 
> generating intermediate code.
> 
> Would you please give me a hint about what did the compiler do to that?

Well, v1 and v2 are defined by identical expressions
=> the compiler transforms it into 1 similar to

> 5   v2=genarray([10000],5);
> 7   v1=with(iv)
> 8        (.<=iv<=[5000]):v2[iv]+v2[iv];
> 9        ([5001]<=iv<=[9000]):v2[iv]-v2[iv];
> 10       ([9001]<=iv<=.):v2[iv]+v2[iv];
> 11       modarray(v1);
> 12    res=print(v1);

Then, the compiler folds the definition of v2 into that of v1
=> we obtain something similar to:

> 7   v1=with(iv)
> 8        (.<=iv<=[5000]): 5 + 5;
> 9        ([5001]<=iv<=[9000]): 5 - 5;
> 10       ([9001]<=iv<=.): 5+ 5;
> 11       modarray(v1);
> 12    res=print(v1);

which finally yields (after constant folding):
[The following was obtained by compiling with -b11]

  _pinl_276__flat_108 = 0;
  _dl_341 = 10;
  v1__SSA0_1 = with ( iv__SSA0_2 )
        ([ 0 ] <= iv__SSA0_2=[_eat_39] (IDXS:_wlidx_368_v1__SSA0_1) < [
5001 ])
        {
          /* empty */
        } : _dl_341 ; ,
        ([ 5001 ] <= iv__SSA0_2=[_eat_39] (IDXS:_wlidx_368_v1__SSA0_1) <
[ 9001 ])
        {
          /* empty */
        } : _pinl_276__flat_108 ; ,
        ([ 9001 ] <= iv__SSA0_2=[_eat_39] (IDXS:_wlidx_368_v1__SSA0_1) <
[ 10000 ])
        {
          /* empty */
        } : _dl_341 ;
      genarray( [ 10000 ] ,IDX(_wlidx_368_v1__SSA0_1));

In my system (actual compiler) this generates 3 simd<x>.c files, one
each for the 3 segments from above.

Which of the above computations do you actually wish to vectorise?
If you want the 2 "initial" vectors v1 and v2 to be actually build you
have to prevent With-Loop-Folding from happenening (this can be achieved 
by calling the compiler with -noWLF) AND you have to define v1 and v2 
differently, such as:

v1 = genarray( [10000], 2);
v2 = genarray( [10000], 3);

' hope that helps a bit.
Best wishes,

  Bodo



More information about the sac-user mailing list