Как я могу повлиять на генерацию кода Delphi Xex для целей Android/ARM?Android

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Как я могу повлиять на генерацию кода Delphi Xex для целей Android/ARM?

Сообщение Anonymous »

Компиляторы Delphi от Embarcadero используют бэкэнд LLVM для создания собственного кода Arm для устройств Android. У меня есть большое количество кода Pascal, которое мне нужно собирать в приложения Android, и я хотел бы знать, как заставить Delphi генерировать более эффективный код. Конечно, должен быть способ передать параметры в сторону LLVM или каким -то образом повлиять на результат? Обычно у любого компилятора будет много вариантов, чтобы повлиять на компиляцию и оптимизацию кода, но цели Delphi, кажется, просто «оптимизация/выключение», и это все. Delphi хочет очень сильно использовать этот стек, и, как правило, он только использует регистры процессора R0-R3 в качестве временных переменных. Возможно, самый безумный из всех, он, кажется, загружает нормальные 32-битные целые числа как четыре операции с 1-байтовой нагрузкой. Как я могу заставить Delphi производить лучший код ARM, и без байто-байтовых хлопот он создает для Android? Это действительно просто загружает 32-битный номер с 4 однобайтными нагрузками. It might be to load the full 32 bits without doing an unaligned word-sized memory load (whether it should avoid that is another thing, which would hint to the whole thing being a compiler bug)
Let's look at this simple function:

Код: Выделить всё

function ReadInteger(APInteger : PInteger) : Integer;
begin
Result := APInteger^;
end;
< /code>
Даже при включенном включении оптимизации Delphi XE7 с пакетом обновлений 1, а также XE6 создают следующий код сборки ARM для этой функции: < /p>
Disassembly of section .text._ZN16Uarmcodetestform11ReadIntegerEPi:

00000000 :
0:    b580          push   {r7, lr}
2:    466f          mov    r7, sp
4:    b083          sub    sp, #12
6:    9002          str    r0, [sp, #8]
8:    78c1          ldrb   r1, [r0, #3]
a:    7882          ldrb   r2, [r0, #2]
c:    ea42 2101     orr.w  r1, r2, r1, lsl #8
10:    7842          ldrb   r2, [r0, #1]
12:    7803          ldrb   r3, [r0, #0]
14:    ea43 2202     orr.w  r2, r3, r2, lsl #8
18:    ea42 4101     orr.w  r1, r2, r1, lsl #16
1c:    9101          str    r1, [sp, #4]
1e:    9000          str    r0, [sp, #0]
20:    4608          mov    r0, r1
22:    b003          add    sp, #12
24:    bd80          pop    {r7, pc}
Просто посчитайте, сколько инструкций и обращений к памяти нужно Delphi для этого. И построение 32-битного целого числа из четырех однобайтовых загрузок... Если я немного изменю функцию и использую параметр var вместо указателя, это будет немного менее запутанно:

Код: Выделить всё

Disassembly of section .text._ZN16Uarmcodetestform14ReadIntegerVarERi:

00000000 :
0:    b580          push   {r7, lr}
2:    466f          mov    r7, sp
4:    b083          sub    sp, #12
6:    9002          str    r0, [sp, #8]
8:    6801          ldr    r1, [r0, #0]
a:    9101          str    r1, [sp, #4]
c:    9000          str    r0, [sp, #0]
e:    4608          mov    r0, r1
10:    b003          add    sp, #12
12:    bd80          pop    {r7, pc}
Я не буду включать здесь дизассемблирование, но для iOS Delphi создает идентичный код для версий указателя и параметра var, и они почти, но не совсем, такие же, как версия параметра var в Android.
Для пояснения: побайтовая загрузка осуществляется только на Android. И только на Android версии параметров указателя и var отличаются друг от друга. На iOS обе версии генерируют один и тот же код.*
Для сравнения, вот что FPC 2.7.1 (версия SVN Trunk от марта 2014 г.) думает о функции с уровнем оптимизации -O2. Версии параметров указателя и var абсолютно одинаковы.
Disassembly of section .text.n_p$armcodetest_$$_readinteger$pinteger$$longint:

00000000 :

0: 6800 ldr r0, [r0, #0]
2: 46f7 mov pc, lr
< /code>
Я также проверил эквивалентную функцию C с компилятором C, которая поставляется с Android NDK. < /p>
int ReadInteger(int *APInteger)
{
return *APInteger;
}
< /code>
и это компилируется в практически одном и том же FPC, сделанном: < /p>
Disassembly of section .text._Z11ReadIntegerPi:

00000000 :
0: 6800 ldr r0, [r0, #0]
2: 4770 bx lr
< /code>
Я больше не работаю в компании, где возник этот вопрос, и не имею доступа к Delphi Xex. Пока я был там, проблема была решена путем миграции в смешанный FPC+GCC (Pascal+C), с неоновой внутренней внутренней частью для некоторых процедур, где это имело значение. (FPC+GCC настоятельно рекомендуется также потому, что он позволяет использовать стандартные инструменты, особенно Valgrind.) Если кто -то может продемонстрировать с достоверными примерами, как они на самом деле способны создавать оптимизированный код руки от Delphi Xex, я рад принять ответ.*


Подробнее здесь: https://stackoverflow.com/questions/279 ... rm-targets
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»