LLVM Pass 简介(3)

这一节介绍一点getelementptr指令的处理。 https://llvm.org/docs/LangRef.html#getelementptr-instruction

这条指令一般用来获取指向结构体指针和指向数组元素的指针操作。语法如下:

<result> = getelementptr <ty>, <ty>* <ptrval>{, [inrange] <ty> <idx>}*
<result> = getelementptr inbounds <ty>, <ty>* <ptrval>{, [inrange] <ty> <idx>}*

上边的是操作数组元素的,下边是操作结构体元素的,完整的说明附在下边:

The first argument is always a type used as the basis for the calculations. The second argument is always a pointer or a vector of pointers, and is the base address to start from. The remaining arguments are indices that indicate which of the elements of the aggregate object are indexed. The interpretation of each index is dependent on the type being indexed into. The first index always indexes the pointer value given as the second argument, the second index indexes a value of the type pointed to (not necessarily the value directly pointed to, since the first index can be non-zero), etc. The first type indexed into must be a pointer value, subsequent types can be arrays, vectors, and structs. Note that subsequent types being indexed into can never be pointers, since that would require loading the pointer before continuing calculation.

The type of each index argument depends on the type it is indexing into. When indexing into a (optionally packed) structure, only i32 integer constants are allowed (when using a vector of indices they must all be the same i32 integer constant). When indexing into an array, pointer or vector, integers of any width are allowed, and they are not required to be constant. These integers are treated as signed values where relevant.

这里主要介绍对getelementptr指令的处理,引入和前边Clang的Visitor相似的处理。

#include "llvm/ADT/Statistic.h"
#include "llvm/IR/Function.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"
#include <map>
#include <string>
#include "llvm/IR/Instructions.h"
#include "llvm/IR/InstVisitor.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
using namespace llvm;

#define DEBUG_TYPE "hello"

STATISTIC(HelloCounter, "Counts number of functions greeted");
namespace {
  struct ProcessInstVisitor : public InstVisitor<ProcessInstVisitor> {
  public:
    ProcessInstVisitor(BasicBlock &bb){
      visit(bb);
    }

    void visitGetElementPtrInst(GetElementPtrInst &GEP){
      
      //instIter->dump();
      errs() <<" Source type : ";
      GEP.getSourceElementType()->print(errs());
      errs() <<" Dest type : ";
      GEP.getResultElementType()->print(errs());
      errs() <<(GEP.isInBounds() ? " InBounds" : " ") ;
        Use *OL = GEP.getOperandList();
      for(uint i=0; i<GEP.getNumOperands(); ++i){
        OL[i]->dump();
      }
    }

  };
  // Hello3 - The second implementation with getAnalysisUsage implemented.
  struct Hello3 : public FunctionPass {
    static char ID; // Pass identification, replacement for typeid
    Hello3() : FunctionPass(ID) {}
    using BasicBlockListType = SymbolTableList<BasicBlock>;

    bool runOnFunction(Function &F) override {
      errs() << "now process funcName: ";
      errs().write_escaped(F.getName()) << '
';
      BasicBlockListType::iterator bbEnd = F.end();
      for(BasicBlockListType::iterator bbIter=F.begin(); bbIter!=bbEnd; ++bbIter){
        errs() <<"bb Tr
";
        BasicBlock &bbs = *bbIter;
        ProcessInstVisitor piv(bbs);
      }
      return false;
    }

    void processGMP();

    // We don't modify the program, so we preserve all analyses.
    void getAnalysisUsage(AnalysisUsage &AU) const override {
      AU.setPreservesAll();
    }
    std::map<std::string, uint> opCodeMap;
  };
}

char Hello3::ID = 0;
static RegisterPass<Hello3>
Z("hello3", "show how to solve getElementType");

因为需要操作数组和结构体,我们这次采用了一个新的测试文件array.c

 1 struct stu{
 2     int number;
 3     char gender;
 4 };
 5 int main(){
 6     int a[3];
 7     a[2] = 1;
 8     struct stu ct;
 9     ct.number = 123;
10     ct.gender = 'm';
11     return 0;
12 }

编程生成bc文件后,测试结果如下:

原文地址:https://www.cnblogs.com/jourluohua/p/14556209.html