summaryrefslogtreecommitdiff
path: root/src/jit/inlinepolicy.h
blob: 45faba9085b7ab129839b3185b78e79f7968215d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// 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"

class CodeSeqSM;

// LegacyPolicy implements the inlining policy used by the jit in its
// initial release.
//
// Generally speaking, the legacy policy expects the inlining attempt
// to fail fast when a fatal or equivalent observation is made. So
// once an observation causes failure, no more observations are
// expected. However for the prejit scan case (where the jit is not
// actually inlining, but is assessing a method's general
// inlinability) the legacy policy allows multiple failing
// observations provided they have the same impact. Only the first
// observation that puts the policy into a failing state is
// remembered. Transitions from failing states to candidate or success
// states are not allowed.

class LegacyPolicy : public InlinePolicy
{
public:

    // Construct a LegacyPolicy
    LegacyPolicy(Compiler* compiler, bool isPrejitRoot)
        : InlinePolicy(isPrejitRoot)
        , inlCompiler(compiler)
        , inlStateMachine(nullptr)
        , inlCodeSize(0)
        , inlNativeSizeEstimate(NATIVE_SIZE_INVALID)
        , inlIsForceInline(false)
        , inlIsForceInlineKnown(false)
        , inlIsInstanceCtor(false)
        , inlIsFromPromotableValueClass(false)
        , inlHasSimd(false)
        , inlLooksLikeWrapperMethod(false)
        , inlArgFeedsConstantTest(false)
        , inlMethodIsMostlyLoadStore(false)
        , inlArgFeedsRangeCheck(false)
        , inlConstantFeedsConstantTest(false)
    {
        // empty
    }

    // Policy observations
    void noteSuccess() override;
    void noteBool(InlineObservation obs, bool value) override;
    void noteFatal(InlineObservation obs) override;
    void noteInt(InlineObservation obs, int value) override;
    void noteDouble(InlineObservation obs, double value) override;

    // Policy determinations
    double determineMultiplier() override;
    int determineNativeSizeEstimate() override;
    bool hasNativeSizeEstimate() override;

    // Policy policies
    bool propagateNeverToRuntime() const override { return true; }

#ifdef DEBUG
    const char* getName() const override { return "LegacyPolicy"; }
#endif

private:

    // Helper methods
    void noteInternal(InlineObservation obs);
    void setCandidate(InlineObservation obs);
    void setFailure(InlineObservation obs);
    void setNever(InlineObservation obs);

    // Constants
    const unsigned MAX_BASIC_BLOCKS = 5;

    // Data members
    Compiler*  inlCompiler;
    CodeSeqSM* inlStateMachine;
    unsigned   inlCodeSize;
    int        inlNativeSizeEstimate;
    bool       inlIsForceInline :1;
    bool       inlIsForceInlineKnown :1;
    bool       inlIsInstanceCtor :1;
    bool       inlIsFromPromotableValueClass :1;
    bool       inlHasSimd :1;
    bool       inlLooksLikeWrapperMethod :1;
    bool       inlArgFeedsConstantTest :1;
    bool       inlMethodIsMostlyLoadStore :1;
    bool       inlArgFeedsRangeCheck :1;
    bool       inlConstantFeedsConstantTest :1;
};

#endif // _INLINE_POLICY_H_