<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://debianws.lexgopc.com/wiki143/index.php?action=history&amp;feed=atom&amp;title=Live-variable_analysis</id>
	<title>Live-variable analysis - Revision history</title>
	<link rel="self" type="application/atom+xml" href="http://debianws.lexgopc.com/wiki143/index.php?action=history&amp;feed=atom&amp;title=Live-variable_analysis"/>
	<link rel="alternate" type="text/html" href="http://debianws.lexgopc.com/wiki143/index.php?title=Live-variable_analysis&amp;action=history"/>
	<updated>2026-05-06T16:35:33Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.1</generator>
	<entry>
		<id>http://debianws.lexgopc.com/wiki143/index.php?title=Live-variable_analysis&amp;diff=2501426&amp;oldid=prev</id>
		<title>imported&gt;GottlobFlegel: improve typesetting of constants and variables</title>
		<link rel="alternate" type="text/html" href="http://debianws.lexgopc.com/wiki143/index.php?title=Live-variable_analysis&amp;diff=2501426&amp;oldid=prev"/>
		<updated>2025-06-09T10:21:33Z</updated>

		<summary type="html">&lt;p&gt;improve typesetting of constants and variables&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;In [[compilers]], &amp;#039;&amp;#039;&amp;#039;live variable analysis&amp;#039;&amp;#039;&amp;#039; (or simply &amp;#039;&amp;#039;&amp;#039;liveness analysis&amp;#039;&amp;#039;&amp;#039;) is a classic [[data-flow analysis]] to calculate the [[Variable (programming)|variables]] that are &amp;#039;&amp;#039;live&amp;#039;&amp;#039; at each point in the program. A variable is &amp;#039;&amp;#039;live&amp;#039;&amp;#039; at some point if it holds a value that may be needed in the future, or equivalently if its value may be read before the next time the variable is written to.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
Consider the following program:&lt;br /&gt;
&lt;br /&gt;
 b = 3&lt;br /&gt;
 c = 5&lt;br /&gt;
 a = f(b * c)&lt;br /&gt;
