本文へ移動
cccskills
無料GitHub で公開日本語紹介

Builtin functions

Carbonコンパイラに組み込み関数を追加する際の登録、型シグネチャ検証、定数評価、LLVMコード生成、テスト方法を案内します。

原文原文の説明を見る

Instructions for registering, mapping, constant evaluating, and lowering builtin functions in the Carbon toolchain.

carbon-language/carbon-langスター 33,929(GitHub 33,929 + cccskills 0)

実行スコア 未検証

インストール方法を見る

こんなときに便利

  • 組み込み関数を登録したいとき
  • 定数評価の処理を実装したいとき
  • LLVM IRへの変換を追加したいとき
  • 組み込み関数のテストを書きたいとき

日本語での紹介

できること

Carbonコンパイラに組み込み関数を追加する一連の作業を扱います。関数種別の登録、名前と引数制約の対応付け、コンパイル時だけ評価する関数の指定、定数評価の実装、実行時呼び出しのLLVM IRへの変換、Preludeからのバインディングまでを順に確認できます。整数や浮動小数点数の値を扱う際の範囲チェックや診断の追加、最小Preludeを使って組み込み関数を個別に検証するテストの作り方も説明しています。

こんなときに便利

Carbonの組み込み関数を新設・変更するコンパイラ開発者向けです。コンパイル時評価と実行時コード生成のどちらに処理を実装するか整理したい場合や、Preludeとの接続、テストの切り分け方を確認したい場合に使えます。

使い方の例

  • 「新しい組み込み関数を登録して定数評価を実装する手順を教えて」
  • 「この組み込み関数をLLVM IRに変換する場所を確認して」
  • 「Preludeに依存せず組み込み関数を検証するテストを作って」

注意点

C++、LLVM IR、Carbonのコンパイラ構成を前提とします。

この紹介文は、公開されている SKILL.md をもとに AI(OpenAI Codex)が作成しました。正確な仕様は下の原文を確認してください。

資料チェック

SKILL.md の記述から、注意が要る操作と導入の前提を AI が確認しました。点数は実際に動かした結果(実行検証)だけで付けています。

安全面送信・削除・コマンド実行などの扱いが明示されているか
A良好コンパイラ内部の実装とテストを扱い、外部送信や削除操作は示されない。
導入のしやすさ必要なツールや API キーが少ないか、書かれているか
B一部不足C++、LLVM IR、Carbon構成を前提とするが、環境導入手順はない。

点数には入れていません。 2026年10月26日 時点で AI(OpenAI Codex)が判定しました。目安なので、入れる前に原文も確認してください。

評価が違うと思ったら、見直しを依頼する

どの項目が、なぜ違うと思うかを書いてください。ログインは不要です。内容を SKILL.md と照らし合わせて評価を作り直し、この欄に反映します。

このフォームは reCAPTCHA で保護されており、Google のプライバシーポリシーと利用規約が適用されます。

含まれるファイル(1)

  • SKILL.md11.3 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Builtin Functions in the Carbon Toolchain

<!-- Part of the Carbon Language project, under the Apache License v2.0 with LLVM Exceptions. See /LICENSE for license information. SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -->

Builtin functions are compiler-recognized primitives mapping directly from Carbon code expressions (via standard prelude bindings) to optimized backend execution. This document defines the complete structural workflow, C++ patterns, constant evaluation logic, machine lowering mechanics, library bindings, and validation strategies required to implement builtin functions in the Carbon compiler.


Technical Flow & Lifecycle

graph TD
  Src[Carbon Source Code] -->|Prelude Map| Sem[Semantic Analysis / SemIR]
  Sem -->|Signature Constraint| Sig[builtin_function_kind.cpp]
  Sem -->|Phase Evaluation| Eval[eval.cpp Constant Interpreter]
  Sem -->|Machine Codegen| Lower[handle_call.cpp LLVM Lowering]
  Eval -->|Diagnostics| Diag[diagnostics/kind.def]
  Lower -->|Native Instructions| LLVM[LLVM IR Generation]

Adding a builtin function involves a 5-step integration:

  1. Define the Builtin Kind: Register the enum in builtin_function_kind.def.
  2. Signature & Compile-Time Registry: Declare the mapping name, parameter constraints, and compile-time evaluation residency in builtin_function_kind.cpp.
  3. Compile-Time Interpreter Support: Wire constant evaluation hooks and bounds/exception diagnostics in eval.cpp.
  4. LLVM IR Lowering Support: Connect target machine generation in handle_call.cpp.
  5. Prelude Library Mapping: Bind primitive interfaces to named builtins under core/prelude/.

Detailed Step-by-Step Implementation Guide

Step 1: Kind Definition & Registration

Register your builtin function name using the X-macro in builtin_function_kind.def:

// toolchain/sem_ir/builtin_function_kind.def

// Converts an integer type to a floating-point type.
CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(IntConvertFloat)

Step 2: Signature Validation & Compile-Time Residence

