static TransIDSet findPredTrans(TransID dstID, const ProfData* profData, const SrcDB& srcDB, const TcaTransIDMap& jmpToTransID) { SrcKey dstSK = profData->transSrcKey(dstID); const SrcRec* dstSR = srcDB.find(dstSK); assertx(dstSR); TransIDSet predSet; for (auto& inBr : dstSR->incomingBranches()) { TransID srcID = folly::get_default(jmpToTransID, inBr.toSmash(), kInvalidTransID); FTRACE(5, "findPredTrans: toSmash = {} srcID = {}\n", inBr.toSmash(), srcID); if (srcID != kInvalidTransID && profData->isKindProfile(srcID)) { auto srcSuccOffsets = profData->transLastSrcKey(srcID).succOffsets(); if (srcSuccOffsets.count(dstSK.offset())) { predSet.insert(srcID); } else { FTRACE(5, "findPredTrans: WARNING: incoming branch with impossible " "control flow between translations: {} -> {}" "(probably due to side exit)\n", srcID, dstID); } } } return predSet; }
TransCFG::TransCFG(FuncId funcId, const ProfData* profData, const SrcDB& srcDB, const TcaTransIDMap& jmpToTransID) { assert(profData); // add nodes for (auto tid : profData->funcProfTransIDs(funcId)) { assert(profData->transRegion(tid) != nullptr); // This will skip DV Funclets if they were already // retranslated w/ the prologues: if (!profData->optimized(profData->transSrcKey(tid))) { int64_t counter = profData->transCounter(tid); int64_t weight = RuntimeOption::EvalJitPGOThreshold - counter; addNode(tid, weight); } } // add arcs for (TransID dstId : nodes()) { SrcKey dstSK = profData->transSrcKey(dstId); RegionDesc::BlockPtr dstBlock = profData->transRegion(dstId)->blocks[0]; const SrcRec* dstSR = srcDB.find(dstSK); FTRACE(5, "TransCFG: adding incoming arcs in dstId = {}\n", dstId); TransIDSet predIDs = findPredTrans(dstSR, jmpToTransID); for (auto predId : predIDs) { if (hasNode(predId)) { auto predPostConds = profData->transRegion(predId)->blocks.back()->postConds(); if (preCondsAreSatisfied(dstBlock, predPostConds)) { FTRACE(5, "TransCFG: adding arc {} -> {}\n", predId, dstId); addArc(predId, dstId, TransCFG::Arc::kUnknownWeight); } } } } // infer arc weights bool changed; do { changed = false; for (TransID tid : nodes()) { int64_t nodeWeight = weight(tid); if (inferredArcWeight(inArcs(tid), nodeWeight)) changed = true; if (inferredArcWeight(outArcs(tid), nodeWeight)) changed = true; } } while (changed); // guess weight or non-inferred arcs for (TransID tid : nodes()) { for (auto arc : outArcs(tid)) { if (arc->weight() == Arc::kUnknownWeight) { arc->setGuessed(); int64_t arcWgt = std::min(weight(arc->src()), weight(arc->dst())) / 2; arc->setWeight(arcWgt); } } } }
TransCFG::TransCFG(FuncId funcId, const ProfData* profData, const SrcDB& srcDB, const TcaTransIDMap& jmpToTransID) { assert(profData); // add nodes for (TransID tid = 0; tid < profData->numTrans(); tid++) { if (profData->transKind(tid) == TransProfile && profData->transRegion(tid) != nullptr && profData->transFuncId(tid) == funcId) { int64_t counter = profData->transCounter(tid); int64_t weight = RuntimeOption::EvalJitPGOThreshold - counter; addNode(tid, weight); } } // add arcs for (TransID dstId : nodes()) { SrcKey dstSK = profData->transSrcKey(dstId); const SrcRec* dstSR = srcDB.find(dstSK); FTRACE(5, "TransCFG: adding incoming arcs in dstId = {}\n", dstId); TransIDSet predIDs = findPredTrans(dstSR, jmpToTransID); for (auto predId : predIDs) { if (hasNode(predId)) { FTRACE(5, "TransCFG: adding arc {} -> {}\n", predId, dstId); addArc(predId, dstId, TransCFG::Arc::kUnknownWeight); } } } // infer arc weights bool changed; do { changed = false; for (TransID tid : nodes()) { int64_t nodeWeight = weight(tid); if (inferredArcWeight(inArcs(tid), nodeWeight)) changed = true; if (inferredArcWeight(outArcs(tid), nodeWeight)) changed = true; } } while (changed); // guess weight or non-inferred arcs for (TransID tid : nodes()) { for (auto arc : outArcs(tid)) { if (arc->weight() == Arc::kUnknownWeight) { arc->setGuessed(); int64_t arcWgt = std::min(weight(arc->src()), weight(arc->dst())) / 2; arc->setWeight(arcWgt); } } } }