• ↑↓ pour naviguer
  • pour ouvrir
  • pour sélectionner
  • ⌘ ⌥ ↵ pour ouvrir dans un panneau
  • ←→ pour naviguer
  • esc pour rejeter
⌘ '
raccourcis clavier

The Problem

Programs repeatedly compute the same expression multiple times — especially in loops, repeated indexing calculations (a[i*cols+j]), and aliased computations. Each redundant computation wastes CPU cycles. The compiler must detect when two expressions compute the same value and reuse the earlier result.

Core Idea

Common Subexpression Elimination (CSE) is a compiler optimization that identifies expressions that have been computed before and whose operands haven’t changed since. It replaces the redundant computation with a reference to the previously computed value. CSE can be local (within a single basic block) or global (across basic blocks using available-expression analysis).

How It Works

Local CSE scans a basic block and builds a table of computed expressions. For each new expression x = a op b, it checks if a op b has already been computed with the same operands and no intervening assignments to a or b. If found, the new computation is replaced with x = previous_temp. Global CSE uses available-expression data-flow analysis to propagate this information across basic blocks in the CFG.

Visual Explanation

cse_example Before Before CSE: t1 = a * b t2 = c + d t3 = a * b  ← redundant x  = t3 + t2 After After CSE: t1 = a * b t2 = c + d      ← t3 eliminated x  = t1 + t2 Before->After Savings Saved: 1 multiplication After->Savings

Semantic Network

semantic_cse THIS Common Subexpr. Elimination PRE1 Code Optimization THIS--PRE1 built from PRE2 Data Flow Analysis THIS--PRE2 built from — needs available expr analysis CON1 Peephole Optimization THIS--CON1 contrasts with — CSE is IR-level, not target-level CON2 Constant Propagation THIS--CON2 contrasts with — CSE targets repeated expressions, not constants REL1 Basic Blocks THIS--REL1 related — local CSE works within a block

Key Properties

  • Local CSE: Works within a single basic block — simple and fast
  • Global CSE: Works across blocks using available-expression data-flow analysis
  • Available expressions: An expression a op b is available at point p if it was computed earlier and operands haven’t changed
  • Safety: Always safe — replacing a computation with a reference to an identical computation preserves semantics
  • Loop benefits: Most impactful in loops where expressions are repeatedly computed with the same operands

Connections

  • Built from: Code Optimization — CSE is a classic compiler optimization technique
  • Built from: Data Flow Analysis — global CSE requires available-expression analysis
  • Contrasts with: Peephole Optimization — CSE works at the IR level, not the target instruction level
  • Contrasts with: Constant Propagation — CSE targets repeated expression evaluation, not constant values
  • Related: Basic Blocks — local CSE operates within a single basic block

Edge Cases & Gotchas

  • Operand aliasing: If a and b can be modified through pointers between the two computations, CSE cannot safely eliminate the redundant computation
  • Cost trade-off: CSE increases register pressure by keeping more values live — may slow down register allocation
  • Global CSE complexity: Available-expression analysis is more complex than reaching-definitions analysis because expressions involve multiple variables
  • Partial redundancy: When an expression is available on some paths but not all — partial redundancy elimination (PRE) is a more sophisticated optimization