ROSE 编译器框架/ROSE 工具
ROSE 是一个编译器框架,用于构建定制的基于编译器的工具。作为 ROSE 版本的一部分,提供了一组示例工具来演示 ROSE 的使用。其中一些对 ROSE 开发人员的日常工作也很有用。
我们列出并简要解释一些使用 ROSE 构建的工具。它们安装在 ROSE_INSTALLATION_TREE/bin 下。
- 有些工具默认情况下未安装。您可能需要 cd 到工具的子目录并键入 "make install"
任何 ROSE 工具(转换器)都像编译器一样工作。您必须提供所有必要的编译标志才能使其正常工作。您必须指定一些包含路径和/或一些要定义的宏。
- 使用 rose 工具的一种方法是在您的 Makefile 中将您的默认编译器(例如 gcc)替换为 rose 工具命令(identityTranslator、outline 等)。因此,当您键入 "make" 时,将在调用该工具时使用所有正确的标志。
- 或者,如果您只对处理单个文件感兴趣。您可以在正常的 "make" 期间手动查看用于编译该单个文件的完整编译命令行(例如 gcc .... -c)。然后,在命令行中将您的编译器 (gcc) 替换为您感兴趣的 rose 工具(例如 outline)。
您必须首先通过键入 configure、make、make install 等来安装 ROSE。
您还必须在从命令行调用 ROSE 工具之前正确设置环境变量。
例如:如果安装路径(或 configure 中的 --prefix 路径)为 /home/opt/rose/install,您可以使用 bash 编写以下脚本以设置环境变量
ROSE_INS=/home/opt/rose/install export ROSE_INS PATH=$ROSE_INS/bin:$PATH export PATH LD_LIBRARY_PATH=$ROSE_INS/lib:$LD_LIBRARY_PATH export LD_LIBRARY_PATH
所有 ROSE 工具都安装在 --prefix 选项指定的路径下。
来源:http://www.rosecompiler.org/ROSE_Tutorial/ROSE-Tutorial.pdf(第 2 章)
这是使用 ROSE 构建的最简单的工具。它接收输入源文件,构建 AST,然后将 AST 重新解析回可编译的源代码。它尽力保留来自输入文件的所有内容。
典型用例
- 没有任何选项,测试 ROSE 是否可以编译您的代码:将您的 Makefile 使用的编译器替换为 identityTranslator
- 打开一些内置的分析、转换或优化阶段,例如 -rose:openmp:lowering 来支持 OpenMP
- 键入 "identityTranslator --help" 以查看所有选项
- 调试基于 ROSE 的转换器:第一步通常是使用 identityTranslator 来排除使用 ROSE 时是否为编译问题
- 使用 identityTranslator 的源代码作为起点来添加自定义分析和转换。identityTranslator 中的代码实际上是几乎所有类型的基于 ROSE 的工具所需的最小代码。
identityTranslator.c
#include "rose.h"
int main(int argc, char *argv[]){
// Build the AST used by ROSE
SgProject *project = frontend(argc, argv);
// Run internal consistency tests on AST
AstTests::runAllTests(project);
// Insert your own manipulation of the AST here...
// Generate source code from AST and call the vendor's compiler
return backend(project);
}
从版本 0.9.9.83 开始,ROSE 具有支持外部插件的新功能。它借用了 Clang 插件 的设计和实现。该接口与 Clang 非常相似,但简化并改进了一些。
使用此功能,您可以将基于 ROSE 的工具开发为动态可加载插件。然后,您可以使用 ROSE 的默认转换器 identityTranslator(或另一个 ROSE 转换器)的命令行选项来
- 加载包含插件的共享库,
- 指定要执行的操作,
- 以及将命令行选项传递给每个操作。
更多信息请访问
由于 ROSE 使用的前端和一些内部处理的限制,identityTranslator 无法生成与输入文件完全相同的输出。
它可能引入的一些显着更改包括
- "int a, b, c;" 被转换为三个 SgVariableDeclaration 语句,
- 宏被展开。
- 在 typedef 类型的常量周围添加了额外的括号(例如,c=Typedef_Example(12); 在输出中被转换为 c = Typedef_Example((12));)
- 将 NULL 转换为 0。
以点格式生成 AST 图的工具。有两个版本
- dotGenerator:简单的 AST 图生成器,显示基本节点和边
- dotGeneratorWholeASTGraph:完整的 AST 图,显示更多详细信息。它提供过滤器选项以显示/隐藏某些 AST 信息。
命令行
dotGeneratorWholeASTGraph yourcode.c // it is best to avoid include any header into your sample code to have a small enough tree to visualize!
./dotGeneratorWholeASTGraph -rose:help | more -rose:help show this help message -rose:dotgraph:asmFileFormatFilter [0|1] Disable or enable asmFileFormat filter -rose:dotgraph:asmTypeFilter [0|1] Disable or enable asmType filter -rose:dotgraph:binaryExecutableFormatFilter [0|1] Disable or enable binaryExecutableFormat filter -rose:dotgraph:commentAndDirectiveFilter [0|1] Disable or enable commentAndDirective filter -rose:dotgraph:ctorInitializerListFilter [0|1] Disable or enable ctorInitializerList filter -rose:dotgraph:defaultFilter [0|1] Disable or enable default filter -rose:dotgraph:defaultColorFilter [0|1] Disable or enable defaultColor filter -rose:dotgraph:edgeFilter [0|1] Disable or enable edge filter -rose:dotgraph:expressionFilter [0|1] Disable or enable expression filter -rose:dotgraph:fileInfoFilter [0|1] Disable or enable fileInfo filter -rose:dotgraph:frontendCompatibilityFilter [0|1] Disable or enable frontendCompatibility filter -rose:dotgraph:symbolFilter [0|1] Disable or enable symbol filter -rose:dotgraph:emptySymbolTableFilter [0|1] Disable or enable emptySymbolTable filter -rose:dotgraph:emptyFunctionParameterListFilter [0|1] Disable or enable emptyFunctionParameterList filter -rose:dotgraph:emptyBasicBlockFilter [0|1] Disable or enable emptyBasicBlock filter -rose:dotgraph:typeFilter [0|1] Disable or enable type filter -rose:dotgraph:variableDeclarationFilter [0|1] Disable or enable variableDeclaration filter -rose:dotgraph:variableDefinitionFilter [0|1] Disable or enable variableDefinitionFilter filter -rose:dotgraph:noFilter [0|1] Disable or enable no filtering Current filter flags' values are: m_asmFileFormat = 0 m_asmType = 0 m_binaryExecutableFormat = 0 m_commentAndDirective = 1 m_ctorInitializer = 0 m_default = 1 m_defaultColor = 1 m_edge = 1 m_emptySymbolTable = 0 m_expression = 0 m_fileInfo = 1 m_frontendCompatibility = 0 m_symbol = 0 m_type = 0 m_variableDeclaration = 0 m_variableDefinition = 0 m_noFilter = 0
有关如何使用这些工具的更多信息,请访问 操作方法
基本概念:概述是指将一段连续语句替换为对包含这些语句的新函数的函数调用的过程。从概念上讲,概述是内联的反向操作。
ROSE 提供了一个名为 AST 概述的内置转换器,它可以概述代码的指定部分并从中生成一个函数。
- AST 概述的官方文档位于 ROSE 教程的第 37 章使用 AST 概述中。 pdf.
- 补充信息可以在此处找到 ROSE 编译器框架/概述
通常,基于 ROSE 的工具在处理大型应用程序时可能会遇到一些问题。用户可能希望让工具继续运行,直到处理完成,并且他们可以检查最终结果,了解有多少源文件成功处理或未成功处理。这类似于 GNU make 的 -k 选项,通过使用该选项,make 会尝试编译所有可以尝试的文件,并显示尽可能多的编译错误。
ROSE 具有内置的 -rose:keep_going 支持。如果启用此功能,并且发生错误,ROSE 将简单地按照原样在您的原始源代码文件上运行您的后端编译器,而不会进行任何修改。
为了进一步简化 -rose:keep_going 的使用,我们提供了 Rose::KeepGoing 命名空间,该命名空间在内部
- 使用 -rose:keep_going,并跟踪成功处理或失败的文件,以及
- 将此类信息保存到日志文件。
创建了一个名为 KeepGoingTranslator 的示例转换器来演示此命名空间的使用。
总而言之,有三个级别的持续支持
- GNU make 的 -k 选项作为构建系统的一部分
- ROSE 的 -rose:keep_going 选项,独立于构建系统。
- Rose::KeepGoing 命名空间,具有额外的日志记录支持
要使用内置支持为每个文件记录消息
# specify where to store success and error logs Rose::KeepGoing::report_filename__fail = boost::filesystem::path(getenv("HOME")).native()+"/mytool-failed_files.txt"; Rose::KeepGoing::report_filename__pass = boost::filesystem::path(getenv("HOME")).native()+"/mytool-passed_files.txt"; # in your tool's traversal, add log messages SgSourceFile* file = getEnclosingSourceFile(forloop); string s(":"); string entry= forloop->get_file_info()->get_filename()+s+oss.str(); // add full filename to each log entries Rose::KeepGoing::File2StringMap[file]+= entry; # in your main(), handle errorss int main ( int argc, char* argv[]) { ... vector<string> argvList(argv, argv+argc); argvList = commandline_processing (argvList); if (CommandlineProcessing::isOption (argvList,"-E","",false)) { preprocessingOnly = true; // we should not put debugging info here. Otherwise polluting the generated preprocessed file!! } SgProject* project = frontend(argvList); ROSE_ASSERT (project != NULL); // register midend signal handling function if (KEEP_GOING_CAUGHT_MIDEND_SIGNAL) { std::cout << "[WARN] " << "Configured to keep going after catching a " << "signal in myTool" << std::endl; Rose::KeepGoing::setMidendErrorCode (project, 100); goto label_end; } else { // Your own traversal for analysis or transformation RoseVisitor visitor; SgFilePtrList file_ptr_list = project->get_fileList(); for (size_t i = 0; i<file_ptr_list.size(); i++) { SgFile* cur_file = file_ptr_list[i]; SgSourceFile* s_file = isSgSourceFile(cur_file); if (s_file != NULL) { visitor.traverseWithinFile(s_file, preorder); } } } label_end: # write log files int status = backend(project); // important: MUST call backend() first, then generate reports. // otherwise, backend errors will not be caught by keep-going feature!! // We want the reports are generated with or without keep_going option // if (MyTool::keep_going) { std::vector<std::string> orig_rose_cmdline(argv, argv+argc); Rose::KeepGoing::generate_reports (project, orig_rose_cmdline); } return status; }
更多信息请访问 ROSE_Compiler_Framework/Inliner
ROSE 内联器在函数调用点内联函数。
关于内联器的官方文档是
- 第 36 章“调用 ROSE 的内联器”教程:http://rosecompiler.org/ROSE_Tutorial/ROSE-Tutorial.pdf
源代码
包含示例翻译器和测试输入文件的测试目录
通过查看 Makefile.am,示例翻译器的源代码将在您的构建树中生成一个名为“inlineEverything”的可执行文件。
您可以使用此工具尝试内联您的示例代码。
相同的 Makefile.am 的 make check 规则包含用于使用该工具的示例命令行。
此工具的源代码
命令行
buildCallGraph -c yourprogram.cpp
命令行
virtualCFG -c yourprogram.c
这是一个可以将 OpenMP 指令自动插入输入串行 C/C++ 代码的工具
该工具是使用 OpenMP 进行自动并行化的实现。它用于探索语义感知自动并行化,如我们的论文* 中所述。
- 源文件当前位于 rose/projects/autoParallelization 中。
- 一个独立的可执行程序(名为 autoPar)被生成并安装到 ROSE 的安装树中(在 ROSE INS/bin 下)。
- 您可以在 rose_build_tree/projects/autoParallelization 中通过键入“make check”来测试该工具
- ROSE 手册中有一节介绍pdf:12.7 自动并行化
出版物
- Chunhua Liao、Daniel J. Quinlan、Jeremiah J. Willcock 和 Thomas Panas,使用高级抽象的现代应用程序的语义感知自动并行化,并行编程杂志,第 38 卷,第 5-6 期,361-378,2010 年 8 月 23 日 LLNL-JRNL-421803
- Chunhua Liao、Daniel J. Quinlan、Jeremiah J. Willcock 和 Thomas Panas,将自动并行化扩展到优化面向多核的高级抽象,在第 5 届 OpenMP 国际研讨会论文集:在极端并行时代发展 OpenMP(德国德累斯顿,2009 年 6 月 3 日至 5 日)。
更多信息请访问 autoPar
这项工作用于自动调整以及其他工具,这些工具将对源代码的引用作为接口的一部分传递。
- 它本质上定义了创建字符串以唯一标识源代码中语言结构的方法
- 然后,任何工具都可以定位 AST 中的相应节点,并为您执行目标分析或转换。
关键信息
- 文档:ROSE 教程的第 46 章:http://rosecompiler.org/ROSE_Tutorial/ROSE-Tutorial.pdf
- 头文件:https://github.com/rose-compiler/rose-develop/blob/master/src/midend/abstractHandle/abstract_handle.h
- 示例使用:https://github.com/rose-compiler/rose-develop/tree/master/projects/autoTuning
- http://rosecompiler.org/autoTuning.pdf 第 6.2 节解释了如何使用抽象句柄在指定循环上使用参数化循环转换。
- https://github.com/rose-compiler/rose-develop/blob/master/tests/roseTests/astInterfaceTests/loopCollapsing.C 接受抽象句柄的循环折叠工具
更多信息请访问
仅执行转换的单个循环翻译器列表。因此,调用者使用确保转换在语义上对您的输入代码是正确的
可以在 Makefile.am 中找到运行这些循环翻译器的示例命令行
- 例如:loopUnrolling -rose:loopunroll:abstract_handle 'Statement<position,5>' -rose:loopunroll:factor 3
还有另一个集成的 loopProcessor,它依赖于复杂的分析来驱动一系列循环优化。
此工具将把变量声明移动到它们最内部可能的已使用范围。
对于一个声明,找到我们可以将它移动到的最内部范围,而不会破坏代码的原始语义。
- 对于一个单独的使用位置,移动到最内部范围。
- 对于多个使用的情况,如果它们之间没有变量重用,我们可能需要复制声明并移动到两个范围,否则,我们将声明移动到多个使用的最内部公共范围。
用户说明:翻译器接受以下选项
- -rose:merge_decl_assign 将把移动的声明与其紧随其后的赋值合并。
- -rose:aggressive :打开激进模式,这将移动带有初始化器的声明,并且跨越循环边界。如果移动跨越了循环边界,将发出警告消息。没有此选项,该工具仅移动不带初始化器的声明以确保安全。
- -rose:debug,默认情况下在测试中打开。一些点图文件将为变量的范围树生成,以用于调试目的。
- -rose:keep_going 将尽可能忽略断言(目前在跳过复杂 for 循环初始化语句列表上的断言)。没有此选项,该工具将在断言失败时停止。
- -rose:identity 将关闭任何转换,并充当身份翻译器。在调试时很有用。
- -rose:trans-tracking 将打开转换跟踪模式,显示移动/合并声明的源语句
- 注意:最近已移动到 tests/nonsmoke/functional/roseTests/astInterfaceTests
测试:make move_diff_check 定义在 https://github.com/rose-compiler/rose-develop/blob/master/tests/roseTests/astInterfaceTests/Makefile.am
更多信息请访问 Declaration move tool
Arithmetic intensity measuring tool :测量循环的算术强度(FLOPS/内存)
一组用于支持将高级领域特定语言转换为 MPI 代码的代码生成函数,并提供一些运行时支持。
- 源代码:https://github.com/rose-compiler/rose-develop/blob/master/projects/ShiftCalculus2/mpiCodeGenerator.C
- 测试:make mpiTests 在 https://github.com/rose-compiler/rose-develop/blob/master/projects/ShiftCalculus2/Makefile.am
一个实用程序,用于将编译数据库 json 文件转换为单个 makefile。
其动机是为了避免侵入用户的构建系统以调用基于 ROSE 的工具。
使用单个 makefile,我们可以自由地替换编译器名称和选项,而无需理解复杂的构建系统。
详细信息请访问:https://github.com/rose-compiler/rose/tree/develop/utilities/compilationDatabase2Makefile
使用步骤
- 生成 compilation_database.json 文件
- 将其转换为 makefile
- 首先从您的构建树中删除所有目标文件!!
- make -f your-makefile clean
- make -k -f your-makefile all # -k 表示如果某些事情出错,则继续执行
将工具重构到一个专门的 rose/tools 目录中。这样,它们将始终默认构建并可用,并且对其他事物的依赖性最小,例如哪些语言开启或关闭(当然,在适用情况下)。
我们目前的想法是,我们应该将用作示例或教程的翻译器与用于创建最终用户工具的翻译器分开。
- 对于教程翻译器,它们不应默认安装为工具。它们的目的是包含在手册或教程的 PDF 文件中,以通过示例向开发人员说明某些内容。示例应该简洁明了。
- 另一方面,用于构建最终用户工具的翻译器应该有更高的标准,以接受针对不同甚至高级功能的命令选项。这些翻译器可以非常复杂,因为它们没有像教程示例那样的页面限制。