LINUX.ORG.RU

Оптимизация строковых констант в gcc

 ,


0

2

Вопрос к знатокам gcc. Есть такой вот листинг:

248       		return Executor_error(1, "-");
08004ee0:   ldr     r1, [pc, #32]   ; (0x8004f04 <Executor_cmd_gpio_w+92>)
08004ee2:   movs    r0, #1

271       			return Executor_error(2, "-");
08004f36:   ldr     r1, [pc, #24]   ; (0x8004f50 <Executor_cmd_gpio_r+72>)
08004f38:   movs    r0, #2
08004f3a:   bl      0x8004dce <Executor_error>
08004f3e:   b.n     0x8004f34 <Executor_cmd_gpio_r+44>
274       		return Executor_error(1, "-");
08004f40:   ldr     r1, [pc, #12]   ; (0x8004f50 <Executor_cmd_gpio_r+72>)
08004f42:   movs    r0, #1
Из коего следует, что константа "-" существует сразу в трех экземплярах [#32, #24, #12], в то время как числовая константа 1 имеет единичную ссылку #1.

Вопрос - можно ли заставить gcc, не плодить строки в таком количестве. Вопрос важен в части оптимизации размеров прошивок микроконтроллеров, где хотелось бы чаще использовать осмысленный текст в логах и других человекочитаемых местах, на данная особенность компиляции не дает для этого никакой разумной возможности.

P. S. Если я правильно трактую содержимое листинга



Последнее исправление: Serbis (всего исправлений: 2)

Ответ на: комментарий от Deleted

а эти строки там как static const?

Нет, литералы же: return Executor_error(1, "-");

-fmerge-all-constants

Не влияет на строковые литералы, которые должны по-дефолту мержиться с включенной оптимизацией

-fmerge-constants

Attempt to merge identical constants (string constants and floating-point constants) across compilation units.

This option is the default for optimized compilation if the assembler and linker support it. Use -fno-merge-constants to inhibit this behavior.

Enabled at levels -O, -O2, -O3, -Os.

annulen ★★★★★
()
Последнее исправление: annulen (всего исправлений: 1)

в то время как числовая константа 1 имеет единичную ссылку #1

Это не ссылка, это число 1 (immediate operand)

annulen ★★★★★
()

#32, #24, #12

Это абсолютный адрес или относительный?
И вообще без знания/указания какой именно ассемблер, разговор смысла не имеет.

anonymous
()

А почему они должны существовать в одном экземпляре?

xpahos ★★★★★
()

оптимизацию включите, gcc автоматом все смержит

anonymous
()

Из тех товарищей, что не знают, что всю жизнь в продакшен DEBUG херачат? Главное уже до листинга добрался. В релиз переключи, лапоть!

anonymous
()
Ответ на: комментарий от annulen

Ааа, спасибо. Непральна всё понял я

Deleted
()
Ответ на: комментарий от anonymous

Очевидно, что относительный, относительно регистра pc

И вообще без знания/указания какой именно ассемблер, разговор смысла не имеет.

RISC-ассемблеры достаточно похожи друг на друга

annulen ★★★★★
()
Ответ на: комментарий от annulen

Если относительный, то последние два указывают на один и тот же адрес, первый - на другой. Скорее всего стоит оптимизация по размеру и используется команда с коротким расстоянием относительного адреса (например не дальше 64 байта). Из-за чего две копии строки: один для первой команды и второй для 2-3-й команд.

anonymous
()

Адрес там относительный (относительно PC programm counter/instruction pointer). Строк 2 по адресам

  • 0x8004f04 <Executor_cmd_gpio_w+92> и
  • 0x8004f50 <Executor_cmd_gpio_r+72>

(причину описали в предыдущем сообщении).

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.