diff options
author | Joseph Tremoulet <jotrem@microsoft.com> | 2017-03-21 17:13:26 -0400 |
---|---|---|
committer | Joseph Tremoulet <jotrem@microsoft.com> | 2017-05-15 20:01:40 -0400 |
commit | a6a8bd2f901997502c9105a0c1b2f517e8898434 (patch) | |
tree | 4dadad844183c38eeca5776be5590608d09901d3 /src/jit/compiler.h | |
parent | fe879dbfd29a6ec1d52f2a2448e595ec99ba2882 (diff) | |
download | coreclr-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.h | 18 |
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(); |