在LLVM自定义pass中,向IR中插入自定义函数,并将debugloc的getfilename的返回值作为参数传递给该函数,给出完整代码示例
时间: 2024-02-01 13:13:29 浏览: 122
下面是一个示例,其中插入了一个名称为“myFunction”的自定义函数,并将debugloc的getfilename的返回值作为参数传递给该函数。这个函数是打印出文件名以及其它一些信息。
```c++
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
using namespace llvm;
namespace {
struct MyPass : public FunctionPass {
static char ID;
MyPass() : FunctionPass(ID) {}
bool runOnFunction(Function &F) override {
LLVMContext &context = F.getContext();
IRBuilder<> builder(context);
// Get the debug info for the current function
DISubprogram *subprogram = F.getSubprogram();
if (!subprogram) {
errs() << "No debug info for function: " << F.getName() << "\n";
return false;
}
// Get the filename from the debug info
StringRef filename = subprogram->getFilename();
// Create the function type and function
Type *voidTy = Type::getVoidTy(context);
Type *int32Ty = Type::getInt32Ty(context);
FunctionType *funcTy = FunctionType::get(voidTy, {int32Ty}, false);
Function *myFunction = Function::Create(
funcTy, GlobalValue::LinkageTypes::ExternalLinkage, "myFunction", &F);
// Insert the call to myFunction at the beginning of the function
BasicBlock &entry = F.getEntryBlock();
builder.SetInsertPoint(&entry, entry.begin());
Value *filenameArg = builder.CreateGlobalStringPtr(filename);
builder.CreateCall(myFunction, {filenameArg});
return true;
}
};
}
char MyPass::ID = 0;
static void registerMyPass(const PassManagerBuilder &,
legacy::PassManagerBase &PM) {
PM.add(new MyPass());
}
static RegisterStandardPasses
RegisterMyPass(PassManagerBuilder::EP_EarlyAsPossible, registerMyPass);
```
在这个示例中,我们首先获取了当前函数的调试信息(debug info),并从中提取出文件名。然后,我们创建了一个新的函数类型和函数对象,将其插入到当前函数中。最后,我们在函数的入口处插入了一个调用新函数的指令,将文件名作为参数传递给该函数。
注意,我们使用了LLVM的IRBuilder来插入指令。IRBuilder是一个方便的工具,可以帮助我们以更简洁的方式构造IR。
阅读全文