如何解决编写LLVM转换过程以在每个函数的开头注入延迟
我是LLVM的新手,我正在尝试编写LLVM转换遍历,该遍历将在运行时为每个被调用函数的开始注入延迟。
我如何相应地更改代码以注入延迟而不是printf? (我正在使用LLVM 10。)
下面是代码:
bool InjectFuncCall::runOnModule(Module &M) {
bool InsertedAtLeastOnePrintf = false;
auto &CTX = M.getContext();
PointerType *PrintfArgTy = PointerType::getUnqual(Type::getInt8Ty(CTX));
// STEP 1: Inject the declaration of printf
// ----------------------------------------
// Create (or _get_ in cases where it's already available) the following
// declaration in the IR module:
// declare i32 @printf(i8*,...)
// It corresponds to the following C declaration:
// int printf(char *,...)
FunctionType *PrintfTy = FunctionType::get(
IntegerType::getInt32Ty(CTX),PrintfArgTy,/*IsVarargs=*/true);
FunctionCallee Printf = M.getorInsertFunction("printf",PrintfTy);
// Set attributes as per inferLibFuncAttributes in BuildLibCalls.cpp
Function *PrintfF = dyn_cast<Function>(Printf.getCallee());
PrintfF->setDoesNotthrow();
PrintfF->addParamAttr(0,Attribute::NoCapture);
PrintfF->addParamAttr(0,Attribute::ReadOnly);
// STEP 2: Inject a global variable that will hold the printf format string
// ------------------------------------------------------------------------
llvm::Constant *PrintfFormatStr = llvm::ConstantDataArray::getString(
CTX,"(llvm-tutor) Hello from: %s\n(llvm-tutor) number of arguments: %d\n");
Constant *PrintfFormatStrVar =
M.getorInsertGlobal("PrintfFormatStr",PrintfFormatStr->getType());
dyn_cast<GlobalVariable>(PrintfFormatStrVar)->setinitializer(PrintfFormatStr);
// STEP 3: For each function in the module,inject a call to printf
// ----------------------------------------------------------------
for (auto &F : M) {
if (F.isDeclaration())
continue;
// Get an IR builder. Sets the insertion point to the top of the function
IRBuilder<> Builder(&*F.getEntryBlock().getFirstInsertionPt());
// Inject a global variable that contains the function name
auto FuncName = Builder.CreateGlobalStringPtr(F.getName());
// Printf requires i8*,but PrintfFormatStrVar is an array: [n x i8]. Add
// a cast: [n x i8] -> i8*
llvm::Value *FormatStrPtr =
Builder.CreatePointerCast(PrintfFormatStrVar,"formatStr");
// The following is visible only if you pass -debug on the command line
// *and* you have an assert build.
LLVM_DEBUG(dbgs() << " Injecting call to printf inside " << F.getName()
<< "\n");
// Finally,inject a call to printf
Builder.CreateCall(
Printf,{FormatStrPtr,FuncName,Builder.getInt32(F.arg_size())});
InsertedAtLeastOnePrintf = true;
}
return InsertedAtLeastOnePrintf;
}
如果有适合初学者的LLVM优秀教程的链接,那也很好。
解决方法
除了必须将参数类型从delay
更改为printf
之外,您必须像声明i8*
一样声明i32
函数。对于教程,您可以查看这些
https://anoopsarkar.github.io/compilers-class/llvm-practice.html\
https://www.usna.edu/Users/cs/wcbrown/courses/F19SI413/lab/l13/lab.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。