ExpandArray<ASSERT_TP>& dep = *optAssertionDep;
if (dep[lclNum] == nullptr)
{
- dep[lclNum] = optNewEmptyAssertSet();
+ dep[lclNum] = BitVecOps::MakeEmpty(apTraits);
}
return dep[lclNum];
}
void Compiler::optAssertionTraitsInit(AssertionIndex assertionCount)
{
apTraits = new (getAllocator()) BitVecTraits(assertionCount, this);
- apFull = BitVecOps::UninitVal();
- apEmpty = BitVecOps::UninitVal();
- BitVecOps::AssignNoCopy(apTraits, apFull, BitVecOps::MakeFull(apTraits));
- BitVecOps::AssignNoCopy(apTraits, apEmpty, BitVecOps::MakeEmpty(apTraits));
+ apFull = BitVecOps::MakeFull(apTraits);
}
/*****************************************************************************
if (assertionIndex > 0)
{
printf(" index=#%02u, mask=", assertionIndex);
-
- // This is an hack to reuse a known empty set in order to display
- // a single bit mask.
- BitVecOps::AddElemD(apTraits, apEmpty, assertionIndex - 1);
- printf("%s", BitVecOps::ToString(apTraits, apEmpty));
- BitVecOps::RemoveElemD(apTraits, apEmpty, assertionIndex - 1);
+ printf("%s", BitVecOps::ToString(apTraits, BitVecOps::MakeSingleton(apTraits, assertionIndex - 1)));
}
printf("\n");
}
ASSERT_TP cur;
if (!optValueNumToAsserts->Lookup(vn, &cur))
{
- cur = optNewEmptyAssertSet();
+ cur = BitVecOps::MakeEmpty(apTraits);
optValueNumToAsserts->Set(vn, cur);
}
BitVecOps::AddElemD(apTraits, cur, index - 1);
JITDUMP("AssertionPropCallback::EndMerge : BB%02d in -> %s\n\n", block->bbNum,
BitVecOps::ToString(apTraits, block->bbAssertionIn));
- // PERF: eliminate this tmp by passing in a OperationTree (AST) to the bitset,
- // so the expr tree is operated on a single bit level. See "expression templates."
- ASSERT_TP tmp = BitVecOps::MakeCopy(apTraits, block->bbAssertionIn);
- BitVecOps::UnionD(apTraits, tmp, block->bbAssertionGen);
- BitVecOps::IntersectionD(apTraits, block->bbAssertionOut, tmp);
-
- BitVecOps::Assign(apTraits, tmp, block->bbAssertionIn);
- BitVecOps::UnionD(apTraits, tmp, mJumpDestGen[block->bbNum]);
- BitVecOps::IntersectionD(apTraits, mJumpDestOut[block->bbNum], tmp);
+ BitVecOps::DataFlowD(apTraits, block->bbAssertionOut, block->bbAssertionGen, block->bbAssertionIn);
+ BitVecOps::DataFlowD(apTraits, mJumpDestOut[block->bbNum], mJumpDestGen[block->bbNum], block->bbAssertionIn);
bool changed = (!BitVecOps::Equal(apTraits, preMergeOut, block->bbAssertionOut) ||
!BitVecOps::Equal(apTraits, preMergeJumpDestOut, mJumpDestOut[block->bbNum]));
}
};
-ASSERT_VALRET_TP Compiler::optNewFullAssertSet()
-{
- return BitVecOps::MakeCopy(apTraits, apFull);
-}
-
-ASSERT_VALRET_TP Compiler::optNewEmptyAssertSet()
-{
- return BitVecOps::MakeCopy(apTraits, apEmpty);
-}
-
/*****************************************************************************
*
* Compute the assertions generated by each block.
// apFull (i.e. all possible bits set), we need to set the bits only for valid
// assertions (note that at this point we are not creating any new assertions).
// Also note that assertion indices start from 1.
- ASSERT_TP apValidFull = optNewEmptyAssertSet();
+ ASSERT_TP apValidFull = BitVecOps::MakeEmpty(apTraits);
for (int i = 1; i <= optAssertionCount; i++)
{
BitVecOps::AddElemD(apTraits, apValidFull, i - 1);
// edges.
for (BasicBlock* block = fgFirstBB; block; block = block->bbNext)
{
- block->bbAssertionIn = optNewEmptyAssertSet();
- if (!bbIsHandlerBeg(block))
+ if (bbIsHandlerBeg(block))
+ {
+ block->bbAssertionIn = BitVecOps::MakeEmpty(apTraits);
+ }
+ else
{
- BitVecOps::Assign(apTraits, block->bbAssertionIn, apValidFull);
+ block->bbAssertionIn = BitVecOps::MakeCopy(apTraits, apValidFull);
}
- block->bbAssertionGen = optNewEmptyAssertSet();
- block->bbAssertionOut = optNewEmptyAssertSet();
- BitVecOps::Assign(apTraits, block->bbAssertionOut, apValidFull);
- jumpDestOut[block->bbNum] = optNewEmptyAssertSet();
- BitVecOps::Assign(apTraits, jumpDestOut[block->bbNum], apValidFull);
+ block->bbAssertionGen = BitVecOps::MakeEmpty(apTraits);
+ block->bbAssertionOut = BitVecOps::MakeCopy(apTraits, apValidFull);
+ jumpDestOut[block->bbNum] = BitVecOps::MakeCopy(apTraits, apValidFull);
}
// Compute the data flow values for all tracked expressions
// IN and OUT never change for the initial basic block B1
- BitVecOps::Assign(apTraits, fgFirstBB->bbAssertionIn, apEmpty);
+ BitVecOps::ClearD(apTraits, fgFirstBB->bbAssertionIn);
return jumpDestOut;
}
}
#endif // DEBUG
+ ASSERT_TP assertions = BitVecOps::MakeEmpty(apTraits);
+
// Perform assertion propagation (and constant folding)
for (BasicBlock* block = fgFirstBB; block; block = block->bbNext)
{
- ASSERT_TP assertions = BitVecOps::MakeCopy(apTraits, block->bbAssertionIn);
+ BitVecOps::Assign(apTraits, assertions, block->bbAssertionIn);
// TODO-Review: EH successor/predecessor iteration seems broken.
// SELF_HOST_TESTS_ARM\jit\Directed\ExcepFilters\fault\fault.exe
class TestBitSetTraits
{
public:
- static IAllocator* GetAllocator(IAllocator* alloc)
+ static void* Alloc(IAllocator* alloc, size_t byteSize)
{
- return alloc;
+ return alloc->Alloc(byteSize);
}
static unsigned GetSize(IAllocator* alloc)
{
static BitSetShortLongRep MakeCopyLong(Env env, BitSetShortLongRep bs);
static bool IsEmptyLong(Env env, BitSetShortLongRep bs);
static unsigned CountLong(Env env, BitSetShortLongRep bs);
+ static bool IsEmptyUnionLong(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2);
static void UnionDLong(Env env, BitSetShortLongRep& bs1, BitSetShortLongRep bs2);
static void DiffDLong(Env env, BitSetShortLongRep& bs1, BitSetShortLongRep bs2);
static void AddElemDLong(Env env, BitSetShortLongRep& bs, unsigned i);
static bool IsSubsetLong(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2);
static bool IsEmptyIntersectionLong(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2);
static void IntersectionDLong(Env env, BitSetShortLongRep& bs1, BitSetShortLongRep bs2);
+ static void DataFlowDLong(Env env,
+ BitSetShortLongRep& out,
+ const BitSetShortLongRep gen,
+ const BitSetShortLongRep in);
+ static void LivenessDLong(Env env,
+ BitSetShortLongRep& in,
+ const BitSetShortLongRep def,
+ const BitSetShortLongRep use,
+ const BitSetShortLongRep out);
#ifdef DEBUG
static const char* ToStringLong(Env env, BitSetShortLongRep bs);
#endif
}
}
+ static bool IsEmptyUnion(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
+ {
+ if (IsShort(env))
+ {
+ return (((size_t)bs1) | ((size_t)bs2)) == 0;
+ }
+ else
+ {
+ return IsEmptyUnionLong(env, bs1, bs2);
+ }
+ }
+
static void UnionD(Env env, BitSetShortLongRep& bs1, BitSetShortLongRep bs2)
{
if (IsShort(env))
}
}
+ static void DataFlowD(Env env, BitSetShortLongRep& out, const BitSetShortLongRep gen, const BitSetShortLongRep in)
+ {
+ if (IsShort(env))
+ {
+ (size_t&)out = (size_t)out & ((size_t)gen | (size_t)in);
+ }
+ else
+ {
+ DataFlowDLong(env, out, gen, in);
+ }
+ }
+
+ static void LivenessD(Env env,
+ BitSetShortLongRep& in,
+ const BitSetShortLongRep def,
+ const BitSetShortLongRep use,
+ const BitSetShortLongRep out)
+ {
+ if (IsShort(env))
+ {
+ (size_t&)in = (size_t)use | ((size_t)out & ~(size_t)def);
+ }
+ else
+ {
+ LivenessDLong(env, in, def, use, out);
+ }
+ }
+
static bool IsSubset(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
{
if (IsShort(env))
if (IsShort(env))
{
assert(sizeof(BitSetShortLongRep) == sizeof(size_t));
- IAllocator* alloc = BitSetTraits::GetDebugOnlyAllocator(env);
- const int CharsForSizeT = sizeof(size_t) * 2;
- char* res = nullptr;
- const int ShortAllocSize = CharsForSizeT + 4;
- res = (char*)alloc->Alloc(ShortAllocSize);
- size_t bits = (size_t)bs;
- unsigned remaining = ShortAllocSize;
- char* ptr = res;
+ const int CharsForSizeT = sizeof(size_t) * 2;
+ char* res = nullptr;
+ const int ShortAllocSize = CharsForSizeT + 4;
+ res = (char*)BitSetTraits::DebugAlloc(env, ShortAllocSize);
+ size_t bits = (size_t)bs;
+ unsigned remaining = ShortAllocSize;
+ char* ptr = res;
if (sizeof(size_t) == sizeof(int64_t))
{
sprintf_s(ptr, remaining, "%016llX", bits);
assert(!IsShort(env));
unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
assert(len > 1); // Or else would not require an array.
- return (BitSetShortLongRep)(BitSetTraits::GetAllocator(env)->Alloc(len * sizeof(size_t)));
+ return (BitSetShortLongRep)(BitSetTraits::Alloc(env, len * sizeof(size_t)));
}
template <typename Env, typename BitSetTraits>
assert(!IsShort(env));
unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
assert(len > 1); // Or else would not require an array.
- BitSetShortLongRep res = (BitSetShortLongRep)(BitSetTraits::GetAllocator(env)->Alloc(len * sizeof(size_t)));
+ BitSetShortLongRep res = (BitSetShortLongRep)(BitSetTraits::Alloc(env, len * sizeof(size_t)));
for (unsigned i = 0; i < len; i++)
{
res[i] = 0;
assert(!IsShort(env));
unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
assert(len > 1); // Or else would not require an array.
- BitSetShortLongRep res = (BitSetShortLongRep)(BitSetTraits::GetAllocator(env)->Alloc(len * sizeof(size_t)));
+ BitSetShortLongRep res = (BitSetShortLongRep)(BitSetTraits::Alloc(env, len * sizeof(size_t)));
for (unsigned i = 0; i < len - 1; i++)
{
res[i] = size_t(-1);
bool BitSetOps</*BitSetType*/ BitSetShortLongRep,
/*Brand*/ BSShortLong,
/*Env*/ Env,
+ /*BitSetTraits*/ BitSetTraits>::IsEmptyUnionLong(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
+{
+ assert(!IsShort(env));
+ unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
+ for (unsigned i = 0; i < len; i++)
+ {
+ if ((bs1[i] | bs2[i]) != 0)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+template <typename Env, typename BitSetTraits>
+void BitSetOps</*BitSetType*/ BitSetShortLongRep,
+ /*Brand*/ BSShortLong,
+ /*Env*/ Env,
+ /*BitSetTraits*/ BitSetTraits>::DataFlowDLong(Env env,
+ BitSetShortLongRep& out,
+ const BitSetShortLongRep gen,
+ const BitSetShortLongRep in)
+{
+ assert(!IsShort(env));
+ unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
+ for (unsigned i = 0; i < len; i++)
+ {
+ out[i] = out[i] & (gen[i] | in[i]);
+ }
+}
+
+template <typename Env, typename BitSetTraits>
+void BitSetOps</*BitSetType*/ BitSetShortLongRep,
+ /*Brand*/ BSShortLong,
+ /*Env*/ Env,
+ /*BitSetTraits*/ BitSetTraits>::LivenessDLong(Env env,
+ BitSetShortLongRep& in,
+ const BitSetShortLongRep def,
+ const BitSetShortLongRep use,
+ const BitSetShortLongRep out)
+{
+ assert(!IsShort(env));
+ unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
+ for (unsigned i = 0; i < len; i++)
+ {
+ in[i] = use[i] | (out[i] & ~def[i]);
+ }
+}
+
+template <typename Env, typename BitSetTraits>
+bool BitSetOps</*BitSetType*/ BitSetShortLongRep,
+ /*Brand*/ BSShortLong,
+ /*Env*/ Env,
/*BitSetTraits*/ BitSetTraits>::EqualLong(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
{
assert(!IsShort(env));
/*BitSetTraits*/ BitSetTraits>::ToStringLong(Env env, BitSetShortLongRep bs)
{
assert(!IsShort(env));
- unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
- const int CharsForSizeT = sizeof(size_t) * 2;
- unsigned allocSz = len * CharsForSizeT + 4;
- unsigned remaining = allocSz;
- IAllocator* alloc = BitSetTraits::GetDebugOnlyAllocator(env);
- char* res = (char*)alloc->Alloc(allocSz);
- char* temp = res;
+ unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
+ const int CharsForSizeT = sizeof(size_t) * 2;
+ unsigned allocSz = len * CharsForSizeT + 4;
+ unsigned remaining = allocSz;
+ char* res = (char*)BitSetTraits::DebugAlloc(env, allocSz);
+ char* temp = res;
for (unsigned i = len; 0 < i; i--)
{
size_t bits = bs[i - 1];
/* Can't simultaneously become live and dead at the same time */
// (deadSet UNION bornSet) != EMPTY
- noway_assert(!VarSetOps::IsEmpty(this, VarSetOps::Union(this, deadSet, bornSet)));
+ noway_assert(!VarSetOps::IsEmptyUnion(this, deadSet, bornSet));
// (deadSet INTERSECTION bornSet) == EMPTY
- noway_assert(VarSetOps::IsEmpty(this, VarSetOps::Intersection(this, deadSet, bornSet)));
+ noway_assert(VarSetOps::IsEmptyIntersection(this, deadSet, bornSet));
#ifdef LEGACY_BACKEND
// In the LEGACY_BACKEND case, we only consider variables that are fully enregisterd
// Keeps tracked cse indices
BitVecTraits* cseTraits;
EXPSET_TP cseFull;
- EXPSET_TP cseEmpty;
/* Generic list of nodes - used by the CSE logic */
// Data structures for assertion prop
BitVecTraits* apTraits;
ASSERT_TP apFull;
- ASSERT_TP apEmpty;
enum optAssertionKind
{
void optImpliedByCopyAssertion(AssertionDsc* copyAssertion, AssertionDsc* depAssertion, ASSERT_TP& result);
void optImpliedByConstAssertion(AssertionDsc* curAssertion, ASSERT_TP& result);
- ASSERT_VALRET_TP optNewFullAssertSet();
- ASSERT_VALRET_TP optNewEmptyAssertSet();
-
#ifdef DEBUG
void optPrintAssertion(AssertionDsc* newAssertion, AssertionIndex assertionIndex = 0);
void optDebugCheckAssertion(AssertionDsc* assertion);
class CompAllocBitSetTraits
{
public:
- static inline IAllocator* GetAllocator(class Compiler* comp);
+ static inline void* Alloc(Compiler* comp, size_t byteSize);
#ifdef DEBUG
- static inline IAllocator* GetDebugOnlyAllocator(class Compiler* comp);
+ static inline void* DebugAlloc(Compiler* comp, size_t byteSize);
#endif // DEBUG
};
{
}
- static inline IAllocator* GetAllocator(BitVecTraits* b);
+ static inline void* Alloc(BitVecTraits* b, size_t byteSize);
#ifdef DEBUG
- static inline IAllocator* GetDebugOnlyAllocator(BitVecTraits* b);
+ static inline void* DebugAlloc(BitVecTraits* b, size_t byteSize);
#endif // DEBUG
static inline unsigned GetSize(BitVecTraits* b);
///////////////////////////////////////////////////////////////////////////////
// static
-IAllocator* CompAllocBitSetTraits::GetAllocator(Compiler* comp)
+void* CompAllocBitSetTraits::Alloc(Compiler* comp, size_t byteSize)
{
- return comp->getAllocatorBitset();
+ return comp->compGetMem(byteSize, CMK_bitset);
}
#ifdef DEBUG
// static
-IAllocator* CompAllocBitSetTraits::GetDebugOnlyAllocator(Compiler* comp)
+void* CompAllocBitSetTraits::DebugAlloc(Compiler* comp, size_t byteSize)
{
- return comp->getAllocatorDebugOnly();
+ return comp->compGetMem(byteSize, CMK_DebugOnly);
}
#endif // DEBUG
///////////////////////////////////////////////////////////////////////////////
// static
-IAllocator* BitVecTraits::GetAllocator(BitVecTraits* b)
+void* BitVecTraits::Alloc(BitVecTraits* b, size_t byteSize)
{
- return b->comp->getAllocatorBitset();
+ return b->comp->compGetMem(byteSize, CMK_bitset);
}
#ifdef DEBUG
// static
-IAllocator* BitVecTraits::GetDebugOnlyAllocator(BitVecTraits* b)
+void* BitVecTraits::DebugAlloc(BitVecTraits* b, size_t byteSize)
{
- return b->comp->getAllocatorDebugOnly();
+ return b->comp->compGetMem(byteSize, CMK_DebugOnly);
}
#endif // DEBUG
}
/* Compute the 'm_liveIn' set */
- VarSetOps::Assign(m_compiler, m_liveIn, m_liveOut);
- VarSetOps::DiffD(m_compiler, m_liveIn, block->bbVarDef);
- VarSetOps::UnionD(m_compiler, m_liveIn, block->bbVarUse);
+ VarSetOps::LivenessD(m_compiler, m_liveIn, block->bbVarDef, block->bbVarUse, m_liveOut);
// Even if block->bbMemoryDef is set, we must assume that it doesn't kill memory liveness from m_memoryLiveOut,
// since (without proof otherwise) the use and def may touch different memory at run-time.
noway_assert(block->bbFlags & BBF_INTERNAL);
- liveInChanged =
- !VarSetOps::Equal(m_compiler, VarSetOps::Intersection(m_compiler, block->bbLiveIn, m_liveIn),
- m_liveIn);
- if (liveInChanged ||
- !VarSetOps::Equal(m_compiler, VarSetOps::Intersection(m_compiler, block->bbLiveOut, m_liveOut),
- m_liveOut))
+ liveInChanged = !VarSetOps::IsSubset(m_compiler, m_liveIn, block->bbLiveIn);
+ if (liveInChanged || !VarSetOps::IsSubset(m_compiler, m_liveOut, block->bbLiveOut))
{
#ifdef DEBUG
if (m_compiler->verbose)
VARSET_TP VARSET_INIT(this, keepAliveVars, volatileVars);
VarSetOps::UnionD(this, keepAliveVars, compCurBB->bbScope); // Don't kill vars in scope
- noway_assert(VarSetOps::Equal(this, VarSetOps::Intersection(this, keepAliveVars, life), keepAliveVars));
+ noway_assert(VarSetOps::IsSubset(this, keepAliveVars, life));
noway_assert(compCurStmt->gtOper == GT_STMT);
noway_assert(endNode || (startNode == compCurStmt->gtStmt.gtStmtExpr));
VARSET_TP VARSET_INIT(this, keepAliveVars, volatileVars);
VarSetOps::UnionD(this, keepAliveVars, block->bbScope); // Don't kill vars in scope
- noway_assert(VarSetOps::Equal(this, VarSetOps::Intersection(this, keepAliveVars, life), keepAliveVars));
+ noway_assert(VarSetOps::IsSubset(this, keepAliveVars, life));
LIR::Range& blockRange = LIR::AsRange(block);
GenTree* firstNonPhiNode = blockRange.FirstNonPhiNode();
// which may expose more dead stores.
fgLocalVarLivenessChanged = true;
- noway_assert(VarSetOps::Equal(this, VarSetOps::Intersection(this, life, block->bbLiveIn), life));
+ noway_assert(VarSetOps::IsSubset(this, life, block->bbLiveIn));
/* set the new bbLiveIn */
//
void Compiler::optCSE_GetMaskData(GenTreePtr tree, optCSE_MaskData* pMaskData)
{
- pMaskData->CSE_defMask = BitVecOps::MakeCopy(cseTraits, cseEmpty);
- pMaskData->CSE_useMask = BitVecOps::MakeCopy(cseTraits, cseEmpty);
+ pMaskData->CSE_defMask = BitVecOps::MakeEmpty(cseTraits);
+ pMaskData->CSE_useMask = BitVecOps::MakeEmpty(cseTraits);
fgWalkTreePre(&tree, optCSE_MaskHelper, (void*)pMaskData);
}
// Init traits and full/empty bitvectors. This will be used to track the
// individual cse indexes.
cseTraits = new (getAllocator()) BitVecTraits(EXPSET_SZ, this);
- cseFull = BitVecOps::UninitVal();
- cseEmpty = BitVecOps::UninitVal();
- BitVecOps::AssignNoCopy(cseTraits, cseFull, BitVecOps::MakeFull(cseTraits));
- BitVecOps::AssignNoCopy(cseTraits, cseEmpty, BitVecOps::MakeEmpty(cseTraits));
+ cseFull = BitVecOps::MakeFull(cseTraits);
/* Allocate and clear the hash bucket table */
if (init_to_zero)
{
/* Initialize to {ZERO} prior to dataflow */
- block->bbCseIn = BitVecOps::MakeCopy(cseTraits, cseEmpty);
+ block->bbCseIn = BitVecOps::MakeEmpty(cseTraits);
}
else
{
block->bbCseOut = BitVecOps::MakeCopy(cseTraits, cseFull);
/* Initialize to {ZERO} prior to locating the CSE candidates */
- block->bbCseGen = BitVecOps::MakeCopy(cseTraits, cseEmpty);
+ block->bbCseGen = BitVecOps::MakeEmpty(cseTraits);
}
// We walk the set of CSE candidates and set the bit corresponsing to the CSEindex
*/
class CSE_DataFlow
{
-private:
- EXPSET_TP m_preMergeOut;
-
- Compiler* m_pCompiler;
+ BitVecTraits* m_pBitVecTraits;
+ EXPSET_TP m_preMergeOut;
public:
- CSE_DataFlow(Compiler* pCompiler) : m_pCompiler(pCompiler)
- {
- }
-
- Compiler* getCompiler()
+ CSE_DataFlow(Compiler* pCompiler) : m_pBitVecTraits(pCompiler->cseTraits), m_preMergeOut(BitVecOps::UninitVal())
{
- return m_pCompiler;
}
// At the start of the merge function of the dataflow equations, initialize premerge state (to detect changes.)
void StartMerge(BasicBlock* block)
{
- m_preMergeOut = BitVecOps::MakeCopy(m_pCompiler->cseTraits, block->bbCseOut);
+ BitVecOps::Assign(m_pBitVecTraits, m_preMergeOut, block->bbCseOut);
}
// During merge, perform the actual merging of the predecessor's (since this is a forward analysis) dataflow flags.
void Merge(BasicBlock* block, BasicBlock* predBlock, flowList* preds)
{
- BitVecOps::IntersectionD(m_pCompiler->cseTraits, block->bbCseIn, predBlock->bbCseOut);
+ BitVecOps::IntersectionD(m_pBitVecTraits, block->bbCseIn, predBlock->bbCseOut);
}
// At the end of the merge store results of the dataflow equations, in a postmerge state.
bool EndMerge(BasicBlock* block)
{
- BitVecTraits* traits = m_pCompiler->cseTraits;
- EXPSET_TP mergeOut = BitVecOps::MakeCopy(traits, block->bbCseIn);
- BitVecOps::UnionD(traits, mergeOut, block->bbCseGen);
- BitVecOps::IntersectionD(traits, mergeOut, block->bbCseOut);
- BitVecOps::Assign(traits, block->bbCseOut, mergeOut);
- return (!BitVecOps::Equal(traits, mergeOut, m_preMergeOut));
+ BitVecOps::DataFlowD(m_pBitVecTraits, block->bbCseOut, block->bbCseGen, block->bbCseIn);
+ return !BitVecOps::Equal(m_pBitVecTraits, block->bbCseOut, m_preMergeOut);
}
};
printf("Labeling the CSEs with Use/Def information\n");
}
#endif
+ EXPSET_TP available_cses = BitVecOps::MakeEmpty(cseTraits);
+
for (BasicBlock* block = fgFirstBB; block; block = block->bbNext)
{
GenTreePtr stmt;
compCurBB = block;
- EXPSET_TP available_cses = BitVecOps::MakeCopy(cseTraits, block->bbCseIn);
+ BitVecOps::Assign(cseTraits, available_cses, block->bbCseIn);
optCSEweight = block->getBBWeight(this);