summaryrefslogtreecommitdiff
path: root/src/jit/inlinepolicy.h
diff options
context:
space:
mode:
authorAndy Ayers <andya@microsoft.com>2016-02-23 15:21:22 -0800
committerAndy Ayers <andya@microsoft.com>2016-02-25 09:42:40 -0800
commit99927794a53ed68b1a55ddba238eff809be79fdc (patch)
tree6e61cc8fe0a9a2d36d050884af247cf3488e17f2 /src/jit/inlinepolicy.h
parent7a6d8a44c0a2f8d3f431c58aa77b95f15f212756 (diff)
downloadcoreclr-99927794a53ed68b1a55ddba238eff809be79fdc.tar.gz
coreclr-99927794a53ed68b1a55ddba238eff809be79fdc.tar.bz2
coreclr-99927794a53ed68b1a55ddba238eff809be79fdc.zip
Inline Refactoring: set up policy for bad inlinees
Move inline policies to their own header and cpp file. Add a method to the policy class to indicate if the policy wants newly discovered `Never` inline cases to change the callee method attributes to Noinline. This is an existing optimization that saves time when the jit sees calls to this callee elsewhere as a possible inline candidates. For example, in the trace below, at for the call at offset 31, the jit determines that `ToInt32` is too large to be inlined and so marks it as noinline. Then when it sees another call to `ToInt31` at offset 44 it immediately fails the inline attempt. ``` Inlines into RegistryTimeZoneInformation:.ctor(ref):this ... [IL=0031 TR=000040] [FAILED: too many il bytes] System.BitConverter:ToInt32(ref,int):int [IL=0044 TR=000049] [FAILED: noinline per IL/cached result] System.BitConverter:ToInt32(ref,int):int [IL=0057 TR=000058] [FAILED: noinline per IL/cached result] System.BitConverter:ToInt32(ref,int):int ``` Diagnostic and experimental policies may choose to disable this optimization to make it easier to locally reason about failed inlines. There were 5 calls to `setMethodAttribs` passing `CORINFO_FLG_BAD_INLINEE`. This change consolidates 4 of them into the inlining code. The remaining call is for a method with verification errors. I've left it as is.
Diffstat (limited to 'src/jit/inlinepolicy.h')
-rw-r--r--src/jit/inlinepolicy.h110
1 files changed, 110 insertions, 0 deletions
diff --git a/src/jit/inlinepolicy.h b/src/jit/inlinepolicy.h
new file mode 100644
index 0000000000..3f883b2bec
--- /dev/null
+++ b/src/jit/inlinepolicy.h
@@ -0,0 +1,110 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+// Inlining Policies
+//
+// This file contains class definitions for various inlining
+// policies used by the jit.
+//
+// -- CLASSES --
+//
+// LegacyPolicy - policy to provide legacy inline behavior
+
+#ifndef _INLINE_POLICY_H_
+#define _INLINE_POLICY_H_
+
+#include "jit.h"
+#include "inline.h"
+
+// LegacyPolicy implements the inlining policy used by the jit in its
+// initial release.
+
+class LegacyPolicy : public InlinePolicy
+{
+public:
+
+ LegacyPolicy()
+ : InlinePolicy()
+ {
+ // empty
+ }
+
+ // Policy observations
+ void noteCandidate(InlineObservation obs) override;
+ void noteSuccess() override;
+ void note(InlineObservation obs) override;
+ void noteFatal(InlineObservation obs) override;
+ void noteInt(InlineObservation obs, int value) override;
+ void noteDouble(InlineObservation obs, double value) override;
+
+ // Policy decisions
+ bool propagateNeverToRuntime() const override { return true; }
+
+#ifdef DEBUG
+ const char* getName() const override { return "LegacyPolicy"; }
+#endif
+
+private:
+
+ // Helper methods
+ void noteInternal(InlineObservation obs, InlineImpact impact);
+ void setFailure(InlineObservation obs);
+ void setNever(InlineObservation obs);
+ void setCommon(InlineDecision decision, InlineObservation obs);
+};
+
+//
+// Enums are used throughout to provide various descriptions.
+//
+// Classes are used as follows. There are 5 sitations where inline
+// candidacy is evaluated. In each case an InlineResult is allocated
+// on the stack to collect information about the inline candidate.
+//
+// 1. Importer Candidate Screen (impMarkInlineCandidate)
+//
+// Creates: InlineCandidateInfo
+//
+// During importing, the IL being imported is scanned to identify
+// inline candidates. This happens both when the root method is being
+// imported as well as when prospective inlines are being imported.
+// Candidates are marked in the IL and given an InlineCandidateInfo.
+//
+// 2. Inlining Optimization Pass -- candidates (fgInline)
+//
+// Creates / Uses: InlineContext
+// Creates: InlineInfo, InlArgInfo, InlLocalVarInfo
+//
+// During the inlining optimation pass, each candidate is further
+// analyzed. Viable candidates will eventually inspire creation of an
+// InlineInfo and a set of InlArgInfos (for call arguments) and
+// InlLocalVarInfos (for callee locals).
+//
+// The analysis will also examine InlineContexts from relevant prior
+// inlines. If the inline is successful, a new InlineContext will be
+// created to remember this inline. In DEBUG builds, failing inlines
+// also create InlineContexts.
+//
+// 3. Inlining Optimization Pass -- non-candidates (fgNoteNotInlineCandidate)
+//
+// Creates / Uses: InlineContext
+//
+// In DEBUG, the jit also searches for non-candidate calls to try
+// and get a complete picture of the set of failed inlines.
+//
+// 4 & 5. Prejit suitability screens (compCompileHelper)
+//
+// When prejitting, each method is scanned to see if it is a viable
+// inline candidate. The scanning happens in two stages.
+//
+// A note on InlinePolicy
+//
+// In the current code base, the inlining policy is distributed across
+// the various parts of the code that drive the inlining process
+// forward. Subsequent refactoring will extract some or all of this
+// policy into a separate InlinePolicy object, to make it feasible to
+// create and experiment with alternative policies, while preserving
+// the existing policy as a baseline and fallback.
+
+
+#endif // _INLINE_POLICY_H_