LINUX.ORG.RU

LLVM. Зачем он вообще нужен?

 ,


3

6

Я понимаю, зачем его используют: чтобы не писать 100500 раз в каждом компиляторе одни и те же алгоритмы оптимизации.

Я не понимаю, почему не использовать просто компиляцию через Си или Си++. Оптимизации сделает компилятор Си. Семантика у LLVM всё равно совпадает с Си, по объёму кода компилятора тоже выигрыша практически нет. Зато если использовать Си, можно использовать любой из компиляторов Си и компилировать для платформ, для которых нет реализации LLVM.

★★★★★

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

Во первых у тебя выход за границы массива.

Да.

Во вторых я не понял, что ты пытался сказать.

Что чтение за границей массива на любом ассемблере или вернёт определённое число или аварийно завершит программу. Повторное чтение вернёт то же самое число.

А на Си чтение за границей массива воспринимается как то, что условие, при котором этого чтения нет, гарантированно истинное.

Но на Си он будет возвращать 1 для всех значений.

https://godbolt.org/z/dv1nKM99T

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

А на Си чтение за границей массива воспринимается как то, что условие, при котором этого чтения нет, гарантированно истинное.

Идеальный пример - это же буквально подмена понятий и спекулятивная интерпретация.

Компилируемый язык (вернее компилятор) на глазах у всех занимается интерпретацией. Тот же бег в темноте со столбами как, например, спекулятивное предсказание выполнения инструкций в процессорах.

Разве кому-то здесь не очевидно что попытка чтения за границей массива должна вызывать явное исключение/ошибку?

А потом все удивляются зачем всякие Go для ширнармасс создают.

Obezyan
()
Ответ на: комментарий от monk

Но на Си он будет возвращать 1 для всех значений.

https://godbolt.org/z/dv1nKM99T

clang со любыми оптимизациями (000000000000=1) https://godbolt.org/z/Y4fdzrTjr

gcc -O0 (000000000000=1) https://godbolt.org/z/Gn97vzcss

gcc -O1 SIGSEGV https://godbolt.org/z/qoKnW1csG

gcc -O{2,3,fast} твой случай

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

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

От какого именно ассемблера? Ассемблер для какого-нибудь студенческого OISC и ассемблер со встроенным ООП для iAPX432 – это разные ассемблеры.

Что именно в твоём понимании делает Brainfuck низкоуровневым? Является ли нетипизированное лямбда-исчисление низкоуровневым в твоём понимании? Там тоже «команд» мало.

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 2)
Ответ на: комментарий от monk

Повторное чтение вернёт то же самое число.

если это очевидно не отображённые на память порты ввода например

али ещё что конкурентное (сори но даже возврат того же самого гарантирован не на всём универсуме ассемблеров :) )|

по коду - а как ща (и везде ли и с какого ) глобальный массив как инитится ежель нет явного заброса байт

ты вот этот код как пример чего ?!?

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

если это очевидно не отображённые на память порты ввода например

Даже в этом случае возвращённое число не всегда будет равно аргументу функции.

ты вот этот код как пример чего ?!?

Что в Си в случае чтения за границей массива может быть истинно ∀x: a[10] == x. А для ассемблера оно будет иногда ложно.

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

какой тезис по коду то?

по кроликам дирихле a достоверно(если data конкуренто не массируют что бы в 0-9(ой 10 тоже) ячейках обнаружились все 12 варианто) 1

чёйта както :

летело два каркадила один зелённый второй на лево

искренне хочу обрести такую лёгкость программирования

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

UB - может делать что угодно, например, генерировать програмное/аппаратное исключение (SIGSEGV), обработчик которого может отформатировать диск.

Это как раз нормально. UB как произвольное действие — это как раз семантика ассемблера.

Но в Си программа переписывается с целью устранения UB. В результате, например, эта программа никогда не упадёт, даже если сразу за массивом data данные чужой программы. Потому что массив data вообще не читается.

monk ★★★★★
() автор топика
Ответ на: комментарий от qulinxao3
int find(int x)
{
  int i;
  for(i = 0; i <= 10; i++)
    if(data[i] == x) return 1;
  return 0;
}

Компилятор Си видит, что data[10] за концом массива. Значит в цикле i не может достичь 10, значит гарантированно в одном из предыдущих элементов должен отработать return 1.

И меняет код на оптимизированный:

int find(int x)
{
  return 1;
}
monk ★★★★★
() автор топика
Ответ на: комментарий от monk

А на Си чтение за границей массива воспринимается как то, что условие, при котором этого чтения нет, гарантированно истинное.

И ты, конечно же, готов доказать этот тезис ссылками на стандарт? Или ты в лучших традициях лора перепутал жопу с пальцем и эвристики оптимизации конкретного компилятора в текущую фазу луны воспринял как стандарт на язык программирования?

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

возможно ваш тезис и верен

но вот этот код както мне не очевидно доказывает ваш тезис:

1. проверятся на наборе(массив из N элементов по факту N+1 значение <- если это не важно для тезиса можно s/<=10/<10/ ?!)

затем на N+1 значении проверяется N+2(различные) пробы -> кролики дирихле вымерли

очевидно одна из проверок будет 0

битовое произведение проверок 0

как истиность тезиса подтверждается фактом что разных проб больше чем множество значений в data + ещё элемент ?!?

