LLVM中常见的数据结构

在介绍数据结构之前,llvm官方首先让我们熟悉isa操作。这是类似于javaisinstance操作,这是在面向对象中用来看对象的类型。如官方的例子

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
class Shape {
public:
  enum ShapeKind {
    SK_Square,
    SK_Circle
  };
  ShapeKind getKind() const { return Kind; }
  Shape(ShapeKind K) : Kind(K) {}
  virtual double computeArea() = 0;

private:
  const ShapeKind Kind;
};

class Square : public Shape {
  double SideLength;
public:
  Square(double S) : Shape(SK_Square), SideLength(S) {}
  double computeArea() override;

  static bool classof(const Shape *S) {
    return S->getKind() == SK_Square;
  }
};

double Square::computeArea() {
    return SideLength * 4;
}

class Circle : public Shape {
  double Radius;
public:
  Circle(double R) : Shape(SK_Circle), Radius(R) {}
  double computeArea() override;
  static bool classof(const Shape *S) {
    return S->getKind() == SK_Circle;
  }
};

double Circle::computeArea() {
    return 2 * 3.14 * Radius;
}

int main() {
    Shape *S = new Circle(4.2);
    if(isa<Circle>(S)) {
        std::cout << S->computeArea() << std::endl;
    }
}

首先定义一个基类,在里面定义了一个枚举类型,表示从该基类派生出来的所有类型。一旦定义一个对象,就可以使用isa来检测该对象是什么类,在llvm这个高度面向对象框架前非常有用. 还有cast进行转化。

  1. StringRef
  2. SmallVector

1. StringRef “llvm/ADT/StringRef.h”

是LLVM中最常用的字符串类。该类可以表达二进制字符串,因为char*类型的字符串需要有\n作为结尾,因此对二进制字符串表示来说并不好,StringRef也可以用std::string来表达,但是性能上标准库可能有点不友好。同时实现了很多很多常用的方法而标准库里面没有的。 StringRef

2. SmallVector “llvm/ADT/SmallVector.h”

是llvm中最常用的数组容器。由于使用场景是小,因此没有标准库vector那种堆分配空间,因此速度很快。SmallVector

3. BitVector “llvm/ADT/BitVector.h”

是llvm中用来操作bit数组的数据结构。实现了常见的bit操作,但是是以数组形式的操作。

4. DenseMap “llvm/ADT/DenseMap.h”

是llvm中的关系容器,可以像std::map一样使用。DenseMap

5. DenseSet “llvm/ADT/DenseSet.h”

是llvm中的集合容器,可以像std::set一样使用。 DenseSet

6.

Reference

  1. L6-LLVM2-1up.pdf

  2. LLVM Programmer’s Manual

  3. llvm blog