Common Subexpression Elimination (CSE) is a compiler optimization that identifies and eliminates redundant calculations of identical expressions within a program or computational graph, replacing them with a single computed value stored in a temporary variable. In the context of neural network compilation, CSE analyzes the dataflow graph to find operations—like a repeated matrix multiplication or activation function on the same input tensors—that produce identical results, removing the duplicate computations. This reduces execution time and computational load, which is critical for efficiency on hardware accelerators like Neural Processing Units (NPUs).
Glossary
Common Subexpression Elimination (CSE)

What is Common Subexpression Elimination (CSE)?
A foundational compiler optimization for computational graphs that directly reduces redundant arithmetic operations.
The optimization is performed during the graph compilation phase, often on an Intermediate Representation (IR). It relies on precise dataflow analysis to ensure the eliminated expression is truly redundant and its value hasn't changed. CSE works synergistically with other passes like constant folding and dead code elimination. For NPU targets, reducing operations through CSE decreases kernel launch overhead and improves memory hierarchy utilization by minimizing redundant data accesses, directly contributing to lower latency and improved power efficiency in AI workloads.
Key Characteristics of CSE
Common Subexpression Elimination (CSE) is a fundamental compiler optimization that identifies and eliminates redundant calculations within a computational graph. Its primary goal is to reduce execution time and computational overhead by caching and reusing results.
Core Optimization Principle
CSE operates on the principle of computational redundancy. It scans the computational graph to find subexpressions—sequences of operations—that produce identical results. When a duplicate is found, the compiler replaces all subsequent instances with a reference to the first computed value. This transforms the graph from a structure with repeated calculations into one with shared intermediate results, directly reducing the number of floating-point operations (FLOPs) executed at runtime.
Scope and Granularity
The effectiveness of CSE depends on its scope of analysis:
- Local CSE: Operates within a single basic block or a small, contiguous sequence of operations. It is fast and common in early optimization passes.
- Global CSE: Analyzes the entire function or computational graph, tracking values across control flow boundaries (like loops and conditionals). This is more powerful but requires sophisticated dataflow analysis.
- Inter-Procedural CSE: Extends analysis across function boundaries, potentially inlining functions to expose more redundancy. This is complex and often used in link-time optimization (LTO).
Interaction with Graph Representation
CSE is heavily influenced by the graph's Intermediate Representation (IR). In an SSA (Static Single Assignment) form, where each variable is assigned once, value identity is explicit, making CSE more straightforward. The compiler often performs CSE after graph canonicalization, which standardizes operator forms (e.g., rewriting (a + b) and (b + a) as identical if addition is commutative), ensuring maximum redundancy is detected. It is a prerequisite for many subsequent optimizations like constant folding and dead code elimination.
Trade-offs and Considerations
While primarily beneficial, CSE introduces trade-offs that compilers must balance:
- Increased Memory Pressure: Storing a computed value for reuse consumes register or stack memory. Aggressive CSE can increase register pressure, potentially causing spills to slower memory.
- Instruction Scheduling Impact: Creating a single, shared computation point may lengthen a critical path if the value is needed early by multiple consumers.
- Side Effects and Purity: CSE can only be applied to pure functions—operations without side effects (e.g.,
sin(x),a + b). It cannot be applied to stateful operations like random number generation or memory writes.
NPU-Specific Implications
For Neural Processing Units (NPUs), CSE is critical but interacts uniquely with hardware:
- Fusion Opportunities: Eliminating a redundant subgraph may remove a candidate for kernel fusion, as the operations are no longer adjacent. The compiler must evaluate the cost-benefit of CSE vs. fusion.
- Precision and Rounding: On hardware using mixed-precision (e.g., FP16, INT8), reusing a value stored in a lower-precision register may propagate rounding errors differently than recomputing in higher precision.
- Scheduling for Parallelism: On massively parallel NPUs, recomputing a value in two separate processing elements (PEs) might be faster than broadcasting it from a single source, depending on data movement costs.
Example: Mathematical Expression
Consider the expression y = (a*b) + (a*b) + c. A naive computation performs (a*b) twice.
Original Computation Graph:
MUL1 = a * b
MUL2 = a * b
ADD1 = MUL1 + MUL2
y = ADD1 + c
After CSE:
MUL1 = a * b // The single, common subexpression
ADD1 = MUL1 + MUL1 // Reuse the result
y = ADD1 + c
The optimization reduces one MUL operation. In a neural network, this pattern occurs with repeated weight multiplications or activation function applications across identical tensor slices.
CSE vs. Related Compiler Optimizations
This table distinguishes Common Subexpression Elimination from other key compiler optimizations used in graph compilation for NPUs, highlighting their primary objectives, scopes, and typical application points.
| Optimization | Primary Objective | Scope of Analysis | Typical Application Point | Key Interaction with CSE |
|---|---|---|---|---|
Common Subexpression Elimination (CSE) | Eliminate redundant calculation of identical expressions | Local basic block or global dataflow | Mid-level IR, after canonicalization | Core technique; often a prerequisite for others |
Constant Folding | Evaluate constant expressions at compile time | Expression trees with compile-time constants | Early IR passes, often before CSE | Creates new constants that CSE can then identify and eliminate |
Dead Code Elimination (DCE) | Remove code that does not affect program output | Dataflow and control-flow graph | Multiple passes, often after CSE and constant propagation | Removes code made dead by CSE's substitution |
Loop-Invariant Code Motion (LICM) | Hoist invariant computations out of loops | Loop bodies and their dominators | Loop optimization phase | Moves expressions to loop preheader, enabling global CSE across iterations |
Copy Propagation | Replace uses of a variable with its directly assigned value | Def-use chains within SSA form | Mid-level optimization, often alongside CSE | Simplifies expressions, potentially creating new common subexpressions for CSE to find |
Peephole Optimization | Replace short instruction sequences with more efficient ones | A small window of adjacent instructions | Low-level IR or assembly, late in the pipeline | Operates on a lower-level representation than typical CSE; can clean up after CSE |
Global Value Numbering (GVN) | Detect and eliminate redundant computations (a form of CSE) | Entire function or region using value equivalence | Mid-level optimization, similar scope to global CSE | A more powerful, value-based algorithm that subsumes syntactic CSE |
Partial Redundancy Elimination (PRE) | Move computations to paths where they are fully redundant to enable elimination | Control-flow graph paths | Advanced optimization pass | Generalizes CSE and LICM to handle partially redundant expressions |
Frequently Asked Questions
Common subexpression elimination (CSE) is a foundational compiler optimization crucial for efficient neural network execution on NPUs. These questions address its core mechanisms, benefits, and role within the compilation pipeline.
Common subexpression elimination (CSE) is a compiler optimization that identifies and eliminates redundant calculations of identical expressions within a computational graph, replacing them with a single stored value. It works by analyzing the dataflow graph of a program, such as a neural network, to find expressions that are computed more than once with the same inputs. When a duplicate is found, the compiler computes the expression once, stores the result in a temporary variable, and replaces all subsequent instances with a reference to that variable. This process reduces computational overhead and can decrease memory traffic by avoiding repeated computation of the same intermediate tensor.
For example, in a graph where the operation y = (a + b) * c appears in two separate branches, CSE would compute (a + b) once, store it as a temporary tmp1, and rewrite the graph to y = tmp1 * c in both locations.
Enabling Efficiency, Speed & Accuracy
Intelligent Analysis, Decision & Execution
We build AI systems for teams that need search across company data, workflow automation across tools, or AI features inside products and internal software.
Talk to Us
Search across company data
Give teams answers from docs, tickets, runbooks, and product data with sources and permissions.
Useful when people spend too long searching or get different answers from different systems.

