Skip to content

CONCEPT Cited by 1 source

Dead-code elimination

Dead-code elimination (DCE) is a linker / compiler pass that drops symbols the reachability analysis proves no entry-path reaches. The result is a smaller binary with the same behaviour.

Two levels:

  • Function-level DCE — remove functions / procedures no call site can reach from the entry point.
  • Method-level DCE — remove methods that no typed call site can resolve to. Harder — requires proving every method lookup is statically decidable.

Why method-DCE is fragile

Method-level DCE is safe only when the linker can prove every method invocation's target at build time. Any form of dynamic dispatch whose target isn't statically known defeats the proof and forces the linker to conservatively keep every candidate.

Go-specific load-bearing examples (from Datadog 2026-02-18):

Scale of impact

Re-enabling method-DCE in the Datadog Agent required patching ~a dozen dependencies' reflect call sites and forking stdlib text/template + html/template into pkg/template/. Result: 16-25 % per binary / ~100 MiB total on Linux amd64. Kubernetes adopted it and reports 16-37 % of its own.

Safety caveat

Aggressive method-DCE is a correctness risk: dropping a method that's actually called at runtime → panic. Static proofs that the linker can verify (non-reflective dispatch) are the only safe path. Datadog considered a different approach — "instrument binaries to emit a list of all methods used at runtime, then edit the compiler artifacts to force the linker to remove all other methods" — but rejected it because "it would have introduced runtime panics if we removed a method that ended up actually being called". Source-level patches the linker can statically reason about are strictly safer.

Not Go-only

Every mature toolchain has an analogous pass:

  • C/C++ link-time optimization (-flto) + --gc-sections.
  • Rust panic=abort + -Z build-std + release-profile defaults.
  • JVM tree-shaking via ProGuard / R8.
  • JavaScript bundler tree-shaking (webpack, Rollup, Vite, esbuild, Turbopack).

Each has its own defeat conditions (eval, reflection, class-loader), the same mechanism class, and the same cure (constrain the dynamic surface so the linker can prove reachability).

Seen in

Last updated · 200 distilled / 1,178 read