summaryrefslogtreecommitdiff
path: root/src/jit/ssarenamestate.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/jit/ssarenamestate.h')
-rw-r--r--src/jit/ssarenamestate.h94
1 files changed, 77 insertions, 17 deletions
diff --git a/src/jit/ssarenamestate.h b/src/jit/ssarenamestate.h
index 1db36c5b37..a8496b6386 100644
--- a/src/jit/ssarenamestate.h
+++ b/src/jit/ssarenamestate.h
@@ -23,6 +23,53 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#include "jitstd.h"
+// Fixed-size array that can hold elements with no default constructor;
+// it will construct them all by forwarding whatever arguments are
+// supplied to its constructor.
+template <typename T, int N>
+class ConstructedArray
+{
+ union {
+ // Storage that gets used to hold the T objects.
+ unsigned char bytes[N * sizeof(T)];
+
+#if defined(_MSC_VER) && (_MSC_VER < 1900)
+ // With MSVC pre-VS2015, the code in the #else branch would hit error C2621,
+ // so in that case just count on pointer alignment being sufficient
+ // (currently T is only ever instantiated as jitstd::list<SsaRenameStateForBlock>)
+
+ // Unused (except to impart alignment requirement)
+ void* pointer;
+#else
+ // Unused (except to impart alignment requirement)
+ T alignedArray[N];
+#endif // defined(_MSC_VER) && (_MSC_VER < 1900)
+ };
+
+public:
+ T& operator[](size_t i)
+ {
+ return *(reinterpret_cast<T*>(bytes + i * sizeof(T)));
+ }
+
+ template <typename... Args>
+ ConstructedArray(Args&&... args)
+ {
+ for (int i = 0; i < N; ++i)
+ {
+ new (bytes + i * sizeof(T), jitstd::placement_t()) T(jitstd::forward<Args>(args)...);
+ }
+ }
+
+ ~ConstructedArray()
+ {
+ for (int i = 0; i < N; ++i)
+ {
+ operator[](i).~T();
+ }
+ }
+};
+
struct SsaRenameStateForBlock
{
BasicBlock* m_bb;
@@ -54,7 +101,7 @@ struct SsaRenameState
typedef unsigned* Counts;
typedef jitstd::list<SsaRenameStateLocDef> DefStack;
- SsaRenameState(const jitstd::allocator<int>& allocator, unsigned lvaCount);
+ SsaRenameState(const jitstd::allocator<int>& allocator, unsigned lvaCount, bool byrefStatesMatchGcHeapStates);
void EnsureCounts();
void EnsureStacks();
@@ -74,32 +121,42 @@ struct SsaRenameState
// 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()
+ // Similar functions for the special implicit memory variable.
+ unsigned CountForMemoryDef()
{
- if (heapCount == 0)
+ if (memoryCount == 0)
{
- heapCount = SsaConfig::FIRST_SSA_NUM;
+ memoryCount = SsaConfig::FIRST_SSA_NUM;
}
- unsigned res = heapCount;
- heapCount++;
+ unsigned res = memoryCount;
+ memoryCount++;
return res;
}
- unsigned CountForHeapUse()
+ unsigned CountForMemoryUse(MemoryKind memoryKind)
{
- return heapStack.back().m_count;
+ if ((memoryKind == GcHeap) && byrefStatesMatchGcHeapStates)
+ {
+ // Share rename stacks in this configuration.
+ memoryKind = ByrefExposed;
+ }
+ return memoryStack[memoryKind].back().m_count;
}
- void PushHeap(BasicBlock* bb, unsigned count)
+ void PushMemory(MemoryKind memoryKind, BasicBlock* bb, unsigned count)
{
- heapStack.push_back(SsaRenameStateForBlock(bb, count));
+ if ((memoryKind == GcHeap) && byrefStatesMatchGcHeapStates)
+ {
+ // Share rename stacks in this configuration.
+ memoryKind = ByrefExposed;
+ }
+ memoryStack[memoryKind].push_back(SsaRenameStateForBlock(bb, count));
}
- void PopBlockHeapStack(BasicBlock* bb);
+ void PopBlockMemoryStack(MemoryKind memoryKind, BasicBlock* bb);
- unsigned HeapCount()
+ unsigned MemoryCount()
{
- return heapCount;
+ return memoryCount;
}
#ifdef DEBUG
@@ -117,13 +174,16 @@ private:
// 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;
+ // Same state for the special implicit memory variables.
+ ConstructedArray<Stack, MemoryKindCount> memoryStack;
+ unsigned memoryCount;
// Number of stacks/counts to allocate.
unsigned lvaCount;
// Allocator to allocate stacks.
jitstd::allocator<void> m_alloc;
+
+ // Indicates whether GcHeap and ByrefExposed use the same state.
+ bool byrefStatesMatchGcHeapStates;
};