Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit a7cf54f

Browse files
mikednBruceForstall
authored andcommitted
Improve SSA dominator computation memory usage (#14965)
* Improve SSA DF computation memory usage DF(b) can be stored in a vector instead of a hashtable (set). Nothing needs a O(1) membership test, the duplicates that may be generated during DF construction can be easily avoided by observing that: * each block in the graph is processed exactly once * during processing the block is added to the relevant DF vectors, at the end of each vector. If the same DF vector is encountered multiple times then checking if the block is already a member is trivial. * Use the same block BitVec for topo sort and IDom * Add BitVecOps::TryAddElemD Makes the code more readable and avoids the duplicated IsShort test that a separate IsMember/AddElemD may generate. * Improve SSA IDF computation memory usage Like DF(b), IDF(b) can be stored in a vector if duplicates are avoided. This can be done by using a BitVector like TopologicalSort and ComputeImmediateDom already do. It's cheaper than using a hashtable (even though it requires a "clear" for every block that has a frontier). Also, storing IDF(b) into a vector makes it easier to track newly added blocks - they're at the end of the vector. Using a separate "delta" set is no longer needed.
1 parent 6b4b00f commit a7cf54f

File tree

7 files changed

+161
-77
lines changed

7 files changed

+161
-77
lines changed

src/jit/bitsetasshortlong.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class BitSetOps</*BitSetType*/ BitSetShortLongRep,
4242
static void UnionDLong(Env env, BitSetShortLongRep& bs1, BitSetShortLongRep bs2);
4343
static void DiffDLong(Env env, BitSetShortLongRep& bs1, BitSetShortLongRep bs2);
4444
static void AddElemDLong(Env env, BitSetShortLongRep& bs, unsigned i);
45+
static bool TryAddElemDLong(Env env, BitSetShortLongRep& bs, unsigned i);
4546
static void RemoveElemDLong(Env env, BitSetShortLongRep& bs, unsigned i);
4647
static void ClearDLong(Env env, BitSetShortLongRep& bs);
4748
static BitSetShortLongRep MakeUninitArrayBits(Env env);
@@ -276,6 +277,23 @@ class BitSetOps</*BitSetType*/ BitSetShortLongRep,
276277
return res;
277278
}
278279

280+
static bool TryAddElemD(Env env, BitSetShortLongRep& bs, unsigned i)
281+
{
282+
assert(i < BitSetTraits::GetSize(env));
283+
if (IsShort(env))
284+
{
285+
size_t mask = ((size_t)1) << i;
286+
size_t bits = (size_t)bs;
287+
bool added = (bits & mask) == 0;
288+
bs = (BitSetShortLongRep)(bits | mask);
289+
return added;
290+
}
291+
else
292+
{
293+
return TryAddElemDLong(env, bs, i);
294+
}
295+
}
296+
279297
static bool IsMember(Env env, const BitSetShortLongRep bs, unsigned i)
280298
{
281299
assert(i < BitSetTraits::GetSize(env));
@@ -644,6 +662,21 @@ void BitSetOps</*BitSetType*/ BitSetShortLongRep,
644662
bs[index] |= mask;
645663
}
646664

665+
template <typename Env, typename BitSetTraits>
666+
bool BitSetOps</*BitSetType*/ BitSetShortLongRep,
667+
/*Brand*/ BSShortLong,
668+
/*Env*/ Env,
669+
/*BitSetTraits*/ BitSetTraits>::TryAddElemDLong(Env env, BitSetShortLongRep& bs, unsigned i)
670+
{
671+
assert(!IsShort(env));
672+
unsigned index = i / BitsInSizeT;
673+
size_t mask = ((size_t)1) << (i % BitsInSizeT);
674+
size_t bits = bs[index];
675+
bool added = (bits & mask) == 0;
676+
bs[index] = bits | mask;
677+
return added;
678+
}
679+
647680
template <typename Env, typename BitSetTraits>
648681
void BitSetOps</*BitSetType*/ BitSetShortLongRep,
649682
/*Brand*/ BSShortLong,

src/jit/block.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,9 +1202,15 @@ struct JitPtrKeyFuncs<BasicBlock> : public JitKeyFuncsDefEquals<const BasicBlock
12021202
// A set of blocks.
12031203
typedef JitHashTable<BasicBlock*, JitPtrKeyFuncs<BasicBlock>, bool> BlkSet;
12041204