Inside builtin_function_kind.cpp:

  1. Define Parameter Constraints: If the parameter requires novel constraints (e.g. "must be a float type"), define a template constraint struct checking the matching SemIR type instruction (such as FloatType or FloatLiteralType). Use pre-established semantic helpers:

    • TypeParam<I, T>: Ensures different parameters resolve to identical type structures (e.g., generic constraint matching).
    • AnyInt, AnyFloat, AnySizedInt, AnySizedFloat, CharCompatible, StdInitializerList, NoReturn.
  2. Map Literal Name & Register Constraint Signature: Declare a BuiltinInfo constant inside namespace BuiltinFunctionInfo matching the macro-defined name:

    // toolchain/sem_ir/builtin_function_kind.cpp
    
    constexpr BuiltinInfo IntConvertFloat = {
        "int.convert_float", ValidateSignature<auto(AnyInt)->AnyFloat>};
    
  3. Establish Compile-Time Residency Status: Update BuiltinFunctionKind::IsCompTimeOnly to determine if a call requires compile-time evaluation:

    • Checked/Diagnostics Primitives: Return true immediately. Runtime lowering of these is illegal (e.g. IntConvertFloatChecked).
    • Runtime Primitives: Return AnyLiteralTypes(sem_ir, arg_ids, return_type_id) to enforce that expressions involving unsized literal values (like IntLiteral or FloatLiteral) are evaluated exclusively at compile-time (as they lack runtime representation).

Step 3: Constant Evaluation Support

Wire the interpreter inside eval.cpp to execute compile-time computations:

  1. Implement Constant Evaluation Logic:

    • Handle the builtin case inside MakeConstantForBuiltinCall (which processes the compile-time execution of the call).

    • Confirm type validation phase is Phase::Concrete to reject incomplete bindings:

      case SemIR::BuiltinFunctionKind::IntConvertFloat: {
        if (phase != Phase::Concrete) {
          return MakeConstantResult(context, call, phase);
        }
        return PerformIntToFloatConvert(context, loc_id, arg_ids[0], call.type_id,
                                        /*require_exact=*/false);
      }
      
    • Extract inputs safely from local value stores (e.g. context.ints().Get(arg.int_id) or context.floats().Get(arg.float_id)).

    • Leverage high-precision LLVM mathematical structures (llvm::APInt, llvm::APFloat, llvm::APSInt) to handle custom bits and signedness safely.

  2. Diagnose Invalid Parameters or Exceptions:

    • Define compile-time diagnostics inside kind.def:

      // toolchain/diagnostics/kind.def
      CARBON_DIAGNOSTIC_KIND(IntTooLargeForFloatType)
      
    • Emplace localized diagnostic formatting messages where they are caught in eval.cpp:

      CARBON_DIAGNOSTIC(IntTooLargeForFloatType, Error,
                        "integer value {0} too large for floating-point type {1}",
                        llvm::APSInt, SemIR::TypeId);
      context.emitter().Emit(loc_id, IntTooLargeForFloatType, val, dest_type_id);
      
    • Return SemIR::ErrorInst::ConstantId to gracefully abort invalid constant generation rather than crashing the compiler.

  3. Fast-Path Range Limits:

    • Before evaluating expensive math operations on giant exponents (e.g. 1.0e1000000), executing range limits check against dest_width + 64 (sized) or IntStore::MaxIntWidth (unsized) is mandatory to prevent out-of-bounds calculations and compile-time memory exhaustion.

Step 4: Machine Code Generation (LLVM Lowering)

Inside handle_call.cpp:

  1. Map to Native LLVM Instructions: For runtime-eligible builtins, map the call inside HandleBuiltinCall to native LLVM IR builder methods:

    case SemIR::BuiltinFunctionKind::IntConvertFloat: {
      auto* operand = context.GetValue(arg_ids[0]);
      auto* dest_type = context.GetTypeOfInst(inst_id);
      bool is_signed = IsSignedInt(context, arg_ids[0]);
      context.SetLocal(
          inst_id, is_signed
                       ? context.builder().CreateSIToFP(operand, dest_type)
                       : context.builder().CreateUIToFP(operand, dest_type));
      return;
    }
    
  2. Assert on Compile-Time-Only Builtins: Throw a hard assertion on lowering-cases for checked validator builtins that should never hit code generation:

    case SemIR::BuiltinFunctionKind::IntConvertFloatChecked: {
      CARBON_CHECK(builtin_kind.IsCompTimeOnly(
          context.sem_ir(), arg_ids,
          context.sem_ir().insts().Get(inst_id).type_id()));
      CARBON_FATAL("Missing constant value for call to comptime-only function");
    }
    

Step 5: Standard Library Prelude Integration

Map the standard library primitive interfaces to your newly minted named builtins under core/prelude/:

  • Primitive Mappings: Bind Carbon methods directly to string-literal builtin equivalents:

    fn Convert[self: Self]() -> Float(To) = "int.convert_float";
    
  • Strict Orphan Rule Compliance: Carbon's orphan rules prohibit implementing interfaces where neither the type nor the interface is locally defined in the backing source module.

    • Literal Conversions: Literal types (like FloatLiteral, IntLiteral) do not have backing Carbon source files. Therefore, an impl of UnsafeAs (which is defined in as.carbon) between two literal types must reside inside as.carbon itself.
    • Sized Conversions: Implementations targeting sized primitives (e.g. Int(N), Float(N)) must reside in their respective type source files (such as int.carbon or float.carbon) where the backing target type resides to prevent duplicate symbols and structural recursion loops.

