Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么某些函数不会触发基于FunctionPass的LLVM过程?_Llvm_Llvm Clang_Llvm Ir - Fatal编程技术网

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

为什么某些函数不会触发基于FunctionPass的LLVM过程?,llvm,llvm-clang,llvm-ir,Llvm,Llvm Clang,Llvm Ir,我正在学习编写LLVM pass,方法是尝试复制示例。passhello.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() : Func

我正在学习编写LLVM pass,方法是尝试复制示例。pass
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);
#include <stdio.h>

int main() {
    printf("Hello World\n");
    return 0;
}
; 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)"}
该程序使用以下命令行编译:
clangworld.c-c-emit llvm-O3-o world.bc

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

#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);
#include <stdio.h>

int main() {
    printf("Hello World\n");
    return 0;
}
; 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)"}
当我对位代码运行pass时:
opt-load hello/libhello.so-hello src/world.bc>/dev/null
,输出是:

Hello: main
然而,关于产出应该是:

Hello: __main
Hello: puts
Hello: main

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

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

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

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


如果您还需要检查函数声明,那么您需要创建一个
模块
过程,并使用
isDeclaration()
调用来区分它们。

您所说的非常有意义。然而,我想知道他们是如何得出上面列出的结果的。我的意思是,如果官方文件如此虚假,我会感到惊讶。@Holmes.Sherlock我认为这只是疏忽。这个例子的目的更多的是为了让建造和运行的机器运转起来;其余的都是doxygen生成的文档和源本身。该文件属于svn回购协议,因此我想任何人都可以修改它。