1205+
// A vector of blocks.
1206+
typedef jitstd::vector<BasicBlock*> BlkVector;
1207+
12051208
// A map of block -> set of blocks, can be used as sparse block trees.
12061209
typedef JitHashTable<BasicBlock*, JitPtrKeyFuncs<BasicBlock>, BlkSet*> BlkToBlkSetMap;
12071210

1211+
// A map of block -> vector of blocks, can be used as sparse block trees.
1212+
typedef JitHashTable<BasicBlock*, JitPtrKeyFuncs<BasicBlock>, BlkVector> BlkToBlkVectorMap;
1213+
12081214
// Map from Block to Block. Used for a variety of purposes.
12091215
typedef JitHashTable<BasicBlock*, JitPtrKeyFuncs<BasicBlock>, BasicBlock*> BlockToBlockMap;
12101216

src/jit/compiler.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2525
#include "jit.h"
2626
#include "opcode.h"
2727
#include "varset.h"
28+
#include "jitstd.h"
29+
#include "jithashtable.h"
2830
#include "gentree.h"
2931
#include "lir.h"
3032
#include "block.h"
@@ -33,10 +35,8 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3335
#include "instr.h"
3436
#include "regalloc.h"
3537
#include "sm.h"
36-
#include "jithashtable.h"
3738
#include "cycletimer.h"
3839
#include "blockset.h"
39-
#include "jitstd.h"
4040
#include "arraystack.h"
4141
#include "hashbv.h"
4242
#include "fp.h"

src/jit/gentree.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2424
#include "ssaconfig.h" // For "SsaConfig::RESERVED_SSA_NUM"
2525
#include "reglist.h"
2626
#include "valuenumtype.h"
27+
#include "jitstd.h"
2728
#include "jithashtable.h"
2829
#include "nodeinfo.h"
2930
#include "simd.h"

src/jit/jithashtable.h

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -264,13 +264,50 @@ class JitHashTable
264264
}
265265
else
266266
{
267-
Node* pNewNode = new (m_alloc) Node(k, v, m_table[index]);
267+
Node* pNewNode = new (m_alloc) Node(m_table[index], k, v);
268268
m_table[index] = pNewNode;
269269
m_tableCount++;
270270
return false;
271271
}
272272
}
273273

274+
//------------------------------------------------------------------------
275+
// Emplace: Associates the specified key with a value constructed in-place
276+
// using the supplied args if the key is not already present.
277+
//
278+
// Arguments:
279+
// k - the key
280+
// args - the args used to construct the value
281+
//
282+
// Return Value:
283+
// A pointer to the existing or newly constructed value.
284+
//
285+
template <class... Args>
286+
Value* Emplace(Key k, Args&&... args)
287+
{
288+
CheckGrowth();
289+
290+
assert(m_tableSizeInfo.prime != 0);
291+
292+
unsigned index = GetIndexForKey(k);
293+
294+
Node* n = m_table[index];
295+
while ((n != nullptr) && !KeyFuncs::Equals(k, n->m_key))
296+
{
297+
n = n->m_next;
298+
}
299+
300+
if (n == nullptr)
301+
{
302+
n = new (m_alloc) Node(m_table[index], k, jitstd::forward<Args>(args)...);
303+
304+
m_table[index] = n;
305+
m_tableCount++;
306+
}
307+
308+
return &n->m_val;
309+
}
310+
274311
//------------------------------------------------------------------------
275312
// Remove: Remove the specified key and its associated value.
276313
//
@@ -592,7 +629,7 @@ class JitHashTable
592629
// Assumptions:
593630
// This must not be the "end" iterator.
594631
//
595-
const Value& GetValue() const
632+
Value& GetValue() const
596633
{
597634
assert(m_node != nullptr);
598635

@@ -721,7 +758,8 @@ class JitHashTable
721758
Key m_key;
722759
Value m_val;
723760

724-
Node(Key k, Value v, Node* next) : m_next(next), m_key(k), m_val(v)
761+
template <class... Args>
762+
Node(Node* next, Key k, Args&&... args) : m_next(next), m_key(k), m_val(jitstd::forward<Args>(args)...)
725763
{
726764
}
727765

0 commit comments

Comments
 (0)