Skip to content

Шурыгин Сергей. Лабораторная работа 3: Backend. Вариант 4. #48

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 47 commits into from

Conversation

PutinVVV
Copy link

  • Цель: Ускорить вычисления вида c - (a * b) на процессорах x86-64 с поддержкой FMA (Fused Multiply-Accumulate).
  • Что делает: Находит в коде последовательность инструкций "умножение + вычитание" (например, VMULSS + VSUBSS).
  • Как оптимизирует: Заменяет эти две инструкции одной специальной FMA-инструкцией (VFNMADD), которая выполняет обе операции за один шаг.
  • Результат: Меньше инструкций и потенциально более быстрый код.

Kuznetsov-Artyom and others added 30 commits February 14, 2025 07:49
1) Move resources
2) Add status build
Вариант 4.
Добавить к статическим, локальным,глобальным объектам и параметрам
функции
соответствующие префиксы (static_, local_, global_, param_).

> Код автоматически переименовывает переменные, добавляя префиксы, и
выводит изменённый исходный код.

**ExampleVisitor**: Просматривает объявления переменных (**VarDecl**),
параметров (**ParmVarDecl**) и выражений ссылок на объявления
(**DeclRefExpr**), добавляя к именам префиксы в зависимости от типа
переменной.

---------

Co-authored-by: Sergey <[email protected]>
This Clang plugin analyzes C++ user-defined types (classes/structs)
using LLVM/Clang's AST traversal capabilities.

### Functionality:
- Extracts class inheritance chains
- Lists fields with types/access modifiers
- Identifies methods with signatures, qualifiers (const/noexcept), and
special properties (virtual/override/pure)

### LLVM/Clang APIs Used:
- `RecursiveASTVisitor` for deep AST traversal
- `CXXRecordDecl` for class declarations
- `CXXBaseSpecifier` for inheritance info
- `FieldDecl`/`CXXMethodDecl` for member analysis

### Workflow:
- Registers as FrontendPlugin
- Traverses Translation Unit AST
- Filters implicit/compiler-generated elements
- Outputs structured type info via LLVM's raw_ostream
…-complr-tech#8)

Решение реализует плагин для Clang, который анализирует исходный код на
предмет неявных преобразований типов. Он использует RecursiveASTVisitor
для обхода абстрактного синтаксического дерева (AST) и отслеживает
преобразования типов в выражениях. Каждый случай неявного преобразования
фиксируется с указанием исходного и целевого типов, а также их порядка в
пределах функции. Результаты выводятся по функциям, где для каждого
преобразования указывается количество. Плагин сортирует и выводит
информацию о преобразованиях для каждого метода.
The task was to analyze user-defined classes and structures
(user-defined types)

For user-defined types, the base types are defined

The type and access modifier are defined for fields.

The methods are defined by the return type and the types of parameters
they accept, the access modifier, virtual, pure virtual, or override.

Implicitly created methods are ignored
…lr-tech#11)

Плагин выводит имя класса или структуры, указывает, является ли тип
структурой или классом, а также является ли он шаблонным, перечисляет
все поля и методы класса, указывая их имена, типы и спецификаторы
доступа, а для методов дополнительно выводит информацию о том, является
ли метод виртуальным, перегруженным оператором или чисто виртуальным.
При наличии базовых классов плагин выводит их имена и спецификаторы
доступа (public, protected, private).
…-tech#9)

**ПОСТАНОВКА ЗАДАЧИ**
Разработать Clang плагин с использованием AST для добавления префиксов к
переменным узлов
следующих типов: VarDecl, DeclRefExpr, ParmVarDecl. Плагин должен
успешно находить объявления переменных
,добавлять префиксы к ним и выводить изменённый код.

**ОПИСАНИЕ РЕШЕНИЯ**
Для обхода AST необходимо использовать стандартный шаблон Clang плагина,
указанный в файлах PR.
Перед обходом следует создать Rewriter - инструмент-модификатор кода
программы, который будет изменять префиксы переменных, в классе
FindNamedClassAction и затем передать в FindNamedClassConsumer для
использования в каждой Translation Unit. Далее в соответствующих
методах, начинающихся с Visit, обнаружить декларации переменных и
определить их область видимости: static, local, global и т.д После
обнаружения создаётся новый префикс и с помощью метода ReplaceText
Rewriter модифицируется исходный код.

