SAPFOR представляет из себя набор проходов (фаз) анализа и преобразования. Каждый проход является отдельным и самодостаточным и выполняется над всеми файлами проекта. Проходы могут иметь зависимости и связи между собой. Например, для построения графа вызовов функций, требуется построение графа циклов.
Структура проекта предполагает разделение анализа и преобразований на группы. Каждая группа должна содержать реализацию анализа (или анализов) и всю необходимую инфраструктуру. Так, (прим. данная информация уже устарела на начало 2018 года)
- DirectiveAnalyzer содержит алгоритмы анализа уже построенных директив,
- Distribution содержит алгоритмы построения распределения данных и генерации директив. Также данная группа содержит в себе реализацию графа CSR для построения графа массивов.
- ExpressionTransform содержит алгоритмы анализа и преобразования индексных выражений массивов
- GraphCall содержит структуру и алгоритмы построения графа вызовов процедур
- GraphLoop содержит структуру и алгоритмы построения графа циклов
- LoopAnalyzer содержит алгоритмы анализа циклов и массивов исходной программы пользователя.
- LoopConverter содержит алгоритм преобразования циклов с метками к DO – END DO виду
- ParallelizationRegion содержит структуру и алгоритмы для работы с областями распараллеливания
- PrivateAnalyzer содержит алгоритмы анализа приватных переменных для тех циклов, у которых есть DVMH директива. Реализация данных алгоритмов используется из компилятора FDVM.
- SageExtensions содержит алгоритмы поиска зависимостей по массивам и скалярам с помощью омега теста. Ищутся приватные переменные, редукционные переменные по скалярам, а также зависимости по массивам - классифицируется тип и длина зависимости.
- VerificationCode содержит алгоритмы проверки исходного кода на предмет несоответствия ограничениям SAPFOR
- VisualizerCalls содержит функции обертки для вызова алгоритмов SAPFOR и передачи информации в визуализатор, написанный на C#/Java. В этом случае SAPFOR собирается как DLL библиотека. Для локальной работы и отладки данная функциональность не нужна и может быть отключена или исключена из сборки. В последней версии SAPFOR собирается также в EXE файл и взаимодействует с промежуточным компонентом между визуализатором и SAPFOR - сервером.
- transforms.cpp - главный файл SAPFOR, в котором происходит запуск определенных фаз анализа и преобразований. В файле transform.h содержится перечисление всех доступных фаз анализа и преобразований.
- и др ...
Рассмотрим некоторые простые проходы. Проход, который называется VERIFY_ENDDO, выполняет проверку соответствия всех циклов программы формату DO – END DO (циклов без метки). Реализация данного прохода находится в файле VerificationCode/LoopChecker.cpp и представляет собой простой проход по всем файлам, а в каждом файле по всем функциям и всем операторам функции с целью поиска операторов цикла и проверки данного цикла на соответствие DO – END DO с помощью встроенного в Sage++ алгоритма isEnddoLoop(). В случае несоответствия происходит накопление ошибочных циклов (а именно - номеров строк) для последующей выдачи ошибки.
Запуск данного прохода происходит в файле transforms.cpp. В функции main происходит считывание опций, введенных из консоли и запуск выбранного прохода на выполнение с помощью функции runPass. Последняя функция также используется для запуска проходов из визуализатора. В данной функции происходит открытие проекта, если он еще не открыт. В момент открытия проекта выполняются некоторые дополнительные проходы, которые проверяют некоторые свойства программы. В данный момент выполняется и проход VERIFY_ENDDO. После создания проекта в зависимости от того, какой проход был выбран, выполняются дополнительные проходы, которые необходимы для выполнения выбранного. Проходы запускаются с помощью функции runAnalysis. Последняя функция выполняет проход по всем файлам проекта и запускает конкретно выбранный проход по программе.
Некоторые проходы могут быть выполнены только над областями распараллеливания. Областей распараллеливания может быть несколько, поэтому необходимо выполнять проходы для всех пользовательских областей распараллеливания. Всегда существует область распараллеливания по умолчанию (вся программа), если никаких других областей в программе не было задано.
Более сложный проход PREPROC_SPF выполняет поиск директив SAPFOR !$SPF в программе пользователя и переводит данные директивы в атрибуты того оператора, к которому они привязаны (следующий оператор в лексическом порядке). Атрибуты являются некоторым "складом" информации любого вида для каждого узла дерева разбора. Атрибуты не сохраняются в дереве разбора после завершения работы с ним и существуют только в момент работы с деревом разбора в памяти. Они сохраняются на все время работы с открытым проектом, они могут быть добавлены или удалены у соответствующего узла дерева разбора. Также, атрибуты никак не отображаются в исходном коде программы при генерации кода по дереву разбора.