# 機能設計書 24-llvm-as

## 概要

本ドキュメントは、LLVM llvm-asの機能設計について記述する。llvm-asは、LLVM アセンブリ言語（.ll形式）からLLVMビットコード（.bc形式）への変換を行うアセンブラツールである。

### 本機能の処理概要

llvm-asは、人間可読なLLVM IR（Intermediate Representation）テキスト形式をバイナリのビットコード形式に変換するツールである。これにより、テキストエディタで作成・編集したIRをコンパイラツールチェーンの他のツールで処理可能な形式に変換できる。

**業務上の目的・背景**：LLVM IRはテキスト形式（.ll）とバイナリ形式（.bc）の2つの表現を持つ。テキスト形式は人間が読み書きしやすいが、バイナリ形式の方がファイルサイズが小さく、パース時間も短い。llvm-asは両形式間の変換を行い、開発・デバッグワークフローを支援する。

**機能の利用シーン**：
- 手書きのLLVM IRテストケースをビットコードに変換
- デバッグ目的でのIRテキスト作成後のビットコード変換
- 教育・学習目的でのIR作成と実行
- CIパイプラインでのIRファイル処理

**主要な処理内容**：
1. コマンドライン引数の解析
2. 入力ファイル（.ll）の読み込み
3. LLVM IRパーサーによるアセンブリ解析
4. モジュール検証（オプション）
5. ビットコードファイル（.bc）の出力

**関連システム・外部連携**：llvm-dis（逆変換）、opt（最適化）、llc（コード生成）

**権限による制御**：特になし。ファイルアクセス権限はOSに依存。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はコマンドラインツールであり、画面は存在しない |

## 機能種別

データ変換ツール / アセンブラ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input file | string | No | 入力.llファイル（デフォルト: stdin） | ファイル存在確認 |
| -o | string | No | 出力ファイル名 | - |
| -f | flag | No | ターミナルへのバイナリ出力を許可 | - |
| -disable-output | flag | No | 出力を無効化 | - |
| -module-hash | flag | No | モジュールハッシュを出力 | - |
| -d | flag | No | パース結果のアセンブリを表示（デバッグ用） | - |
| -disable-verify | flag | No | 検証をスキップ（危険） | - |
| -data-layout | string | No | データレイアウト文字列を指定 | - |

### 入力データソース

- 標準入力または.llファイル
- LLVM アセンブリ言語形式

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| .bcファイル | binary | LLVMビットコード形式 |
| エラーメッセージ | text | パースエラー情報（stderr） |

### 出力先

- 標準出力または指定されたファイル
- 入力が`x.ll`の場合、デフォルト出力は`x.bc`

## 処理フロー

### 処理シーケンス

