# 機能設計書 84-コード生成（LLVM）

## 概要

本ドキュメントは、JuliaコンパイラにおけるLLVMコード生成機能の設計を記述する。本機能は、最適化済みのJulia IR（Intermediate Representation）からLLVM IR への変換を行い、最終的にネイティブマシンコードを生成するための基盤を提供する。

### 本機能の処理概要

LLVM コード生成は、Julia の型推論・最適化パスを経たIRをLLVM IRに変換し、ネイティブコード生成のための中間表現を構築する。

**業務上の目的・背景**：Julia は「高い開発生産性」と「高い実行性能」の両立を目標としている。LLVM をバックエンドとして採用することで、LLVM の豊富な最適化パスとマルチプラットフォーム対応のコード生成器を活用し、x86_64、AArch64、ARMなど多数のターゲットアーキテクチャに対してネイティブコードを生成できる。コード生成層は Julia の型システムとLLVM の型システムの橋渡しを行う重要なコンポーネントである。

**機能の利用シーン**：JIT コンパイル時（初回呼び出し時）および AOT コンパイル時（sysimage生成時）に自動的に呼び出される。開発者は `@code_llvm` マクロで生成されるLLVM IRを確認できる。

**主要な処理内容**：
1. Julia IR → LLVM IR 変換: 各 Julia IR 文を対応する LLVM 命令に変換
2. 型マッピング: Julia の型システムを LLVM の型システムにマッピング
3. GC ルート挿入: ガベージコレクションのためのルート追跡コード挿入
4. ccall/foreigncall 処理: C 関数呼び出しのための引数マーシャリングとコード生成
5. デバッグ情報生成: DWARF デバッグ情報の付与
6. 名前付け: LLVM 値への意味のある名前の付与（デバッグ容易性）

**関連システム・外部連携**：最適化パス（No.82）からの最適化済みIRを入力とし、JITコンパイル（No.85）またはAOTコンパイル（No.86）に出力を渡す。GCランタイム（No.87）との連携でGCルートの管理を行う。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はコンパイラ内部機能であり、直接的なUI画面は存在しない |

## 機能種別

計算処理（コンパイラのコード変換処理）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| CodeInstance | jl_code_instance_t* | Yes | コンパイル対象のメソッド特殊化情報 | 有効なCodeInstanceであること |
| CodeInfo | jl_code_info_t* | Yes | 最適化済みのIR | - |
| jl_codegen_params_t | struct | Yes | コード生成パラメータ（ターゲット情報等） | - |

### 入力データソース

- 最適化パス（optimize.jl）からの最適化済み CodeInfo
- MethodInstance のメタデータ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| LLVM Module | llvm::Module | 生成されたLLVM IRを含むモジュール |
| Function Pointer | void* | JIT コンパイル後の関数ポインタ（JIT時） |
| Object File | バイナリ | AOTコンパイル時のオブジェクトファイル |

### 出力先

- JIT コンパイル: メモリ上にコンパイルされ関数ポインタとして格納
- AOT コンパイル: sysimage として .so/.dylib/.dll に書き出し

## 処理フロー

### 処理シーケンス

```
1. LLVM Module の初期化
   └─ ターゲット情報に基づいて Module を作成
2. 関数シグネチャの変換
   └─ Julia の関数型を LLVM の関数型にマッピング
3. 基本ブロックの生成
   └─ Julia IR の基本ブロック構造を LLVM 基本ブロックに変換
4. 各命令の変換
   └─ call, invoke, getfield, setfield!, 算術演算等を LLVM 命令に変換
5. GC ルートの挿入
   └─ jl_gc_push / jl_gc_pop の挿入とルート追跡
6. ccall の処理
   └─ 引数のマーシャリング、呼び出し規約の設定
7. デバッグ情報の付与
   └─ DIBuilder による DWARF 情報の生成
8. 名前の付与
   └─ setName / setNameWithField による可読性向上
```

### フローチャート

