1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
13 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
14 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
18 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
19 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
26 // Fixed-size array that can hold elements with no default constructor;
27 // it will construct them all by forwarding whatever arguments are
28 // supplied to its constructor.
29 template <typename T, int N>
30 class ConstructedArray
33 // Storage that gets used to hold the T objects.
34 unsigned char bytes[N * sizeof(T)];
36 #if defined(_MSC_VER) && (_MSC_VER < 1900)
37 // With MSVC pre-VS2015, the code in the #else branch would hit error C2621,
38 // so in that case just count on pointer alignment being sufficient
39 // (currently T is only ever instantiated as jitstd::list<SsaRenameStateForBlock>)
41 // Unused (except to impart alignment requirement)
44 // Unused (except to impart alignment requirement)
46 #endif // defined(_MSC_VER) && (_MSC_VER < 1900)
50 T& operator[](size_t i)
52 return *(reinterpret_cast<T*>(bytes + i * sizeof(T)));
55 template <typename... Args>
56 ConstructedArray(Args&&... args)
58 for (int i = 0; i < N; ++i)
60 new (bytes + i * sizeof(T), jitstd::placement_t()) T(jitstd::forward<Args>(args)...);
66 for (int i = 0; i < N; ++i)
73 struct SsaRenameStateForBlock
78 SsaRenameStateForBlock(BasicBlock* bb, unsigned count) : m_bb(bb), m_count(count)
81 SsaRenameStateForBlock() : m_bb(nullptr), m_count(0)
86 // A record indicating that local "m_loc" was defined in block "m_bb".
87 struct SsaRenameStateLocDef
92 SsaRenameStateLocDef(BasicBlock* bb, unsigned lclNum) : m_bb(bb), m_lclNum(lclNum)
99 typedef jitstd::list<SsaRenameStateForBlock> Stack;
100 typedef Stack** Stacks;
101 typedef unsigned* Counts;
102 typedef jitstd::list<SsaRenameStateLocDef> DefStack;
104 SsaRenameState(const jitstd::allocator<int>& allocator, unsigned lvaCount, bool byrefStatesMatchGcHeapStates);
109 // Requires "lclNum" to be a variable number for which a new count corresponding to a
110 // definition is desired. The method post increments the counter for the "lclNum."
111 unsigned CountForDef(unsigned lclNum);
113 // Requires "lclNum" to be a variable number for which an ssa number at the top of the
114 // stack is required i.e., for variable "uses."
115 unsigned CountForUse(unsigned lclNum);
117 // Requires "lclNum" to be a variable number, and requires "count" to represent
118 // an ssa number, that needs to be pushed on to the stack corresponding to the lclNum.
119 void Push(BasicBlock* bb, unsigned lclNum, unsigned count);
121 // Pop all stacks that have an entry for "bb" on top.
122 void PopBlockStacks(BasicBlock* bb);
124 // Similar functions for the special implicit memory variable.
125 unsigned CountForMemoryDef()
127 if (memoryCount == 0)
129 memoryCount = SsaConfig::FIRST_SSA_NUM;
131 unsigned res = memoryCount;
135 unsigned CountForMemoryUse(MemoryKind memoryKind)
137 if ((memoryKind == GcHeap) && byrefStatesMatchGcHeapStates)
139 // Share rename stacks in this configuration.
140 memoryKind = ByrefExposed;
142 return memoryStack[memoryKind].back().m_count;
145 void PushMemory(MemoryKind memoryKind, BasicBlock* bb, unsigned count)
147 if ((memoryKind == GcHeap) && byrefStatesMatchGcHeapStates)
149 // Share rename stacks in this configuration.
150 memoryKind = ByrefExposed;
152 memoryStack[memoryKind].push_back(SsaRenameStateForBlock(bb, count));
155 void PopBlockMemoryStack(MemoryKind memoryKind, BasicBlock* bb);
157 unsigned MemoryCount()
168 // Map of lclNum -> count.
171 // Map of lclNum -> SsaRenameStateForBlock.
174 // This list represents the set of locals defined in the current block.
175 DefStack definedLocs;
177 // Same state for the special implicit memory variables.
178 ConstructedArray<Stack, MemoryKindCount> memoryStack;
179 unsigned memoryCount;
181 // Number of stacks/counts to allocate.
184 // Allocator to allocate stacks.
185 jitstd::allocator<void> m_alloc;
187 // Indicates whether GcHeap and ByrefExposed use the same state.
188 bool byrefStatesMatchGcHeapStates;