【问题标题】:Can gcc/clang optimize initialization computing?gcc/clang 可以优化初始化计算吗?
【发布时间】:2018-11-29 15:16:28
【问题描述】:

我最近编写了一个解析器生成器工具,它采用 BNF 语法(作为字符串)和一组操作(作为函数指针数组)并输出解析器(= 状态自动机,在堆上分配)。然后我使用另一个函数在我的输入数据上使用该解析器并生成一个抽象语法树。

在初始解析器生成中,有很多步骤,我想知道 gcc 或 clang 是否能够优化这一点,给定解析器生成函数的常量输入(并且从不使用指针值,只取消引用它们) ?是否可以在编译时运行该函数,并将结果(也就是分配的内存)嵌入到可执行文件中?

(显然,这将使用链接时间优化,因为编译器需要能够检查整个函数是否确实具有相同参数的相同结果)

【问题讨论】:

  • 为什么不考虑从解析器生成器工具生成 C(或 C++)代码?这是惯例!
  • “...分配在堆上”这让我觉得 - 不,不可能。
  • 原则上是可以的。但我假设你生成的解析器会有很多指针。当您加载并运行它时,不能保证它是正确的。
  • @BasileStarynkevitch 我确实考虑过,事实上我最初使用了这种方法。但它增加了一些复杂性,因为从 C 生成 C 并不是那么有趣,而且我还必须在构建系统级别考虑这一点。如果我要重做那个项目(一个外壳),我肯定会这样做,因为在启动时构建解析器可能是相当高的成本,因为语法足够复杂。但我很想知道是否有像这样的编译器优化用例。顺便抱歉回复晚了^.
  • 顺便说一句,在 Linux 和 POSIX 系统上,您可能会在 /tmp/tempcode.c 中生成一些临时 C 代码,将其编译为插件 (gcc -Wall -O -fPIC -shared /tmp/tempcode.c -o /tmp/tempcode.so),然后将 dlopen 编译为 /tmp/tempcode.so 插件。见dlopen(3)dlsym(3)

标签: c gcc compilation compiler-optimization compile-time


【解决方案1】:

在这种情况下,您可以做的是让代码生成代码。

将您的初始解析器生成器作为独立运行的单独代码段。此代码的输出将是一个头文件,其中包含一组初始化为正确值的变量定义。然后在你的主代码中使用这个文件。

例如,假设您有一个程序需要知道在给定字节中设置的位数。您可以在需要时手动执行此操作:

int count_bits(uint8_t b)
{
    int count = 0;
    while (b) {
        count += b & 1;
        b >>= 1;
    }
    return count;
}

或者您可以在单独的程序中生成表格:

int main()
{
    FILE *header = fopen("bitcount.h", "w");
    if (!header) {
        perror("fopen failed");
        exit(1);
    }

    fprintf(header, "int bit_counts[256] = {\n");

    int count;
    unsigned v;

    for (v=0,count=0; v<256; v++) {
        uint8_t b = v;
        while (b) {
            count += b & 1;
            b >>= 1;
        }
        fprintf(header, "    %d,\n" count);
    }

    fprintf(header, "};\n");
    fclose(header);
    return 0;
}

这将创建一个名为 bitcount.h 的文件,如下所示:

int bit_counts[256] = {
    0,
    1,
    1,
    2,
    ...
    7,
};

您可以包含在“真实”代码中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-25
    • 2016-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-10
    • 1970-01-01
    相关资源
    最近更新 更多