• LLVM 笔记(五)—— LLVM IR


    ilocker:关注 Android 安全(新手) QQ: 2597294287

    LLVM 的 IR (Intermediate Representation) 是其设计中的最重要的部分。优化器在进行代码优化时所进行的分析和转换都是针对 IR 的。

    在设计 IR 时,考虑到了很多明确的目标,包括:支持轻量级的运行时优化、交叉函数/过程间优化、整体程序分析和侵入式调整转换等等。

    原文:including supporting lightweight runtime optimizations, cross-function/interprocedural optimizations, whole program analysis, and aggressive restructuring transformations, etc.

    LLVM IR 本身具备定义良好的语义,下面是一个 .ll 文件的简单示例:

    define i32 @add1(i32 %a, i32 %b) {
    entry:
      %tmp1 = add i32 %a, %b
      ret i32 %tmp1
    }
    
    define i32 @add2(i32 %a, i32 %b) {
    entry:
      %tmp1 = icmp eq i32 %a, 0
      br i1 %tmp1, label %done, label %recurse
    
    recurse:
      %tmp2 = sub i32 %a, 1
      %tmp3 = add i32 %b, 1
      %tmp4 = call i32 @add2(i32 %tmp2, i32 %tmp3)
      ret i32 %tmp4
    
    done:
      ret i32 %b
    }

    这段 IR 对应的 c 代码如下:

    1 unsigned add1(unsigned a, unsigned b) {
    2   return a+b;
    3 }
    4 
    5 unsigned add2(unsigned a, unsigned b) {
    6   if (a == 0) 
    7 return b;
    8   return add2(a-1, b+1);
    9 }

    从示例可以看出,LLVM IR 是一个 low-level RISC-like 虚拟指令集,支持 add、subtract (减)、compare、branch 指令。支持 label,并且通常看起来像是一种奇怪格式的汇编语言。

    与大多数 RISC 指令集不同,LLVM IR 是强类型的,并具有一个简单的类型系统。如:i32 是 32 位整数,而 i32** 是指向 32 位整数的指针的指针。

    LLVM IR 抽象了一些机器细节。比如,借助 call 和 ret 指令及其显示参数抽象了调用约定 (call convention)。

    LLVM IR 不使用一套固定的命名寄存器,而是使用以 % 字符命名的临时变量 (如:%tmp1、%a、%b)。

    LLVM IR 有三种定义形式:上面示例中的文本形式;内存中的数据结构 (做优化时使用);高效的密集型的磁盘二进制“位代码 (bitcode)”格式。

    llvm-as 工具可以将 .ll 文件 (文本形式的 IR) 转换为 .bc 文件 (位代码格式的 IR)。llvm-dis 工具可以将 .bc 文件转换为 .ll 文件。

    优化器针对 IR 进行优化,而不用去管前端输入的是何种编程语言,后端生成的是何种目标平台的指令。LLVM IR 在设计时必须考虑到前端能够容易生成 IR,并且支持针对真实的目标平台执行重要的优化。

  • 相关阅读:
    输入流输出流打印到文件
    前缀和
    树形dp
    快速幂 ,快速幂优化,矩形快速幂(java)
    尾递归
    java中bigInteger的应用
    求树的最大直径
    买不到的数目
    ccpc 长春站 G
    大学ACM第二周心得
  • 原文地址:https://www.cnblogs.com/ilocker/p/4908722.html
Copyright © 2020-2023  润新知