```mermaid
flowchart TD
    A[CodeInstance 入力] --> B[LLVM Module 初期化]
    B --> C[関数シグネチャ変換]
    C --> D[基本ブロック生成]
    D --> E[命令変換ループ]
    E --> F{命令の種類}
    F -->|call/invoke| G[関数呼び出し生成]
    F -->|foreigncall| H[ccall 処理]
    F -->|GotoNode/GotoIfNot| I[分岐命令生成]
    F -->|ReturnNode| J[return 命令生成]
    F -->|その他| K[対応する LLVM 命令生成]
    G --> L[GC ルート挿入]
    H --> L
    I --> L
    J --> L
    K --> L
    L --> M{全命令処理完了?}
    M -->|No| E
    M -->|Yes| N[デバッグ情報付与]
    N --> O[LLVM Module 出力]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-84-01 | 型マッピング | Julia のプリミティブ型は対応する LLVM 型に直接マッピングされる | 型変換時 |
| BR-84-02 | GC ルート | ヒープ割当てオブジェクトへの参照は GC ルートとして追跡される | オブジェクト参照時 |
| BR-84-03 | 効果情報利用 | encode_effects の結果がコード生成の最適化判定に使用される | effects_foldable 判定時 |
| BR-84-04 | 値の名前付与 | Constant には名前を付与しない（setName の assert で検証） | 全ての setName 呼び出し |
| BR-84-05 | フィールド名解決 | NamedTuple と通常の struct でフィールド名解決ロジックが異なる | setNameWithField 呼び出し時 |

### 計算ロジック

特になし。型マッピングは Julia と LLVM の型体系の対応表に基づく。

## データベース操作仕様

本機能はデータベースを使用しない。

### 操作別データベース影響一覧

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | LLVM 検証エラー | 生成した LLVM IR が不正 | llvm::verifyFunction でデバッグビルド時に検出 |
| - | assert 失敗 | setName が Constant に対して呼ばれた | コンパイラバグとして報告 |

### リトライ仕様

該当なし。

## トランザクション仕様

該当なし。

## パフォーマンス要件

- コード生成はJITコンパイルのクリティカルパスであるため、高速に完了すべき
- LLVM 値の名前付けは `shouldDiscardValueNames()` でリリースビルド時に省略可能
- Polly（多面体最適化）は `USE_POLLY` フラグで有効化可能

## セキュリティ考慮事項

- `@inbounds` による境界チェック除去はバッファオーバーフローのリスクとなりうる
- ccall による外部関数呼び出しはメモリ安全性の保証を超える

## 備考

- `llvm-version.h` でLLVMバージョン依存のコードが `JL_LLVM_VERSION` マクロで分岐されている
- ITT API（Intel VTune）サポートが `USE_ITTAPI` フラグで有効化可能
- `DEBUG_TYPE "julia_irgen_codegen"` でLLVMの統計情報とデバッグ出力を制御

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | jitlayers.h | `src/jitlayers.h` | jl_codegen_params_t 構造体: コード生成の全パラメータ |
| 1-2 | codegen.cpp | `src/codegen.cpp` | 型ヘルパー関数（88-135行目）: getInt1Ty 等の LLVM 型取得ユーティリティ |

**読解のコツ**: codegen.cpp は非常に大きなファイル（数千行）であるため、関数単位で読み進めることを推奨する。`setName`/`maybeSetName`/`setNameWithField`（150-199行目）は全体で頻用されるユーティリティであり、先に理解しておくとよい。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | codegen.cpp | `src/codegen.cpp` | emit_function: メインのコード生成エントリーポイント |
| 2-2 | jitlayers.cpp | `src/jitlayers.cpp` | JIT レイヤーからの codegen 呼び出し |

#### Step 3: ccall 処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ccall.cpp | `src/ccall.cpp` | foreigncall の引数マーシャリングと呼び出し生成 |

### プログラム呼び出し階層図

```
jl_compile_method_internal (jitlayers.cpp)
    |
    +-- jl_emit_code (codegen.cpp)
    |      +-- emit_function
    |      |      +-- 基本ブロック生成
    |      |      +-- 命令変換ループ
    |      |      |      +-- emit_ssaval / emit_expr
    |      |      |      +-- emit_ccall (ccall.cpp)
    |      |      +-- GC ルート挿入
    |      |      +-- デバッグ情報生成
    |      +-- setName / setNameWithField
    |
    +-- LLVM Module 最適化パス
    +-- ネイティブコード生成
```

### データフロー図

```
[入力]                        [処理]                     [出力]

CodeInstance         --> jl_emit_code              --> LLVM Module
  +-- CodeInfo       --> emit_function             --> LLVM Function
  +-- MethodInstance --> 型マッピング               --> LLVM Types
                     --> 命令変換                   --> LLVM Instructions
                     --> GCルート挿入              --> GC Intrinsics
                     --> デバッグ情報               --> DWARF Metadata
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| codegen.cpp | `src/codegen.cpp` | ソース | Julia IR → LLVM IR 変換のメインファイル |
| ccall.cpp | `src/ccall.cpp` | ソース | foreigncall（C関数呼び出し）の処理 |
| jitlayers.h | `src/jitlayers.h` | ヘッダ | コード生成パラメータ・JITレイヤーの型定義 |
| jitlayers.cpp | `src/jitlayers.cpp` | ソース | JIT コンパイルレイヤー（codegen の呼び出し元） |
| intrinsics.cpp | `src/intrinsics.cpp` | ソース | Julia Intrinsic関数のLLVM IR生成 |
| llvm-version.h | `src/llvm-version.h` | ヘッダ | LLVM バージョン互換性マクロ |
| processor.h | `src/processor.h` | ヘッダ | プロセッサ検出・ターゲット情報 |
