This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Track single def locals in importer #21251
Merged
AndyAyersMS
merged 2 commits into
dotnet:master
from
AndyAyersMS:TrackSingleDefLocalsInImporter
Nov 29, 2018
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -387,11 +387,7 @@ void Compiler::lvaInitThisPtr(InitVarDscInfo* varDscInfo) | |
if (!info.compIsStatic) | ||
{ | ||
varDsc->lvIsParam = 1; | ||
#if ASSERTION_PROP | ||
varDsc->lvSingleDef = 1; | ||
#endif | ||
|
||
varDsc->lvIsPtr = 1; | ||
varDsc->lvIsPtr = 1; | ||
|
||
lvaArg0Var = info.compThisArg = varDscInfo->varNum; | ||
noway_assert(info.compThisArg == 0); | ||
|
@@ -474,9 +470,7 @@ void Compiler::lvaInitRetBuffArg(InitVarDscInfo* varDscInfo) | |
varDsc->lvType = TYP_BYREF; | ||
varDsc->lvIsParam = 1; | ||
varDsc->lvIsRegArg = 1; | ||
#if ASSERTION_PROP | ||
varDsc->lvSingleDef = 1; | ||
#endif | ||
|
||
if (hasFixedRetBuffReg()) | ||
{ | ||
varDsc->lvArgReg = theFixedRetBuffReg(); | ||
|
@@ -564,9 +558,6 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo) | |
|
||
CorInfoTypeWithMod corInfoType = info.compCompHnd->getArgType(&info.compMethodInfo->args, argLst, &typeHnd); | ||
varDsc->lvIsParam = 1; | ||
#if ASSERTION_PROP | ||
varDsc->lvSingleDef = 1; | ||
#endif | ||
|
||
lvaInitVarDsc(varDsc, varDscInfo->varNum, strip(corInfoType), typeHnd, argLst, &info.compMethodInfo->args); | ||
|
||
|
@@ -1046,11 +1037,7 @@ void Compiler::lvaInitGenericsCtxt(InitVarDscInfo* varDscInfo) | |
|
||
LclVarDsc* varDsc = varDscInfo->varDsc; | ||
varDsc->lvIsParam = 1; | ||
#if ASSERTION_PROP | ||
varDsc->lvSingleDef = 1; | ||
#endif | ||
|
||
varDsc->lvType = TYP_I_IMPL; | ||
varDsc->lvType = TYP_I_IMPL; | ||
|
||
if (varDscInfo->canEnreg(TYP_I_IMPL)) | ||
{ | ||
|
@@ -1112,10 +1099,6 @@ void Compiler::lvaInitVarArgsHandle(InitVarDscInfo* varDscInfo) | |
// that other problems are fixed. | ||
lvaSetVarAddrExposed(varDscInfo->varNum); | ||
|
||
#if ASSERTION_PROP | ||
varDsc->lvSingleDef = 1; | ||
#endif | ||
|
||
if (varDscInfo->canEnreg(TYP_I_IMPL)) | ||
{ | ||
/* Another register argument */ | ||
|
@@ -2706,54 +2689,60 @@ void Compiler::lvaUpdateClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool | |
// We should already have a class | ||
assert(varDsc->lvClassHnd != nullptr); | ||
|
||
#if defined(DEBUG) | ||
// We should only be updating classes for single-def locals. | ||
assert(varDsc->lvSingleDef); | ||
|
||
// In general we only expect one update per local var. However if | ||
// a block is re-imported and that block has the only STLOC for | ||
// the var, we may see multiple updates. All subsequent updates | ||
// should agree on the type, since reimportation is triggered by | ||
// type mismatches for things other than ref types. | ||
if (varDsc->lvClassInfoUpdated) | ||
{ | ||
assert(varDsc->lvClassHnd == clsHnd); | ||
assert(varDsc->lvClassIsExact == isExact); | ||
} | ||
// Now see if we should update. | ||
// | ||
// New information may not always be "better" so do some | ||
// simple analysis to decide if the update is worthwhile. | ||
const bool isNewClass = (clsHnd != varDsc->lvClassHnd); | ||
bool shouldUpdate = false; | ||
|
||
// This counts as an update, even if nothing changes. | ||
varDsc->lvClassInfoUpdated = true; | ||
// Are we attempting to update the class? Only check this when we have | ||
// an new type and the existing class is inexact... we should not be | ||
// updating exact classes. | ||
if (!varDsc->lvClassIsExact && isNewClass) | ||
{ | ||
// Todo: improve this analysis by adding a new jit interface method | ||
DWORD newAttrs = info.compCompHnd->getClassAttribs(clsHnd); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Computing class attribs is relatively expensive operation. It computes a ton more than just the |
||
DWORD oldAttrs = info.compCompHnd->getClassAttribs(varDsc->lvClassHnd); | ||
|
||
#endif // defined(DEBUG) | ||
// Avoid funny things with __Canon by only merging if both shared or both unshared | ||
if ((newAttrs & CORINFO_FLG_SHAREDINST) == (oldAttrs & CORINFO_FLG_SHAREDINST)) | ||
{ | ||
// If we merge types and we get back the old class, the new class is more | ||
// specific and we should update to it. | ||
CORINFO_CLASS_HANDLE mergeClass = info.compCompHnd->mergeClasses(clsHnd, varDsc->lvClassHnd); | ||
|
||
// If previous type was exact, there is nothing to update. Would | ||
// like to verify new type is compatible but can't do this yet. | ||
if (varDsc->lvClassIsExact) | ||
{ | ||
return; | ||
if (mergeClass == varDsc->lvClassHnd) | ||
{ | ||
shouldUpdate = true; | ||
} | ||
} | ||
else if ((newAttrs & CORINFO_FLG_SHAREDINST) == 0) | ||
{ | ||
// Update if we go from shared to unshared | ||
shouldUpdate = true; | ||
} | ||
} | ||
|
||
// Are we updating the type? | ||
if (varDsc->lvClassHnd != clsHnd) | ||
// Else are we attempting to update exactness? | ||
else if (isExact && !varDsc->lvClassIsExact && !isNewClass) | ||
{ | ||
JITDUMP("\nlvaUpdateClass: Updating class for V%02i from (%p) %s to (%p) %s %s\n", varNum, | ||
dspPtr(varDsc->lvClassHnd), info.compCompHnd->getClassName(varDsc->lvClassHnd), dspPtr(clsHnd), | ||
info.compCompHnd->getClassName(clsHnd), isExact ? " [exact]" : ""); | ||
|
||
varDsc->lvClassHnd = clsHnd; | ||
varDsc->lvClassIsExact = isExact; | ||
return; | ||
shouldUpdate = true; | ||
} | ||
|
||
// Class info matched. Are we updating exactness? | ||
if (isExact) | ||
{ | ||
JITDUMP("\nlvaUpdateClass: Updating class for V%02i (%p) %s to be exact\n", varNum, dspPtr(varDsc->lvClassHnd), | ||
info.compCompHnd->getClassName(varDsc->lvClassHnd)); | ||
JITDUMP("\nlvaUpdateClass:%s Updating class for V%02u from (%p) %s%s to (%p) %s%s\n", varNum, | ||
shouldUpdate ? "" : " NOT", dspPtr(varDsc->lvClassHnd), info.compCompHnd->getClassName(varDsc->lvClassHnd), | ||
varDsc->lvClassIsExact ? " [exact]" : "", dspPtr(clsHnd), info.compCompHnd->getClassName(clsHnd), | ||
isExact ? " [exact]" : ""); | ||
|
||
if (shouldUpdate) | ||
{ | ||
varDsc->lvClassHnd = clsHnd; | ||
varDsc->lvClassIsExact = isExact; | ||
return; | ||
} | ||
|
||
// Else we have the same handle and (in)exactness as before. Do nothing. | ||
return; | ||
} | ||
|
||
|
@@ -4155,6 +4144,10 @@ void Compiler::lvaComputeRefCounts(bool isRecompute, bool setSlotNumbers) | |
{ | ||
varDsc->lvSlotNum = lclNum; | ||
} | ||
|
||
// Set initial value for lvSingleDef for explicit and implicit | ||
// argument locals as they are "defined" on entry. | ||
varDsc->lvSingleDef = varDsc->lvIsParam; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this where we get the 'this' pointers lcSingleDef set to true? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. |
||
} | ||
|
||
JITDUMP("\n*** lvaComputeRefCounts -- explicit counts ***\n"); | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still have varDsc->lvSingleDef here?
It is important to mark the 'this' pointer as a single def variable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is set later on (as you note below).