如何实现AssemblyAnnotationWriter来打印元数据

时间:2014-01-19 01:37:39

标签: llvm llvm-ir

我正在学习如何在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");

    }

1 个答案:

答案 0 :(得分:0)

注释仅作为LLVM IR打印输出中的注释存在。它们实际上并不是IR的一部分,因此它们不是你在传递中“添加”的东西。

使用AssemblyAnnotationWriter的方法是将其作为第二个参数传递给print函数(例如Module::print)。你可以在里面传递,但这不是你自动完成的事情。具体来说,使传递继承自AssemblyAnnotationWriter是荒谬的 - 您在问题中显示的第一种方法,在单独的类中继承它,是正确的方法。

简而言之,如果您希望在传递中打印模块,请在其上调用print。如果要为打印输出添加注释,请调用相同的print,但将CommentWriter的实例作为第二个参数传递。