```
1. 初期化
   └─ InitLLVMでLLVM初期化
   └─ コマンドライン引数解析

2. LLVMContext作成
   └─ IRパース用のコンテキスト

3. アセンブリファイル解析
   └─ parseAssemblyFileWithIndex()呼び出し
   └─ データレイアウト設定（オプション）
   └─ ModuleとModuleSummaryIndex取得

4. モジュール検証（-disable-verify未指定時）
   └─ verifyModule()呼び出し
   └─ エラー時は終了

5. デバッグ出力（-d指定時）
   └─ パース結果のIRを標準エラー出力

6. ビットコード出力
   └─ 出力ファイル名推論（必要時）
   └─ WriteBitcodeToFile()呼び出し
   └─ モジュールハッシュ出力（オプション）
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[InitLLVM]
    B --> C[コマンドライン解析]
    C --> D[LLVMContext作成]
    D --> E{disable-verify?}
    E -->|Yes| F[parseAssemblyFileWithIndexNoUpgradeDebugInfo]
    E -->|No| G[parseAssemblyFileWithIndex]
    F --> H{パース成功?}
    G --> H
    H -->|No| I[エラー出力・終了]
    H -->|Yes| J{disable-verify?}
    J -->|Yes| L{dump-asm?}
    J -->|No| K[verifyModule]
    K --> M{検証成功?}
    M -->|No| I
    M -->|Yes| L
    L -->|Yes| N[IR出力 to stderr]
    L -->|No| O{disable-output?}
    N --> O
    O -->|Yes| P[終了]
    O -->|No| Q[WriteOutputFile]
    Q --> P
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 出力ファイル名推論 | 入力が`x.ll`の場合、出力は`x.bc` | -oオプション未指定時 |
| BR-002 | stdin入力時 | 出力はstdoutへ | 入力が`-`の場合 |
| BR-003 | モジュール検証デフォルト | 検証はデフォルトで有効 | -disable-verify未指定時 |

### 計算ロジック

特になし。パースと出力のみ。

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | Parse Error | IRパース失敗 | IR構文を修正 |
| 1 | Verify Error | モジュール検証失敗 | IR内容を修正 |
| 1 | File Error | 出力ファイル作成失敗 | パーミッション確認 |

### リトライ仕様

エラー時は終了コード1で終了。リトライは呼び出し元の責任。

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

該当なし（ファイル変換ツール）

## パフォーマンス要件

- 大規模IRファイルのパースは時間がかかる場合がある
- ビットコード出力はテキストよりコンパクト

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

- -disable-verifyは危険なオプションとして警告
- ファイル出力はOSの権限システムに従う

## 備考

- llvm-disと対になるツール（.bc → .ll変換）
- ThinLTOインデックスもサポート

---

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

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

### 推奨読解順序

#### Step 1: メインソースを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | llvm-as.cpp | `llvm/tools/llvm-as/llvm-as.cpp` | ツール全体の実装 |

**主要処理フロー**:
- **33-63行目**: コマンドラインオプション定義
- **65-108行目**: WriteOutputFile()関数 - ビットコード出力処理
- **110-163行目**: main()関数 - メイン処理フロー

**読解のコツ**: cl::opt/cl::OptionCategoryはLLVMのコマンドラインパーサー。各オプションの定義を確認する。

#### Step 2: main関数の詳細を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | llvm-as.cpp | `llvm/tools/llvm-as/llvm-as.cpp` | main関数の処理フロー |

**主要処理フロー**:
- **110-113行目**: LLVM初期化とコマンドライン解析
- **114行目**: LLVMContext作成
- **117-130行目**: アセンブリファイルのパース（検証有無で分岐）
- **131-135行目**: パース失敗時のエラー処理
- **137行目**: デバッグイントリンシック宣言の削除
- **141-151行目**: モジュール検証
- **153-157行目**: デバッグ出力（-d指定時）
- **159-160行目**: 出力処理

#### Step 3: 出力処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | llvm-as.cpp | `llvm/tools/llvm-as/llvm-as.cpp` | WriteOutputFile関数 |

**主要処理フロー**:
- **66-75行目**: 出力ファイル名の推論ロジック
- **77-83行目**: 出力ファイルのオープン
- **85-104行目**: ビットコード出力（モジュール/インデックス分岐）
- **107行目**: 出力ファイルの確定

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

```
main()
    │
    ├─ InitLLVM()
    │
    ├─ cl::ParseCommandLineOptions()
    │
    ├─ parseAssemblyFileWithIndex() または
    │  parseAssemblyFileWithIndexNoUpgradeDebugInfo()
    │      └─ AsmParser（LLVM内部）
    │
    ├─ verifyModule()
    │      └─ IR検証（LLVM内部）
    │
    └─ WriteOutputFile()
           ├─ ToolOutputFile()
           ├─ WriteBitcodeToFile() または
           │  writeIndexToFile()
           └─ Out->keep()
```

### データフロー図

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

.llファイル/stdin ────────▶ parseAssemblyFileWithIndex()
                                   │
                                   ▼
                              Module*
                              ModuleSummaryIndex*
                                   │
                                   ▼
                           verifyModule()（オプション）
                                   │
                                   ▼
                           WriteOutputFile()
                                   │
                                   ▼
                           WriteBitcodeToFile() ──────▶ .bcファイル/stdout
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| llvm-as.cpp | `llvm/tools/llvm-as/llvm-as.cpp` | ソース | メイン実装 |
| CMakeLists.txt | `llvm/tools/llvm-as/CMakeLists.txt` | ビルド設定 | ビルドスクリプト |
| Parser.h | `llvm/include/llvm/AsmParser/Parser.h` | ヘッダ | パーサーAPI |
| BitcodeWriter.h | `llvm/include/llvm/Bitcode/BitcodeWriter.h` | ヘッダ | ビットコード出力API |
| Verifier.h | `llvm/include/llvm/IR/Verifier.h` | ヘッダ | 検証API |
| Module.h | `llvm/include/llvm/IR/Module.h` | ヘッダ | Module定義 |
| LLVMContext.h | `llvm/include/llvm/IR/LLVMContext.h` | ヘッダ | Context定義 |
