From c6024a627463d1c37690fd615baed54f44e67690 Mon Sep 17 00:00:00 2001 From: Brian Sullivan Date: Thu, 31 Oct 2019 11:05:47 -0700 Subject: [PATCH] Tiered rejit work items (dotnet/coreclr#27147) * Use info.compFullName as the input to create the JIT's MethodHash Update JitOrder to print out MethodHash and PerfScore Change eeGetMethodFullName to expand class and struct names for the argument types and the return type Fixed issue where bad edge weight were set in fgFoldConditional Made flEdgeWeightMin and flEdgeWeightMax private fields Added new method setEdgeWeights Added support method eeGetArgClass Added source for Tool to parse JitOrder output and associate PerfScores * Remove jitOrderParser.cs Commit migrated from https://github.com/dotnet/coreclr/commit/c6697a00ef7ecba6012b1a52f13401ce06b8295b --- src/coreclr/src/jit/block.h | 21 ++++-- src/coreclr/src/jit/compiler.cpp | 71 ++++++++++++------- src/coreclr/src/jit/compiler.h | 1 + src/coreclr/src/jit/ee_il_dll.hpp | 7 ++ src/coreclr/src/jit/eeinterface.cpp | 76 +++++++++++++++++--- src/coreclr/src/jit/flowgraph.cpp | 134 ++++++++++++++++++++---------------- src/coreclr/src/jit/morph.cpp | 31 ++++++--- src/coreclr/src/jit/optimizer.cpp | 28 +++----- 8 files changed, 244 insertions(+), 125 deletions(-) diff --git a/src/coreclr/src/jit/block.h b/src/coreclr/src/jit/block.h index 4632cca..55b0593 100644 --- a/src/coreclr/src/jit/block.h +++ b/src/coreclr/src/jit/block.h @@ -1277,13 +1277,23 @@ struct BasicBlockList struct flowList { - flowList* flNext; // The next BasicBlock in the list, nullptr for end of list. - BasicBlock* flBlock; // The BasicBlock of interest. + flowList* flNext; // The next BasicBlock in the list, nullptr for end of list. + BasicBlock* flBlock; // The BasicBlock of interest. + unsigned flDupCount; // The count of duplicate "edges" (use only for switch stmts) +private: BasicBlock::weight_t flEdgeWeightMin; BasicBlock::weight_t flEdgeWeightMax; - unsigned flDupCount; // The count of duplicate "edges" (use only for switch stmts) +public: + BasicBlock::weight_t edgeWeightMin() const + { + return flEdgeWeightMin; + } + BasicBlock::weight_t edgeWeightMax() const + { + return flEdgeWeightMax; + } // These two methods are used to set new values for flEdgeWeightMin and flEdgeWeightMax // they are used only during the computation of the edge weights @@ -1292,13 +1302,14 @@ struct flowList // bool setEdgeWeightMinChecked(BasicBlock::weight_t newWeight, BasicBlock::weight_t slop, bool* wbUsedSlop); bool setEdgeWeightMaxChecked(BasicBlock::weight_t newWeight, BasicBlock::weight_t slop, bool* wbUsedSlop); + void setEdgeWeights(BasicBlock::weight_t newMinWeight, BasicBlock::weight_t newMaxWeight); - flowList() : flNext(nullptr), flBlock(nullptr), flEdgeWeightMin(0), flEdgeWeightMax(0), flDupCount(0) + flowList() : flNext(nullptr), flBlock(nullptr), flDupCount(0), flEdgeWeightMin(0), flEdgeWeightMax(0) { } flowList(BasicBlock* blk, flowList* rest) - : flNext(rest), flBlock(blk), flEdgeWeightMin(0), flEdgeWeightMax(0), flDupCount(0) + : flNext(rest), flBlock(blk), flDupCount(0), flEdgeWeightMin(0), flEdgeWeightMax(0) { } }; diff --git a/src/coreclr/src/jit/compiler.cpp b/src/coreclr/src/jit/compiler.cpp index c835035..8b27640 100644 --- a/src/coreclr/src/jit/compiler.cpp +++ b/src/coreclr/src/jit/compiler.cpp @@ -3996,8 +3996,8 @@ void Compiler::compSetOptimizationLevel() sscanf_s(histr, "%x", &methHashHi); if (methHash >= methHashLo && methHash <= methHashHi) { - printf("MinOpts for method %s, hash = 0x%x.\n", - info.compFullName, info.compMethodHash()); + printf("MinOpts for method %s, hash = %08x.\n", + info.compFullName, methHash); printf(""); // in our logic this causes a flush theMinOptsValue = true; } @@ -5495,7 +5495,12 @@ unsigned Compiler::Info::compMethodHash() const { if (compMethodHashPrivate == 0) { - compMethodHashPrivate = compCompHnd->getMethodHash(compMethodHnd); + // compMethodHashPrivate = compCompHnd->getMethodHash(compMethodHnd); + assert(compFullName != nullptr); + assert(*compFullName != 0); + COUNT_T hash = HashStringA(compFullName); // Use compFullName to generate the hash, as it contains the signature + // and return type + compMethodHashPrivate = hash; } return compMethodHashPrivate; } @@ -5588,31 +5593,42 @@ void Compiler::compCompileFinish() { // clang-format off headerPrinted = true; - printf(" | Profiled | Exec- | Method has | calls | Num |LclV |AProp| CSE | Reg |bytes | %3s code size | \n", Target::g_tgtCPUName); - printf(" mdToken | | RGN | Count | EH | FRM | LOOP | NRM | IND | BBs | Cnt | Cnt | Cnt | Alloc | IL | HOT | COLD | method name \n"); - printf("---------+-----+------+----------+----+-----+------+-----+-----+-----+-----+-----+-----+---------+------+-------+-------+-----------\n"); - // 06001234 | PRF | HOT | 219 | EH | ebp | LOOP | 15 | 6 | 12 | 17 | 12 | 8 | 28 p2 | 145 | 211 | 123 | System.Example(int) + printf(" | Profiled | Method | Method has | calls | Num |LclV |AProp| CSE | Perf |bytes | %3s codesize| \n", Target::g_tgtCPUName); + printf(" mdToken | CNT | RGN | Hash | EH | FRM | LOOP | NRM | IND | BBs | Cnt | Cnt | Cnt | Score | IL | HOT | CLD | method name \n"); + printf("---------+------+------+----------+----+-----+------+-----+-----+-----+-----+-----+-----+---------+------+-------+-----+\n"); + // 06001234 | 1234 | HOT | 0f1e2d3c | EH | ebp | LOOP | 15 | 6 | 12 | 17 | 12 | 8 | 1234.56 | 145 | 1234 | 123 | System.Example(int) // clang-format on } printf("%08X | ", currentMethodToken); - CorInfoRegionKind regionKind = info.compMethodInfo->regionKind; - - if (opts.altJit) + if (fgHaveProfileData()) { - printf("ALT | "); - } - else if (fgHaveProfileData()) - { - printf("PRF | "); + if (profCallCount <= 9999) + { + printf("%4d | ", profCallCount); + } + else if (profCallCount <= 999500) + { + printf("%3dK | ", (profCallCount + 500) / 1000); + } + else + { + printf("%3dM | ", (profCallCount + 500000) / 1000000); + } } else { - printf(" | "); + printf(" | "); } - if (regionKind == CORINFO_REGION_NONE) + CorInfoRegionKind regionKind = info.compMethodInfo->regionKind; + + if (opts.altJit) + { + printf("ALT | "); + } + else if (regionKind == CORINFO_REGION_NONE) { printf(" | "); } @@ -5633,7 +5649,7 @@ void Compiler::compCompileFinish() printf("UNKN | "); } - printf("%8d | ", profCallCount); + printf("%08x | ", info.compMethodHash()); if (compHndBBtabCount > 0) { @@ -5691,10 +5707,18 @@ void Compiler::compCompileFinish() #endif // FEATURE_ANYCSE } - printf(" LSRA |"); // TODO-Cleanup: dump some interesting LSRA stat into the order file? + if (info.compPerfScore < 9999.995) + { + printf(" %7.2f |", info.compPerfScore); + } + else + { + printf(" %7.0f |", info.compPerfScore); + } + printf(" %4d |", info.compMethodInfo->ILCodeSize); printf(" %5d |", info.compTotalHotCodeSize); - printf(" %5d |", info.compTotalColdCodeSize); + printf(" %3d |", info.compTotalColdCodeSize); printf(" %s\n", eeGetMethodFullName(info.compMethodHnd)); printf(""); // in our logic this causes a flush @@ -6115,9 +6139,8 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr, #ifdef DEBUG if (JitConfig.DumpJittedMethods() == 1 && !compIsForInlining()) { - printf("Compiling %4d %s::%s, IL size = %u, hsh=0x%x %s\n", Compiler::jitTotalMethodCompiled, - info.compClassName, info.compMethodName, info.compILCodeSize, info.compMethodHash(), - compGetTieringName()); + printf("Compiling %4d %s::%s, IL size = %u, hash=%08x\n", Compiler::jitTotalMethodCompiled, info.compClassName, + info.compMethodName, info.compILCodeSize, info.compMethodHash(), compGetTieringName()); } if (compIsForInlining()) { @@ -8638,7 +8661,7 @@ void cFuncIR(Compiler* comp) { BasicBlock* block; - printf("Method %s::%s, hsh=0x%x\n", comp->info.compClassName, comp->info.compMethodName, + printf("Method %s::%s, hash=%08x\n", comp->info.compClassName, comp->info.compMethodName, comp->info.compMethodHash()); printf("\n"); diff --git a/src/coreclr/src/jit/compiler.h b/src/coreclr/src/jit/compiler.h index 0970639..7561d0d 100644 --- a/src/coreclr/src/jit/compiler.h +++ b/src/coreclr/src/jit/compiler.h @@ -6950,6 +6950,7 @@ public: var_types eeGetArgType(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO* sig); var_types eeGetArgType(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO* sig, bool* isPinned); + CORINFO_CLASS_HANDLE eeGetArgClass(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE list); unsigned eeGetArgSize(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO* sig); // VOM info, method sigs diff --git a/src/coreclr/src/jit/ee_il_dll.hpp b/src/coreclr/src/jit/ee_il_dll.hpp index ce602ba..4a937d1 100644 --- a/src/coreclr/src/jit/ee_il_dll.hpp +++ b/src/coreclr/src/jit/ee_il_dll.hpp @@ -109,6 +109,13 @@ inline var_types Compiler::eeGetArgType(CORINFO_ARG_LIST_HANDLE list, CORINFO_SI return JITtype2varType(strip(type)); } +/*****************************************************************************/ +inline CORINFO_CLASS_HANDLE Compiler::eeGetArgClass(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE list) +{ + CORINFO_CLASS_HANDLE argClass = info.compCompHnd->getArgClass(sig, list); + return argClass; +} + /***************************************************************************** * * Native Direct Optimizations diff --git a/src/coreclr/src/jit/eeinterface.cpp b/src/coreclr/src/jit/eeinterface.cpp index 5a0e412..d2efd79 100644 --- a/src/coreclr/src/jit/eeinterface.cpp +++ b/src/coreclr/src/jit/eeinterface.cpp @@ -28,10 +28,10 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX /*****************************************************************************/ /***************************************************************************** -* -* Filter wrapper to handle exception filtering. -* On Unix compilers don't support SEH. -*/ + * + * Filter wrapper to handle exception filtering. + * On Unix compilers don't support SEH. + */ struct FilterSuperPMIExceptionsParam_eeinterface { @@ -43,6 +43,7 @@ struct FilterSuperPMIExceptionsParam_eeinterface CORINFO_ARG_LIST_HANDLE argLst; CORINFO_METHOD_HANDLE hnd; const char* returnType; + const char** pArgNames; EXCEPTION_POINTERS exceptionPointers; }; @@ -103,17 +104,50 @@ const char* Compiler::eeGetMethodFullName(CORINFO_METHOD_HANDLE hnd) /* figure out the signature */ + param.pThis->eeGetMethodSig(param.hnd, ¶m.sig); + + // allocate space to hold the class names for each of the parameters + + if (param.sig.numArgs > 0) + { + param.pArgNames = getAllocator(CMK_DebugOnly).allocate(param.sig.numArgs); + } + else + { + param.pArgNames = nullptr; + } + PAL_TRY(FilterSuperPMIExceptionsParam_eeinterface*, pParam, ¶m) { unsigned i; - pParam->pThis->eeGetMethodSig(pParam->hnd, &pParam->sig); pParam->argLst = pParam->sig.args; for (i = 0; i < pParam->sig.numArgs; i++) { var_types type = pParam->pThis->eeGetArgType(pParam->argLst, &pParam->sig); - - pParam->siglength += strlen(varTypeName(type)); + switch (type) + { + case TYP_REF: + case TYP_STRUCT: + { + CORINFO_CLASS_HANDLE clsHnd = pParam->pThis->eeGetArgClass(&pParam->sig, pParam->argLst); + // For some SIMD struct types we can get a nullptr back from eeGetArgClass on Linux/X64 + if (clsHnd != NO_CLASS_HANDLE) + { + const char* clsName = pParam->pThis->eeGetClassName(clsHnd); + if (clsName != nullptr) + { + pParam->pArgNames[i] = clsName; + break; + } + } + } + __fallthrough; + default: + pParam->pArgNames[i] = varTypeName(type); + break; + } + pParam->siglength += strlen(pParam->pArgNames[i]); pParam->argLst = pParam->pJitInfo->compCompHnd->getArgNext(pParam->argLst); } @@ -124,9 +158,30 @@ const char* Compiler::eeGetMethodFullName(CORINFO_METHOD_HANDLE hnd) pParam->siglength += (pParam->sig.numArgs - 1); } - if (JITtype2varType(pParam->sig.retType) != TYP_VOID) + var_types retType = JITtype2varType(pParam->sig.retType); + if (retType != TYP_VOID) { - pParam->returnType = varTypeName(JITtype2varType(pParam->sig.retType)); + switch (retType) + { + case TYP_REF: + case TYP_STRUCT: + { + CORINFO_CLASS_HANDLE clsHnd = pParam->sig.retTypeClass; + if (clsHnd != NO_CLASS_HANDLE) + { + const char* clsName = pParam->pThis->eeGetClassName(clsHnd); + if (clsName != nullptr) + { + pParam->returnType = clsName; + break; + } + } + } + __fallthrough; + default: + pParam->returnType = varTypeName(retType); + break; + } pParam->siglength += strlen(pParam->returnType) + 1; // don't forget the delimiter ':' } @@ -175,8 +230,7 @@ const char* Compiler::eeGetMethodFullName(CORINFO_METHOD_HANDLE hnd) for (i = 0; i < param.sig.numArgs; i++) { var_types type = eeGetArgType(param.argLst, ¶m.sig); - strcat_s(retName, length, varTypeName(type)); - + strcat_s(retName, length, param.pArgNames[i]); param.argLst = info.compCompHnd->getArgNext(param.argLst); if (i + 1 < param.sig.numArgs) { diff --git a/src/coreclr/src/jit/flowgraph.cpp b/src/coreclr/src/jit/flowgraph.cpp index 569e584..fcc2e2b 100644 --- a/src/coreclr/src/jit/flowgraph.cpp +++ b/src/coreclr/src/jit/flowgraph.cpp @@ -1125,31 +1125,29 @@ flowList* Compiler::fgAddRefPred(BasicBlock* block, // If our caller has given us the old edge weights // then we will use them. // - flow->flEdgeWeightMin = oldEdge->flEdgeWeightMin; - flow->flEdgeWeightMax = oldEdge->flEdgeWeightMax; + flow->setEdgeWeights(oldEdge->edgeWeightMin(), oldEdge->edgeWeightMax()); } else { // Set the max edge weight to be the minimum of block's or blockPred's weight // - flow->flEdgeWeightMax = min(block->bbWeight, blockPred->bbWeight); + BasicBlock::weight_t newWeightMax = min(block->bbWeight, blockPred->bbWeight); // If we are inserting a conditional block the minimum weight is zero, // otherwise it is the same as the edge's max weight. if (blockPred->NumSucc() > 1) { - flow->flEdgeWeightMin = BB_ZERO_WEIGHT; + flow->setEdgeWeights(BB_ZERO_WEIGHT, newWeightMax); } else { - flow->flEdgeWeightMin = flow->flEdgeWeightMax; + flow->setEdgeWeights(flow->edgeWeightMax(), newWeightMax); } } } else { - flow->flEdgeWeightMin = BB_ZERO_WEIGHT; - flow->flEdgeWeightMax = BB_MAX_WEIGHT; + flow->setEdgeWeights(BB_ZERO_WEIGHT, BB_MAX_WEIGHT); } } return flow; @@ -11438,7 +11436,7 @@ BasicBlock* Compiler::fgConnectFallThrough(BasicBlock* bSrc, BasicBlock* bDst) flowList* newEdge = fgGetPredForBlock(jmpBlk, bSrc); - jmpBlk->bbWeight = (newEdge->flEdgeWeightMin + newEdge->flEdgeWeightMax) / 2; + jmpBlk->bbWeight = (newEdge->edgeWeightMin() + newEdge->edgeWeightMax()) / 2; if (bSrc->bbWeight == 0) { jmpBlk->bbWeight = 0; @@ -11449,7 +11447,7 @@ BasicBlock* Compiler::fgConnectFallThrough(BasicBlock* bSrc, BasicBlock* bDst) jmpBlk->bbFlags |= BBF_RUN_RARELY; } - BasicBlock::weight_t weightDiff = (newEdge->flEdgeWeightMax - newEdge->flEdgeWeightMin); + BasicBlock::weight_t weightDiff = (newEdge->edgeWeightMax() - newEdge->edgeWeightMin()); BasicBlock::weight_t slop = BasicBlock::GetSlopFraction(bSrc, bDst); // @@ -13091,6 +13089,23 @@ bool flowList::setEdgeWeightMaxChecked(BasicBlock::weight_t newWeight, BasicBloc return result; } +//------------------------------------------------------------------------ +// setEdgeWeights: Sets the minimum lower (flEdgeWeightMin) value +// and the maximum upper (flEdgeWeightMax) value +// Asserts that the max value is greater or equal to the min value +// +// Arguments: +// theMinWeight - the new minimum lower (flEdgeWeightMin) +// theMaxWeight - the new maximum upper (flEdgeWeightMin) +// +void flowList::setEdgeWeights(BasicBlock::weight_t theMinWeight, BasicBlock::weight_t theMaxWeight) +{ + assert(theMinWeight <= theMaxWeight); + + flEdgeWeightMin = theMinWeight; + flEdgeWeightMax = theMaxWeight; +} + #ifdef DEBUG void Compiler::fgPrintEdgeWeights() { @@ -13111,19 +13126,19 @@ void Compiler::fgPrintEdgeWeights() printf(FMT_BB " ", bSrc->bbNum); - if (edge->flEdgeWeightMin < BB_MAX_WEIGHT) + if (edge->edgeWeightMin() < BB_MAX_WEIGHT) { - printf("(%u", edge->flEdgeWeightMin); + printf("(%u", edge->edgeWeightMin()); } else { printf("(MAX"); } - if (edge->flEdgeWeightMin != edge->flEdgeWeightMax) + if (edge->edgeWeightMin() != edge->edgeWeightMax()) { - if (edge->flEdgeWeightMax < BB_MAX_WEIGHT) + if (edge->edgeWeightMax() < BB_MAX_WEIGHT) { - printf("..%u", edge->flEdgeWeightMax); + printf("..%u", edge->edgeWeightMax()); } else { @@ -13450,8 +13465,7 @@ void Compiler::fgComputeEdgeWeights() if (!bSrc->hasProfileWeight() || !bDst->hasProfileWeight()) { - edge->flEdgeWeightMin = BB_ZERO_WEIGHT; - edge->flEdgeWeightMax = BB_MAX_WEIGHT; + edge->setEdgeWeights(BB_ZERO_WEIGHT, BB_MAX_WEIGHT); } slop = BasicBlock::GetSlopFraction(bSrc, bDst) + 1; @@ -13470,7 +13484,7 @@ void Compiler::fgComputeEdgeWeights() case BBJ_SWITCH: case BBJ_EHFINALLYRET: case BBJ_EHFILTERRET: - if (edge->flEdgeWeightMax > bSrc->bbWeight) + if (edge->edgeWeightMax() > bSrc->bbWeight) { // The maximum edge weight to block can't be greater than the weight of bSrc assignOK &= edge->setEdgeWeightMaxChecked(bSrc->bbWeight, slop, &usedSlop); @@ -13484,7 +13498,7 @@ void Compiler::fgComputeEdgeWeights() } // The maximum edge weight to block can't be greater than the weight of bDst - if (edge->flEdgeWeightMax > bDstWeight) + if (edge->edgeWeightMax() > bDstWeight) { assignOK &= edge->setEdgeWeightMaxChecked(bDstWeight, slop, &usedSlop); } @@ -13532,31 +13546,31 @@ void Compiler::fgComputeEdgeWeights() { otherEdge = fgGetPredForBlock(bSrc->bbNext, bSrc); } - noway_assert(edge->flEdgeWeightMin <= edge->flEdgeWeightMax); - noway_assert(otherEdge->flEdgeWeightMin <= otherEdge->flEdgeWeightMax); + noway_assert(edge->edgeWeightMin() <= edge->edgeWeightMax()); + noway_assert(otherEdge->edgeWeightMin() <= otherEdge->edgeWeightMax()); // Adjust edge->flEdgeWeightMin up or adjust otherEdge->flEdgeWeightMax down - diff = ((int)bSrc->bbWeight) - ((int)edge->flEdgeWeightMin + (int)otherEdge->flEdgeWeightMax); + diff = ((int)bSrc->bbWeight) - ((int)edge->edgeWeightMin() + (int)otherEdge->edgeWeightMax()); if (diff > 0) { - assignOK &= edge->setEdgeWeightMinChecked(edge->flEdgeWeightMin + diff, slop, &usedSlop); + assignOK &= edge->setEdgeWeightMinChecked(edge->edgeWeightMin() + diff, slop, &usedSlop); } else if (diff < 0) { assignOK &= - otherEdge->setEdgeWeightMaxChecked(otherEdge->flEdgeWeightMax + diff, slop, &usedSlop); + otherEdge->setEdgeWeightMaxChecked(otherEdge->edgeWeightMax() + diff, slop, &usedSlop); } // Adjust otherEdge->flEdgeWeightMin up or adjust edge->flEdgeWeightMax down - diff = ((int)bSrc->bbWeight) - ((int)otherEdge->flEdgeWeightMin + (int)edge->flEdgeWeightMax); + diff = ((int)bSrc->bbWeight) - ((int)otherEdge->edgeWeightMin() + (int)edge->edgeWeightMax()); if (diff > 0) { assignOK &= - otherEdge->setEdgeWeightMinChecked(otherEdge->flEdgeWeightMin + diff, slop, &usedSlop); + otherEdge->setEdgeWeightMinChecked(otherEdge->edgeWeightMin() + diff, slop, &usedSlop); } else if (diff < 0) { - assignOK &= edge->setEdgeWeightMaxChecked(edge->flEdgeWeightMax + diff, slop, &usedSlop); + assignOK &= edge->setEdgeWeightMaxChecked(edge->edgeWeightMax() + diff, slop, &usedSlop); } if (!assignOK) @@ -13568,11 +13582,11 @@ void Compiler::fgComputeEdgeWeights() } #ifdef DEBUG // Now edge->flEdgeWeightMin and otherEdge->flEdgeWeightMax) should add up to bSrc->bbWeight - diff = ((int)bSrc->bbWeight) - ((int)edge->flEdgeWeightMin + (int)otherEdge->flEdgeWeightMax); + diff = ((int)bSrc->bbWeight) - ((int)edge->edgeWeightMin() + (int)otherEdge->edgeWeightMax()); noway_assert((-((int)slop) <= diff) && (diff <= ((int)slop))); // Now otherEdge->flEdgeWeightMin and edge->flEdgeWeightMax) should add up to bSrc->bbWeight - diff = ((int)bSrc->bbWeight) - ((int)otherEdge->flEdgeWeightMin + (int)edge->flEdgeWeightMax); + diff = ((int)bSrc->bbWeight) - ((int)otherEdge->edgeWeightMin() + (int)edge->edgeWeightMax()); noway_assert((-((int)slop) <= diff) && (diff <= ((int)slop))); #endif // DEBUG } @@ -13608,8 +13622,8 @@ void Compiler::fgComputeEdgeWeights() // We are processing the control flow edge (bSrc -> bDst) bSrc = edge->flBlock; - maxEdgeWeightSum += edge->flEdgeWeightMax; - minEdgeWeightSum += edge->flEdgeWeightMin; + maxEdgeWeightSum += edge->edgeWeightMax(); + minEdgeWeightSum += edge->edgeWeightMin(); } // maxEdgeWeightSum is the sum of all flEdgeWeightMax values into bDst @@ -13625,20 +13639,20 @@ void Compiler::fgComputeEdgeWeights() // otherMaxEdgesWeightSum is the sum of all of the other edges flEdgeWeightMax values // This can be used to compute a lower bound for our minimum edge weight - noway_assert(maxEdgeWeightSum >= edge->flEdgeWeightMax); - UINT64 otherMaxEdgesWeightSum = maxEdgeWeightSum - edge->flEdgeWeightMax; + noway_assert(maxEdgeWeightSum >= edge->edgeWeightMax()); + UINT64 otherMaxEdgesWeightSum = maxEdgeWeightSum - edge->edgeWeightMax(); // otherMinEdgesWeightSum is the sum of all of the other edges flEdgeWeightMin values // This can be used to compute an upper bound for our maximum edge weight - noway_assert(minEdgeWeightSum >= edge->flEdgeWeightMin); - UINT64 otherMinEdgesWeightSum = minEdgeWeightSum - edge->flEdgeWeightMin; + noway_assert(minEdgeWeightSum >= edge->edgeWeightMin()); + UINT64 otherMinEdgesWeightSum = minEdgeWeightSum - edge->edgeWeightMin(); if (bDstWeight >= otherMaxEdgesWeightSum) { // minWeightCalc is our minWeight when every other path to bDst takes it's flEdgeWeightMax value BasicBlock::weight_t minWeightCalc = (BasicBlock::weight_t)(bDstWeight - otherMaxEdgesWeightSum); - if (minWeightCalc > edge->flEdgeWeightMin) + if (minWeightCalc > edge->edgeWeightMin()) { assignOK &= edge->setEdgeWeightMinChecked(minWeightCalc, slop, &usedSlop); } @@ -13649,7 +13663,7 @@ void Compiler::fgComputeEdgeWeights() // maxWeightCalc is our maxWeight when every other path to bDst takes it's flEdgeWeightMin value BasicBlock::weight_t maxWeightCalc = (BasicBlock::weight_t)(bDstWeight - otherMinEdgesWeightSum); - if (maxWeightCalc < edge->flEdgeWeightMax) + if (maxWeightCalc < edge->edgeWeightMax()) { assignOK &= edge->setEdgeWeightMaxChecked(maxWeightCalc, slop, &usedSlop); } @@ -13664,7 +13678,7 @@ void Compiler::fgComputeEdgeWeights() } // When flEdgeWeightMin equals flEdgeWeightMax we have a "good" edge weight - if (edge->flEdgeWeightMin == edge->flEdgeWeightMax) + if (edge->edgeWeightMin() == edge->edgeWeightMax()) { // Count how many "good" edge weights we have // Each time through we should have more "good" weights @@ -13734,7 +13748,7 @@ EARLY_EXIT:; bSrc = edge->flBlock; // This is the control flow edge (bSrc -> bDst) - if (edge->flEdgeWeightMin != edge->flEdgeWeightMax) + if (edge->edgeWeightMin() != edge->edgeWeightMax()) { fgRangeUsedInEdgeWeights = true; break; @@ -13835,12 +13849,12 @@ bool Compiler::fgOptimizeBranchToEmptyUnconditional(BasicBlock* block, BasicBloc BasicBlock::weight_t edgeWeight; - if (edge1->flEdgeWeightMin != edge1->flEdgeWeightMax) + if (edge1->edgeWeightMin() != edge1->edgeWeightMax()) { // // We only have an estimate for the edge weight // - edgeWeight = (edge1->flEdgeWeightMin + edge1->flEdgeWeightMax) / 2; + edgeWeight = (edge1->edgeWeightMin() + edge1->edgeWeightMax()) / 2; // // Clear the profile weight flag // @@ -13851,7 +13865,7 @@ bool Compiler::fgOptimizeBranchToEmptyUnconditional(BasicBlock* block, BasicBloc // // We only have the exact edge weight // - edgeWeight = edge1->flEdgeWeightMin; + edgeWeight = edge1->edgeWeightMin(); } // @@ -13874,23 +13888,27 @@ bool Compiler::fgOptimizeBranchToEmptyUnconditional(BasicBlock* block, BasicBloc // // Update the edge2 min/max weights // - if (edge2->flEdgeWeightMin > edge1->flEdgeWeightMin) + BasicBlock::weight_t newEdge2Min; + BasicBlock::weight_t newEdge2Max; + + if (edge2->edgeWeightMin() > edge1->edgeWeightMin()) { - edge2->flEdgeWeightMin -= edge1->flEdgeWeightMin; + newEdge2Min = edge2->edgeWeightMin() - edge1->edgeWeightMin(); } else { - edge2->flEdgeWeightMin = BB_ZERO_WEIGHT; + newEdge2Min = BB_ZERO_WEIGHT; } - if (edge2->flEdgeWeightMax > edge1->flEdgeWeightMin) + if (edge2->edgeWeightMax() > edge1->edgeWeightMin()) { - edge2->flEdgeWeightMax -= edge1->flEdgeWeightMin; + newEdge2Max = edge2->edgeWeightMax() - edge1->edgeWeightMin(); } else { - edge2->flEdgeWeightMax = BB_ZERO_WEIGHT; + newEdge2Max = BB_ZERO_WEIGHT; } + edge2->setEdgeWeights(newEdge2Min, newEdge2Max); } } @@ -14195,7 +14213,7 @@ bool Compiler::fgOptimizeSwitchBranches(BasicBlock* block) if (fgHaveValidEdgeWeights) { flowList* edge = fgGetPredForBlock(bDest, block); - BasicBlock::weight_t branchThroughWeight = edge->flEdgeWeightMin; + BasicBlock::weight_t branchThroughWeight = edge->edgeWeightMin(); if (bDest->bbWeight > branchThroughWeight) { @@ -15101,7 +15119,7 @@ bool Compiler::fgOptimizeSwitchJumps() { BasicBlock* bDst = *jumpTab; flowList* edgeToDst = fgGetPredForBlock(bDst, bSrc); - double outRatio = (double) edgeToDst->flEdgeWeightMin / (double) bSrc->bbWeight; + double outRatio = (double) edgeToDst->edgeWeightMin() / (double) bSrc->bbWeight; if (outRatio >= 0.60) { @@ -15271,7 +15289,7 @@ void Compiler::fgReorderBlocks() { if (edge != edgeFromPrev) { - if (edge->flEdgeWeightMax >= edgeFromPrev->flEdgeWeightMin) + if (edge->edgeWeightMax() >= edgeFromPrev->edgeWeightMin()) { moveDestUp = false; break; @@ -15368,9 +15386,9 @@ void Compiler::fgReorderBlocks() // A takenRation of 0.90 means taken 90% of the time, not taken 10% of the time // double takenCount = - ((double)edgeToDest->flEdgeWeightMin + (double)edgeToDest->flEdgeWeightMax) / 2.0; + ((double)edgeToDest->edgeWeightMin() + (double)edgeToDest->edgeWeightMax()) / 2.0; double notTakenCount = - ((double)edgeToBlock->flEdgeWeightMin + (double)edgeToBlock->flEdgeWeightMax) / 2.0; + ((double)edgeToBlock->edgeWeightMin() + (double)edgeToBlock->edgeWeightMax()) / 2.0; double totalCount = takenCount + notTakenCount; double takenRatio = takenCount / totalCount; @@ -15382,7 +15400,7 @@ void Compiler::fgReorderBlocks() else { // set profHotWeight - profHotWeight = (edgeToBlock->flEdgeWeightMin + edgeToBlock->flEdgeWeightMax) / 2 - 1; + profHotWeight = (edgeToBlock->edgeWeightMin() + edgeToBlock->edgeWeightMax()) / 2 - 1; } } else @@ -17423,7 +17441,7 @@ bool Compiler::fgIsBetterFallThrough(BasicBlock* bCur, BasicBlock* bAlt) noway_assert(edgeFromCur != nullptr); noway_assert(edgeFromAlt != nullptr); - result = (edgeFromAlt->flEdgeWeightMin > edgeFromCur->flEdgeWeightMax); + result = (edgeFromAlt->edgeWeightMin() > edgeFromCur->edgeWeightMax()); } else { @@ -19947,16 +19965,16 @@ bool Compiler::fgDumpFlowGraph(Phases phase) } if (validWeights) { - unsigned edgeWeight = (edge->flEdgeWeightMin + edge->flEdgeWeightMax) / 2; + unsigned edgeWeight = (edge->edgeWeightMin() + edge->edgeWeightMax()) / 2; fprintf(fgxFile, "\n weight="); fprintfDouble(fgxFile, ((double)edgeWeight) / weightDivisor); - if (edge->flEdgeWeightMin != edge->flEdgeWeightMax) + if (edge->edgeWeightMin() != edge->edgeWeightMax()) { fprintf(fgxFile, "\n minWeight="); - fprintfDouble(fgxFile, ((double)edge->flEdgeWeightMin) / weightDivisor); + fprintfDouble(fgxFile, ((double)edge->edgeWeightMin()) / weightDivisor); fprintf(fgxFile, "\n maxWeight="); - fprintfDouble(fgxFile, ((double)edge->flEdgeWeightMax) / weightDivisor); + fprintfDouble(fgxFile, ((double)edge->edgeWeightMax()) / weightDivisor); } if (edgeWeight > 0) diff --git a/src/coreclr/src/jit/morph.cpp b/src/coreclr/src/jit/morph.cpp index fbeae00..500606a 100644 --- a/src/coreclr/src/jit/morph.cpp +++ b/src/coreclr/src/jit/morph.cpp @@ -14984,8 +14984,8 @@ bool Compiler::fgFoldConditional(BasicBlock* block) if (block->hasProfileWeight()) { // The edge weights for (block -> bTaken) are 100% of block's weight - edgeTaken->flEdgeWeightMin = block->bbWeight; - edgeTaken->flEdgeWeightMax = block->bbWeight; + + edgeTaken->setEdgeWeights(block->bbWeight, block->bbWeight); if (!bTaken->hasProfileWeight()) { @@ -15002,8 +15002,7 @@ bool Compiler::fgFoldConditional(BasicBlock* block) if (bTaken->countOfInEdges() == 1) { // There is only one in edge to bTaken - edgeTaken->flEdgeWeightMin = bTaken->bbWeight; - edgeTaken->flEdgeWeightMax = bTaken->bbWeight; + edgeTaken->setEdgeWeights(bTaken->bbWeight, bTaken->bbWeight); // Update the weight of block block->inheritWeight(bTaken); @@ -15013,22 +15012,34 @@ bool Compiler::fgFoldConditional(BasicBlock* block) if (bUpdated != nullptr) { + BasicBlock::weight_t newMinWeight; + BasicBlock::weight_t newMaxWeight; + flowList* edge; // Now fix the weights of the edges out of 'bUpdated' switch (bUpdated->bbJumpKind) { case BBJ_NONE: - edge = fgGetPredForBlock(bUpdated->bbNext, bUpdated); - edge->flEdgeWeightMax = bUpdated->bbWeight; + edge = fgGetPredForBlock(bUpdated->bbNext, bUpdated); + newMaxWeight = bUpdated->bbWeight; + newMinWeight = min(edge->edgeWeightMin(), newMaxWeight); + edge->setEdgeWeights(newMinWeight, newMaxWeight); break; + case BBJ_COND: - edge = fgGetPredForBlock(bUpdated->bbNext, bUpdated); - edge->flEdgeWeightMax = bUpdated->bbWeight; + edge = fgGetPredForBlock(bUpdated->bbNext, bUpdated); + newMaxWeight = bUpdated->bbWeight; + newMinWeight = min(edge->edgeWeightMin(), newMaxWeight); + edge->setEdgeWeights(newMinWeight, newMaxWeight); __fallthrough; + case BBJ_ALWAYS: - edge = fgGetPredForBlock(bUpdated->bbJumpDest, bUpdated); - edge->flEdgeWeightMax = bUpdated->bbWeight; + edge = fgGetPredForBlock(bUpdated->bbJumpDest, bUpdated); + newMaxWeight = bUpdated->bbWeight; + newMinWeight = min(edge->edgeWeightMin(), newMaxWeight); + edge->setEdgeWeights(newMinWeight, newMaxWeight); break; + default: // We don't handle BBJ_SWITCH break; diff --git a/src/coreclr/src/jit/optimizer.cpp b/src/coreclr/src/jit/optimizer.cpp index c513177..fc29d32 100644 --- a/src/coreclr/src/jit/optimizer.cpp +++ b/src/coreclr/src/jit/optimizer.cpp @@ -4289,18 +4289,14 @@ void Compiler::fgOptWhileLoop(BasicBlock* block) { bTest->bbFlags |= BBF_RUN_RARELY; // All out edge weights are set to zero - edgeToNext->flEdgeWeightMin = BB_ZERO_WEIGHT; - edgeToNext->flEdgeWeightMax = BB_ZERO_WEIGHT; - edgeToJump->flEdgeWeightMin = BB_ZERO_WEIGHT; - edgeToJump->flEdgeWeightMax = BB_ZERO_WEIGHT; + edgeToNext->setEdgeWeights(BB_ZERO_WEIGHT, BB_ZERO_WEIGHT); + edgeToJump->setEdgeWeights(BB_ZERO_WEIGHT, BB_ZERO_WEIGHT); } else { // Update the our edge weights - edgeToNext->flEdgeWeightMin = BB_ZERO_WEIGHT; - edgeToNext->flEdgeWeightMax = min(edgeToNext->flEdgeWeightMax, newWeightTest); - edgeToJump->flEdgeWeightMin = BB_ZERO_WEIGHT; - edgeToJump->flEdgeWeightMax = min(edgeToJump->flEdgeWeightMax, newWeightTest); + edgeToNext->setEdgeWeights(BB_ZERO_WEIGHT, min(edgeToNext->edgeWeightMax(), newWeightTest)); + edgeToJump->setEdgeWeights(BB_ZERO_WEIGHT, min(edgeToJump->edgeWeightMax(), newWeightTest)); } } } @@ -7399,9 +7395,9 @@ void Compiler::fgCreateLoopPreHeader(unsigned lnum) noway_assert(edgeToJump != nullptr); loopEnteredCount = - ((double)edgeToNext->flEdgeWeightMin + (double)edgeToNext->flEdgeWeightMax) / 2.0; + ((double)edgeToNext->edgeWeightMin() + (double)edgeToNext->edgeWeightMax()) / 2.0; loopSkippedCount = - ((double)edgeToJump->flEdgeWeightMin + (double)edgeToJump->flEdgeWeightMax) / 2.0; + ((double)edgeToJump->edgeWeightMin() + (double)edgeToJump->edgeWeightMax()) / 2.0; } else { @@ -9089,17 +9085,15 @@ void Compiler::optOptimizeBools() noway_assert(edge1 != nullptr); noway_assert(edge2 != nullptr); - BasicBlock::weight_t edgeSumMin = edge1->flEdgeWeightMin + edge2->flEdgeWeightMin; - BasicBlock::weight_t edgeSumMax = edge1->flEdgeWeightMax + edge2->flEdgeWeightMax; - if ((edgeSumMax >= edge1->flEdgeWeightMax) && (edgeSumMax >= edge2->flEdgeWeightMax)) + BasicBlock::weight_t edgeSumMin = edge1->edgeWeightMin() + edge2->edgeWeightMin(); + BasicBlock::weight_t edgeSumMax = edge1->edgeWeightMax() + edge2->edgeWeightMax(); + if ((edgeSumMax >= edge1->edgeWeightMax()) && (edgeSumMax >= edge2->edgeWeightMax())) { - edge1->flEdgeWeightMin = edgeSumMin; - edge1->flEdgeWeightMax = edgeSumMax; + edge1->setEdgeWeights(edgeSumMin, edgeSumMax); } else { - edge1->flEdgeWeightMin = BB_ZERO_WEIGHT; - edge1->flEdgeWeightMax = BB_MAX_WEIGHT; + edge1->setEdgeWeights(BB_ZERO_WEIGHT, BB_MAX_WEIGHT); } /* Get rid of the second block (which is a BBJ_COND) */ -- 2.7.4