Updating VariableLiveRange
authorBrian Bohe <t-brboh@microsoft.com>
Fri, 21 Feb 2020 19:43:36 +0000 (11:43 -0800)
committerBrian Bohe <t-brboh@microsoft.com>
Fri, 21 Feb 2020 21:31:01 +0000 (13:31 -0800)
When a variable is being born at the same location it
died at the previous assembly instruction (in the same
group of instructions), we reported as it was alive
the whole time.

src/coreclr/src/jit/codegencommon.cpp
src/coreclr/src/jit/emit.cpp
src/coreclr/src/jit/emit.h
src/coreclr/src/jit/emitpub.h

index 1af9bc0..0bcd836 100644 (file)
@@ -11466,10 +11466,21 @@ void CodeGenInterface::VariableLiveKeeper::VariableLiveDescriptor::startLiveRang
     // Is the first "VariableLiveRange" or the previous one has been closed so its "m_EndEmitLocation" is valid
     noway_assert(m_VariableLiveRanges->empty() || m_VariableLiveRanges->back().m_EndEmitLocation.Valid());
 
-    // Creates new live range with invalid end
-    m_VariableLiveRanges->emplace_back(varLocation, emitLocation(), emitLocation());
-    m_VariableLiveRanges->back().m_StartEmitLocation.CaptureLocation(emit);
-
+    if (!m_VariableLiveRanges->empty() &&
+        m_VariableLiveRanges->back().m_EndEmitLocation.IsPreviousIns(emit) &&
+        siVarLoc::Equals(&varLocation, &(m_VariableLiveRanges->back().m_VarLocation)))
+    {
+        // The variable is being born at the exactly same place just one assembly instructtion.
+        // We assume it never died.
+        m_VariableLiveRanges->back().m_EndEmitLocation.Init();
+    }
+    else
+    {
+        // Creates new live range with invalid end
+        m_VariableLiveRanges->emplace_back(varLocation, emitLocation(), emitLocation());
+        m_VariableLiveRanges->back().m_StartEmitLocation.CaptureLocation(emit);
+    }
+    
 #ifdef DEBUG
     if (!m_VariableLifeBarrier->hasLiveRangesToDump())
     {
index 9288f6c..a95e70c 100644 (file)
@@ -65,6 +65,15 @@ UNATIVE_OFFSET emitLocation::GetFuncletPrologOffset(emitter* emit) const
     return emit->emitCurIGsize;
 }
 
+// Returns true if the emitter is on the next instruction of the same group than this emitLocation
+bool emitLocation::IsPreviousIns(const emitter* emit) const
+{
+    assert(Valid());
+    bool sameGroup = ig == emit->emitCurIG;
+    bool sameInsNum = emitGetInsNumFromCodePos(codePos) == emitGetInsNumFromCodePos(emit->emitCurOffset()) - 1;
+    return sameGroup && sameInsNum;
+}
+
 #ifdef DEBUG
 void emitLocation::Print() const
 {
index 37a1795..89d09e3 100644 (file)
@@ -191,6 +191,8 @@ public:
 
     UNATIVE_OFFSET GetFuncletPrologOffset(emitter* emit) const;
 
+    bool emitLocation::IsPreviousIns(const emitter* emit) const;
+
 #ifdef DEBUG
     void Print() const;
 #endif // DEBUG
@@ -2389,7 +2391,7 @@ inline unsigned emitGetInsOfsFromCodePos(unsigned codePos)
     return (codePos >> 16);
 }
 
-inline unsigned emitter::emitCurOffset()
+inline unsigned emitter::emitCurOffset() const
 {
     unsigned codePos = emitCurIGinsCnt + (emitCurIGsize << 16);
 
index cd28e03..bc8abf3 100644 (file)
@@ -65,7 +65,7 @@ void emitFinishPrologEpilogGeneration();
 /************************************************************************/
 
 void*    emitCurBlock();
-unsigned emitCurOffset();
+unsigned emitCurOffset() const;
 
 UNATIVE_OFFSET emitCodeOffset(void* blockPtr, unsigned codeOffs);