**СПИСОК ИЗМЕНЕНИЙ**
- Переименована переменная класса Rewriter;
- Названия директорий л/р приведены в соответствие требованиям;
- Убран артефакт // в файле с плагином;
- Дублирование кода в файле с плагином значительно устранено;
- Тест усложнён: добавлены дополнительные CHECK;
- Нестрогая проверка строк изменена на строгую;
- Добавлены пустые строки в конец файлов с плагином и тестом;
- В контексте функции добавления префиксов теперь возвращается
спецзначение ;
в том случае, если не удалось определить область видимости переменной;
- Исключено дублирование обработки префиксов для параметров функции;
- Установлен правильный порядок проверок области видимости переменных;
- Обобщена обработка узлов VarDecl, DeclRefExpr, ParmVarDecl в одном
методе;
- Бесполезные методы убраны из кода;
…plr-tech#7)

Плагин обходит абстрактное синтаксическое дерево (AST) программы,
используя механизм `RecursiveASTVisitor`. Класс `ImplicitConvVisitor`
перехватывает узлы `ImplicitCastExpr`, соответствующие неявным
преобразованиям. Игнорируются преобразования, не влияющие на семантику
такие как `LValueToRValue`, `NoOp`, `FunctionToPointerDecay`. Для
каждого преобразования извлекаются исходный и целевой типы, а также
контекст — функция, где оно произошло. Статистика сохраняется в виде
отображения `[функция -> (тип_источник -> тип_цель) -> количество]`.
После обхода AST результаты выводятся в стандартный поток ошибок,
включая общее число преобразований.
…omplr-tech#13)

Clang плагин `CastCounter` реализует одноимённый класс, наследованный от
`RecursiveASTVisitor` и выполняющий обход AST, выявляя случаи неявного
приведения типов. В классе `CastCounter` реализованы методы:

- `VisitFunctionDecl`, получающий имя функции, в которую попали при
обходе;

- `VisitCXXConstructExpr`, проверяющий случаи, когда аргумент передаётся
в конструктор и вызывает преобразование

- `VisitImplicitCastExpr`, анализирующий неявные преобразования
(игнорирует LValueToRValue, FunctionToPointerDecay)

- `getResult` выводит информацию о найденных преобразованиях.

Информация о преобразованиях содержится в мапе `CastMap`. Класс
`CastCounterConsumer` управляет запуском обхода AST и вызывает
`getResult`. Класс `CastCounterAction` регистрирует плагин в компиляторе
Clang.

Тест для плагина выполнен согласно образцам `example`.
…mplr-tech#18)

Плагин ClangAST_4 для Clang автоматически добавляет префиксы (static_,
global_, local_, param_) к именам переменных и параметров функций, чтобы
обозначить их область видимости. Он использует RecursiveASTVisitor для
обхода AST и Rewriter для изменения кода. PrefixVisitor выполняет анализ
и переименование, PrefixConsumer запускает обработку, а PrefixAction
управляет работой плагина и выводит измененный код.
…mplr-tech#15)

Плагин анализирует пользовательский тип данных, определяя, обладает ли
структура наследованием, содержит ли поля и методы. При наличии
элементов выводится их описание: тип данных, уровень доступа, а также
характеристики методов — виртуальные, чисто виртуальные или
переопределенные.

---------

Co-authored-by: Arseniy Obolenskiy <[email protected]>
…ech#30)

Код реализует плагин для Clang, который анализирует неявные
преобразования типов в исходном коде. Он посещает функции и выражения,
такие как неявные преобразования, касты и конструкторы, чтобы
отслеживать, какие типы преобразуются друг в друга. Когда обнаруживается
преобразование типов, оно записывается в список. Плагин выводит отчет о
том, какие функции выполняют неявные преобразования типов, с указанием
исходного и целевого типов.
…omplr-tech#21)

Плагин использует возможности Clang для обхода абстрактного
синтаксического дерева (AST) и регистрирует все случаи неявных
преобразований, происходящих в коде. При каждом неявном преобразовании
плагин фиксирует типы, участвующие в преобразовании, и подсчитывает их
количество для каждой функции. Результаты анализа выводятся для каждой
функции, отображается имя и список неявных преобразований с
соответствующими количествами.
…omplr-tech#12)

