TransID ProfData::addTransProfile(const RegionDescPtr& region, const PostConditions& pconds) { TransID transId = m_numTrans++; auto const lastBcOff = region->lastSrcKey().offset(); assertx(region); DEBUG_ONLY auto const nBlocks = region->blocks().size(); assertx(nBlocks == 1); region->renumberBlock(region->entry()->id(), transId); for (auto& b : region->blocks()) b->setProfTransID(transId); region->blocks().back()->setPostConds(pconds); auto const startSk = region->start(); m_transRecs.emplace_back(new ProfTransRec(lastBcOff, startSk, region)); // If the translation corresponds to a DV Funclet, then add an entry // into dvFuncletDB. auto const func = startSk.func(); auto const funcId = func->getFuncId(); auto const bcOffset = startSk.offset(); if (func->isDVEntry(bcOffset)) { auto const nParams = func->getDVEntryNumParams(bcOffset); // Normal DV funclets don't have type guards, and thus have a // single translation. However, some special functions written // in hhas (e.g. array_map) have complex DV funclets that get // retranslated for different types. For those functions, // m_dvFuncletDB keeps the TransID for their first translation. if (!m_dvFuncletDB.count(std::make_tuple(funcId, nParams))) { m_dvFuncletDB.emplace(std::make_tuple(funcId, nParams), transId); } } m_funcProfTrans[funcId].push_back(transId); return transId; }
ProfTransRec::ProfTransRec(Offset lastBcOff, SrcKey sk, RegionDescPtr region) : m_kind(TransKind::Profile) , m_lastBcOff(lastBcOff) , m_sk(sk) , m_region(region) { assertx(region != nullptr && !region->empty() && region->start() == sk); }
ProfTransRec::ProfTransRec(TransID id, TransKind kind, Offset lastBcOff, SrcKey sk, RegionDescPtr region) : m_id(id) , m_kind(kind) , m_lastBcOff(lastBcOff) , m_region(region) , m_sk(sk) { assertx(region == nullptr || (!region->empty() && region->start() == sk)); }
TransID ProfData::addTransProfile(const RegionDescPtr& region, const PostConditions& pconds) { TransID transId = m_numTrans++; Offset lastBcOff = findLastBcOffset(region); assert(region); DEBUG_ONLY size_t nBlocks = region->blocks().size(); assert(nBlocks == 1 || (nBlocks > 1 && region->entry()->inlinedCallee())); region->renumberBlock(region->entry()->id(), transId); region->blocks().back()->setPostConditions(pconds); auto const startSk = region->start(); m_transRecs.emplace_back(new ProfTransRec(transId, TransKind::Profile, lastBcOff, startSk, region)); // If the translation corresponds to a DV Funclet, then add an entry // into dvFuncletDB. const Func* func = startSk.func(); FuncId funcId = func->getFuncId(); Offset bcOffset = startSk.offset(); if (func->isDVEntry(bcOffset)) { int nParams = func->getDVEntryNumParams(bcOffset); // Normal DV funclets don't have type guards, and thus have a // single translation. However, some special functions written // in hhas (e.g. array_map) have complex DV funclets that get // retranslated for different types. For those functions, // m_dvFuncletDB keeps the TransID for their first translation. if (m_dvFuncletDB.get(funcId, nParams) == kInvalidTransID) { m_dvFuncletDB.add(funcId, nParams, transId); } } m_funcProfTrans[funcId].push_back(transId); return transId; }