[LLVM] 通过PassManager 写MachineFunctionpass

 

简介:

     最近在做和llvm后端有关的项目,研究了一下llvm的Pass manager.

大家比较熟悉的是llvm里有几种形式,具体的参照官方的文档.

http://llvm.org/docs/WritingAnLLVMPass.html.

这里主要介绍一种MachineFunction Pass 通过Pass Manager运行MachineFunction Pass.

通过建立PassManager, 在通过add()方法,将MachineFunction的pass加入PassManager.

通过PassManager的run方法在module上运行pass.

 

例子:

下面通过在llvm的llc工程中加入PassManager 然后运行MachineFunctionPass.

llc项目文件列表:

CMakeLists.txt
helloMF.cpp
helloMF.h
llc.cpp
LLVMBuild.txt

1.CMakeLists.txt修改如下:

+++ b/tools/llc/CMakeLists.txt
@@ -8,6 +8,7 @@ set(LLVM_LINK_COMPONENTS
   MC
   MIRParser
   ScalarOpts
+  ipo
   SelectionDAG
   Support
   Target
@@ -20,8 +21,14 @@ set(LLVM_NO_DEAD_STRIP 1)
 
 add_llvm_tool(llc
   llc.cpp
+  helloMF.cpp
   DEPENDS
   intrinsics_gen
+  LLVMipo
   )
+
+if(USE_LLVM_DYLIB)
+  target_link_libraries(llc LLVMipo)
+endif()
+#add_dependencies(llc LLVMipo)

2.helloMF.h

#ifndef HELLOMF_H
#define HELLOMF_H

#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/PassSupport.h"
#include "llvm/PassRegistry.h"
#include "llvm/IR/LegacyPassManager.h"
using namespace llvm;
namespace llvm {
class TestMF: public MachineFunctionPass {
public:
  static char ID;
  TestMF() : MachineFunctionPass(ID) {
  }
  bool runOnMachineFunction(MachineFunction &Fn);
};

}// name space
#endif // HELLOMF_H

3.helloMF.cpp

#include "helloMF.h"
#include "llvm/InitializePasses.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/PassSupport.h"
#include "llvm/PassRegistry.h"
#include "llvm/IR/LegacyPassManager.h"
#include  "llvm/Transforms/IPO/PassManagerBuilder.h"

using namespace llvm;

namespace llvm {
char TestMF::ID = 0;
static RegisterPass<TestMF> Z("MyMF", "MyMFPass Pass", false, false);
static void registerHelloMFPass(const PassManagerBuilder &,
                        legacy::PassManagerBase &PM) {
  PM.add(new TestMF());
}

static RegisterStandardPasses
  TestMFPass(PassManagerBuilder::EP_EarlyAsPossible, 
                 registerHelloMFPass);

bool TestMF::runOnMachineFunction(MachineFunction &Fn) {
    errs() << "I saw a function called " << Fn.getName() << "!\n";
    return false;
}
}
HelloMFPass(const PassManagerBuilder &,
                        legacy::PassManagerBase &PM) {
  PM.add(new TestMF());
}

static RegisterStandardPasses
  TestMFPass(PassManagerBuilder::EP_EarlyAsPossible, 
                 registerHelloMFPass);

bool TestMF::runOnMachineFunction(MachineFunction &Fn) {
    errs() << "I saw a function called " << Fn.getName() << "!\n";
    return false;
}
}

4.llc.cpp

 

-
+#include "helloMF.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
@@ -50,7 +50,11 @@
 #include "llvm/Support/ToolOutputFile.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/Transforms/IPO/PassManagerBuilder.h"
  //Use to add AnalysisID pass.
  static bool addPass(legacy::PassManager &PM, AnalysisID PassID, llvm::TargetPassConfig &TPC) {
  if (!PassID)
    return false;


  IdentifyingPassPtr TargetID = TPC.getPassSubstitution(PassID);
  Pass *P = Pass::createPass(TargetID.getID());
  if (!P) {
    errs() << ": pass-name " << P->getPassName() << " is not created.\n";
    return true;
  }


  PM.add(P);
  return false;
}
//Add the PassManager
  Triple TheTriple = Triple(TripleName);
  FileType = TargetMachine::CGFT_ObjectFile;

  //Figure out where we are going to send the output.
  std::unique_ptr<ToolOutputFile> Out =
     GetOutputStream(TheTarget->getName(), TheTriple.getOS(), ToolName.data());

  if (!Out)
    return ;

  raw_pwrite_stream *OS = &Out->os();
  legacy::PassManager PM;
  LLVMTargetMachine &LLVMTM = static_cast<LLVMTargetMachine&>(*Target);

  if (RunPassNames->empty()) {
    TargetPassConfig &TPC = *LLVMTM.createPassConfig(PM);
    if (TPC.hasLimitedCodeGenPipeline()) {
      errs() << ToolName << ": run-pass cannot be used with "
             << TPC.getLimitedCodeGenPipelineReason(" and ") << ".\n";
      return;
    }

    TPC.setDisableVerify(NoVerify);
    PM.add(&TPC);
    PM.add(machineModuleInfo);
    PM.add(new TestMF());
    //Add Alalysis pass by pass ID    
    //addPass(PM, &PassID, TPC);
    TPC.printAndVerify("");
    for (const std::string &RunPassName : *RunPassNames) {
      if (addPass(PM, ToolName, RunPassName, TPC))
        return;
    }
    TPC.setInitialized();
  } 

  cl::PrintOptionValues();
  PM.run(module);

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值