LLVMWhat is?

LLVM is a framework system of architecture compilers, written in C++, used to optimize compile-time, link-time, run-time, and idle-time of programs written in any programming language. Keep it open to developers, and open source on GitHub

iniOSWhether or notSwiftorOCThe middle of them meansIRAre allLLVMAre standard three-step designs built on top of the LLVM architecture

How to generateLLVMfile

Because Swift and OC compile tools are different, the commands used to generate LLVM files are different.

  • OCThe compilation tool isclang:
Clang-s-emit - LLVM file nameCopy the code
  • SwiftUsing aswiftc:
Swiftc-emit -ir File nameCopy the code

For convenience, you can write a script in Xcode to generate LLVM quickly. The script method refer to my article on generating SIL files.

  • OC:
clang -S -emit-llvm CLLVM/main.c > ./main.ll && open main.ll
Copy the code
  • Swift:
swiftc -emit-ir SwiftSIL/main.swift | xcrun swift-demangle > ./main.ll && open main.ll
Copy the code

Generate the first oneLLVMfile

Create a macOS project in C under Xcode and paste it with the following code:

struct munger_struct{
    int f1;
    int f2;
};
void munge(struct munger_struct *P){
    P[0].f1 = P[1].f1 + P[2].f2;
}
struct munger_struct* array[3].
Copy the code

Then generate the LLVM file:

; Declare the structure type
%struct.munger_struct = type { i32. i32 }
; Declares the array type and size
@array = common global [3 x %struct.munger_struct*] zeroinitializer. align 16
; Function Attrs: noinline nounwind optnone ssp uwtable
define void @munge(%struct.munger_struct* % 0) # 0 {
  ; Struct. Munger_struct * *; %2; munger_struct* *
  % 2 = alloca %struct.munger_struct*. align 8
  store %struct.munger_struct* % 0. %struct.munger_struct六四屠杀% 2. align 8
  ; Retrieves the array pointer to the structure from %2
  % 3 = load %struct.munger_struct*. %struct.munger_struct六四屠杀% 2. align 8
  ; Gets a pointer to munger_struct with subscript 1 from an array pointer
  % 4 = getelementptr inbounds %struct.munger_struct. %struct.munger_struct* % 3. i64 1
  ; Retrieves the pointer to the first element from the structure
  % 5 = getelementptr inbounds %struct.munger_struct. %struct.munger_struct* % 4. i32 0. i32 0
  ; Fetch the value of the element pointer
  % 6 = load i32. i32* % 5. align 4
  ; Repeat the above steps
  % 7 = load %struct.munger_struct*. %struct.munger_struct六四屠杀% 2. align 8
  % 8 = getelementptr inbounds %struct.munger_struct. %struct.munger_struct* % 7. i64 2
  % 9 = getelementptr inbounds %struct.munger_struct. %struct.munger_struct* % 8. i32 0. i32 1
  % 10 = load i32. i32* % 9. align 4
  % 11 = add nsw i32 % 6. % 10
  % 12 = load %struct.munger_struct*. %struct.munger_struct六四屠杀% 2. align 8
  % 13 = getelementptr inbounds %struct.munger_struct. %struct.munger_struct* % 12. i64 0
  % 14 = getelementptr inbounds %struct.munger_struct. %struct.munger_struct* % 13. i32 0. i32 0
  store i32 % 11. i32* % 14. align 4
  ret void
}
Copy the code

LLVMSyntax parsing

  • i: Plastic surgeryInterger, followed by a number indicating the number of bits.
  • align: Align size
  • Type*: said isTypePointer to type
  • alloca: Creates heap space
  • load: Indicates the value from the address pointed to by the pointer
  • store: Assignment operation
  • getelementptrGet an element pointer from an array or structure.
<result> = getelementptr <ty>. <ty>* <ptrval>{. [inrange] <ty> <id x>}*
<result> = getelementptr inbounds <ty>. <ty>* <ptrval>{. [inrange] <ty> <idx>}*
Copy the code

Inbounds is followed by a step type, which can be omitted, then by a pointer to the base address, and finally by the number of offsets to be made. The getelementptr of an array is easier to understand, but the getelementptr of a structure is followed by two offsets, the first of which refers to an offset relative to itself and the second to the subscript of the elements inside the structure.

  • %T = type {<type list>}: This represents a structure
  • [<elementnumber> x <elementtype>]: this represents an array,elementnumberIt’s the number of elements,elementtypeRepresents an array element type.

conclusion

In fact, I found that grammar is simpler than I imagined.

Once you understand the LLVM file, you can delve into the underlying implementation of iOS