1

我正在学习如何在 llvm 中编写通行证。我正在尝试实施

virtual void emitFunctionAnnot(const Function *, formatted_raw_ostream &){}

http://llvm.org/doxygen/AssemblyAnnotationWriter_8h_source.html#[uses]=1给出的,在函数开始之前 打印。

emitFunctionAnnot(&F, ferrs());如果我手动调用内部runOnFunction()方法,下面的代码可以工作,emitFunctionAnnot我已经覆盖了 which()。但是,如果不将其称为 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");

    }
4

1 回答 1

0

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

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

简而言之,如果您想要打印通行证中的模块,请致电print。如果要向打印输出添加注释,请调用相同的print方法,但将您的实例CommentWriter作为第二个参数传递。

于 2014-01-19T07:37:49.750 回答