JIT: null out inline gc type locals after inline body
authorAndy Ayers <andya@microsoft.com>
Fri, 10 Feb 2017 00:43:55 +0000 (16:43 -0800)
committerAndy Ayers <andya@microsoft.com>
Tue, 14 Feb 2017 20:03:13 +0000 (12:03 -0800)
commit1baa7b85bec1b5d23c0a80b256d652c443f4ab60
tree9dd6af04ef44f86c00ab3bd8bfaa762efa262f35
parent9bca33359d4c96af362d8073d936ce918a84dece
JIT: null out inline gc type locals after inline body

Inlining can sometimes end up stretching GC lifetimes for inlinee
locals past the end of the inlinee method body.

This change extends the work done for inlining methods with pinned
locals to null out all gc ref type locals. If there are any gc type
locals, the return value is copied to a temp inside the inlinee body,
and then at the end of the body the gc type locals are set to null.

In most cases these null stores end up getting removed by dead code
elimination, but if the local ends up untracked, the store remains
and limits the active GC lifetime.

This change requires more extensive use of the return value spill temp
(since we must be absolutely sure the return value expression does not
depend on any of the locals). We now use the spill temp if any local is
a gc ref type (used or not).

More widespread use of the spill temp exposed an issue in the tail call
transformation, where the side effect flags were overly pessimistic for
a post tail-call GT_COMMA statement that represented an ignored return
value from an inlined call. The root issue is that the return value
placeholder is given a GTF_CALL effect but later when the actual return
value expression is substituted in place there may be no side effect --
in particular this happens when the return value expression is the spill
temp.

So, we also update the post tail-call side-effect-free statment check to
look through the potentially pessimistic GT_COMMA flags and check for side
effects on the child nodes.

Closes dotnet/coreclr#9218.

Commit migrated from https://github.com/dotnet/coreclr/commit/05721eebc54af7bb535f8afb7c67a557cbac5dd5
src/coreclr/src/jit/flowgraph.cpp
src/coreclr/src/jit/importer.cpp
src/coreclr/src/jit/inline.h
src/coreclr/src/jit/morph.cpp