summaryrefslogtreecommitdiff
path: root/src/jit/nodeinfo.h
blob: 3eb4e5cefc41c0d3a994a5192cca96202d550f56 (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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//


#ifndef _NODEINFO_H_
#define _NODEINFO_H_

class LinearScan;
typedef unsigned int LsraLocation;

class TreeNodeInfo
{
public:

    TreeNodeInfo()
    {
        loc             = 0;
        _dstCount       = 0;    
        _srcCount       = 0;
        _internalIntCount  = 0;
        _internalFloatCount  = 0;

        srcCandsIndex         = 0;
        dstCandsIndex         = 0;
        internalCandsIndex    = 0;
        isLocalDefUse         = false;
        isInitialized         = false;
        isHelperCallWithKills = false;
        isLsraAdded           = false;
        isDelayFree           = false;
        hasDelayFreeSrc       = false;
        isTgtPref             = false;
    }

    // dst
    __declspec(property(put=setDstCount, get=getDstCount))
        int dstCount;
    void setDstCount(int count)
    {
        assert(count == 0 || count == 1);
        _dstCount = (char) count;
    }
    int getDstCount() { return _dstCount; }

    // src
    __declspec(property(put=setSrcCount, get=getSrcCount))
        int srcCount;
    void setSrcCount(int count)
    {
        _srcCount = (char) count;
        assert(_srcCount == count);
    }
    int getSrcCount() { return _srcCount; }

    // internalInt
    __declspec(property(put=setInternalIntCount, get=getInternalIntCount))
        int internalIntCount;
    void setInternalIntCount(int count)
    {
        _internalIntCount = (char) count;
        assert(_internalIntCount == count);
    }
    int getInternalIntCount() { return _internalIntCount; }

    // internalFloat
    __declspec(property(put=setInternalFloatCount, get=getInternalFloatCount))
        int internalFloatCount;
    void setInternalFloatCount(int count)
    {
        _internalFloatCount = (char) count;
        assert(_internalFloatCount == count);
    }
    int getInternalFloatCount() { return _internalFloatCount; }

    // SrcCandidates are constraints of the consuming (parent) operation applied to this node
    // (i.e. what registers it is constrained to consume).
    regMaskTP getSrcCandidates(LinearScan *lsra);
    void      setSrcCandidates(LinearScan *lsra, regMaskTP mask);
    // DstCandidates are constraints of this node (i.e. what registers it is constrained to produce).
    regMaskTP getDstCandidates(LinearScan *lsra);
    void      setDstCandidates(LinearScan *lsra, regMaskTP mask);
    // InternalCandidates are constraints of the registers used as temps in the evaluation of this node.
    regMaskTP getInternalCandidates(LinearScan *lsra);
    void      setInternalCandidates(LinearScan *lsra, regMaskTP mask);
    void      addInternalCandidates(LinearScan *lsra, regMaskTP mask);

    LsraLocation  loc;

private:
    unsigned char _dstCount;    
    unsigned char _srcCount;    
    unsigned char _internalIntCount;
    unsigned char _internalFloatCount;

public:
    unsigned char srcCandsIndex;
    unsigned char dstCandsIndex;
    unsigned char internalCandsIndex;


    // isLocalDefUse identifies trees that produce a value that is not consumed elsewhere.
    // Examples include stack arguments to a call (they are immediately stored), lhs of comma
    // nodes, or top-level nodes that are non-void.
    unsigned char isLocalDefUse:1;
    // isInitialized is set when the tree node is handled.
    unsigned char isInitialized:1;
    // isHelperCallWithKills is set when this is a helper call that kills more than just its in/out regs.
    unsigned char isHelperCallWithKills:1;
    // Is this node added by LSRA, e.g. as a resolution or copy/reload move.
    unsigned char isLsraAdded:1;
    // isDelayFree is set when the register defined by this node will interfere with the destination
    // of the consuming node, and therefore it must not be freed immediately after use.
    unsigned char isDelayFree:1;
    // hasDelayFreeSrc is set when this node has sources that are marked "isDelayFree".  This is because,
    // we may eventually "contain" this node, in which case we don't want it's children (which have
    // already been marked "isDelayFree" to be handled that way when allocating.
    unsigned char hasDelayFreeSrc:1;
    // isTgtPref is set to true when we have a rmw op, where we would like the result to be allocated
    // in the same register as op1.
    unsigned char isTgtPref:1;


public:

#ifdef DEBUG
    void dump(LinearScan *lsra);
#endif // DEBUG

    // This method checks to see whether the information has been initialized,
    // and is in a consistent state
    bool IsValid(LinearScan *lsra)
    {
        return (isInitialized &&
                ((getSrcCandidates(lsra)|getInternalCandidates(lsra)|getDstCandidates(lsra)) & ~(RBM_ALLFLOAT|RBM_ALLINT)) == 0);
    }
};

#endif // _NODEINFO_H_