Pass known Func*s through in the region translator
Pretty straightforward, since the hard part of figuring out when the Func* is known is still handled in Translator::analyze.
Esse commit está contido em:
@@ -78,6 +78,12 @@ void RegionDesc::Block::addReffinessPred(SrcKey sk, const ReffinessPred& pred) {
|
||||
checkInvariants();
|
||||
}
|
||||
|
||||
void RegionDesc::Block::setKnownFunc(SrcKey sk, const Func* func) {
|
||||
assert(m_knownFuncs.find(sk) == m_knownFuncs.end());
|
||||
m_knownFuncs.insert(std::make_pair(sk, func));
|
||||
checkInvariants();
|
||||
}
|
||||
|
||||
/*
|
||||
* Check invariants on a RegionDesc::Block.
|
||||
*
|
||||
@@ -85,8 +91,8 @@ void RegionDesc::Block::addReffinessPred(SrcKey sk, const ReffinessPred& pred) {
|
||||
* non-fallthrough instructions mid-block and no control flow (not
|
||||
* counting calls as control flow).
|
||||
*
|
||||
* 2. Each SrcKey in m_typePreds, m_byRefs, and m_refPreds is within the bounds
|
||||
* of the block.
|
||||
* 2. Each SrcKey in m_typePreds, m_byRefs, m_refPreds, and m_knownFuncs is
|
||||
* within the bounds of the block.
|
||||
*
|
||||
* 3. Each local id referred to in the type prediction list is valid.
|
||||
*
|
||||
@@ -146,6 +152,9 @@ void RegionDesc::Block::checkInvariants() const {
|
||||
for (auto& refPred : m_refPreds) {
|
||||
rangeCheck("reffiness prediction", refPred.first);
|
||||
}
|
||||
for (auto& func : m_knownFuncs) {
|
||||
rangeCheck("known Func*", func.first);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@@ -160,6 +169,7 @@ RegionDescPtr createRegion(const Transl::Tracelet& tlet) {
|
||||
assert(sk == tlet.m_instrStream.first->source);
|
||||
auto unit = tlet.m_instrStream.first->unit();
|
||||
|
||||
const Func* topFunc = nullptr;
|
||||
Block* curBlock;
|
||||
auto newBlock = [&] {
|
||||
region->blocks.push_back(
|
||||
@@ -173,6 +183,11 @@ RegionDescPtr createRegion(const Transl::Tracelet& tlet) {
|
||||
assert(ni->unit() == unit);
|
||||
|
||||
curBlock->addInstruction();
|
||||
|
||||
if (curBlock->length() == 1 || ni->funcd != topFunc) {
|
||||
topFunc = ni->funcd;
|
||||
curBlock->setKnownFunc(sk, topFunc);
|
||||
}
|
||||
if (!ni->noOp && isFPassStar(ni->op())) {
|
||||
curBlock->setParamByRef(
|
||||
sk, ni->preppedByRef ? RegionDesc::ParamByRef::Yes
|
||||
@@ -349,8 +364,11 @@ std::string show(const RegionDesc::Block& b) {
|
||||
auto typePreds = makeMapWalker(b.typePreds());
|
||||
auto byRefs = makeMapWalker(b.paramByRefs());
|
||||
auto refPreds = makeMapWalker(b.reffinessPreds());
|
||||
|
||||
auto knownFuncs= makeMapWalker(b.knownFuncs());
|
||||
auto skIter = b.start();
|
||||
|
||||
const Func* currentFunc = nullptr;
|
||||
|
||||
for (int i = 0; i < b.length(); ++i) {
|
||||
while (typePreds.hasNext(skIter)) {
|
||||
folly::toAppend(" predict: ", show(typePreds.next()), "\n", &ret);
|
||||
@@ -359,15 +377,27 @@ std::string show(const RegionDesc::Block& b) {
|
||||
folly::toAppend(" predict reffiness: ", show(refPreds.next()), "\n",
|
||||
&ret);
|
||||
}
|
||||
|
||||
std::string knownFunc;
|
||||
if (knownFuncs.hasNext(skIter)) {
|
||||
currentFunc = knownFuncs.next();
|
||||
}
|
||||
if (currentFunc) {
|
||||
knownFunc = folly::format(" (top func: {})",
|
||||
currentFunc->fullName()->data()).str();
|
||||
}
|
||||
|
||||
std::string byRef;
|
||||
if (byRefs.hasNext(skIter)) {
|
||||
byRef = folly::format(" (passed {})", show(byRefs.next())).str();
|
||||
}
|
||||
|
||||
folly::toAppend(
|
||||
" ",
|
||||
skIter.offset(),
|
||||
" ",
|
||||
instrToString((Op*)b.unit()->at(skIter.offset()), b.unit()),
|
||||
knownFunc,
|
||||
byRef,
|
||||
"\n",
|
||||
&ret
|
||||
|
||||
@@ -140,6 +140,7 @@ class RegionDesc::Block {
|
||||
typedef flat_multimap<SrcKey, TypePred> TypePredMap;
|
||||
typedef flat_map<SrcKey, ParamByRef> ParamByRefMap;
|
||||
typedef flat_multimap<SrcKey, ReffinessPred> RefPredMap;
|
||||
typedef flat_map<SrcKey, const Func*> KnownFuncMap;
|
||||
|
||||
public:
|
||||
explicit Block(const Func* func, Offset start, int length)
|
||||
@@ -187,6 +188,12 @@ public:
|
||||
*/
|
||||
void addReffinessPred(SrcKey, const ReffinessPred&);
|
||||
|
||||
/*
|
||||
* Update the statically known Func*. It remains active until another is
|
||||
* specified, so pass nullptr to indicate that there is no longer a known
|
||||
* Func*.
|
||||
*/
|
||||
void setKnownFunc(SrcKey, const Func*);
|
||||
|
||||
/*
|
||||
* The following getters return references to the metadata maps holding the
|
||||
@@ -197,6 +204,7 @@ public:
|
||||
const TypePredMap& typePreds() const { return m_typePreds; }
|
||||
const ParamByRefMap& paramByRefs() const { return m_byRefs; }
|
||||
const RefPredMap& reffinessPreds() const { return m_refPreds; }
|
||||
const KnownFuncMap& knownFuncs() const { return m_knownFuncs; }
|
||||
|
||||
private:
|
||||
void checkInvariants() const;
|
||||
@@ -208,6 +216,7 @@ private:
|
||||
TypePredMap m_typePreds;
|
||||
ParamByRefMap m_byRefs;
|
||||
RefPredMap m_refPreds;
|
||||
KnownFuncMap m_knownFuncs;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -3785,9 +3785,11 @@ Translator::translateRegion(const RegionDesc& region,
|
||||
|
||||
for (auto const& block : region.blocks) {
|
||||
SrcKey sk = block->start();
|
||||
auto typePreds = makeMapWalker(block->typePreds());
|
||||
auto byRefs = makeMapWalker(block->paramByRefs());
|
||||
auto refPreds = makeMapWalker(block->reffinessPreds());
|
||||
const Func* topFunc = nullptr;
|
||||
auto typePreds = makeMapWalker(block->typePreds());
|
||||
auto byRefs = makeMapWalker(block->paramByRefs());
|
||||
auto refPreds = makeMapWalker(block->reffinessPreds());
|
||||
auto knownFuncs = makeMapWalker(block->knownFuncs());
|
||||
|
||||
for (unsigned i = 0; i < block->length(); ++i, sk.advance(block->unit())) {
|
||||
// Emit prediction guards. If this is the first instruction in the
|
||||
@@ -3811,6 +3813,11 @@ Translator::translateRegion(const RegionDesc& region,
|
||||
m_hhbcTrans->guardRefs(pred.arSpOffset, pred.mask, pred.vals);
|
||||
}
|
||||
|
||||
// Update the current funcd, if we have a new one.
|
||||
if (knownFuncs.hasNext(sk)) {
|
||||
topFunc = knownFuncs.next();
|
||||
}
|
||||
|
||||
// Create and initialize the instruction.
|
||||
NormalizedInstruction inst;
|
||||
inst.source = sk;
|
||||
@@ -3818,6 +3825,7 @@ Translator::translateRegion(const RegionDesc& region,
|
||||
inst.breaksTracelet =
|
||||
i == block->length() - 1 && block == region.blocks.back();
|
||||
inst.changesPC = opcodeChangesPC(inst.op());
|
||||
inst.funcd = topFunc;
|
||||
populateImmediates(inst);
|
||||
|
||||
// We can get a more precise output type for interpOne if we know all of
|
||||
@@ -3908,6 +3916,7 @@ Translator::translateRegion(const RegionDesc& region,
|
||||
assert(!typePreds.hasNext());
|
||||
assert(!byRefs.hasNext());
|
||||
assert(!refPreds.hasNext());
|
||||
assert(!knownFuncs.hasNext());
|
||||
}
|
||||
|
||||
traceEnd();
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário