summaryrefslogtreecommitdiff
path: root/src/jit/compiler.h
diff options
context:
space:
mode:
authorJoseph Tremoulet <jotrem@microsoft.com>2017-03-21 17:13:26 -0400
committerJoseph Tremoulet <jotrem@microsoft.com>2017-05-15 20:01:40 -0400
commita6a8bd2f901997502c9105a0c1b2f517e8898434 (patch)
tree4dadad844183c38eeca5776be5590608d09901d3 /src/jit/compiler.h
parentfe879dbfd29a6ec1d52f2a2448e595ec99ba2882 (diff)
downloadcoreclr-a6a8bd2f901997502c9105a0c1b2f517e8898434.tar.gz
coreclr-a6a8bd2f901997502c9105a0c1b2f517e8898434.tar.bz2
coreclr-a6a8bd2f901997502c9105a0c1b2f517e8898434.zip
Morph implicit byrefs after struct promotion
Change the phase ordering with respect to address-exposed analysis, struct promotion, and implicit byref rewriting. This is done to subject implicit byref parameters to struct promotion; when an implicit byref is to be promoted, generate a new local of the struct type, promote it, and insert code at method entry to initialize the new local by struct-copy from the parameter. As part of the reordering, run address-exposed analysis before implicit byref rewriting, so that the results of address-exposed analysis can be consulted in determining whether promoting each implicit byref is beneficial (in light of the cost of the struct copy), and effectively avoid promoting those which are not deemed beneficial. This change treats all implicit byref promotions as NOT beneficial; it reorders the phases but produces no asm diffs. A subsequent change will identify beneficial implicit byref promotions. To make this work, the implicit byref rewriting happens in a few stages: - fgMarkImplicitByRefArgs now does nothing more than flag which args are implicit byrefs, and runs before struct promotion. - fgRetypeImplicitByRefArgs actually retypes the parameters (from struct to pointer), and decides which promotions are beneficial. It inserts the initializing struct copies for beneficial ones, and annotates non-beneficial ones so their appearances will be rewritten via the pointer parameter. It runs after struct promotion and address-escape analysis. - fgMorphImplicitByRefArgs is moved out of fgMarkAddressExposedLocals, and into fgMorphBlocks. It rewrites any implicit byref parameters which have not been promoted to have the extra indirection at all their references. - fgMarkDemotedImplicitByRefArgs runs after fgMorphBlocks, and cleans up some of the LclVarDsc annotations used to communicate across the previous pieces.
Diffstat (limited to 'src/jit/compiler.h')
-rw-r--r--src/jit/compiler.h18
1 files changed, 17 insertions, 1 deletions
diff --git a/src/jit/compiler.h b/src/jit/compiler.h
index 81adcf026f..5d9cb88263 100644
--- a/src/jit/compiler.h
+++ b/src/jit/compiler.h
@@ -714,6 +714,8 @@ public:
CORINFO_CLASS_HANDLE lvClassHnd; // class handle for the local, or null if not known
+ CORINFO_FIELD_HANDLE lvFieldHnd; // field handle for promoted struct fields
+
BYTE* lvGcLayout; // GC layout info for structs
#if ASSERTION_PROP
@@ -4865,8 +4867,22 @@ private:
void fgPromoteStructs();
fgWalkResult fgMorphStructField(GenTreePtr tree, fgWalkData* fgWalkPre);
fgWalkResult fgMorphLocalField(GenTreePtr tree, fgWalkData* fgWalkPre);
+
+ // Identify which parameters are implicit byrefs, and flag their LclVarDscs.
void fgMarkImplicitByRefArgs();
- bool fgMorphImplicitByRefArgs(GenTree** pTree, fgWalkData* fgWalkPre);
+
+ // Change implicit byrefs' types from struct to pointer, and for any that were
+ // promoted, create new promoted struct temps.
+ void fgRetypeImplicitByRefArgs();
+
+ // Rewrite appearances of implicit byrefs (manifest the implied additional level of indirection).
+ bool fgMorphImplicitByRefArgs(GenTreePtr tree);
+ GenTreePtr fgMorphImplicitByRefArgs(GenTreePtr tree, bool isAddr);
+
+ // Clear up annotations for any struct promotion temps created for implicit byrefs that
+ // wound up unused (due e.g. to being address-exposed and not worth promoting).
+ void fgMarkDemotedImplicitByRefArgs();
+
static fgWalkPreFn fgMarkAddrTakenLocalsPreCB;
static fgWalkPostFn fgMarkAddrTakenLocalsPostCB;
void fgMarkAddressExposedLocals();