Я учусь писать пропуски в llvm. Я пытаюсь реализоватьКак реализовать AssemblyAnnotationWriter для печати метаданных
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");
}