LLVM里的寄存器分配 - 准备工作(一)

本文是关于LLVM寄存器分配的科研笔记,详细介绍了在进行寄存器分配前的主要准备工作,包括PHI消除、二地址转换、LiveInterval计算等。通过分析LLVM编译过程中MIR的演变,阐述了如何处理SSA形式的中间表示,为后续的寄存器分配奠定基础。
摘要由CSDN通过智能技术生成

1 背景介绍

本文档是基于 LLVM 的寄存器分配系列科研笔记第一篇,以一个 C 语言程序为主干介绍 LLVM 在寄存器分配前做的一些主要工作,分析在寄存器分配前期可能的写操作来源,并记录了我在研究 LLVM 后端中 SSA 形式的中间表示时的一些想法(私货)。


2 进入寄存器分配

我们以下述 C 语言源码为例开始本文的说明:

int foo(int a, int b, int e) {
   
  b = a + e;
  a = b * e;
  e = a * b;
  b = a * e;
  b = b * e;
  return b;
}

根据我的上一篇博文 LLVM SSA 介绍 可知,经过 mem2reg pass 后,最初 Clang 默认生成的 Alloca/Load/Store 形式的 IR 被转化成了完全 SSA 形式的 IR。这时,源变量在 SSA IR 中已经有了许多重命名,如下述代码所示,%add、%mul2、%mul3 都是源程序变量(以下简称源变量)b 的重命名:

define i32 @foo(i32 %a, i32 %b, i32 %e) #0 {
entry:
  %add = add nsw i32 %a, %e
  %mul = mul nsw i32 %add, %e
  %mul1 = mul nsw i32 %mul, %add
  %mul2 = mul nsw i32 %mul, %mul1
  %mul3 = mul nsw i32 %mul2, %mul1
  ret i32 %mul3
}

这个结果是很直观的,SSA IR 中的每一条指令都与源程序中每一条语句一一对应。在此 SSA IR 里,所有重命名都是虚拟寄存器,这些重命名在后面的 MIR 中是以 <%vreg + idx> (%vreg0、%vreg1…) 的虚拟寄存器形式表示的。但是,并不是 SSA IR 中所有的重命名都会在 MIR 中生成相应的<%vreg + idx>。我们可以分析刚刚进入寄存器分配时此程序的 MIR,通过给 llc 添加 -print-after=livevars 选项(给 llc 加上 -help-hidden 选项可以查看 -print-after 支持的所有 pass 名称)可以观察做了活变量分析后的 MIR,此阶段的 MIR 尚未做 PHI 指令消除和二地址转换:

Frame Objects:
  fi#-3: size=4, align=4, fixed, at location [SP+12]
  fi#-2: size=4, align=4, fixed, at location [SP+8]
  fi#-1: size=4, align=4, fixed, at location [SP+4]

BB#0: derived from LLVM BB %entry
        %vreg0<def> = MOV32rm <fi#-3>, 1, %noreg, 0, %noreg; mem:LD4[FixedStack-3] GR32:%vreg0
        %vreg1&l
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值