summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndy Ayers <andya@microsoft.com>2018-07-20 14:56:09 -0700
committerGitHub <noreply@github.com>2018-07-20 14:56:09 -0700
commit699028a7a033991f01a72211a88a534ef1360c3a (patch)
tree1106ee9a2cc4dfb4649ca4c6f6f702003b4af786 /src
parentc98addeee64e0bca467079c7e9b9c359818f144c (diff)
downloadcoreclr-699028a7a033991f01a72211a88a534ef1360c3a.tar.gz
coreclr-699028a7a033991f01a72211a88a534ef1360c3a.tar.bz2
coreclr-699028a7a033991f01a72211a88a534ef1360c3a.zip
JIT: handle implicit local var references via local var attribute bit (#19012)
Instead of relying on ref count bumps, add a new attribute bit to local vars to indicate that they may have implicit references (prolog, epilog, gc, eh) and may not have any IR references. Use this attribute bit to ensure that the ref count and weighted ref count for such variables are never reported as zero, and as a result that these variables end up being allocated and reportable. This is another preparatory step for #18969 and frees the jit to recompute explicit ref counts via an IR scan without having to special case the counts for these variables. The jit can no longer describe implicit counts other than 1 and implicit weights otehr than BB_UNITY_WEIGHT, but that currently doesn't seem to be very important. The new bit fits into an existing padding void so LclVarDsc remains at 128 bytes (for windows x64).
Diffstat (limited to 'src')
-rw-r--r--src/jit/compiler.h13
-rw-r--r--src/jit/compiler.hpp5
-rw-r--r--src/jit/lclvars.cpp22
-rw-r--r--src/jit/liveness.cpp9
4 files changed, 30 insertions, 19 deletions
diff --git a/src/jit/compiler.h b/src/jit/compiler.h
index e5d4d67efe..570d8d9c8e 100644
--- a/src/jit/compiler.h
+++ b/src/jit/compiler.h
@@ -307,6 +307,9 @@ public:
unsigned char lvClassInfoUpdated : 1; // true if this var has updated class handle or exactness
#endif
+ unsigned char lvImplicitlyReferenced : 1; // true if there are non-IR references to this local (prolog, epilog, gc,
+ // eh)
+
union {
unsigned lvFieldLclStart; // The index of the local var representing the first field in the promoted struct
// local. For implicit byref parameters, this gets hijacked between
@@ -604,6 +607,11 @@ private:
public:
unsigned short lvRefCnt() const
{
+ if (lvImplicitlyReferenced && (m_lvRefCnt == 0))
+ {
+ return 1;
+ }
+
return m_lvRefCnt;
}
@@ -627,6 +635,11 @@ public:
unsigned lvRefCntWtd() const
{
+ if (lvImplicitlyReferenced && (m_lvRefCntWtd == 0))
+ {
+ return BB_UNITY_WEIGHT;
+ }
+
return m_lvRefCntWtd;
}
diff --git a/src/jit/compiler.hpp b/src/jit/compiler.hpp
index c4a50c0fa9..da00abcd03 100644
--- a/src/jit/compiler.hpp
+++ b/src/jit/compiler.hpp
@@ -1797,9 +1797,8 @@ inline unsigned Compiler::lvaGrabTempWithImplicitUse(bool shortLifetime DEBUGARG
// address-exposed -- DoNotEnregister should suffice?
lvaSetVarAddrExposed(lclNum);
- // We need lvRefCnt to be non-zero to prevent various asserts from firing.
- varDsc->setLvRefCnt(1);
- varDsc->setLvRefCntWtd(BB_UNITY_WEIGHT);
+ // Note the implicit use
+ varDsc->lvImplicitlyReferenced = 1;
return lclNum;
}
diff --git a/src/jit/lclvars.cpp b/src/jit/lclvars.cpp
index e72ae11cf5..00110b0e6a 100644
--- a/src/jit/lclvars.cpp
+++ b/src/jit/lclvars.cpp
@@ -4026,10 +4026,8 @@ void Compiler::lvaMarkLocalVars()
lvaTable[info.compLvFrameListRoot].lvType = TYP_I_IMPL;
- /* Set the refCnt, it is used in the prolog and return block(s) */
-
- lvaTable[info.compLvFrameListRoot].setLvRefCnt(2);
- lvaTable[info.compLvFrameListRoot].setLvRefCntWtd(2 * BB_UNITY_WEIGHT);
+ // This local has implicit prolog and epilog references
+ lvaTable[info.compLvFrameListRoot].lvImplicitlyReferenced = 1;
}
}
@@ -4148,16 +4146,16 @@ void Compiler::lvaMarkLocalVars()
}
#endif
- if (lvaKeepAliveAndReportThis() && lvaTable[0].lvRefCnt() == 0)
+ if (lvaKeepAliveAndReportThis())
{
- lvaTable[0].setLvRefCnt(1);
+ lvaTable[0].lvImplicitlyReferenced = 1;
// This isn't strictly needed as we will make a copy of the param-type-arg
// in the prolog. However, this ensures that the LclVarDsc corresponding to
// info.compTypeCtxtArg is valid.
}
- else if (lvaReportParamTypeArg() && lvaTable[info.compTypeCtxtArg].lvRefCnt() == 0)
+ else if (lvaReportParamTypeArg())
{
- lvaTable[info.compTypeCtxtArg].setLvRefCnt(1);
+ lvaTable[info.compTypeCtxtArg].lvImplicitlyReferenced = 1;
}
lvaLocalVarRefCounted = true;
@@ -4176,12 +4174,8 @@ void Compiler::lvaAllocOutgoingArgSpaceVar()
{
lvaOutgoingArgSpaceVar = lvaGrabTemp(false DEBUGARG("OutgoingArgSpace"));
- lvaTable[lvaOutgoingArgSpaceVar].lvType = TYP_LCLBLK;
-
- /* Set the refCnts */
-
- lvaTable[lvaOutgoingArgSpaceVar].setLvRefCnt(1);
- lvaTable[lvaOutgoingArgSpaceVar].setLvRefCntWtd(BB_UNITY_WEIGHT);
+ lvaTable[lvaOutgoingArgSpaceVar].lvType = TYP_LCLBLK;
+ lvaTable[lvaOutgoingArgSpaceVar].lvImplicitlyReferenced = 1;
}
noway_assert(lvaOutgoingArgSpaceVar >= info.compLocalsCount && lvaOutgoingArgSpaceVar < lvaCount);
diff --git a/src/jit/liveness.cpp b/src/jit/liveness.cpp
index 3c34681daa..9f8910f1e3 100644
--- a/src/jit/liveness.cpp
+++ b/src/jit/liveness.cpp
@@ -1047,9 +1047,14 @@ void Compiler::fgExtendDbgLifetimes()
unsigned lclNum = 0;
for (LclVarDsc *varDsc = lvaTable; lclNum < lvaCount; lclNum++, varDsc++)
{
- if (varDsc->lvRefCnt() == 0 && varDsc->lvIsRegArg)
+ if (lclNum >= info.compArgsCount)
{
- varDsc->setLvRefCnt(1);
+ break; // early exit for loop
+ }
+
+ if (varDsc->lvIsRegArg)
+ {
+ varDsc->lvImplicitlyReferenced = true;
}
}