我正在学习如何在llvm中编写传递。我正在努力实施
virtual void emitFunctionAnnot(const Function *, formatted_raw_ostream &){}
在http://llvm.org/doxygen/AssemblyAnnotationWriter_8h_source.html处给出
在开始功能之前打印#[uses]=1
。
如果我在emitFunctionAnnot(&F, ferrs());
方法中手动调用runOnFunction()
,我已覆盖(emitFunctionAnnot
),则下面的代码有效。但是,如果不称之为manullay就不应该工作,因为这是重写它的全部要点。我相信在重写时我做错了什么。我花了无数个小时试图调试它。我将不胜感激任何帮助。
这是我到目前为止所做的。
#include "llvm/Pass.h"
#include "llvm/PassManager.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/DebugInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/InstIterator.h"
#include "llvm/IR/Instruction.h"
#include "llvm/DebugInfo.h"
#include "llvm/Assembly/AssemblyAnnotationWriter.h"
#include <ostream>
#include <fstream>
#include <iostream>
#include <stdlib.h>
using namespace llvm;
namespace {
class CommentWriter : public AssemblyAnnotationWriter {
public:
virtual void emitFunctionAnnot(const Function *F,
formatted_raw_ostream &OS) {
OS << "; [#uses=" << F->getNumUses() << ']'; // Output # uses
OS << '\n';
}
};
class FunctionInfo : public FunctionPass, public AssemblyAnnotationWriter{
public:
static char ID;
FunctionInfo() : FunctionPass(ID) {}
void emitFunctionAnnot(const Function *F, formatted_raw_ostream &OS) {
errs() << "CALLED";
OS << "; [#uses=" << F->getNumUses() << ']'; // Output # uses
OS << '\n';
}
virtual bool runOnFunction(Function &F) {
// emitFunctionAnnot(&F, ferrs());
for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I){
Instruction &II = *I;
errs() << *I;
}
return false;
}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
}
};
char FunctionInfo::ID = 0;
// clang -c -Xclang -load -Xclang ./FunctionInfo.so loop.c
static void registerMyPass(const PassManagerBuilder &,
PassManagerBase &PM) {
PM.add(new FunctionInfo());
}
RegisterStandardPasses
RegisterMyPass(PassManagerBuilder::EP_EarlyAsPossible,
registerMyPass);
RegisterPass<FunctionInfo> X("function-info", "Function Information");
}
答案 0 :(得分:0)
注释仅作为LLVM IR打印输出中的注释存在。它们实际上并不是IR的一部分,因此它们不是你在传递中“添加”的东西。
使用AssemblyAnnotationWriter
的方法是将其作为第二个参数传递给print
函数(例如Module::print
)。你可以在里面传递,但这不是你自动完成的事情。具体来说,使传递继承自AssemblyAnnotationWriter
是荒谬的 - 您在问题中显示的第一种方法,在单独的类中继承它,是正确的方法。
简而言之,如果您希望在传递中打印模块,请在其上调用print
。如果要为打印输出添加注释,请调用相同的print
,但将CommentWriter
的实例作为第二个参数传递。