summaryrefslogtreecommitdiff
path: root/src/jit/ssarenamestate.h
blob: 1db36c5b37dc2e205f877e9f2aad42324ef6bbac (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
// 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.

// ==++==
//

//

//
// ==--==

/*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XX                                                                           XX
XX                                  SSA                                      XX
XX                                                                           XX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
*/

#pragma once

#include "jitstd.h"

struct SsaRenameStateForBlock
{
    BasicBlock* m_bb;
    unsigned    m_count;

    SsaRenameStateForBlock(BasicBlock* bb, unsigned count) : m_bb(bb), m_count(count)
    {
    }
    SsaRenameStateForBlock() : m_bb(nullptr), m_count(0)
    {
    }
};

// A record indicating that local "m_loc" was defined in block "m_bb".
struct SsaRenameStateLocDef
{
    BasicBlock* m_bb;
    unsigned    m_lclNum;

    SsaRenameStateLocDef(BasicBlock* bb, unsigned lclNum) : m_bb(bb), m_lclNum(lclNum)
    {
    }
};

struct SsaRenameState
{
    typedef jitstd::list<SsaRenameStateForBlock> Stack;
    typedef Stack**                              Stacks;
    typedef unsigned*                            Counts;
    typedef jitstd::list<SsaRenameStateLocDef>   DefStack;

    SsaRenameState(const jitstd::allocator<int>& allocator, unsigned lvaCount);

    void EnsureCounts();
    void EnsureStacks();

    // Requires "lclNum" to be a variable number for which a new count corresponding to a
    // definition is desired. The method post increments the counter for the "lclNum."
    unsigned CountForDef(unsigned lclNum);

    // Requires "lclNum" to be a variable number for which an ssa number at the top of the
    // stack is required i.e., for variable "uses."
    unsigned CountForUse(unsigned lclNum);

    // Requires "lclNum" to be a variable number, and requires "count" to represent
    // an ssa number, that needs to be pushed on to the stack corresponding to the lclNum.
    void Push(BasicBlock* bb, unsigned lclNum, unsigned count);

    // Pop all stacks that have an entry for "bb" on top.
    void PopBlockStacks(BasicBlock* bb);

    // Similar functions for the special implicit "Heap" variable.
    unsigned CountForHeapDef()
    {
        if (heapCount == 0)
        {
            heapCount = SsaConfig::FIRST_SSA_NUM;
        }
        unsigned res = heapCount;
        heapCount++;
        return res;
    }
    unsigned CountForHeapUse()
    {
        return heapStack.back().m_count;
    }

    void PushHeap(BasicBlock* bb, unsigned count)
    {
        heapStack.push_back(SsaRenameStateForBlock(bb, count));
    }

    void PopBlockHeapStack(BasicBlock* bb);

    unsigned HeapCount()
    {
        return heapCount;
    }

#ifdef DEBUG
    // Debug interface
    void DumpStacks();
#endif

private:
    // Map of lclNum -> count.
    Counts counts;

    // Map of lclNum -> SsaRenameStateForBlock.
    Stacks stacks;

    // This list represents the set of locals defined in the current block.
    DefStack definedLocs;

    // Same state for the special implicit Heap variable.
    Stack    heapStack;
    unsigned heapCount;

    // Number of stacks/counts to allocate.
    unsigned lvaCount;

    // Allocator to allocate stacks.
    jitstd::allocator<void> m_alloc;
};