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 檔案中,以透過示例向開發人員說明某些內容。示例應該簡潔明瞭。
- 另一方面,用於構建終端使用者工具的翻譯器應該有更高的標準,以接受針對不同甚至高階功能的命令選項。這些翻譯器可以非常複雜,因為它們沒有像教程示例那樣的頁面限制。