diff options
author | Pat Gavlin <pagavlin@microsoft.com> | 2017-01-09 12:12:14 -0800 |
---|---|---|
committer | Pat Gavlin <pagavlin@microsoft.com> | 2017-01-10 10:21:13 -0800 |
commit | 4b2c59bcee02ea95844abfe00e86b1cb7adfdd0f (patch) | |
tree | 700607cbcf3098f7301906239027e02d1848f318 /src | |
parent | 0fa2c31d2b65a266e016180e785c37febaa45fca (diff) | |
download | coreclr-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.cpp | 33 |
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: |