Данный плагин выводит информацию о пользовательском типе данных:
является ли структура наследственной, имеет ли какие-либо поля и методы
и, если имеет, выводит информацию о них(тип данных, уровень доступа,
является ли метод виртуальным/чисто виртуальным/переопределенным)

---------

Co-authored-by: Kuznetsov-Artyom <[email protected]>
…-complr-tech#14)

Реализован Clang плагин, который добавляет к статическим, локальным,
глобальным объектам и параметрам функции
соответствующие префиксы (static_, local_, global_, param_). 

Класс PrefixVisitor обходит AST (Abstract Syntax Tree) с помощью
RecursiveASTVisitor и добавляет префиксы к переменным и параметрам в
зависимости от их типа, а также обновляет имена переменных в вызовах
функций, чтобы они соответствовали новым именам с префиксами.

**Используемые API LLVM/Clang:**

- RecursiveASTVisitor для обхода AST
- VarDecl для работы с переменными
- ParmVarDecl для работы с параметрами функций
- CallExpr для анализа вызовов функций
- Rewriter для модификации исходного кода

---------

Co-authored-by: Arseniy Obolenskiy <[email protected]>
Co-authored-by: Aleksey <[email protected]>
…omplr-tech#17)

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

---------

Co-authored-by: Arseniy Obolenskiy <[email protected]>
…lr-tech#19)

## General
Реализован плагин для clang который работает с abstract syntax tree,
который строит clang во время frontend-analysis исходного кода.
## Specific
Наш плагин умеет различать пользовательские типы данных, анализировать
их и принтить их:
- Имена
- Struct или class
- Структуру наследования
- Поля
- - Модификаторы доступа
- - Типы
- Методы
- -Возвращаемое значение
- -Квалификаторы доступа
- -Являются ли методы 
- - - Виртуальными
- - - Чисто виртуальными
- - - Перегруженными
- - - Статическими

---------

Co-authored-by: Torcna <[email protected]>
Co-authored-by: Arseniy Obolenskiy <[email protected]>
…plr-tech#31)

Реализация плагина Clang, анализирующий исходный код C++ и подсчитывает
количество неявных преобразований типов (implicit casts) в функциях. Он
использует Clang AST (Abstract Syntax Tree) для обхода узлов и сбора
статистики. Не учитываются неявные преобразования укзателей функций. Для
тестирования плагина были написаны lit тесты.

---------

Co-authored-by: Arseniy <>
…NN-complr-tech#36)

Плагин обходит абстрактное синтаксическое дерево (AST) программы,
используя механизм `RecursiveASTVisitor`. Класс `ImplicitConvVisitor`
перехватывает узлы `ImplicitCastExpr`, соответствующие неявным
преобразованиям. Игнорируются преобразования, не влияющие на семантику
такие как `LValueToRValue`, `NoOp`, `FunctionToPointerDecay`. Для
каждого преобразования извлекаются исходный и целевой типы, а также
контекст — функция, где оно произошло. Статистика сохраняется в виде
отображения `[функция -> (тип_источник -> тип_цель) -> количество]`.
После обхода AST результаты выводятся в стандартный поток ошибок,
включая общее число преобразований.
revert: NN-complr-tech#29
Была проведена замена std::map на llvm:MapVector, так как
llvm::MapVector сохраняет порядок вставки функций в AST. Это
гарантирует, что при выводе функции будут перечислены в том же порядке,
в котором они встречались в исходном коде, что исключит дальнейшее
появление ошибок
…mplr-tech#32)

Реализован Clang-плагин, который автоматически добавляет префиксы к
именам переменных в исходном коде в зависимости от их области видимости.
Используя RecursiveASTVisitor, он обходит AST, находит объявления
переменных (VarDecl, ParmVarDecl) и ссылки на них (DeclRefExpr). Метод
determinePrefix определяет нужный префикс: global_, local_, static_,
param_. Rewriter переименовывает переменные в исходном коде.
PrefixConsumer запускает обход AST, а PrefixAction инициализирует
Rewriter и записывает изменения в выходной поток.

---------

Co-authored-by: Alexey-Solovev <[email protected]>
Co-authored-by: Kuznetsov-Artyom <[email protected]>
…omplr-tech#33)

