summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPat Gavlin <pagavlin@microsoft.com>2017-01-09 12:12:14 -0800
committerPat Gavlin <pagavlin@microsoft.com>2017-01-10 10:21:13 -0800
commit4b2c59bcee02ea95844abfe00e86b1cb7adfdd0f (patch)
tree700607cbcf3098f7301906239027e02d1848f318 /src
parent0fa2c31d2b65a266e016180e785c37febaa45fca (diff)
downloadcoreclr-4b2c59bcee02ea95844abfe00e86b1cb7adfdd0f.tar.gz
coreclr-4b2c59bcee02ea95844abfe00e86b1cb7adfdd0f.tar.bz2
coreclr-4b2c59bcee02ea95844abfe00e86b1cb7adfdd0f.zip
Do not rerun LVA if only live-out has changed.
If only the live-out set for a block changes during live variable analysis, the LVA algorithm does not need to be re-run. As per the dataflow equations for LVA: liveOut(block) = union(liveIn(s) for all s in successors(block)) Thus, unless a change to the live-out set for a block propagates through to a change to the live-in set for that block, it will not affect the live-in/out sets of any of its predecessors and liveness need not be re-run.
Diffstat (limited to 'src')
-rw-r--r--src/jit/liveness.cpp33
1 files changed, 17 insertions, 16 deletions
diff --git a/src/jit/liveness.cpp b/src/jit/liveness.cpp
index 3a2fe3e650..f06ca4891e 100644
--- a/src/jit/liveness.cpp
+++ b/src/jit/liveness.cpp
@@ -1067,7 +1067,6 @@ class LiveVarAnalysis
{
Compiler* m_compiler;
- bool m_changed;
bool m_hasPossibleBackEdge;
bool m_heapLiveIn;
@@ -1077,7 +1076,6 @@ class LiveVarAnalysis
LiveVarAnalysis(Compiler* compiler)
: m_compiler(compiler)
- , m_changed(false)
, m_hasPossibleBackEdge(false)
, m_heapLiveIn(false)
, m_heapLiveOut(false)
@@ -1086,7 +1084,7 @@ class LiveVarAnalysis
{
}
- void PerBlockAnalysis(BasicBlock* block, bool updateInternalOnly, bool keepAliveThis)
+ bool PerBlockAnalysis(BasicBlock* block, bool updateInternalOnly, bool keepAliveThis)
{
/* Compute the 'liveOut' set */
VarSetOps::ClearD(m_compiler, m_liveOut);
@@ -1148,8 +1146,8 @@ class LiveVarAnalysis
/* Has there been any change in either live set? */
- if (!VarSetOps::Equal(m_compiler, block->bbLiveIn, m_liveIn) ||
- !VarSetOps::Equal(m_compiler, block->bbLiveOut, m_liveOut))
+ bool liveInChanged = !VarSetOps::Equal(m_compiler, block->bbLiveIn, m_liveIn);
+ if (liveInChanged || !VarSetOps::Equal(m_compiler, block->bbLiveOut, m_liveOut))
{
if (updateInternalOnly)
{
@@ -1157,10 +1155,9 @@ class LiveVarAnalysis
noway_assert(block->bbFlags & BBF_INTERNAL);
- if (!VarSetOps::Equal(m_compiler, VarSetOps::Intersection(m_compiler, block->bbLiveIn, m_liveIn),
- m_liveIn) ||
- !VarSetOps::Equal(m_compiler, VarSetOps::Intersection(m_compiler, block->bbLiveOut, m_liveOut),
- m_liveOut))
+ liveInChanged = !VarSetOps::Equal(m_compiler, VarSetOps::Intersection(m_compiler, block->bbLiveIn, m_liveIn), m_liveIn);
+ if (liveInChanged ||
+ !VarSetOps::Equal(m_compiler, VarSetOps::Intersection(m_compiler, block->bbLiveOut, m_liveOut), m_liveOut))
{
#ifdef DEBUG
if (m_compiler->verbose)
@@ -1175,23 +1172,23 @@ class LiveVarAnalysis
VarSetOps::UnionD(m_compiler, block->bbLiveIn, m_liveIn);
VarSetOps::UnionD(m_compiler, block->bbLiveOut, m_liveOut);
- m_changed = true;
}
}
else
{
VarSetOps::Assign(m_compiler, block->bbLiveIn, m_liveIn);
VarSetOps::Assign(m_compiler, block->bbLiveOut, m_liveOut);
- m_changed = true;
}
}
- if ((block->bbHeapLiveIn == 1) != m_heapLiveIn || (block->bbHeapLiveOut == 1) != m_heapLiveOut)
+ const bool heapLiveInChanged = (block->bbHeapLiveIn == 1) != m_heapLiveIn;
+ if (heapLiveInChanged || (block->bbHeapLiveOut == 1) != m_heapLiveOut)
{
block->bbHeapLiveIn = m_heapLiveIn;
block->bbHeapLiveOut = m_heapLiveOut;
- m_changed = true;
}
+
+ return liveInChanged || heapLiveInChanged;
}
void Run(bool updateInternalOnly)
@@ -1200,9 +1197,10 @@ class LiveVarAnalysis
m_compiler->lvaKeepAliveAndReportThis() && m_compiler->lvaTable[m_compiler->info.compThisArg].lvTracked;
/* Live Variable Analysis - Backward dataflow */
+ bool changed;
do
{
- m_changed = false;
+ changed = false;
/* Visit all blocks and compute new data flow values */
@@ -1234,7 +1232,10 @@ class LiveVarAnalysis
}
}
- PerBlockAnalysis(block, updateInternalOnly, keepAliveThis);
+ if (PerBlockAnalysis(block, updateInternalOnly, keepAliveThis))
+ {
+ changed = true;
+ }
}
// if there is no way we could have processed a block without seeing all of its predecessors
// then there is no need to iterate
@@ -1242,7 +1243,7 @@ class LiveVarAnalysis
{
break;
}
- } while (m_changed);
+ } while (changed);
}
public: