Частичная оценка / специализация с LLVM-gcc или gcc - PullRequest
5 голосов
/ 03 марта 2011

Я заинтересован в (частичной) оценке времени компиляции для c / c ++ (не с параметрами шаблона, как в c ++).Давайте рассмотрим следующий случай (взят из [1]):

double mypower(double x, int n) {
  int i;
  double ret = x;
  for (i = 1; i < n; i++) {
    ret *= x;
  }
  return ret;
}

Затем вы вызываете эту функцию где-то в коде с помощью:

mypower(x,3); // y varies all the time, 

Затем компилятор может оптимизировать это (например,цикл раскатывания).Некоторые часто используемые функции, которые я использую, могут действительно выиграть от этой оптимизации (проверено созданием специализированной функции вручную).В презентации [1] описывается процесс, в котором функция ищется и заменяется специализированной версией функции.Это похоже на работу.Но это не кажется универсальным, код должен быть написан для функций, которые должны быть заменены.

Презентация, похоже, с 2008 года, я не смог найти ничего существенного больше информации, чем в этом источнике.Так что-нибудь улучшилось с тех пор?Я бы предпочел какой-то автоматизм, который делает то же самое для всех функций, возможно, управляемых синтаксисом атрибута (например, __attribute__(peval) ...).Далее я хотел бы, чтобы то же самое работало для объектно-ориентированного кода, создавая специализированные классы для различных объектов ([2], кажется, предполагает, что это невозможно).

Кроме того, я хотел бы, чтобы эта специализация работала не только для констант, найденных в коде.Я думаю о программе, скомпилированной для LLVM IR (байт-код) может сделать следующее:

  1. Запуск программы во время фазы инициализации в интерпретаторе, во время этой фазы инициализации программа может прочитать некоторыеКонфигурация из файла.После инициализации интерпретатор останавливается.

  2. Некоторые переменные (включая переменные-члены) фиксируются с этого момента.Извлеките эти переменные (например, помеченные атрибутом во время компиляции).

  3. Создание специализированных функций и классов.Клонируйте их в байт-код.

  4. Запустите JIT для создания собственного машинного кода.

Это много, что я прошу, и только несколько вычисленийИнтенсивные программы выиграют от такой оптимизации.Но некоторые люди должны работать над этим.Я, вероятно, просто не знаю подходящих поисковых терминов для подачи в Google.

Примечание. Пожалуйста, не предлагайте шаблоны классов с нетиповыми параметрами или ручной специализацией, я уже это делаю.Я просто предпочел бы, чтобы компилятор выполнял эту работу за меня.

Ссылки:

[1] Презентация, как выполнить частичную оценку в LLVM

[2] Форумное сообщение о частичной оценке

Ответы [ 2 ]

1 голос
/ 22 марта 2011

Это в основном на арене межпроцедурных оптимизаций. У llvm есть несколько из них, в частности, распространение IP-констант, которое поможет, если вы используете mypower (x, 3) на всех сайтах вызовов в модуле перевода. То, что вы описываете, возможно, но на самом деле еще не сделано. Улучшение прохода IPCP - это то, что вы хотели бы изучить, сделав его клонирующим и специализирующим функцию на определенном сайте вызовов. Это может, если у вас достаточно блоков перевода, привести к довольно большому раздутию кода, поэтому люди и не задумывались над этим.

Вероятно, это еще более полезно на уровне LTO, когда вы можете просматривать все вызовы в программе.

0 голосов
/ 24 марта 2011

Вы можете сделать это, используя преобразования источника в источник.

Наш комплект реинжиниринга программного обеспечения DMS может быть использован для реализации этого. DMS использует явные определения языка для синтаксического анализа исходного кода в AST, довольно распечатки AST обратно в исходный код, предоставляет различные виды таблиц символов, возможности управления / потока данных и предоставляет возможность преобразования, позволяющую создавать собственные преобразователи исходного кода. DMS имеет множество внешних интерфейсов для разных языков , включая C и C ++ с полными препроцессорами.

Чтобы выполнить свою задачу с помощью DMS, вы должны использовать синтаксический анализатор C для анализа всего кода вашей системы (потому что вы должны проверять все сайты вызовов на предмет частичной специализации). Вам необходимо определить способ указать частичную оценку, которую вы хотите; Один из способов, как вы предложили, - написать вызов функции с аргументами, привязанными к константе, но вы можете обобщить это на аргументы, привязанные к произвольным выражениям. Такая спецификация может быть проанализирована анализатором паттернов DMS, который может обрабатывать произвольные нетерминалы lnaguage, например, вызов функции: -} Вам нужно где-то парковать эти спецификации; возможно, в качестве дополнительного внешнего файла или в виде комментариев на рассматриваемых сайтах вызовов или рядом с ними.

При анализе спецификации частично-eval вам нужно найти имя вызова функции, чтобы определить действительную интересующую функцию; это где-то в этом стеке источников, и таблица символов облегчит его поиск. При наличии сайта вызова со специализацией AST для идентифицированной функции может быть реплицирован, а аргументы заменены; используя, вероятно, только небольшое количество преобразований, но вы должны следить за захватом аргумента лексической областью внутри специализированной функции. Чтобы обойти это, могут потребоваться дополнительные преобразования. После создания нового имени и сокращенного списка аргументов для указанной функции необходимо повторно вставить его AST рядом с исходным сайтом определения функции, соответствующим образом изменить сайт вызова и выплюнуть измененные AST. Независимо от того, хотите ли вы добавить дополнительные преобразования в циклы развертывания для особых случаев или что-то еще, что вас интересует, также практично.

DMS использовался для выполнения масштабных преобразований в коде C и C ++; это кажется "технически" легким. Есть небольшой вопрос знакомства с таким инструментом, как DMS; там есть хорошая кривая обучения.

...