High-Fidelity Validation & Test Authoring

Follow the Toolchain tests skill with specialized patterns for builtins:

1. Checker Builtin File Splits

Create validation splits under toolchain/check/testdata/builtins/:

  • Test Naming Convention: All tests under toolchain/check/testdata/builtins/ must be named after the builtin they are testing, replacing . characters in the builtin name with / (directories). For example, a test for the builtin "char_literal.convert" must be located at toolchain/check/testdata/builtins/char_literal/convert.carbon.
  • Minimal Prelude & Direct Call Isolation: Builtin tests must not test the prelude library or operators. They must use the minimal primitive prelude (// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/primitives.carbon) or a smaller prelude, and explicitly declare and call the builtin functions under test directly (e.g., fn Add(a: f64, b: f64) -> f64 = "float.add";). This isolates the testing of compiler builtins from the library prelude.
  • Min-Prelude Limitations: Standard operators (like +, -, /, <, etc.) are not available in minimized preludes because the core operators library isn't imported. To write tests with a minimal footprint, call primitive builtins directly (e.g. float.negate, float.div) inside your test code to build expressions.
  • Canonicalized Float Comparison: In SemIR, real literal representations with identical mathematical values can result in mismatched RealId objects based on spelling variations. Verify compile-time constant conversions using canonicalized comparison functions (e.g. passing converted results through Expect(X as f64)) to completely avoid spelling mismatches in expected outputs.
  • Locals Bypass: If validating generic implicit conversions, compile-time arguments cannot take local runtime variable parameters. Validate compile-time conversions by passing literal constants directly, and sized variable implicit conversions at runtime.

2. Machine Codegen Lowering Splits

Create testing splits under toolchain/lower/testdata/builtins/:

  • Emplace a simple carbon binding to the tested builtin.
  • Confirm matching LLVM metadata target definitions are mapped precisely (e.g., matching sitofp i32 %a to float, fptosi float %a to i32).

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

コメント

ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。

まだコメントはありません。最初のコメントを書いてみませんか。

送信するとすぐに公開されます。メールアドレスや電話番号などの個人情報は書かないでください。URL は 2 つまでです。

0 / 1000 文字

このフォームは reCAPTCHA で保護されており、Google のプライバシーポリシーと利用規約が適用されます。

同じリポジトリのスキル

Accessing GitHub issues

無料概要あり

コマンドラインからGitHub issueの本文やコメントを読み取り専用で確認し、URLや番号から対象リポジトリを指定する手順を案内します。

  • issueの本文とコメントを読みたいとき
  • URLからissueの内容を確認したいとき
  • 別リポジトリのissueを参照したいとき
carbon-language/carbon-lang3.4万2026年10月26日 更新

Agent tools

無料概要あり

AIアシスタントがCarbonのコードベースを扱う際に、専用ツールでファイルを閲覧・検索・編集し、一時ファイルを管理するためのルールを示します。

  • Carbonのファイルを規則に沿って検索したいとき
  • 専用ツールを使ったファイル編集を確認したいとき
  • 一時ファイルの置き場所と削除ルールを確認したいとき
carbon-language/carbon-lang3.4万2026年10月26日 更新

Bazel usage

無料概要あり

Bazeliskを使ったCarbonプロジェクトのビルド、テスト、実行、デバッグの基本手順を確認し、対象を絞った検証やASanの利用方法も把握できます。

  • Carbonのコードをビルドしたいとき
  • 変更箇所に関係するテストを実行したいとき
  • Bazelで作ったバイナリを起動したいとき
carbon-language/carbon-lang3.4万2026年10月26日 更新

Code style

無料概要あり

Carbonツールチェーンのコードを書く際に、言語ごとの整形方法やコメント、命名、ドキュメント、コミットメッセージの基準を確認できます。

  • Carbonコードの書式を整えたいとき
  • コメントやドキュメントを見直したいとき
  • コードの名前が意味に合うか確認したいとき
carbon-language/carbon-lang3.4万2026年10月26日 更新

Diagnostics

無料概要あり

Carbonコンパイラのエラーや警告を定義し、書式やソース位置のラベルを整え、テストで網羅性を確かめる方法を案内します。

  • 診断メッセージを追加したいとき
  • エラー位置にラベルを付けたいとき
  • 診断文の表記を統一したいとき
carbon-language/carbon-lang3.4万2026年10月26日 更新

GitHub CLI usage

無料概要あり

`gh`でGitHubのIssue、プルリクエスト、リポジトリを読み取り専用で検索・確認し、必要な情報を絞り込む方法を案内します。

  • Issueの内容や状態を確認したいとき
  • PRの差分やチェック状況を見たいとき
  • GitHub上のコードやリポジトリを検索したいとき
carbon-language/carbon-lang3.4万2026年10月26日 更新

carbon-language のスキルをすべて見る

このスキルの問題を報告する