Deleting 19,000 Lines of Dead Compiler Code Without Blindly Trusting Large Language Models
An engineer removed ~19,000 lines of dead compiler code in one week with zero regressions by combining Large Language Models with static call-graph validation. The methodology categorizes code into four risk buckets and uses scaffolding tests to verify complete removal.

Why it matters
You can safely execute high-risk legacy refactors by using static analysis to bound LLM context and double-checking model deletions with deterministic call graphs.
TL;DR
- 01Do not ask an LLM to find dead code globally; trace dependency paths deterministically using clangd and compile_commands.json first.
- 02Categorize every refactor candidate into Mechanical, Cross-ownership, Side effects, or Surgery buckets before touching source code.
- 03Write temporary scaffolding deletion tests that assert the total absence of retired symbols before initiating edits.
Key facts
- Code deleted
- ~19,000 lines
- Time to complete
- About 1 week
- Production regressions after 1 month
- 0
- Classification categories
- Mechanical deletion, Cross-ownership, Side effects, Surgery
Eliminating the Token Tax of Dead Code
Dead code creates a compounding penalty in modern agentic workflows. When an agent reads an obsolete compiler path or deprecated API, it often adopts those conventions as few-shot examples for fresh pull requests. Deleting 19k lines of interleaved compiler code without regressions requires strict boundaries between deterministic tooling and stochastic model judgment.
Bounding Context via Static Analysis and Color Marking
Rather than passing an entire codebase into an LLM, the refactor began by parsing the retired flag --XYZ using compile_commands.json. An LLM traversed callers and marked them with two strict semantic tags:
RED: Internal logic directly branches on or alters behavior based on the flag.BLUE: The function merely forwards or prepares the flag data into the configuration struct.
To ensure no dynamic edges were dropped without trusting the model blindly, an independent static call-graph tool was executed from the same origin. If both tools hit the identical function set, the surface area was deemed complete.
Four-Tier Risk Classification
Every marked node was assigned by the model into a risk tier that dictated the testing protocol: 1. Mechanical Deletion: Entire functions unreachable without the flag. Verified with deletion tests that fail if the old symbol exists. 2. Cross-Ownership: Boundary interfaces shared with other teams. Isolated using the Adapter Pattern. 3. Side Effects: Functions mutating shared globals or stacks. Excluded from automated LLM edits and audited manually. 4. Surgery: Functions containing mixed active and dead branches. Excised line-by-line under surgical regression checks.
Try it in 2 minutes
// RED, MECHANICAL-DELETION: reached only through the flag's branch.
void addFlowXPasses(PassManager &pm);
// RED, SURGERY: keep default branch, excise retired branch.
void buildPipeline(PassManager &pm, const PipelineConfig &cfg);cpp
✓ When to use
- Pruning large multi-thousand line technical debt blocks and retired feature flags in systems codebases.
- Scenarios where AI coding agents keep hallucinating deleted APIs and legacy conventions in new pull requests.
✕ When NOT to use
- Small refactors where dead code is contained within a single file without shared side effects.
- Dynamic languages where reflection and runtime lookups completely obscure call graphs from static analysis tools.
What to do today
- Generate a compile_commands.json for your C++ or systems repository to trace dynamic call hierarchies before refactoring.
- Add scaffolding deletion unit tests that fail if a deprecated configuration flag or artifact is still emitted by your build.
- Split refactoring tasks for coding agents into discrete mechanical removals versus surgical multi-branch edits.