LLVM IR 笔记

                     

贡献者: addis

  • 本文处于草稿阶段。
预备知识 LLVM 笔记

   LLVM IR (Intermediate Representation) 是 LLVM 的一个 portable 的中间语言。使用 LLVM 的编译器会先把高级语言编译成 IR,然后再做进一步优化。LLVM IR 的语法和汇编语言类似。

   一个完整的例子,可以编译运行

代码 1:test.ll
; Declare the main function
define i32 @main() {
  entry:
    ; Allocate stack space for a single 32-bit integer in the stack memory
    ; `var` is a pointer
    %var = alloca i32

    ; Store the value 42 into the variable on memory stack
    store i32 42, i32* %var

    ; Load the value of the variable into a [virtual] register
    %val = load i32, i32* %var

    ; Return the value of the register
    ret i32 %val
}

   编译:

llvm-as test.ll -o test.bc # 编译成 bitcode
clang test.bc -o test # 编译成可执行文件
./test # 执行
echo $? # 查看返回值(exit status)

   以下是一个函数例子:计算两个整数相加。

define i32 @add(i32 %a, i32 %b) {
  entry:
    %sum = add i32 %a, %b
    ret i32 %sum
}

   调用该函数

define i32 @main() {
  entry:
    ; set a=10, b=20 in registers
    %a = add i32 0, 10
    %b = add i32 0, 20
    %sum = call i32 @add(i32 %a, i32 %b)
    ret i32 %sum
}

   其中对 a, b 的赋值也可以用

%a = or i32 10, 0
%b = or i32 20, 0

   第三种方法是从内存 stack 中加载到 register

define i32 @main() {
  entry:
    %a = alloca i32
    %b = alloca i32
    store i32 10, i32* %a
    store i32 20, i32* %b
    %a_val = load i32, i32* %a
    %b_val = load i32, i32* %b
    %sum = call i32 @add(i32 %a_val, i32 %b_val)
    ret i32 %sum
}

1. 常识

2. 判断

3. 循环

   一个什么都不做的空循环

define void @countUpTo(i32 %limit) {
  entry:
    ; Initialize loop variable
    %i = alloca i32
    store i32 0, i32* %i

    ; Jump to the loop condition check
    br label %loop.cond

  loop.cond:
    ; Load loop variable
    %i.val = load i32, i32* %i

    ; Check if the loop variable is less than the limit
    %cond = icmp slt i32 %i.val, %limit
    br i1 %cond, label %loop.body, label %loop.end

  loop.body:
    ; Increment the loop variable
    %next.val = add i32 %i.val, 1
    store i32 %next.val, i32* %i

    ; Jump back to the loop condition
    br label %loop.cond

  loop.end:
    ; Exit point of the loop
    ret void
}

   生成数组 [1,2,3,4]

define void @assignArray() {
  entry:
    ; Allocate an array of 4 integers on the stack
    %array = alloca [4 x i32]

    ; Loop counter
    %i = alloca i32
    store i32 0, i32* %i

    ; Jump to the loop condition
    br label %loop.cond

  loop.cond:
    ; Load the loop counter
    %i.val = load i32, i32* %i

    ; Check if the loop counter is less than 4
    %cond = icmp slt i32 %i.val, 4
    br i1 %cond, label %loop.body, label %loop.end

  loop.body:
    ; Calculate the address of the current array element
    %addr = getelementptr [4 x i32], [4 x i32]* %array, i32 0, i32 %i.val

    ; Assign the corresponding value (i+1) to the array element
    %val = add i32 %i.val, 1
    store i32 %val, i32* %addr

    ; Increment the loop counter
    %next.i = add i32 %i.val, 1
    store i32 %next.i, i32* %i

    ; Jump back to the loop condition
    br label %loop.cond

  loop.end:
    ; Exit point of the loop
    ret void
}

   要在 heap 中分配内存,取决于所在系统,一般调用 C 语言的 malloc

declare i8* @malloc(i32) ; 声明 malloc

define i32* @createArray() {
  entry:
    ; Calculate the size of the array (4 integers)
    %size = mul i32 4, 4 ; size for 4 integers (assuming i32 is 4 bytes)

    ; Call malloc to allocate memory on the heap
    %arrayPtr = call i8* @malloc(i32 %size)

    ; Cast the returned i8* (generic pointer) to i32* (pointer to integers)
    %typedArrayPtr = bitcast i8* %arrayPtr to i32*

    ; Return the pointer to the allocated memory
    ret i32* %typedArrayPtr
}


致读者: 小时百科一直以来坚持所有内容免费无广告,这导致我们处于严重的亏损状态。 长此以往很可能会最终导致我们不得不选择大量广告以及内容付费等。 因此,我们请求广大读者热心打赏 ,使网站得以健康发展。 如果看到这条信息的每位读者能慷慨打赏 20 元,我们一周就能脱离亏损, 并在接下来的一年里向所有读者继续免费提供优质内容。 但遗憾的是只有不到 1% 的读者愿意捐款, 他们的付出帮助了 99% 的读者免费获取知识, 我们在此表示感谢。

                     

友情链接: 超理论坛 | ©小时科技 保留一切权利