У меня следующий код изменен из Hello.cpp из дерева исходных текстов LLVM. В настоящее время код печатает функции, инструкции и операнды.
Я также хочу напечатать имя файла источника и набор функций, инструкций и доступных переменных. Кто-нибудь может показать мне, как это сделать?
$ cat Hello.cpp
/* vim: set noexpandtab tabstop=2: */
#include "llvm/ADT/Statistic.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
#define DEBUG_TYPE "hello"
STATISTIC(HelloCounter, "Counts number of functions greeted");
namespace {
// Hello - The first implementation, without getAnalysisUsage.
struct Hello : public FunctionPass {
static char ID; // Pass identification, replacement for typeid
Hello() : FunctionPass(ID) {}
bool runOnFunction(Function &F) override {
++HelloCounter;
errs() << "Hello: ";
errs().write_escaped(F.getName()) << '\n';
for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
errs() << "I:" << *I << "\n";
for (Use &U : I->operands()) {
Value *v = U.get();
errs() << "v:" << *v << "\n";
}
}
return false;
}
};
}
char Hello::ID = 0;
static RegisterPass<Hello> X("hello", "Hello World Pass");
$ ./main.sh ;./opt.sh
Hello: main
I: %1 = alloca i32, align 4
v:i32 1
I: store i32 0, i32* %1, align 4
v:i32 0
v: %1 = alloca i32, align 4
I: call void (...) bitcast (void ()* @f to void (...)*)()
v:void (...)* bitcast (void ()* @f to void (...)*)
I: ret i32 0
v:i32 0
Hello: f
I: %1 = load i32, i32* @U, align 4
v:@U = common dso_local global i32 0, align 4
I: %2 = add nsw i32 %1, 1
v: %1 = load i32, i32* @U, align 4
v:i32 1
I: store i32 %2, i32* @U, align 4
v: %2 = add nsw i32 %1, 1
v:@U = common dso_local global i32 0, align 4
I: ret void
==> main.sh <==
#!/usr/bin/env bash
# vim: set noexpandtab tabstop=2:
compile=(
c++
-I"$HOME"/opt/llvm/include
-std=c++11 -Wall -pedantic
-g -fPIC
-fno-rtti
-o Hello.cpp.o -c Hello.cpp
)
"${compile[@]}"
link=(
c++
-Wl,-flat_namespace -Wl,-undefined -Wl,suppress
-o x.so
Hello.cpp.o
)
"${link[@]}"
==> opt.sh <==
#!/usr/bin/env bash
# vim: set noexpandtab tabstop=2:
cmd=(
~/opt/llvm/bin/opt
-load x.so
-hello
)
"${cmd[@]}" < hello.bc > /dev/null
==> hello.c <==
/* vim: set noexpandtab tabstop=2: */
#include <stdio.h>
int U;
void f();
int main() {
f();
return 0;
}
==> f.c <==
/* vim: set noexpandtab tabstop=2: */
#include <stdio.h>
extern int U;
void f() {
++U;
}