MAEC TOOL NEWS:
MAECT-CC32R-010916D
M32Rファミリ用クロスツールキットCC32Rの使用上の注意事項を連絡します。
- const領域かつvolatile領域を複数回連続アクセスする場合の最適化に関する注意事項
- 該当製品
CC32R V.1.00 Release 1 ~ V.3.00 Release 1
- 内容
const領域かつvolatile領域を同じオフセット演算を使って複数回連続アクセスする場合、-O4を含む最適化を行うと内部エラーになることがあります。
- 2.1 発生条件
- 以下5点の条件をすべて満たす場合に発生することがあります。
- (1) -O4を含む最適化オプションを指定している(つまり-O4, -O5, -O6, -O7, -Otimeのみ、または-Ospaceのみを指定している)。
- (2) 以下のいずれかの変数が、const型とvolatile型の両方で宣言されている (ただし、ビットフィールドは除きます)。
- (a) 構造体、共用体のメンバ
- (b) 配列の要素
- (c) ポインタ+オフセット値で示される場所
- (3) (2)の変数が占める領域を連続して複数回アクセスしている。
- (4) (3)の連続アクセスの間に、関数の呼び出しおよび任意のポインタを使った間接代入を行っていない。
- (5) (3)の連続アクセスの式において、領域を表す部分のみは共通である。
- [(5)の例] 配列aがconst volatile型である場合
| 該当する | : a[5] + 3 と a[5] + 4 ← a[5] のみが共通 |
| 該当しない | : a[5] + 3 と a[5] + 3 ← a[5] + 3 までが共通 |
- 【注意】
- 上記(5)の条件が満たされない場合でも、条件(1)~(4)を満たす場合は、2001年8月16日発行のMAEC TOOL NEWS (MAECT-CC32R-010816D) 「volatile領域を複数回連続アクセスする場合の注意事項」 に該当します。
- 2.2 発生例
[ソースファイル例1:sample1.c]
-----------------------------------------------------------------------
extern const volatile struct {
int a;
int b;
} v_strarea;
void foo(void)
{
while (v_strarea.a & 4); /* 条件(2)-(a),(3),(5) */
/* 条件(4) */
while (!(v_strarea.a & 8)); /* 条件(2)-(a),(3),(5) */
}
-----------------------------------------------------------------------
[ソースファイル例2:sample2.c]
-----------------------------------------------------------------------
extern const volatile unsigned short v_array[];
void foo(void)
{
while (v_array[7] & 4); /* 条件(2)-(b),(3),(5) */
/* 条件(4) */
while (!(v_array[7] & 8)); /* 条件(2)-(b),(3),(5) */
}
-----------------------------------------------------------------------
[ソースファイル例3:sample3.c]
-----------------------------------------------------------------------
extern const volatile long *v_ptr;
int foo(void)
{
int answer;
answer = (*(v_ptr + 7) & 4); /* 条件(2)-(c),(3),(5) */
/* 条件(4) */
answer *= (*(v_ptr + 7) & 8); /* 条件(2)-(c),(3),(5) */
return answer;
}
-----------------------------------------------------------------------
[ CC32Rのコマンド操作例(%はプロンプトを表します) ]
-----------------------------------------------------------------------
% cc32R -c -O4 sample1.c
% cc32R -c -O4 sample2.c
% cc32R -c -O4 sample3.c
-----------------------------------------------------------------------
- 回避策
- 次の(1)~(2)のいずれかの方法で回避してください。
- (1) -O4レベルの最適化を抑止する
- ※-O4を含む最適化は、-O5, -O6, -O7, -Otimeのみ、または-Ospaceのみを指定しているときに行われます。-Otimeまたは-Ospaceを使用する場合は、同時に-O3, -O2, -O1, -O0のいずれかを指定してください。
- (2) 該当領域をvolatile型のポインタを使ってアクセスする
[ソースファイル例1:sample1.cの回避例]
------------------------------------------------------------------------
extern const volatile struct s_tag {
int a;
int b;
} v_strarea;
void foo(void)
{
const volatile int *ptr = &v_strarea.a;
while (*ptr & 4);
while (!(*ptr & 8));
}
-----------------------------------------------------------------------
[ソースファイル例2:sample2.cの回避例]
-----------------------------------------------------------------------
extern const volatile unsigned short v_array[];
void
foo(void)
{
const volatile unsigned short *ptr = &v_array[7];
while (*ptr & 4);
while (!(*ptr & 8));
}
-----------------------------------------------------------------------
[ソースファイル例3:sample3.cの回避例]
-----------------------------------------------------------------------
extern const volatile long *v_ptr;
int foo(void)
{
int answer;
const volatile long *ptr = v_ptr + 7;
answer = (*ptr & 4);
answer *= (*ptr & 8);
return answer;
}
-----------------------------------------------------------------------