Value numbering is a technique of determining when two
computations in a program are equivalent and eliminating one of them with a semantics-preserving
optimization
Mathematical optimization (alternatively spelled ''optimisation'') or mathematical programming is the selection of a best element, with regard to some criteria, from some set of available alternatives. It is generally divided into two subfiel ...
.
Global value numbering
Global value numbering (GVN) is a
compiler optimization
An optimizing compiler is a compiler designed to generate code that is optimized in aspects such as minimizing program execution time, memory usage, storage size, and power consumption. Optimization is generally implemented as a sequence of op ...
based on the
static single assignment form
In compiler design, static single assignment form (often abbreviated as SSA form or simply SSA) is a type of intermediate representation (IR) where each variable is assigned exactly once. SSA is used in most high-quality optimizing compilers for ...
(SSA) intermediate representation. It sometimes helps eliminate
redundant code that
common subexpression elimination
In compiler theory, common subexpression elimination (CSE) is a compiler optimization that searches for instances of identical expressions (i.e., they all evaluate to the same value), and analyzes whether it is worthwhile replacing them with a sin ...
(CSE) does not. At the same time, however, CSE may eliminate code that GVN does not, so both are often found in modern compilers. Global value numbering is distinct from
local value numbering in that the value-number mappings hold across basic block boundaries as well, and different algorithms are used to compute the mappings.
Global value numbering works by assigning a value number to variables and expressions. The same value number is assigned to those variables and expressions which are equivalent. For instance, in the following code:
w := 3
x := 3
y := x + 4
z := w + 4
a good GVN routine would assign the same value number to
w
and
x
, and the same value number to
y
and
z
. For instance, the map
would constitute an optimal value-number mapping for this block.
Using this information, the previous code fragment may be safely transformed into:
w := 3
x := w
y := w + 4
z := y
Depending on the code following this fragment,
copy propagation In compiler theory
In computing, a compiler is a computer program that Translator (computing), translates computer code written in one programming language (the ''source'' language) into another language (the ''target'' language). The name "co ...
may be able to remove the assignments to
x
and to
z
.
The reason that GVN is sometimes more powerful than CSE comes from the fact that CSE matches lexically identical expressions whereas the GVN tries to determine an underlying equivalence. For instance, in the code:
a := c × d
e := c
f := e × d
Without copy propagation, CSE would ''not'' eliminate the recomputation assigned to
f
, but even a poor GVN algorithm should discover and eliminate this redundancy.
In IRs and source languages where rebinding (assigning to the same variable more than once) is possible, SSA form is required to perform GVN so that false
mappings are not created.
Local value numbering
Local value numbering (LVN) is a
compiler optimization
An optimizing compiler is a compiler designed to generate code that is optimized in aspects such as minimizing program execution time, memory usage, storage size, and power consumption. Optimization is generally implemented as a sequence of op ...
that aims to find multiple instances of equivalent expressions (i.e. expressions which yield the same result) and replace them with the first occurrence. LVN is a local optimization, meaning that unlike
global value numbering, it operates on a single
basic block
In compiler construction, a basic block is a straight-line code sequence with no branches in except to the entry and no branches out except at the exit. This restricted form makes a basic block highly amenable to analysis. Compilers usually decom ...
at a time.
Local value numbering works by assigning a unique number to each operation and remembering these associations. Subsequent instructions are then looked up and, in case an identical instruction has already been registered, replaced with the previous instruction's result. For example:
a ← 4 a is tagged as #1
b ← 5 b is tagged as #2
c ← a + b c (#1 + #2) is tagged as #3
d ← 5 d is tagged as #2, the same as b
e ← a + d e, being '#1 + #2' is tagged as #3
By assigning numbers to instructions, comparing for duplicates is turned into simple integer comparisons. In this particular example,
c
and
e
are assigned the same number (#3), thus signalling to the compiler that any references to
e
may simply be replaced with ones to
c
.
Difficulties and extensions
Issues when not using SSA
A naive implementation might attempt to perform the optimization by directly using the variable names instead of numbers. However, this approach does not work when the values of variables can change. Consider the
pseudocode
In computer science, pseudocode is a description of the steps in an algorithm using a mix of conventions of programming languages (like assignment operator, conditional operator, loop) with informal, usually self-explanatory, notation of actio ...
:
a ← 1 a is tagged as #1
b ← 2 b is tagged as #2
c ← a + b c is tagged as #3
b ← 3
d ← a + b d is incorrectly tagged as #3
In this scenario,
d
is incorrectly assigned the number 3 because the arguments match those of
c
. This is incorrect, however, because
b
has changed value from 2 to 3, making the actual results differ. Using the SSA representation resolves this disparity.
Using mathematical identities
A simple implementation might also be unable to catch all equivalent expressions, even when they only differ by the order of their operands. In the following example,
a
and
b
could be assigned the same number:
a ← 1 + 2
b ← 2 + 1
This issue can easily be resolved either by assigning the same number to both cases (i.e.
a + b
and
b + a
are both recorded with the same number) or by sorting the operands before checking for equivalents.
Local value numbering optimizers may also be aware of mathematical identities. Assuming
a
is an
integer
An integer is the number zero (0), a positive natural number (1, 2, 3, ...), or the negation of a positive natural number (−1, −2, −3, ...). The negations or additive inverses of the positive natural numbers are referred to as negative in ...
, all of the following expressions can be assigned the same value:
b ← a + 0
c ← a * 1
d ← min(a, MAX_INT)
e ← max(a, a)
f ← a & 0xFF..FF (assuming '&' denotes
bitwise AND
In computer programming, a bitwise operation operates on a bit string, a bit array or a binary numeral (considered as a bit string) at the level of its individual bits. It is a fast and simple action, basic to the higher-level arithmetic operat ...
)
See also
*
Partial redundancy elimination
*
Optimizing compiler
An optimizing compiler is a compiler designed to generate code that is optimized in aspects such as minimizing program execution time, memory usage, storage size, and power consumption. Optimization is generally implemented as a sequence of op ...
*
Common subexpression elimination
In compiler theory, common subexpression elimination (CSE) is a compiler optimization that searches for instances of identical expressions (i.e., they all evaluate to the same value), and analyzes whether it is worthwhile replacing them with a sin ...
References
Further reading
*
https://web.archive.org/web/20170629213307/http://static.aminer.org/pdf/PDF/000/546/451/a_unified_approach_to_global_program_optimization.pdf -->* Alpern, Bowen, Wegman, Mark N., and Zadeck, F. Kenneth. "Detecting Equality of Variables in Programs.", ''Conference Record of the Fifteenth Annual ACM Symposium on Principles of Programming Languages'' (
POPL
The annual ACM SIGPLAN- SIGACT Symposium on Principles of Programming Languages (POPL) is an academic conference in the field of computer science, with focus on fundamental principles in the design, definition, analysis, and implementation of pro ...
), ACM Press, San Diego, CA, USA, January 1988, pages 1–11.
* L. Taylor Simpson, "Value-Driven Redundancy Elimination." Technical Report 96-308, Computer Science Department, Rice University, 1996. (Author's Ph.D. thesis)
*
*
{{Compiler optimizations
Compiler optimizations