<?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=Loop-invariant_code_motion</id>
	<title>Loop-invariant code motion - 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=Loop-invariant_code_motion"/>
	<link rel="alternate" type="text/html" href="http://debianws.lexgopc.com/wiki143/index.php?title=Loop-invariant_code_motion&amp;action=history"/>
	<updated>2026-05-05T18:28:01Z</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=Loop-invariant_code_motion&amp;diff=5256866&amp;oldid=prev</id>
		<title>imported&gt;Jochen Burghardt: /* Invariant code detection */ the authors are active, not their paper (and shorter); rm 2nd wikilink (kept 1st one since a draft seems to be forthcoming)</title>
		<link rel="alternate" type="text/html" href="http://debianws.lexgopc.com/wiki143/index.php?title=Loop-invariant_code_motion&amp;diff=5256866&amp;oldid=prev"/>
		<updated>2025-09-04T14:41:18Z</updated>

		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;Invariant code detection: &lt;/span&gt; the authors are active, not their paper (and shorter); rm 2nd wikilink (kept 1st one since a draft seems to be forthcoming)&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Previous revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 14:41, 4 September 2025&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l37&quot;&gt;Line 37:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 37:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;For example, if all reaching definitions for the operands of some simple expression are outside of the loop, the expression can be moved out of the loop.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;For example, if all reaching definitions for the operands of some simple expression are outside of the loop, the expression can be moved out of the loop.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Recent work by &lt;/del&gt;Moyen, Rubiano and [[Thomas Seiller|Seiller]] &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;uses &lt;/del&gt;data-flow dependence analysis &amp;lt;ref&amp;gt;{{cite book |last1=Moyen |first1=Jean-Yves |last2=Rubiano |first2=Thomas |last3=Seiller |first3=Thomas |chapter=Loop Quasi-Invariant Chunk Detection |title=Automated Technology for Verification and Analysis |series=Lecture Notes in Computer Science |date=2017 |volume=10482 |pages=91–108 |doi=10.1007/978-3-319-68167-2_7|isbn=978-3-319-68166-5 }}&amp;lt;/ref&amp;gt; to detect not only invariant commands but larger code fragments such as an inner loop. The analysis also detects quasi-invariants of arbitrary degrees, that is commands or code fragments that become invariant after a fixed number of iterations of the loop body. This technique was later used by Aubert, Rubiano, Rusch, and &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[[Thomas &lt;/del&gt;Seiller&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|Seiller]] &lt;/del&gt;to automatically parallelise loops.&amp;lt;ref&amp;gt;{{cite book |last1=Aubert |first1=Clément |last2=Rubiano |first2=Thomas  &lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Moyen, Rubiano and [[Thomas Seiller|Seiller]] &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;used &lt;/ins&gt;data-flow dependence analysis&amp;lt;ref&amp;gt;{{cite book |last1=Moyen |first1=Jean-Yves |last2=Rubiano |first2=Thomas |last3=Seiller |first3=Thomas |chapter=Loop Quasi-Invariant Chunk Detection |title=Automated Technology for Verification and Analysis |series=Lecture Notes in Computer Science |date=2017 |volume=10482 |pages=91–108 |doi=10.1007/978-3-319-68167-2_7|isbn=978-3-319-68166-5 }}&amp;lt;/ref&amp;gt; to detect not only invariant commands but larger code fragments such as an inner loop. The analysis also detects quasi-invariants of arbitrary degrees, that is commands or code fragments that become invariant after a fixed number of iterations of the loop body. This technique was later used by Aubert, Rubiano, Rusch, and Seiller to automatically parallelise loops.&amp;lt;ref&amp;gt;{{cite book |last1=Aubert |first1=Clément |last2=Rubiano |first2=Thomas  &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|last3=Rusch |first3=Neea |last4=Seiller |first4=Thomas |chapter= Distributing and Parallelizing Non-canonical Loops |title= Verification, Model Checking, and Abstract Interpretation |series=Lecture Notes in Computer Science |date=2023 |volume=13881 |pages=91–108 |doi=10.1007/978-3-031-24950-1_1 }}&amp;lt;/ref&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|last3=Rusch |first3=Neea |last4=Seiller |first4=Thomas |chapter= Distributing and Parallelizing Non-canonical Loops |title= Verification, Model Checking, and Abstract Interpretation |series=Lecture Notes in Computer Science |date=2023 |volume=13881 |pages=91–108 |doi=10.1007/978-3-031-24950-1_1 }}&amp;lt;/ref&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>imported&gt;Jochen Burghardt</name></author>
	</entry>
	<entry>
		<id>http://debianws.lexgopc.com/wiki143/index.php?title=Loop-invariant_code_motion&amp;diff=480268&amp;oldid=prev</id>
		<title>imported&gt;WikiCleanerBot: v2.05b - Bot T20 CW#61 - Fix errors for CW project (Reference before punctuation)</title>
		<link rel="alternate" type="text/html" href="http://debianws.lexgopc.com/wiki143/index.php?title=Loop-invariant_code_motion&amp;diff=480268&amp;oldid=prev"/>
		<updated>2024-12-19T05:14:29Z</updated>

		<summary type="html">&lt;p&gt;v2.05b - &lt;a href=&quot;/wiki143/index.php?title=User:WikiCleanerBot&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;User:WikiCleanerBot (page does not exist)&quot;&gt;Bot T20 CW#61&lt;/a&gt; - Fix errors for &lt;a href=&quot;/wiki143/index.php?title=WP:WCW&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;WP:WCW (page does not exist)&quot;&gt;CW project&lt;/a&gt; (Reference before punctuation)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{short description|Type of compiler optimization}}&lt;br /&gt;
{{More citations needed|date=January 2021}}&lt;br /&gt;
&lt;br /&gt;
In [[computer programming]], [[loop-invariant code]] consists of statements or expressions (in an [[imperative programming|imperative]] [[programming language]]) that can be moved outside the body of a loop without affecting the semantics of the program. &amp;#039;&amp;#039;&amp;#039;Loop-invariant code motion&amp;#039;&amp;#039;&amp;#039; (also called &amp;#039;&amp;#039;&amp;#039;hoisting&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;scalar promotion&amp;#039;&amp;#039;&amp;#039;) is a [[compiler optimization]] that performs this movement automatically.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
In the following code sample, two optimizations can be applied.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int i = 0;&lt;br /&gt;
while (i &amp;lt; n) {&lt;br /&gt;
    x = y + z;&lt;br /&gt;
    a[i] = 6 * i + x * x;&lt;br /&gt;
    ++i;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although the calculation &amp;lt;code&amp;gt;x = y + z&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;x * x&amp;lt;/code&amp;gt; is loop-invariant, precautions must be taken before moving the code outside the loop. It is possible that the loop condition is &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; (for example, if &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; holds a negative value), and in such case, the loop body should not be executed at all. One way of guaranteeing correct behaviour is using a conditional branch outside of the loop. Evaluating the loop condition can have [[Side effect (computer science)|side effects]], so an additional evaluation by the &amp;lt;code&amp;gt;if&amp;lt;/code&amp;gt; construct should be compensated by replacing the &amp;lt;code&amp;gt;while&amp;lt;/code&amp;gt; loop with a &amp;lt;code&amp;gt;[[Do while loop|do {} while]]&amp;lt;/code&amp;gt;. If the code used &amp;lt;code&amp;gt;do {} while&amp;lt;/code&amp;gt; in the first place, the whole guarding process is not needed, as the loop body is guaranteed to execute at least once.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int i = 0;&lt;br /&gt;
if (i &amp;lt; n) {&lt;br /&gt;
    x = y + z;&lt;br /&gt;
    int const t1 = x * x;&lt;br /&gt;
    do {&lt;br /&gt;
        a[i] = 6 * i + t1;&lt;br /&gt;
        ++i;&lt;br /&gt;
    } while (i &amp;lt; n);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code can be optimized further. For example, [[strength reduction]] could remove the two multiplications inside the loop (&amp;lt;code&amp;gt;6*i&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;a[i]&amp;lt;/code&amp;gt;), and [[induction variable]] elimination could then elide &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; completely. Since &amp;lt;code&amp;gt;6 * i&amp;lt;/code&amp;gt; must be in lock step with &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; itself, there is no need to have both.&lt;br /&gt;
&lt;br /&gt;
==Invariant code detection==&lt;br /&gt;
Usually, a [[Reaching definition|reaching definitions analysis]] is used to detect whether a statement or expression is loop invariant.&lt;br /&gt;
&lt;br /&gt;
For example, if all reaching definitions for the operands of some simple expression are outside of the loop, the expression can be moved out of the loop.&lt;br /&gt;
&lt;br /&gt;
Recent work by Moyen, Rubiano and [[Thomas Seiller|Seiller]] uses data-flow dependence analysis &amp;lt;ref&amp;gt;{{cite book |last1=Moyen |first1=Jean-Yves |last2=Rubiano |first2=Thomas |last3=Seiller |first3=Thomas |chapter=Loop Quasi-Invariant Chunk Detection |title=Automated Technology for Verification and Analysis |series=Lecture Notes in Computer Science |date=2017 |volume=10482 |pages=91–108 |doi=10.1007/978-3-319-68167-2_7|isbn=978-3-319-68166-5 }}&amp;lt;/ref&amp;gt; to detect not only invariant commands but larger code fragments such as an inner loop. The analysis also detects quasi-invariants of arbitrary degrees, that is commands or code fragments that become invariant after a fixed number of iterations of the loop body. This technique was later used by Aubert, Rubiano, Rusch, and [[Thomas Seiller|Seiller]] to automatically parallelise loops.&amp;lt;ref&amp;gt;{{cite book |last1=Aubert |first1=Clément |last2=Rubiano |first2=Thomas &lt;br /&gt;
|last3=Rusch |first3=Neea |last4=Seiller |first4=Thomas |chapter= Distributing and Parallelizing Non-canonical Loops |title= Verification, Model Checking, and Abstract Interpretation |series=Lecture Notes in Computer Science |date=2023 |volume=13881 |pages=91–108 |doi=10.1007/978-3-031-24950-1_1 }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Benefits==&lt;br /&gt;
Loop-invariant code which has been hoisted out of a loop is executed less often, providing a speedup.  Another effect of this transformation is allowing constants to be stored in registers and not having to calculate the address and access the memory (or cache line) at each iteration.&lt;br /&gt;
&lt;br /&gt;
However, if too many variables are created, there will be high [[register pressure]], especially on processors with few registers, like the 32-bit [[x86]]. If the compiler runs out of registers, some variables will be [[register spilling|spilled]]. To counteract this, the inverse optimization can be performed, [[rematerialization]].&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Code motion]]&lt;br /&gt;
* [[Loop invariant]]&lt;br /&gt;
&lt;br /&gt;
==Further reading==&lt;br /&gt;
* Aho, Alfred V.; Sethi, Ravi; &amp;amp; Ullman, Jeffrey D. (1986). Compilers: Principles, Techniques, and Tools. Addison Wesley. {{ISBN|0-201-10088-6}}.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
{{Reflist}}&lt;br /&gt;
&lt;br /&gt;
==External links==&lt;br /&gt;
* [https://web.archive.org/web/20170806083023/http://www.compileroptimizations.com/category/hoisting.htm Compiler Optimizations &amp;amp;mdash; Hoisting]&lt;br /&gt;
&lt;br /&gt;
{{Compiler optimizations}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Compiler optimizations]]&lt;/div&gt;</summary>
		<author><name>imported&gt;WikiCleanerBot</name></author>
	</entry>
</feed>