Эльбрус/lcc: различия между версиями
м (→howto: +int128) |
м (поправил в целом) |
||
Строка 29: | Строка 29: | ||
=== segfault === | === segfault === | ||
работа /opt/mcst/lcc-home/1.23.12/e2k-v3-linux/bin/ecf_opt64 завершена по сигналу Segmentation fault (11) | |||
При падении компилятора остаётся только вешать [[#bugreport|отчёт об ошибке]] в lcc. | При падении компилятора остаётся только вешать [[#bugreport|отчёт об ошибке]] в lcc. | ||
Строка 53: | Строка 53: | ||
=== -std=c++11 === | === -std=c++11 === | ||
По умолчанию в 1.23 идёт -std=c++03, как и в gcc 5.5; если код подразумевает более новый стандарт | Ошибки могут быть довольно разнообразными; скажем, | ||
"nullptr" не определен | |||
По умолчанию в 1.23 идёт -std=c++03, как и в gcc 5.5; если код подразумевает более новый стандарт без учёта этого в системе сборки -- включаем явно: | |||
%ifarch %e2k | %ifarch %e2k | ||
Строка 114: | Строка 118: | ||
Если в исходной строке запуска была указана опция <tt>-o</tt> с именем бинарного объекта, её стоит удалить. | Если в исходной строке запуска была указана опция <tt>-o</tt> с именем бинарного объекта, её стоит удалить. | ||
= оптимизация = | = оптимизация = | ||
Строка 122: | Строка 123: | ||
По умолчанию lcc выставляет второй уровень оптимизации, как и gcc (<tt>-O2</tt>). Это достаточно консервативно с его стороны, поскольку множество полезных оптимизаций включаются только на третьем уровне (<tt>-O2</tt>); при этом прыгать на четвёртый бездумно не стоит, т.к. туда сложены потенциально опасные оптимизации и такие, которые могут привести к обратному эффекту -- понижению производительности полученного кода. | По умолчанию lcc выставляет второй уровень оптимизации, как и gcc (<tt>-O2</tt>). Это достаточно консервативно с его стороны, поскольку множество полезных оптимизаций включаются только на третьем уровне (<tt>-O2</tt>); при этом прыгать на четвёртый бездумно не стоит, т.к. туда сложены потенциально опасные оптимизации и такие, которые могут привести к обратному эффекту -- понижению производительности полученного кода. | ||
При отладке стоит понижать уровень оптимизации (<tt>-O1</tt> и даже <tt>-O0</tt>) и порой ''отключать'' генерацию отладочной информации (<tt>-g0</tt>, см. выше). | При отладке стоит понижать уровень оптимизации (<tt>-O1</tt> и даже <tt>-O0</tt>) и порой ''отключать'' генерацию отладочной информации (<tt>-g0</tt>, см. [[#misoptimization|выше]]). | ||
= примечания = | |||
<references/> | |||
[[Категория:E2K]] | [[Категория:E2K]] |
Версия от 20:31, 30 июня 2019
lcc на e2k
Сразу оговорюсь: речь именно о родном режиме работы lcc, кроссовым (собирать для e2k, сидя на x86) мы не пользуемся.
Основная часть проблем, возникающих при сборке рассчитанного на gcc программного обеспечения сводится к тому, что lcc -- это всё же не gcc, несмотря на выставленный __GCC__ соответственно заявленной в `lcc -v` совместимой версии; порой даже проще прикинуться ICC или clang, у которых во многом схожие ограничения -- начиная с того, что они тоже не gcc.
В любом случае мы стараемся донести их до коллег, занимающихся lcc, ради возможности улучшения будущих версий.
В то же время компилятор предоставляет богатые возможности оптимизации под весьма благодарную за них VLIW-платформу, причём от ветки к ветке производительность одного и того же исходного кода на одной и той же аппаратуре в среднем растёт.
проблемы
фронтэнд
Надо понимать, что МЦСТ применяет в lcc сторонний фронтэнд разработки Edisson Data Group (EDG), как несколько раньше делал и Intel в своём icc.
Собственно, в основном проблемы здесь -- и с новыми версиями стандартов вроде C++17 (ждём lcc 1.24), и с отсутствием поддержки как некоторых расширений GNU (в первую очередь вложенных функций -- nested functions, и массивов переменной длины -- variable length arrays, VLA), так и ряда языков -- Objective C, D, Ada, Go -- либо конкретных опций, специфичных для gcc или других компиляторов.
Стоит отметить, что часть "проблем" на самом деле относится именно к собираемому софту и находится в нём -- просто gcc или смотрит сквозь пальцы, ограничиваясь предупреждениями, или не делает даже их, что позволяет фактическим ошибкам оставаться в коде даже с -Werror.
бэкенд
С ним бывают проблемы в основном двух типов: неверная оптимизация или сбой самого оптимизатора.
misoptimization
Обычно замечается по странным сбоям в работе программы (особенно Illegal instruction, оно же SIGILL); диагностируется по корректности работы собранного с -O0 и/или -g0 кода; исправляется в компиляторе или обходится в коде.
segfault
работа /opt/mcst/lcc-home/1.23.12/e2k-v3-linux/bin/ecf_opt64 завершена по сигналу Segmentation fault (11)
При падении компилятора остаётся только вешать отчёт об ошибке в lcc.
howto
Маленький сборник проверенных на пакетах для e2k-alt-linux рецептов.
UTF-8 BOM
Проблема (#2418): строгий фронтэнд с негодованием спотыкается на трёхбайтном маркере в начале файла, указывающем, что используется кодировка UTF-8 (обычно оставлен текстовым редактором); изменение этого поведения ожидается в версии 1.24, а до того может понадобиться:
%ifarch %e2k # strip UTF-8 BOM for lcc < 1.24 find -type f -name '*.cpp' -o -name '*.hpp' -o -name '*.h' -print0 | xargs -r0 sed -ri 's,^\xEF\xBB\xBF,,' %endif
Такие пакеты при обходе проблемы в альте обычно получают подобную запись в %changelog:
- E2K: strip UTF-8 BOM for lcc < 1.24
-std=c++11
Ошибки могут быть довольно разнообразными; скажем,
"nullptr" не определен
По умолчанию в 1.23 идёт -std=c++03, как и в gcc 5.5; если код подразумевает более новый стандарт без учёта этого в системе сборки -- включаем явно:
%ifarch %e2k # -std=c++03 by default as of lcc 1.23.12 %add_optflags -std=c++11 %endif
- E2K: explicit -std=c++11
символьные константы
Проблема (#3940): по умолчанию символьные константы в UTF-8 не будут разобраны фронтэндом:
lcc: "static_unicode_sets.h", строка 111: ошибка: слишком много символов в символьной константе {RUPEE_SIGN, u'₨'}, ^
Добавим опцию -finput-charset=utf8:
%ifarch %e2k # lcc 1.23.12 doesn't grok u'’' by default %add_optflags -finput-charset=utf8 %endif
- E2K: expect UTF-8 input
__builtin
В lcc 1.23 не поддерживается ряд типично ожидаемых от заявленного gcc5 builtin'ов[1], в т.ч.: __builtin_mul_overflow_p, __builtin_constant_p, __builtin_uadd_overflow, __builtin_sub_overflow, __builtin_add_overflow.
Смысл патча обычно заключается в добавлении проверки на lcc <= 1.23 -- например, для включающих gnulib проектов:
-#if 5 <= __GNUC__ && !defined __ICC +#if 5 <= __GNUC__ && !defined __ICC && !(defined __LCC__ && __LCC__ <= 123) ... -#elif 5 <= __GNUC__ && !defined __ICC && !__STRICT_ANSI__ +#elif 5 <= __GNUC__ && !defined __ICC && \ + !(defined __LCC__ && __LCC__ <= 123) && !__STRICT_ANSI__
Также не поддерживается vector_shuffle (#3982 о libfreetype >= 2.9) -- пока неясно, будет ли реализация в lcc.
int128
int128_t, uint128_t и Decimal128 на lcc < 1.24 нет (#1802); пока применяем аналогичные вышеизложенным для __builtin_* обходы либо прикидываемся 32-битной платформой с максимум 64-битными целыми, смотря по ситуации (такие в сизифе оказались довольно редки, апстрим libtommath патчик уже принял).
bugreport
Пишем на user@mcst заявку на регистрацию в системе отслеживания ошибок (с рабочего адреса и указав серийный номер используемого "Эльбруса").
Если проблема с неподдерживамой опцией -- следует вешать одно сообщение об ошибке на одну опцию; максимум одно сообщение с перечислением нескольких связанных между собой опций в течение одного дня (это связано с порядком обработки багрепортов компиляторщиками и экономит им силы на синхронизации обстановки с внутренним багтрекером).
Если произошёл сбой компиляции, к отчёту об ошибке стоит приложить препроцессированный исходник (-E) и строчку запуска -- например,
g++ -Wall -O2 -DNDEBUG -std=c++11 -c -I ./include/ ./core/xhtmlgenerator.cpp
...превращается в:
$ g++ -Wall -O2 -DNDEBUG -std=c++11 -c -I ./include/ ./core/xhtmlgenerator.cpp -E -o test.pp.cpp
Если в исходной строке запуска была указана опция -o с именем бинарного объекта, её стоит удалить.
оптимизация
По умолчанию lcc выставляет второй уровень оптимизации, как и gcc (-O2). Это достаточно консервативно с его стороны, поскольку множество полезных оптимизаций включаются только на третьем уровне (-O2); при этом прыгать на четвёртый бездумно не стоит, т.к. туда сложены потенциально опасные оптимизации и такие, которые могут привести к обратному эффекту -- понижению производительности полученного кода.
При отладке стоит понижать уровень оптимизации (-O1 и даже -O0) и порой отключать генерацию отладочной информации (-g0, см. выше).
примечания
- ↑ исправлено в 1.24, но тот будет прикидываться gcc7, от которого ожидают ещё более новых builtin'ов, в свою очередь