This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Champs,
This is a question about C compiler for C6000 architecture (especially C64x+).
A distributor engineer has said that #pragma DATA_ALIGN overrode architecture's natural alignment to a smaller alignment as explained below in detail.
As described in the section 2.13 Linking C6400 Code With C6200/C6700/Older C6400 Object Code of SPRU187U, the alignment of top-level arrays for the C6400 family is 8 bytes. The compiler always try to use STDW or LDDW instead of STNDW or LDNDW even if an array is declared externally as following.
extern int array[100];
...
for (i = 0; i < 100; i ++)
foo = array[i];
However, the engineer found that we could override the alignment by #pragma DATA_ALIGN(array, 4) in the separate file which actually defined the array[100].
In the case, the above code does not work as expected if the array is NOT aligned to 8. (Instead we need LDNDW or STNDW.)
My question is, when we specify smaller alignment size than architecture's natural (or default) one, can the pragma override the alignment to the smaller value? How can we tell compiler that the array[] is aligned at 4 bytes instead of 8? I found that #pragma DATA_ALIGN could not applied to the extern declaration as following.
#pragma DATA_ALIGN(array, 4);
extern int array[100]; // Did not work. Compiler warns of this.
_nassert((int) array % 8 == 4); // This neither work.
Compiler version is 7.3.9. Any suggestion would be helpful.
Regards,
Atsushi
DATA_ALIGN is not supposed to be able to reduce the alignment of any object. It is a defect that the compiler did not emit a diagnostic message about this. I've submitted SDSCM00046231 to track this issue. (Note that the warning you get when applying the pragma to the declaration is not relevant; the warning you get means you must apply it to a definition, not a declaration.)
Hi Archaeologist,
Thank you very much for filing the issue.
On the other hand, if we can't apply the pragma for extern declaration, how can we tell compiler (or optimizer) alignment of a variable as a hint? If a variable is defined in the source file, compiler has a chance to see the alignment. But it has no chance if it is defined in a different file and only see an extern declaration. Is _nassert() the only way to give a hint to optimizer?
Regards,
Atsushi
Atsushi,
_nassert() is the recommended way to tell the compiler that a pointer or array is aligned to a certain level. There are examples in the C Compiler User's Guide for this.
SPRU187u said:
int dot_product(short *x, short *y, short z)
{
_nassert (((int)(x) & 0x3) == 0);
_nassert (((int)(y) & 0x3) == 0);
...
This may not be the only way, but it is the way TI recommends in the User's Guide. If I have misunderstood the question, I apologize for jumping in.
Regards,
RandyP
Note that the pragma is changing the actual alignment of the object. That's why you can't apply it to a declaration: the variable is defined somewhere else, and its alignment is determined at that location.
The _nassert makes a claim about the alignment of the object, which the compiler can exploit, but it does not enforce that alignment. If the object has a different alignment than the assertion says, there could be incorrect results.
Randy,
Thank you for your jump-in.
I understood that we could ensure the alignment is 8 bytes or 16 bytes and compiler is allowed to access elements of an array by SIMD (or wide data width instruction).
However, I'm not sure how we can tell that the alignment is smaller than architecture default (e.g. 4 bytes alignment for int[] is smaller than 8 bytes for C64 or later default). I tried the following but it did not affect optimization. It still generated STDW instead of STNDW.
_nassert((int) buffer % 8 == 4);
Should it be bit operation instead of modulo (%)? Or _nassert((int) buffer % 8 != 0)? :)
Regards,
Atsushi
You cannot; it is a bug that DATA_ALIGN allowed you to change the actual alignment of the object. The code where the _nassert is rightly believes that no such array could have less than the default alignment of an array of that type.
Hi Archaeologist,
It did make sense. I agree with you. Thanks!
Why I asked is, when we simply pass a pointer (int*) to a function, it does not assume that the int* is not aligned at 8 bytes (possibly at a &buffer[1], &buffer[3], etc.), so the compiler tries to use STNDW or LDNDW. But the my question was about the alignment of a top-level array. It must be aligned at 8 bytes always if is not compiled by C6200 compiler.
Thank you for clarification.
Regards,
Atsushi