Self-Compiler is a research prototype for making the GCC C/C++ compiler AI-extensible.
The project now has a real compiler-native vertical slice: a GPL-compatible shared plugin is loaded into GCC's cc1 or cc1plus process, executes as a GIMPLE pass after SSA construction, extracts per-function IR features, and exposes a conservative policy hook over GCC's optimization-pass gates. The existing generate-and-validate repair loop remains as the driver-level supervisor for source edits that cannot safely occur inside a parser callback.
This is no longer framed as “an AI tool that happens to call GCC.” The target architecture is:
GCC-AI compiler
C / C++ source
|
v
GCC lexer + parser <---- diagnostic repair advisor
|
GENERIC
|
GIMPLE / SSA <---- learned optimization policy [working plugin]
|
RTL <---- future target-cost/scheduling policy
|
machine code
|
tests + benchmarks ----> reward/evidence ----> offline trainer
The trusted kernel remains GCC. AI proposes bounded decisions; GCC's parser, type system, IR invariants, assembler, linker, tests, analyzers, and benchmarks remain the acceptance authority.
self_compiler/gcc_plugin/ai_native_plugin.cc is compiled against the exact plugin headers shipped with the host GCC. It runs inside the frontend and emits JSON Lines such as:
{"schema":"gcc-ai.telemetry.v1","event":"function-ir","function":"find","basic_blocks":9,"gimple_statements":12,"phi_nodes":2,"calls":0,"branches":2}The initial feature surface includes:
- GIMPLE statement count
- basic-block count
- PHI-node count
- call count
- conditional/switch branch count
- function and source location
A policy artifact can conservatively disable a named optimization pass:
disable_pass=evrp
The plugin uses GCC's PLUGIN_OVERRIDE_GATE callback and records every applied decision. It deliberately cannot force-enable passes: GCC may have left a pass disabled because its prerequisites do not hold.
This is the same broad research direction as MILEPOST GCC, which combined GCC plugins, program features, runtime behavior, and learned optimization selection, and later MLGO's use of learned policies inside industrial compiler heuristics. The next scientific step is not “add an LLM everywhere”; it is to choose one expensive heuristic, define a feature/action/reward contract, train against measured outcomes, and beat a fixed GCC baseline under held-out workloads.
The Python repair layer handles compilation failure, static-analysis repair, reproducible runtime correction, and measured optimization experiments. Candidate source is staged without touching the original, compiled, tested, promoted atomically, and then revalidated from the real source path. Unexpected failure rolls back automatically.
The supervisor now consumes GCC's native JSON diagnostic format. Compiler-authored fix-its are applied first as surgical, half-open byte-range edits; they support UTF-8 source and are accepted only when every edit in a diagnostic is valid for the current translation unit. AI is consulted only when GCC did not provide an applicable edit.
Runtime self-correction can use GDB's machine-interface protocol. A failing direct execution is reproduced under GDB, and the model receives a structured signal plus stack frames, function names, source locations, and addresses rather than undifferentiated stderr.
This layer currently lives above the GCC process because syntax errors occur before a GIMPLE plugin can run. Moving the diagnostic/edit channel into a GCC fork is the next frontend milestone, described in the architecture document.
Requirements:
- GCC and G++ from the same installation
- GCC plugin development headers
- Python 3.10+
Portable builder:
python -m self_compiler.build_pluginOn Windows, GCC frontends are separate PE executables, so the builder produces two matched DLLs:
build/gcc-plugin/ai_native_c.dll
build/gcc-plugin/ai_native_cpp.dll
On ELF platforms it produces one ai_native.so whose unresolved GCC symbols are resolved by the loading frontend.
PowerShell users can also run:
powershell -NoProfile -ExecutionPolicy Bypass -File scripts/build_gcc_plugin.ps1C:
python -m self_compiler.gcc_native \
--compiler gcc \
--telemetry build/c-run.jsonl \
-- -O2 program.c -o programC++:
python -m self_compiler.gcc_native \
--compiler g++ \
--telemetry build/cpp-run.jsonl \
-- -O2 program.cpp -o programApply an experimental policy:
python -m self_compiler.gcc_native \
--compiler gcc \
--telemetry build/policy-run.jsonl \
--policy gcc_plugin/example.policy \
-- -O2 program.c -o programAfter installation, the equivalent commands are gcc-ai-build-plugin and gcc-ai.
The plugin can also be loaded without the Python launcher:
gcc -O2 \
-fplugin=/absolute/path/ai_native_c.dll \
-fplugin-arg-ai_native_c-output=/absolute/path/run.jsonl \
program.c -o programA missing semicolon prevents the frontend from producing valid GENERIC/GIMPLE, so a normal optimization plugin never sees that function. The rigorous repair sequence is:
parse error
|
+--> deterministic GCC fix-it, when available
|
+--> bounded AI edit proposal for ambiguous cases
|
v
in-memory source overlay
|
re-lex + re-parse
|
semantic compilation
|
tests / analyzers
|
emit patch or promote source
The current supervisor implements that hierarchy. This command demonstrates the deliberately limited offline fallback for a missing semicolon that GCC 14 does not fix automatically in this diagnostic shape:
python -m self_compiler.cli \
--repair --offline --max-attempts 1 \
examples/missing_semicolon.c -- -Wall -WextraThe --offline repair is deliberately just a semicolon demonstration. Gemini-backed repair requires GEMINI_API_KEY; missing credentials are never silently treated as AI.
For a reproducible crash with compiler debug information:
python -m self_compiler.cli \
--self-correct --debugger gdb \
examples/null_deref.c -- -g -O0Repeat --program-arg VALUE to pass arguments during direct execution. GDB capture currently applies to direct execution; an arbitrary shell-based --test-cmd cannot be safely reconstructed as debugger arguments.
- Frontend: AI augments ambiguous diagnostics and repair proposals, but the deterministic parser must accept the result.
- Middle end: learned models replace selected hand-tuned heuristics such as inlining, vectorization profitability, unrolling, or pass ordering.
- Backend: learned cost models may advise instruction selection/scheduling or register-allocation heuristics, while RTL legality remains deterministic.
- Feedback: real code size, compile time, runtime, energy, and hardware counters provide rewards—not an LLM's opinion.
- Deployment: small pinned local models or policy tables run in bounded time. Network LLM calls do not sit in GCC's hot compilation path.
- Safety: every model and feature schema is versioned; deterministic fallback, replay, differential testing, and rollback are mandatory.
“Self-correcting program” here means the compiler can propose and validate a new program revision. Runtime self-modifying machine code is a different—and much riskier—system. Learned on-chip execution control from the attached idea is a hardware/microarchitecture project, not a GCC compiler phase, and should be pursued separately after the compiler policy loop is empirically sound.
- GCC officially supports plugins that inspect and transform code and register new passes through compiler callbacks: GCC Plugin API.
- GCC uses GENERIC, GIMPLE, and RTL as progressively lower representations: GENERIC, GIMPLE, and RTL.
- MILEPOST GCC already demonstrated a machine-learning-enabled self-tuning GCC using program features and optimization feedback: IBM Research summary.
- MLGO demonstrated that a learned policy can replace a bounded compiler heuristic and reported up to 7% size reduction for its LLVM inlining case: MLGO paper.
- GCC diagnostics already support machine-readable fix-it hints, and GCC's own guidance says those edits should be verified to compile: GCC diagnostic guidelines.
Therefore, “GCC plus AI” alone is not novel. A credible contribution needs a sharply defined decision point, a reproducible training/evaluation corpus, held-out workloads and architectures, comparison against GCC's heuristic and autotuning baselines, and evidence for runtime, code size, compile-time overhead, determinism, and semantic preservation.
ruff format --check .
ruff check .
python -m pytest -qThe integration suite builds plugins against the installed GCC, loads them into both the real C and C++ frontends, compiles and runs programs, validates JSON telemetry, proves that a policy reaches an actual GCC pass gate, applies a real GCC-authored source fix before AI, and captures a real SIGSEGV call chain through GDB/MI.
- The GIMPLE telemetry/pass-gate vertical slice is real and locally verified.
- The policy is currently an explicit artifact; no learned model has yet beaten GCC on a held-out benchmark.
- Syntax repair is still supervised at driver level, not patched into a maintained GCC fork, but its primary edit channel now comes from GCC's own structured fix-its.
- The telemetry schema is intentionally small and not sufficient for a serious inlining/vectorization policy yet.
- No claim is made that analyzer/test-adequate repairs are universally correct.
- No live Gemini call was used in the compiler-plugin verification.
- LTO/frontend-plugin compatibility has not yet been established; current evidence covers ordinary C and C++ compilation.