Gcc 自动展开并输出C/C++;代码
我正在做一个实验,第一步是将一个循环(来自C/C++)展开十几次(例如:10、50等),然后输出C/C++展开的代码。是否有任何工具,我可以用来自动化这样的展开 换句话说,我需要的是:Gcc 自动展开并输出C/C++;代码,gcc,compiler-construction,llvm,cpu-architecture,icc,Gcc,Compiler Construction,Llvm,Cpu Architecture,Icc,我正在做一个实验,第一步是将一个循环(来自C/C++)展开十几次(例如:10、50等),然后输出C/C++展开的代码。是否有任何工具,我可以用来自动化这样的展开 换句话说,我需要的是: C/C++ source/loop --->> TOOL (Unroll by X) ----> Unrolled C/C++ source/loop Clang似乎是一个很好的工具,因为它在源代码到源代码的转换方面大肆宣传。我查看了是否有人进行了源代码到源代码的展开,发现了一个名为Scou
C/C++ source/loop --->> TOOL (Unroll by X) ----> Unrolled C/C++ source/loop
Clang似乎是一个很好的工具,因为它在源代码到源代码的转换方面大肆宣传。我查看了是否有人进行了源代码到源代码的展开,发现了一个名为Scout的项目,它基于Clang构建,可以实现您需要的功能: 幻灯片:
视频:我们的源到源转换引擎 , 可以用它来做这件事 DMS可以接受 个别规则写为
rule rule_name(metavariables_with_syntax_categories)
:syntax_category->syntax_category
= left_hand_side_pattern_to_match
-> right_hand_side_replacement_after_substitution
下面我提供了一个(未经测试的)集合,它非常接近这个标记。它们直接受到展开循环的经典编译器优化的启发
这个。。。在“…”中,您看到的意思是“(C++语法表示)…”;这些是“这里是域文本元概念,而不是C++字符串引用。
Fo在“…”中表示元变量FoO,它表示C++代码的块(树)。
\bar(…\,…)表示“在…上调用的元函数bar”,注意“元命令”拼写为\,元括号()用于区分元函数和域(“C++”)语法。
有关此类规则语法的更多详细信息,请参见链接
unquoted模式UNROLL和ReplaceIbyEXP定义了“元函数”,可以将其视为应用更多转换的意图
在这里,UNROLL抓住了我们想要重复n次代码块的概念。有两个(有效的递归)规则来实现这个概念,一个用于“重复零次”的基本情况生成一个空语句列表,另一个生成代码块,然后重复n-1次。然后,ReplaceIbyEXP调整我在复制的代码块中使用的索引
external pattern ReplaceIbyEXP(s:statements,i:IDENTIFIER,r:expression):statements;
pattern UNROLL_1(s:statements,i:IDENTIFIER,k:INT_LITERAL,c:INT_LITERAL)
:statements->statements;
rule UNROLL_1(s:statements,i:IDENTIFIER,d:INT_LITERAL,c:INT_LITERAL)
:statements->statements
= UNROLL(s,i,d,c) -> ";" if c=="0";
rule UNROLL_N((s:statements,i:IDENTIFIER,d:INT_LITERAL,c:INT_LITERAL)
:statements->statements
= UNROLL(s,i,d,c)
-> "\ReplaceIbyEXP\(\s\,\i\,(\i+\d)\)
\UNROLL\(\s,\i,\add\(\d\,1\),\subtract\(\c\,1\))" if c!="1";
rule UNROLL_FOR_k(i:IDENTIFIER,s:statements,limit:INT_LITERAL)
:statements->statements
= "for (\i=0;\i<\limit;\i++) { \s }"
-> "for (\i=0;\i<\limit;\i+=k) { \UNROLL(\s\,\i\,0,k) }"
externalpattern ReplaceIbyEXP(s:statements,i:IDENTIFIER,r:expression):语句;
模式展开1(s:statements,i:IDENTIFIER,k:INT\u LITERAL,c:INT\u LITERAL)
:语句->语句;
规则展开1(s:statements,i:IDENTIFIER,d:INT\u LITERAL,c:INT\u LITERAL)
:语句->语句
=展开(s,i,d,c)->“;“如果c==”0”;
规则展开N((s:statements,i:IDENTIFIER,d:INT\u LITERAL,c:INT\u LITERAL)
:语句->语句
=展开(s、i、d、c)
->“\ReplaceIbyEXP\(\s\,\i\,(\i+\d)\)
\展开\(\s、\i、\add \(\d\,1\)、\subtract \(\c\,1\)“如果c!=“1”;
为k展开规则(i:IDENTIFIER,s:statements,limit:INT\u LITERAL)
:语句->语句
=“对于(\i=0;\i)我认为大多数编译器/抖动在代码转换为其他更像程序集的表示形式后执行这种优化(尽管通常仍然与平台无关),以这种形式执行分析和应用更改要容易得多。您需要展开的源代码可读性和可移植性吗?@Leeor:您是对的。但是,对于这个实验,我需要进一步手动更改代码。@delnan:这些现在不是个大问题,因为如果我找不到自动执行的工具,我需要o手动操作。这样我就可以用一些时间来换取可移植性/可读性。我会使用boost预处理器库。它有一个非常充分的(而且有些令人惊讶的)功能索引中继器的实现:默认情况下最多只能重复256次;如果需要更多,则需要找到不同的模板解决方案。提示:gcc-E-P
(或将gcc
更改为clang
)只需预处理并输出结果,而无需烦人的#line
指令,因此您可以将其用作图表中的“工具”。