天天看点

LLVM学习笔记-代码实例HowToUseJIT 分析(一)

37 #include "llvm/LLVMContext.h"

38 #include "llvm/Module.h"

39 #include "llvm/Constants.h"

40 #include "llvm/DerivedTypes.h"

41 #include "llvm/Instructions.h"

42 #include "llvm/ExecutionEngine/JIT.h"

43 #include "llvm/ExecutionEngine/Interpreter.h"

44 #include "llvm/ExecutionEngine/GenericValue.h"

45 #include "llvm/Target/TargetSelect.h"

46 #include "llvm/Support/ManagedStatic.h"

47 #include "llvm/Support/raw_ostream.h"

48 using namespace llvm;

49

50 int main() {

51

52 InitializeNativeTarget();

53

54 LLVMContext Context;

55

56 // Create some module to put our function into it.

57 Module *M = new Module("test", Context);

58

59 // Create the add1 function entry and insert this entry into module M. The

60 // function will have a return type of "int" and take an argument of "int".

61 // The '0' terminates the list of argument types.

62 Function *Add1F =

63 cast<Function>(M->getOrInsertFunction("add1", Type::getInt32Ty(Context),

64 Type::getInt32Ty(Context),

65 (Type *)0));

在HowToUseJIT这个例子是演示了如何用LLVM创建两个函数并执行的过程,其函数的c语言原型如下:

 int add1(int x) {

   return x+1;

 }

 int foo() {

   return add1(10);

 }

一、InitializeNativeTarget

在 上面的示例函数52行调用了InitializeNativeTarget函数,这个函数主要是用来初始化相应于主机的目标机,JIT应用程序通过这个

函数调用来确保目标机的相应库已经链接到程序中。其函数实现如下:

101 inline bool InitializeNativeTarget() {

102 // If we have a native target, initialize it to ensure it is linked in.

103 #ifdef LLVM_NATIVE_TARGET

104 LLVM_NATIVE_TARGETINFO();

105 LLVM_NATIVE_TARGET();

106 return false;

107 #else

108 return true;

109 #endif

110 }

二、LLVMContext

HowToUseJIT代码的54行声明了一个类型为LLVMContext的实例Context,这个类在文件include/llvm/LLVMContext.h定义。在代码中对这个类注释如下:

/// This is an important class for using LLVM in a threaded context.  It

/// (opaquely) owns and manages the core "global" data of LLVM's core

/// infrastructure, including the type and constant uniquing tables.

/// LLVMContext itself provides no locking guarantees, so you should be careful

/// to have one context per thread.

我理解这个LLVMContext针对每一个线程记录了线程本地的变量,即对于每一个LLVM的线程,都对应了这样一个context的实例。

三、Module

然后在代码的57行初始化了一个module变量。在代码注释中对Module的描述如下:

/// A Module instance is used to store all the information related to an

/// LLVM module. Modules are the top level container of all other LLVM

/// Intermediate Representation (IR) objects. Each module directly contains a

/// list of globals variables, a list of functions, a list of libraries (or

/// other modules) this module depends on, a symbol table, and various data

/// about the target's characteristics.

一个Module的实例用于存储一个模块中的所有信息,是其他所有LLVM中间表示对象的容器。每个目标会直接包含一个全局变量的列表,

一个函数的列表,和这个模块依赖的函数库的列表,一个符号表,和这个目标特性的一些数据。

其中Module的类声明中有如下成员变量:

public:

  typedef iplist<GlobalVariable> GlobalListType;

  /// The type for the list of functions.

  typedef iplist<Function> FunctionListType;

  /// The type for the list of aliases.

  typedef iplist<GlobalAlias> AliasListType;

  /// The type for the list of named metadata.

  typedef ilist<NamedMDNode> NamedMDListType;

  /// The type for the list of dependent libraries.

  typedef std::vector<std::string> LibraryListType;

private:

  LLVMContext &Context;           ///< The LLVMContext from which types and

                                  ///< constants are allocated.

public:

  /// Get the target endian information.

  /// @returns Endianess - an enumeration for the endianess of the target

  Endianness getEndianness() const;

  /// Get the target pointer size.

  /// @returns PointerSize - an enumeration for the size of the target's pointer

  PointerSize getPointerSize() const;

  /// Get the global data context.

  /// @returns LLVMContext - a container for LLVM's global information

  LLVMContext &getContext() const { return Context; }

四、

继续阅读