Automate internal workflows
Use AI to route work, draft outputs, trigger actions, and keep approvals and logs in place.
Useful when repetitive work moves across multiple tools and teams.

Add AI to products and internal tools
Build assistants, guided actions, or decision support into the software your team or customers already use.
Useful when AI needs to be part of the product, not a separate tool.
Related Terms
Common Subexpression Elimination is one of many compiler passes used to optimize computational graphs for execution. These related techniques work in concert to reduce computation, memory usage, and kernel launch overhead.
Constant Folding
A compiler optimization that evaluates expressions consisting solely of compile-time constants during compilation, replacing them with their computed result. This eliminates runtime computation entirely.
- Example: An expression like
(2.0 * 3.14) + 1.0is replaced with the constant7.28in the compiled graph. - Interaction with CSE: Often runs before CSE, as folding constants can create new opportunities to identify identical subexpressions.
Dead Code Elimination (DCE)
A compiler pass that identifies and removes code that does not affect the program's final output. This includes operations whose results are never consumed, or variables that are never read.
- Purpose: Reduces binary size, execution time, and memory footprint.
- Relation to CSE: CSE can sometimes create 'dead' code—values that are computed and stored but then never used if all references to the original subexpressions are replaced. A subsequent DCE pass is required to clean this up.
Graph Fusion
A compiler optimization that merges multiple adjacent operators or nodes within a computational graph into a single, compound kernel. This is a key strategy for NPU acceleration.
- Primary Benefit: Drastically reduces kernel launch overhead and minimizes costly intermediate memory writes and reads between operators.
- Contrast with CSE: While CSE targets identical expressions (often within a single operator or across similar ops), fusion targets different but adjacent operators to create a new, more efficient monolithic operation.
Static Single Assignment (SSA) Form
An intermediate representation (IR) property where each variable is assigned exactly once. This form is foundational for modern compiler optimizations.
- Key Advantage: Simplifies dataflow analysis, making it trivial to see where values are defined and used.
- Enabler for CSE: CSE is far more straightforward to implement on an SSA-form IR. Identifying identical expressions that produce the same value is simplified because each value has a unique definition point.
Peephole Optimization
A low-level, local optimization that examines short sequences of instructions (a 'peephole') and replaces them with faster or shorter sequences without changing semantics.
- Scope: Operates on a very localized, instruction-by-instruction level, often in the compiler backend.
- Comparison to CSE: CSE is a global optimization that analyzes the entire graph or function. Peephole optimizations are local patterns (e.g., replacing
x * 2withx << 1). They can be applied after CSE to further optimize the generated low-level code.
Memory Planning
A compiler pass that allocates memory buffers for all tensors in a computational graph, aiming to minimize peak memory usage through intelligent reuse and in-place operations.
- Critical for Edge AI: Essential for deploying models on memory-constrained NPUs and edge devices.
- Synergy with CSE: CSE directly reduces the number of unique intermediate tensors that need to be allocated. By computing a value once and reusing it, memory planning has fewer buffers to manage and can achieve a lower overall peak memory footprint.

About the author
Prasad Kumkar
CEO & MD, Inference Systems
Prasad Kumkar is the CEO & MD of Inference Systems and writes about AI systems architecture, LLM infrastructure, model serving, evaluation, and production deployment. Over 5+ years, he has worked across computer vision models, L5 autonomous vehicle systems, and LLM research, with a focus on taking complex AI ideas into real-world engineering systems.
His work and writing cover AI systems, large language models, AI agents, multimodal systems, autonomous systems, inference optimization, RAG, evaluation, and production AI engineering.
Partnered with leading AI, data, and software stack.
How We Work
Custom AI workflows for your Business
One-fit-all AI don't work for modern businesses. At Inferensys, we aim to understand your business & custom requirements; which we use to define most efficient agentic workflows, the data, and the tools for your business.
01
Review the use case
We understand the task, the users, and where AI can actually help.
Read more02
Pick the right approach
We define what needs search, automation, or product integration.
Read more03
Build the first useful version
We implement the part that proves the value first.
Read more04
Improve from there
We add the checks and visibility needed to keep it useful.
Read moreThe first call is a practical review of your use case and the right next step.
Talk to Us