llvm - 为什么某些函数不会触发基于 FunctionPass 的 LLVM 通过?

标签 llvm llvm-clang llvm-ir

我正在通过尝试重现来学习编写 LLVM pass hello world例子。通行证 hello.cpp 如下所示:

#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

namespace {
  struct Hello : public FunctionPass {
    static char ID;
    Hello() : FunctionPass(ID) {}

    bool runOnFunction(Function &F) override {
      errs() << "Hello: ";
      errs().write_escaped(F.getName()) << '\n';
      return false;
    }
  };
}

char Hello::ID = 0;9
static RegisterPass<Hello> X("hello", "Hello World Pass", false, false);

示例程序world.c如下所示:

#include <stdio.h>

int main() {
    printf("Hello World\n");
    return 0;
}

该程序使用以下命令行编译:clang world.c -c -emit-llvm -O3 -o world.bc

llvm-dis 生成的位码如下所示:

; ModuleID = 'src/hello.bc'
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

@str = private unnamed_addr constant [12 x i8] c"Hello World\00"

; Function Attrs: nounwind uwtable
define i32 @main() #0 {
  %puts = tail call i32 @puts(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @str, i64 0, i64 0))
  ret i32 0
}

; Function Attrs: nounwind
declare i32 @puts(i8* nocapture) #1

attributes #0 = { nounwind uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind }

!llvm.ident = !{!0}

!0 = !{!"clang version 3.8.0 (tags/RELEASE_380/final)"}

当我在位码上运行传递:opt -load hello/libhello.so -hello src/world.bc >/dev/null时,输出为:

Hello: main

但是,tutorial声称输出应该是:

Hello: __main
Hello: puts
Hello: main

为什么前两个函数没有触发我的通行证?

最佳答案

我已阅读该教程,但我从未见过任何名为 __main 的符号。 我一直认为它曾经是 LLVM/Clang 旧版本的某种遗留物,被插入并用作可执行文件的入口点。

无论如何,您的位码文件中都没有任何具有此类名称的函数的定义或声明。

此外,我认为正在输出的 puts 函数是教程中的一个错误。函数传递应该对函数的主体执行分析/转换。对 puts 的引用只是一个声明,因为它是在 C 标准库中定义的外部符号,并且将在链接期间解析。它在位码文件中没有定义主体。

如果您还需要遍历函数声明,那么您需要创建一个 Module 传递并使用 isDeclaration() function打电话来区分它们。

关于llvm - 为什么某些函数不会触发基于 FunctionPass 的 LLVM 通过?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43431373/

相关文章:

c++ - LLVM 优化器不能处理简单的情况?

c++ - 如何区分 Clang AST 访问者中的函数定义和函数声明

c++ - OSX10.10下安装clang libcxx时报Unknown option error?

LLVM IR 优化

c++ - lldb 没有启动应用程序

c++ - llvm clang struct 动态创建函数

c - macOS llvm 找不到 stdio.h 了

c - 如何自托管 Clang?

llvm - LLVM 的整数溢出捕获?

llvm - 构建 LLVM 会耗尽所有 RAM