InlineRefactoring: start to capture failures in the inline tree
This change starts capturing information about failed inlines in the
inline tree. Not all failures are captured yet; see below for notes.
Sample trees showing a failure:
```
Inlines into Secant:Inner(byref,byref,double,double,int,byref)
[IL=0004 TR=000008] [FAILED: exceeds profit threshold] Secant:FF(double):double
[IL=0023 TR=000036] [native size estimate ok] Secant:FF(double):double
```
InlineContext is revised to have 3 static constructors: one for the
root context, one for successful inlines, and one for failed inlines.
Successful inlines are always captured in the tree, since they are used
to track inline depth and recursion. Failures are only captured in
DEBUG and are just there for diagnostic purposes. The success and
failure constructors also link the new contexts into the tree at the
proper spot.
With this the jit can now capture failures for calls that were
initially identified as candidates. Top-level non-candidates are still
screened out in fgInline, and lower-level non-candidates simply aren't
seen at all by the current code. This will be addressed in a subsequent
change.
New calls can appear in the gap between caller and callee, as the code
for the two is stitched together. These are never candidates and never
given candidate screening. For now, if a new failing context is unable
to find a parent context from the IR, the code assumes the IR was
created in this gap. Down the road we may want to insist that all IR be
covered by some InlineContext (eg for improved debugging of optimized
code).
The InlineContext now also captures and prints the tree ID of the call
to make it easier to relate back to IR dumps.
Commit migrated from https://github.com/dotnet/coreclr/commit/
ea53f9a34f4c658b207c214568e78c2635629711