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);
}
在 上面的示例函数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 }
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; }
四、