&lt;br /&gt;
The set of live variables between lines 2 and 3 is {&amp;lt;code&amp;gt;b&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;c&amp;lt;/code&amp;gt;} because both are used in the multiplication on line 3. But the set of live variables after line 1 is only {&amp;lt;code&amp;gt;b&amp;lt;/code&amp;gt;}, since variable &amp;lt;code&amp;gt;c&amp;lt;/code&amp;gt; is updated later, on line 2. The value of variable &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; is not used in this code.&lt;br /&gt;
&lt;br /&gt;
Note that the assignment to &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; may be eliminated as &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; is not used later, but there is insufficient information to justify removing all of line 3 as &amp;lt;code&amp;gt;f&amp;lt;/code&amp;gt; may have [[Side effect (computer science)|side effects]] (printing &amp;lt;code&amp;gt;b * c&amp;lt;/code&amp;gt;, perhaps).&lt;br /&gt;
&lt;br /&gt;
== Expression in terms of dataflow equations ==&lt;br /&gt;
&lt;br /&gt;
Liveness analysis is a &amp;quot;backwards may&amp;quot; analysis. The analysis is done in a [[Data-flow_analysis#Backward_Analysis|backwards]] order, and the dataflow [[confluence operator]] is [[set union]]. In other words, if applying liveness analysis to a function with a particular number of logical branches within it, the analysis is performed starting from the end of the function working towards the beginning (hence &amp;quot;backwards&amp;quot;), and a variable is considered live if any of the branches moving forward within the function might potentially (hence &amp;quot;may&amp;quot;) need the variable&amp;#039;s current value. This is in contrast to a &amp;quot;backwards must&amp;quot; analysis which would instead enforce this condition on all branches moving forward.&lt;br /&gt;
&lt;br /&gt;
The dataflow equations used for a given basic block &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and exiting block &amp;lt;math&amp;gt;\mathit{final}&amp;lt;/math&amp;gt; in live variable analysis are the following:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
{\mbox{GEN}}[s] &amp;lt;/math&amp;gt;: The set of variables that are used in s before any assignment in the same basic block.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
{\mbox{KILL}}[s] &amp;lt;/math&amp;gt;: The set of variables that are assigned a value in s (in many books that discuss compiler design, KILL (s) is also defined as the set of variables assigned a value in s &amp;#039;&amp;#039;before any use&amp;#039;&amp;#039;, but this does not change the solution of the dataflow equation):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
{\mbox{LIVE}}_{\mathrm{in}}[s] = {\mbox{GEN}}[s] \cup ({\mbox{LIVE}}_{\mathrm{out}}[s] - {\mbox{KILL}}[s])&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
{\mbox{LIVE}}_{\mathrm{out}}[\mathit{final}] = {\emptyset} &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
{\mbox{LIVE}}_{\mathrm{out}}[s] = \bigcup_{p \in \mathrm{succ}[s]} {\mbox{LIVE}}_{\mathrm{in}}[p]&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
{\mbox{GEN}}[d : y \leftarrow f(x_1,\cdots,x_n)] = \{x_1,...,x_n\}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
{\mbox{KILL}}[d : y \leftarrow f(x_1,\cdots,x_n)] = \{y\}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The in-state of a block is the set of variables that are live at the start of the block. Its out-state is the set of variables that are live at the end of it. The out-state is the union of the in-states of the block&amp;#039;s successors. The transfer function of a statement is applied by making the variables that are written dead, then making the variables that are read live.&lt;br /&gt;
&lt;br /&gt;
== Second example ==&lt;br /&gt;
{|&lt;br /&gt;
|&lt;br /&gt;
 // in: {}; predecessor blocks: none&lt;br /&gt;
 b1: a = 3; &lt;br /&gt;
     b = 5;&lt;br /&gt;
     d = 4;&lt;br /&gt;
     x = 100; //x is never being used later thus not in the out set {a,b,d}&lt;br /&gt;
     if a &amp;gt; b then&lt;br /&gt;
 // out: {a,b,d}    //union of all (in) successors of b1 =&amp;gt; b2: {a,b}, and b3:{b,d}  &lt;br /&gt;
 &lt;br /&gt;
 // in: {a,b}; predecessor blocks: b1&lt;br /&gt;
 b2: c = a + b;&lt;br /&gt;
     d = 2;&lt;br /&gt;
 // out: {b,d}&lt;br /&gt;
 &lt;br /&gt;
 // in: {b,d}; predecessor blocks: b1 and b2&lt;br /&gt;
 b3: endif&lt;br /&gt;
     c = 4;&lt;br /&gt;
     return b * d + c;&lt;br /&gt;
 // out:{}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The in-state of b3 only contains &amp;#039;&amp;#039;b&amp;#039;&amp;#039; and &amp;#039;&amp;#039;d&amp;#039;&amp;#039;, since &amp;#039;&amp;#039;c&amp;#039;&amp;#039; has been written. The out-state of b1 is the union of the in-states of b2 and b3. The definition of &amp;#039;&amp;#039;c&amp;#039;&amp;#039; in b2 can be removed, since &amp;#039;&amp;#039;c&amp;#039;&amp;#039; is not live immediately after the statement.&lt;br /&gt;
&lt;br /&gt;
Solving the data flow equations starts with initializing all in-states and out-states to the empty set. The work list is initialized by inserting the exit point (b3) in the work list (typical for backward flow). Its computed in-state differs from the previous one, so its predecessors b1 and b2 are inserted and the process continues. The progress is summarized in the table below.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! processing&lt;br /&gt;
! out-state&lt;br /&gt;
! old in-state &lt;br /&gt;
! new in-state&lt;br /&gt;
! work list&lt;br /&gt;
|-&lt;br /&gt;
| b3&lt;br /&gt;
| {}&lt;br /&gt;
| {}&lt;br /&gt;
| {b,d}&lt;br /&gt;
| (b1,b2)&lt;br /&gt;
|-&lt;br /&gt;
| b1&lt;br /&gt;
| {b,d}&lt;br /&gt;
| {}&lt;br /&gt;
| {}&lt;br /&gt;
| (b2)&lt;br /&gt;
|-&lt;br /&gt;
| b2&lt;br /&gt;
| {b,d}&lt;br /&gt;
| {}&lt;br /&gt;
| {a,b}&lt;br /&gt;
| (b1)&lt;br /&gt;
|-&lt;br /&gt;
| b1&lt;br /&gt;
| {a,b,d}&lt;br /&gt;
| {}&lt;br /&gt;
| {}&lt;br /&gt;
| ()&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note that b1 was entered in the list before b2, which forced processing b1 twice (b1 was re-entered as predecessor of b2). Inserting b2 before b1 would have allowed earlier completion.&lt;br /&gt;
&lt;br /&gt;
Initializing with the empty set is an optimistic initialization: all variables start out as dead. Note that the out-states cannot shrink from one iteration to the next, although the out-state can be smaller than the in-state. This can be seen from the fact that after the first iteration the out-state can only change by a change of the in-state. Since the in-state starts as the empty set, it can only grow in further iterations.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
{{reflist|30em}}&lt;br /&gt;
{{cite book|last1=Aho|first1=Alfred|last2=Lam|first2=Monica|last3=Sethi|first3=Ravi|last4=Ullman|first4=Jeffrey|year=2007|edition=2|title=Compilers: Principles, Techniques, and Tools|page=608}}&lt;br /&gt;
{{Compiler optimizations}}&lt;br /&gt;
[[Category:Compiler optimizations]]&lt;br /&gt;
[[Category:Data-flow analysis]]&lt;br /&gt;
[[Category:Static program analysis]]&lt;/div&gt;</summary>
		<author><name>imported&gt;GottlobFlegel</name></author>
	</entry>
</feed>