この記事は個人的な学習メモです。
- 前記事
MIRの構成
エンベデッドモジュール
MIRの前半にはLLVM IRのモジュールが記載される。これは、MIRにはグローバル変数や外部関数への参照、関数属性、メタデータ、デバッグ情報に相当するものがないため、IRの情報を完全にMIRに置き換えることができないという理由がある。
マシンファンクション
MIRの後半にはマシンファンクションが記載される。
マシンファンクションは複数のアトリビュートで構成される。
- name: ファンクションを識別する名前
- body: マシン基本ブロックとその命令列
- callSites: ファンクションのコールサイト情報
---
name: inc
tracksRegLiveness: true
liveins:
- { reg: '$rdi' }
callSites:
- { bb: 0, offset: 3, fwdArgRegs:
- { arg: 0, reg: '$edi' } }
body: |
bb.0.entry:
liveins: $rdi
$eax = MOV32rm $rdi, 1, _, 0, _
$eax = INC32r killed $eax, implicit-def dead $eflags
MOV32mr killed $rdi, 1, _, 0, _, $eax
CALL64pcrel32 @foo <regmask...>
RETQ $eax
...
マシン命令の構成
マシン基本ブロック
マシンファンクションのbodyに書かれるマシン命令は、基本ブロックの単位で記載される。
基本ブロックにはbb.<ID>
のように識別IDを含むラベルがついている。また、bb.<ID>.<name>
のようにIDに加えて名前をつけることもできる。
bb.0.entry
<instructions>
bb.1:
<instructions>
ブロックの参照
定義したマシン基本ブロックを参照するときは%bb.<ID>
や%bb.<ID>.<name>
とする。
サクセッサー
successors
はサクセッサーとなるブロックを記載する際のアトリビュートである。分岐先として複数のブロックを記載することができる。
bb.0.entry:
successors: %bb.1.then, %bb.2.else
<instructions>
bb.1.then:
<instructions>
bb.2.else:
<instructions>
分岐のブランチウェイトを記載することもできる。以下は2つのサクセッサーのブランチウェイトが32, 16で分岐することを示している。
bb.0.entry:
successors: %bb.1.then(32), %bb.2.else(16)
生存するレジスタ
マシン基本ブロックの開始時にデータが割り付けられているレジスタはliveins
として宣言する。
bb.0.entry:
liveins: $edi, $esi
その他の属性
マシン基本ブロックの属性としてIsAddressTaken
, IsLandingPad
, IsInlineAsmBrIndirectTarget
, Alignment
を付与することができる。
bb.0.entry (address-taken):
<instructions>
bb.2.else (align 4):
<instructions>
bb.3(landing-pad, align 4):
<instructions>
bb.4 (inlineasm-br-indirect-target):
<instructions>