 |
|
 |
MAEC TOOL NEWS:
MAECT-M3T-CC32R_2-020516D
A Note on Cross-Tool Kit M3T-CC32R
|
Please take note of the following problem in using cross-tool kit M3T-CC32R for the M32R family MCUs:
- On programs using a loop statement that includes a conditional construct in which two array elements are referred to by the subscript of the same variable
- Versions Concerned
M3T-CC32R V.1.00 Release 1 -- V.3.20 Release 1
- Description
When a loop statement (for, while, or do--while) includes a conditional construct (an if or loop statement) that contains two assignment expressions, and the right terms of these expressions are the array references by the subscript of the same variable, optimization may cause one of the assignment expressions to be omitted at compilation.
- 2.1 Conditions
- This problem may occur if the following eight conditions are satisfied:
- (1) An optimizing option covering -O4's function is used (any of the following options is selected: -O4, -O5, -O6, -O7, -Otime only, or -Ospace only)
- (2) A loop statement is described.
- (3) The loop statement in (2) includes a conditional construct.
- (4) In the loop statement in (2), two contiguous expressions that assign values to variables exist each before and within the conditional construct in (3).
- (5) The right terms of the two expressions in (4) are the same expressions that satisfy the following conditions:
- (a) an array is referenced by using a pointer to the const area,
- (b) the subscript of an array is a variable, and
- (c) the type of reference is either of:
- (i) the one to a member of arrays of structures (array[idx].x, for example)
- (ii) the one to a two-dimensional array (array[idx][0], for example)
- (6) Before and within the conditional construct in (3) are used different variables as the subscripts of arrays.
- (7) The variables in (6) are referred to or altered outside the loop statement in (2).
- (8) Before or within the conditional construct in (3) exist array references using the same pointer and variable in (5)-(a) and -(b)
- 2.2 Examples
[Example 1: Source file "sample1.c"]
----------------------------------------------------------------------
extern void func(int, int);
struct xydata { int x, y; };
int flag, glb_data;
const struct xydata *array; /* Condition (5)(a) */
void
foo(void)
{
int idx;
int data1, data2;
int check;
idx = glb_data; /* Condition (7) */
while (flag) { /* Condition (2) */
data1 = array[idx].x; /* Conditions (4), (5)(b),
(5)(c)(i), and (6) */
data2 = array[idx].x; /* Conditions (4), (5)(b),
(5)(c)(i), and (6) */
check = array[idx].y; /* Condition (8) */
if (check) { /* Condition (3) */
++idx; /* Condition (6) */
data1 = array[idx].x; /* Conditions (4), (5)(b),
(5)(c)(i), and (6) */
data2 = array[idx].x; /* Conditions (4), (5)(b),
(5)(c)(i), and (6) */
}
func(data1, data2);
}
}
----------------------------------------------------------------------
[Example 2: Source file "sample2.c"]
----------------------------------------------------------------------
extern void func(int, int);
int flag, glb_data;
const int (*array)[2]; /* Condition (5)(a) */
void
foo(void)
{
int idx = 0;
int data1, data2;
glb_data = idx; /* Condition (7) */
while (flag) { /* Condition (2) */
data1 = array[idx][0]; /* Conditions (4), (5)(b),
(5)(c)(ii), and (6) */
data2 = array[idx][0]; /* Conditions (4), (5)(b),
(5)(c)(ii), and (6) */
while (array[idx][1]) { /* Conditions (3) and (8) */
++idx; /* Condition (6) */
data1 = array[idx][0]; /* Conditions (4), (5)(b),
(5)(c)(ii), and (6) */
data2 = array[idx][0]; /* Conditions (4), (5)(b),
(5)(c)(ii), and (6) */
}
func(data1, data2);
}
}
----------------------------------------------------------------------
[Examples of typing commands in M3T-CC32R (a % sign denotes a prompt)]
------------------------------------------------------------------------
% cc32R -c -O4 sample1.c ; Condition (1)
% cc32R -c -O4 sample2.c ; Condition (1)
------------------------------------------------------------------------
- Compiling the source code in Examples 1 and 2 will omit to assign the value to data1 in each conditional construct of an if and while statements included in the first loop (while) statement. Because the value of idx within the conditional construct is incremented and is not the same as the one in front of the conditional construct, the omission is wrong.
- Workaround
- This problem will be circumvented in any of the following ways:
- (1) Suppress optimization in the -O4 level.
Optimization covering the -O4 option will be performed when optimizing option -04, -O5, -O6, -O7, -Otime only or -Ospace only has been selected. If you want to use -Otime or -Ospace, select any of these options, -O0, -O1, -O2, and -O3, at the same time.
- (2) Declare the variables that are assigned values to be volatile.
[Example: "sample1.c" and "sample2.c"]
-----------------------------------------------------------------------
At declaring the types of data1 and data2, also declare them to be
volatile, that is, "volatile int data1, data2;" instead of
"int data1, data2;"
-----------------------------------------------------------------------
- (3) Use pointers to separate an array and its members, or the first and second subscripts in an array reference.
[Example 1: "sample1.c"]
------------------------------------------------------------------------
extern void func(int, int);
struct xydata { int x, y; };
int flag, glb_data;
const struct xydata *array;
void
foo(void)
{
int idx;
int data1, data2;
int check;
const struct xydata *ptr; /* Pointer ptr prepared */
idx = glb_data;
while (flag) {
ptr = &array[idx]; /* ptr assigned */
data1 = ptr->x; /* Member x referred to by ptr */
data2 = ptr->x; /* Member x referred to by ptr */
check = array[idx].y;
if (check) {
++idx;
ptr = &array[idx]; /* ptr assigned */
data1 = ptr->x;
data2 = ptr->x;
}
func(data1, data2);
}
}
--------------------------------------------------------------------
[Example 2: "sample2.c"]
--------------------------------------------------------------------
extern void func(int, int);
int flag, glb_data;
const int (*array)[2];
void
foo(void)
{
int idx = 0;
int data1, data2;
const int *ptr; /* Pointer ptr prepared */
glb_data = idx;
while (flag) {
ptr = array[idx]; /* ptr assigned */
data1 = ptr[0]; /* Column referenced by ptr */
data2 = ptr[0]; /* Column referenced by ptr */
while (array[idx][1]) {
++idx;
ptr = array[idx]; /* ptr assigned */
data1 = ptr[0];
data2 = ptr[0];
} func(data1, data2);
}
}
--------------------------------------------------------------------
|
 |