diff options
Diffstat (limited to 'src/jit/optcse.cpp')
-rw-r--r-- | src/jit/optcse.cpp | 88 |
1 files changed, 49 insertions, 39 deletions
diff --git a/src/jit/optcse.cpp b/src/jit/optcse.cpp index d23b4cd198..3ff4cea385 100644 --- a/src/jit/optcse.cpp +++ b/src/jit/optcse.cpp @@ -301,15 +301,15 @@ Compiler::fgWalkResult Compiler::optCSE_MaskHelper(GenTreePtr* pTree, fgWalkData if (IS_CSE_INDEX(tree->gtCSEnum)) { - unsigned cseIndex = GET_CSE_INDEX(tree->gtCSEnum); - EXPSET_TP cseBit = genCSEnum2bit(cseIndex); + unsigned cseIndex = GET_CSE_INDEX(tree->gtCSEnum); + unsigned cseBit = genCSEnum2bit(cseIndex); if (IS_CSE_DEF(tree->gtCSEnum)) { - pUserData->CSE_defMask |= cseBit; + BitVecOps::AddElemD(comp->cseTraits, pUserData->CSE_defMask, cseBit); } else { - pUserData->CSE_useMask |= cseBit; + BitVecOps::AddElemD(comp->cseTraits, pUserData->CSE_useMask, cseBit); } } @@ -321,8 +321,8 @@ Compiler::fgWalkResult Compiler::optCSE_MaskHelper(GenTreePtr* pTree, fgWalkData // void Compiler::optCSE_GetMaskData(GenTreePtr tree, optCSE_MaskData* pMaskData) { - pMaskData->CSE_defMask = 0; - pMaskData->CSE_useMask = 0; + pMaskData->CSE_defMask = BitVecOps::MakeCopy(cseTraits, cseEmpty); + pMaskData->CSE_useMask = BitVecOps::MakeCopy(cseTraits, cseEmpty); fgWalkTreePre(&tree, optCSE_MaskHelper, (void*)pMaskData); } @@ -355,14 +355,14 @@ bool Compiler::optCSE_canSwap(GenTree* op1, GenTree* op2) optCSE_GetMaskData(op2, &op2MaskData); // We cannot swap if op1 contains a CSE def that is used by op2 - if ((op1MaskData.CSE_defMask & op2MaskData.CSE_useMask) != 0) + if (!BitVecOps::IsEmptyIntersection(cseTraits, op1MaskData.CSE_defMask, op2MaskData.CSE_useMask)) { canSwap = false; } else { // We also cannot swap if op2 contains a CSE def that is used by op1. - if ((op2MaskData.CSE_defMask & op1MaskData.CSE_useMask) != 0) + if (!BitVecOps::IsEmptyIntersection(cseTraits, op2MaskData.CSE_defMask, op1MaskData.CSE_useMask)) { canSwap = false; } @@ -495,6 +495,14 @@ void Compiler::optValnumCSE_Init() optCSEtab = nullptr; #endif + // 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)); + /* Allocate and clear the hash bucket table */ optCSEhash = new (this, CMK_CSE) CSEdsc*[s_optCSEhashSize](); @@ -631,8 +639,8 @@ unsigned Compiler::optValnumCSE_Index(GenTreePtr tree, GenTreePtr stmt) C_ASSERT((signed char)MAX_CSE_CNT == MAX_CSE_CNT); - unsigned CSEindex = ++optCSECandidateCount; - EXPSET_TP CSEmask = genCSEnum2bit(CSEindex); + unsigned CSEindex = ++optCSECandidateCount; + // EXPSET_TP CSEmask = genCSEnum2bit(CSEindex); /* Record the new CSE index in the hashDsc */ hashDsc->csdIndex = CSEindex; @@ -649,10 +657,11 @@ unsigned Compiler::optValnumCSE_Index(GenTreePtr tree, GenTreePtr stmt) #ifdef DEBUG if (verbose) { + EXPSET_TP tempMask = BitVecOps::MakeSingleton(cseTraits, genCSEnum2bit(CSEindex)); printf("\nCSE candidate #%02u, vn=", CSEindex); vnPrint(vnlib, 0); - printf(" cseMask=%s in BB%02u, [cost=%2u, size=%2u]: \n", genES2str(genCSEnum2bit(CSEindex)), - compCurBB->bbNum, tree->gtCostEx, tree->gtCostSz); + printf(" cseMask=%s in BB%02u, [cost=%2u, size=%2u]: \n", genES2str(cseTraits, tempMask), compCurBB->bbNum, + tree->gtCostEx, tree->gtCostSz); gtDispTree(tree); } #endif // DEBUG @@ -773,19 +782,18 @@ void Compiler::optValnumCSE_InitDataFlow() if (init_to_zero) { /* Initialize to {ZERO} prior to dataflow */ - - block->bbCseIn = 0; + block->bbCseIn = BitVecOps::MakeCopy(cseTraits, cseEmpty); } else { /* Initialize to {ALL} prior to dataflow */ - - block->bbCseIn = EXPSET_ALL; + block->bbCseIn = BitVecOps::MakeCopy(cseTraits, cseFull); } - block->bbCseOut = EXPSET_ALL; + + block->bbCseOut = BitVecOps::MakeCopy(cseTraits, cseFull); /* Initialize to {ZERO} prior to locating the CSE candidates */ - block->bbCseGen = 0; + block->bbCseGen = BitVecOps::MakeCopy(cseTraits, cseEmpty); } // We walk the set of CSE candidates and set the bit corresponsing to the CSEindex @@ -801,7 +809,7 @@ void Compiler::optValnumCSE_InitDataFlow() while (lst != nullptr) { BasicBlock* block = lst->tslBlock; - block->bbCseGen |= genCSEnum2bit(CSEindex); + BitVecOps::AddElemD(cseTraits, block->bbCseGen, genCSEnum2bit(CSEindex)); lst = lst->tslNext; } } @@ -814,7 +822,7 @@ void Compiler::optValnumCSE_InitDataFlow() bool headerPrinted = false; for (BasicBlock* block = fgFirstBB; block; block = block->bbNext) { - if (block->bbCseGen != 0) + if (block->bbCseGen != nullptr) { if (!headerPrinted) { @@ -822,7 +830,7 @@ void Compiler::optValnumCSE_InitDataFlow() headerPrinted = true; } printf("BB%02u", block->bbNum); - printf(" cseGen = %s\n", genES2str(block->bbCseGen)); + printf(" cseGen = %s\n", genES2str(cseTraits, block->bbCseGen)); } } } @@ -857,21 +865,24 @@ public: // At the start of the merge function of the dataflow equations, initialize premerge state (to detect changes.) void StartMerge(BasicBlock* block) { - m_preMergeOut = block->bbCseOut; + m_preMergeOut = BitVecOps::MakeCopy(m_pCompiler->cseTraits, 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) { - block->bbCseIn &= predBlock->bbCseOut; + BitVecOps::IntersectionD(m_pCompiler->cseTraits, block->bbCseIn, predBlock->bbCseOut); } // At the end of the merge store results of the dataflow equations, in a postmerge state. bool EndMerge(BasicBlock* block) { - EXPSET_TP mergeOut = block->bbCseOut & (block->bbCseIn | block->bbCseGen); - block->bbCseOut = mergeOut; - return (mergeOut != m_preMergeOut); + 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)); } }; @@ -905,8 +916,8 @@ void Compiler::optValnumCSE_DataFlow() for (BasicBlock* block = fgFirstBB; block; block = block->bbNext) { printf("BB%02u", block->bbNum); - printf(" cseIn = %s", genES2str(block->bbCseIn)); - printf(" cseOut = %s", genES2str(block->bbCseOut)); + printf(" cseIn = %s", genES2str(cseTraits, block->bbCseIn)); + printf(" cseOut = %s", genES2str(cseTraits, block->bbCseOut)); printf("\n"); } @@ -946,7 +957,7 @@ void Compiler::optValnumCSE_Availablity() compCurBB = block; - EXPSET_TP available_cses = block->bbCseIn; + EXPSET_TP available_cses = BitVecOps::MakeCopy(cseTraits, block->bbCseIn); optCSEweight = block->getBBWeight(this); @@ -961,13 +972,13 @@ void Compiler::optValnumCSE_Availablity() { if (IS_CSE_INDEX(tree->gtCSEnum)) { - EXPSET_TP mask = genCSEnum2bit(tree->gtCSEnum); - CSEdsc* desc = optCSEfindDsc(tree->gtCSEnum); - unsigned stmw = block->getBBWeight(this); + unsigned int cseBit = genCSEnum2bit(tree->gtCSEnum); + CSEdsc* desc = optCSEfindDsc(tree->gtCSEnum); + unsigned stmw = block->getBBWeight(this); /* Is this expression available here? */ - if (available_cses & mask) + if (BitVecOps::IsMember(cseTraits, available_cses, cseBit)) { /* This is a CSE use */ @@ -993,8 +1004,7 @@ void Compiler::optValnumCSE_Availablity() tree->gtCSEnum = TO_CSE_DEF(tree->gtCSEnum); /* This CSE will be available after this def */ - - available_cses |= mask; + BitVecOps::AddElemD(cseTraits, available_cses, cseBit); } #ifdef DEBUG if (verbose && IS_CSE_INDEX(tree->gtCSEnum)) @@ -1236,6 +1246,7 @@ public: { printf("\nSorted CSE candidates:\n"); /* Print out the CSE candidates */ + EXPSET_TP tempMask; for (unsigned cnt = 0; cnt < m_pCompiler->optCSECandidateCount; cnt++) { Compiler::CSEdsc* dsc = sortTab[cnt]; @@ -1255,8 +1266,9 @@ public: use = dsc->csdUseWtCnt; // weighted use count (excluding the implicit uses at defs) } + tempMask = BitVecOps::MakeSingleton(m_pCompiler->cseTraits, genCSEnum2bit(dsc->csdIndex)); printf("CSE #%02u,cseMask=%s,useCnt=%d: [def=%3u, use=%3u", dsc->csdIndex, - genES2str(genCSEnum2bit(dsc->csdIndex)), dsc->csdUseCount, def, use); + genES2str(m_pCompiler->cseTraits, tempMask), dsc->csdUseCount, def, use); printf("] :: "); m_pCompiler->gtDispTree(expr, nullptr, nullptr, true); } @@ -2038,7 +2050,7 @@ public: assert(m_pCompiler->fgRemoveRestOfBlock == false); /* re-morph the statement */ - m_pCompiler->fgMorphBlockStmt(blk, stm DEBUGARG("optValnumCSE")); + m_pCompiler->fgMorphBlockStmt(blk, stm->AsStmt() DEBUGARG("optValnumCSE")); } while (lst != nullptr); } @@ -2516,8 +2528,6 @@ void Compiler::optCleanupCSEs() // for (BasicBlock* block = fgFirstBB; block; block = block->bbNext) { - unsigned blkFlags = block->bbFlags; - // And clear all the "visited" bits on the block // block->bbFlags &= ~(BBF_VISITED | BBF_MARKED); |