Плагин использует возможности Clang для обхода абстрактного
синтаксического дерева (AST) и автоматического изменения исходного кода
на основе анализа структуры программы. Префиксы добавляются в процессе
обхода AST с помощью класса ExampleVisitor, который проверяет тип и
область видимости переменной. В зависимости от того, является ли
переменная локальной, статической, глобальной или параметром функции, к
её имени добавляется соответствующий префикс (local_, static_, global_,
param_). Изменения выполняются через clang::Rewriter, который заменяет
старые имена на новые в исходном коде.
…plr-tech#37)

Реализован плагин, который добавляет к именам статических, глобальных,
локальных переменных соответственно префиксы static_, global_, local_ и
к именам параметров функций - префикс param_.

Плагин изменяет имена не только при объявлении переменной, но и везде,
где эта переменная используется.
Также плагин может принимать при запуске два аргумента командной строки:
--help - выводит описание плагина и список аргументов, которые плагин
умеет принимать;
--no-log - отключает логирование каждого места, в котором прошло
изменение имени переменной или параметра.

---------

Co-authored-by: root <root@MSI>
Вариант 2 на compiler explorer:
https://compiler-explorer.com/z/P6z8G1M9x
Проходим по дереву с помощью recursive visitor. Как только попадаем в
объявление параметров функции или объявление переменной, то проверяем
используется переменная или нет, а также есть ли уже атрибут
[[maybe_unused]]. Если переменная не используется и атрибута еще нет, то
добавляем атрибут. Код переписывается с помощью интерфейса rewriter. В
конце берем готовый буфер из rewriter и перенаправляем его в вывод.
Тесты включают в себя проверку глобальной переменной, проверку
параметров функции и тела функции, а также переменной, уже помеченной
как Unused. Дополнительно реализован флаг --help, позволяющий узнать
подробнее про данный плагин.
DSolo03 and others added 17 commits March 20, 2025 14:07
…plr-tech#16)

Плагин обходит все переменные и параметры функций и если данная
переменная не используется, то помечает ее аттрибутом `maybe_unused`.
После этого, плагин обходит все функции, делая `dump` их AST.
Обход реализован двумя обходчиками: `UnusedVisitor` и `DumpVisitor`.
Сначала вызывается `UnusedVisitor`, который помечает переменные и
параметры функций, а затем вызывается `DumpVisitor` выводящий `dump` AST
для всех функций, для проверки наличия аттрибута `maybe_unused` при
помощи тестов.
…-tech#40)

This Clang plugin analyzes C++ classes and prints their inheritance,
fields, and methods.

1. **ClassInfoVisitor**

- Traverses the AST, finds class declarations, and checks their
definitions.
- Outputs the class name, base classes, fields, and methods.

**Processing methods:**

- **PrintBaseClassesInfo()** – prints the list of base classes.
- **PrintFieldsInfo()** – displays fields with their types and access
specifiers.
- **PrintMethodsInfo(**) – prints methods with their parameters, return
type, and specifiers (virtual, override, const).

2. **ClassInfoConsumer** – initiates AST traversal.

3. **ClassInfoAction** – registers the plugin in Clang.
…lr-tech#39)

Проверка неиспользуемых переменных, если такие имеются, выводится UNUSED
VAR
…r-tech#54)

Цель лабораторной работы: с помощью механизма обхода AST переименовать
переменные в соответствии со следующим правилом:
- для локальных переменных добавляется приставка `local_`
- для глобальных переменных добавляется приставка `global_`
- для статических переменных добавляется приставка `static_`
- для параметров функции добавляется приставка `param_`

Основной задействованный функционал:
- `VisitVarDecl` - обрабатывает объявления переменных
- - проверяет валидность имени переменной
- - конструирует новое имя
- - заменяет исходное имя на новое
- - сохраняет имя в `unordered_map` `rewrittenDecl`
- `VisitParmVarDecl `- обрабатывает объявления параметров функций
(аналогично `VisitVarDecl`)
- `VisitDeclRefExpr `- обрабатывает ссылки на переменные (заменяет на
соответствующее имя из `rewrittenDecl`)

---------

Signed-off-by: Mikhail Ivanov <[email protected]>
…plr-tech#51)

Плагин проходится по всем параметрам и переменным программы. Если
переменная нигде не используется, то она помечается флагом
[[maybe_unused]].

---------

Co-authored-by: m-ly4 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.