Gcc 自动展开并输出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++)展开十几次(例如:10、50等),然后输出C/C++展开的代码。是否有任何工具,我可以用来自动化这样的展开

换句话说,我需要的是:

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
指令,因此您可以将其用作图表中的“工具”。