реально доставили

qulinxao3 ★★
()
Последнее исправление: qulinxao3 (всего исправлений: 1)
Ответ на: комментарий от qulinxao3

давай пусть data[2] или даже data[1]

c соответсвующем сокращением трасы и проверяемых значений:

позязуся (можно запринтить ) покажи трассу и состояния локальных

ну или сам с карандашём протрасируйся

имхо как то сказачно вот это вот всё - а ведь ещё даже не пятница

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

А на Си чтение за границей массива воспринимается как то, что условие, при котором этого чтения нет, гарантированно истинное.

В стандарте написано, что программа, содержащая UB может делать что угодно.

Подожди-подожди. Ты искренне надеешься, что я не замечу подмены тезиса?

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

как истиность тезиса подтверждается фактом что разных проб больше чем множество значений в data + ещё элемент ?!?

Переданное значение (проба) должно быть равно какому-то значению из data + ещё один элемент. Если передано больше разных проб, чем множество значений, то хоть одна проба должна не попасть во множество значений.

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

может быть и так

однако тут не важно ибо мощьность множества значений (data + следующее значение) заведомо меньше чем длина(data) +2

т.е если код не упадёт то a всегда 1

какое это отношение к UB!?!

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

Так ты отказываешься защищать свой тезис

А на Си чтение за границей массива воспринимается как то, что условие, при котором этого чтения нет, гарантированно истинное.

?

Что угодно включает в себя изменение кода на такой, при котором чтения нет.

Это уже другой тезис. Ты готов его защищать цитатами из стандарта? Или опять будет игра в напёрстки?

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

т.е если код не упадёт то a всегда 1

a = "в множестве есть 1" и "в множестве есть 2" и ...

Если хоть одного из чисел 1..12 в множестве нет, то a = 0 (ложь).

какое это отношение к UB!?!

А UB позволяет в множестве из 11 элементов увидеть, что есть 12 разных значений.

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

Что угодно включает в себя изменение кода на такой, при котором чтения нет.

Это уже другой тезис. Ты готов его защищать цитатами из стандарта? Или опять будет игра в напёрстки?

В стандарте написано «что угодно». Изменение кода работающей программы включено в понятие «что угодно» по определению понятия «что угодно».

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

В стандарте написано «что угодно». Изменение кода работающей программы включено в понятие «что угодно» по определению понятия «что угодно».

Подожди-ка, сейчас твой тезис уже трансформировался в «UB даёт непредсказуемый результат».

Ты точно хочешь выразить какую-то логически связанную мысль?

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

хз почему копулятор сверхоптимизировал

вообще тут это не причём

твой исходный код(начальный на который ?)

произведение 12 битовых проверок всегда будет тождественно 0 - это твоё исходное утверждение(тезис) ?

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

произведение 12 битовых проверок всегда будет тождественно 0 - это твоё исходное утверждение(тезис) ?

Математически это так. Для семантики ассемблера (в которой ячейки памяти имеют определённые значения) это так.

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

по стандарту али «тут так принято»?

В стандарте нет ни одной запятой про оптимизацию. Но стандарт позволяет одной и той же программе, полностью ему соответствующей и даже не имеющей никакого UB, выдавать разные численные результаты (на разных платформах, компиляторах, опциях). В стандарте Си нет гарантий на идентичность вычислений между реализациями. Разумеетcя, для программ с UB всё это тоже применимо.

Теперь мы наблюдаем картину, как люди, не осознающие этого факта, пытаются на основе этой разницы вывести какие-то несуществующие закономерности о самом языке программирования.

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

В стандарте Си нет гарантий на идентичность вычислений между реализациями.

Частичная есть. На целочисленные в рамках значений попадающих в минимальный диапазон для типа.

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

не сообщая(остовляя при ебе ) своё мнение об истинности вот этих двух ваших тезисов(сложносоставленных из двух абзацев первый о стандарте и второй о наблюдении за людьми ...)

как это помогает отрефлексировать и уяснить как monk пришёл к такому выводу - его модель отражающее поведение его кода

.

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

Частичная есть. На целочисленные в рамках значений попадающих в минимальный диапазон для типа.

Внезапно, нет. Там нет явных требований на результат операций, и сложение двух единиц в полном соответствии со стандартом может дать 3. Минимальная размерность лишь гарантирует минимально допустимый диапазон значений переменных встроенных типов.

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

Значит в цикле i не может достичь 10,

Но ведь может, это явно указано в условии цикла for (i <= 10)

значит гарантированно в одном из предыдущих элементов должен отработать return 1.

В том то и дело что не должен. Компилятор прячет ошибку вместо сигнализирования о ней. И это считается нормой. И к тому же оч коряво прячет, после этой «оптимизации» find(11) тоже вернёт 1.

Obezyan
()
Ответ на: комментарий от LamerOk

комплиятор выкинет часть написанного кода.

Компилятор в данном случае выкинет буквально всю суть логики работы программы. Зато бегает быстро, до первого столба.

Obezyan
()
Ответ на: комментарий от LamerOk

Там нет явных требований на результат операций, и сложение двух единиц в полном соответствии со стандартом может дать 3.

Есть. 6.5.6.

The result of the binary + operator is the sum of the operands.
monk ★★★★★
() автор топика