8.169 --share_inlineable_strings, --no_share_inlineable_strings

同じインライン化された文字列リテラルの複数のインスタンスで、同じオブジェクトを使用するかどうかを制御します。

--share_inlineable_strings オプションでは、インライン化された文字列リテラルのすべてのインスタンスで、同じオブジェクトを使用します。特に、以下のようになります。
  • 同じ変換単位の文字列リテラルは、その変換単位で同じオブジェクトになります。
  • 外から見えるインライン関数の文字列リテラルは、すべての変換単位で同じオブジェクトになります。
その結果、同じ値を持つ異なる文字列リテラルが、同じオブジェクトになる可能性があります。
--no_share_inlineable_strings オプションでは、この動作が行われなくなります。つまり、パフォーマンスが向上するかコードサイズが小さくなる場合、コンパイラは文字列リテラルを共有するだけになります。例えば、ADR 命令の範囲外にある文字列リテラルについて考えてみましょう。この場合、アドレスはリテラルプールから読み込まなければなりません。これにはコストが 4 バイトかかり、ADR 命令より低速です。その結果、–Otime では、コンパイラは範囲外であった文字列を共有しません。–Ospace では、コンパイラは 4 バイトより小さい文字列を共有しません。

--share_inlineable_strings オプションと --no_share_inlineable_strings オプションは、以下における文字列リテラルに影響を及ぼします。
  • インラインで宣言されていないが、コンパイラがインライン化することにした C または C++ 関数。
  • C のインライン関数。
C++ インライン関数での文字列の動作は、これらのオプションからは切り離されており、C++ ABI によって定義されています。

以下のサンプルコードを考えてみます。
#include <stdio.h>

extern inline char *getString(void) { return "abc"; }

int main(int argc, char **argv)
{
  char *a = getString();
  char *(*ptr)() = getString;
  char *b = ptr();


  int a_addr=(int)a;
  int b_addr=(int)b;


  printf("String \"%s\" from getString() called directly is an object at address:          %d\n", a, a_addr);
  printf("String \"%s\" from getString() called using a pointer is an object at address:   %d\n", b, b_addr);

  if (a_addr == b_addr) {
    printf("Objects are the same.\n");
  } else {
    printf("Objects are different.\n");
  }
}
デフォルト(つまり、--share_inlineable_strings オプション)では、文字列リテラルの両方のインスタンスで、1 つの共有されたオブジェクトを使用します。
armcc --share_inlineable_strings  --c99 test.c  -o-
コンパイルされたイメージを実行すると、以下の出力が生成されます。
String "abc" from getString() called directly is an object at address:          36812
String "abc" from getString() called using a pointer is an object at address:   36812
Objects are the same.
同じコードを --no_share_inlineable_strings オプションでコンパイルすると、複数の文字列オブジェクトが生成されます。
armcc --no_share_inlineable_strings  --c99 test.c  -o-
コンパイルされたイメージを実行すると、以下の出力が生成されます。
String "abc" from getString() called directly is an object at address:          33004
String "abc" from getString() called using a pointer is an object at address:   36616
Objects are different.
関連する参考文書
8.143 -Ospace
8.144 -Otime
非機密扱いPDF file icon PDF 版ARM DUI0472LJ
Copyright © 2010-2015 ARM.All rights reserved.