Beispiel #1
0
TransCFG::TransCFG(FuncId funcId,
                   const ProfData* profData,
                   const SrcDB& srcDB,
                   const TcaTransIDMap& jmpToTransID) {
  assertx(profData);

  // add nodes
  for (auto tid : profData->funcProfTransIDs(funcId)) {
    assertx(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 weight = profData->absTransCounter(tid);
      addNode(tid, weight);
    }
  }

  // add arcs
  for (TransID dstId : nodes()) {
    SrcKey dstSK = profData->transSrcKey(dstId);
    RegionDesc::BlockPtr dstBlock = profData->transRegion(dstId)->entry();
    FTRACE(5, "TransCFG: adding incoming arcs in dstId = {}\n", dstId);
    TransIDSet predIDs = findPredTrans(dstId, profData, srcDB, jmpToTransID);
    for (auto predId : predIDs) {
      if (hasNode(predId)) {
        auto predPostConds =
          profData->transRegion(predId)->blocks().back()->postConds();
        SrcKey predSK = profData->transSrcKey(predId);
        if (preCondsAreSatisfied(dstBlock, predPostConds) &&
            predSK.resumed() == dstSK.resumed()) {
          FTRACE(5, "TransCFG: adding arc {} -> {} ({} -> {})\n",
                 predId, dstId, showShort(predSK), showShort(dstSK));
          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 for 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);
      }
    }
  }
}
Beispiel #2
0
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);
      }
    }
  }
}
Beispiel #3
0
bool TransCFG::hasArc(TransID srcId, TransID dstId) const {
  assertx(hasNode(srcId));
  assertx(hasNode(dstId));
  for (auto arc : outArcs(srcId)) {
    if (arc->dst() == dstId) return true;
  }
  return false;
}
Beispiel #4
0
TransCFG::ArcPtrVec TransCFG::arcs() const {
  ArcPtrVec arcs;
  for (auto node : nodes()) {
    const ArcPtrVec& nodeOutArcs = outArcs(node);
    arcs.insert(arcs.end(), nodeOutArcs.begin(), nodeOutArcs.end());
  }
  return arcs;
}
Beispiel #5
0
void TransCFG::print(std::string fileName, FuncId funcId,
                     const ProfData* profData,
                     const TransIDSet* selected) const {
  FILE* file = fopen(fileName.c_str(), "wt");
  if (!file) return;

  fprintf(file, "digraph CFG {\n");

  fprintf(file, "# function: %s\n",
          Func::fromFuncId(funcId)->fullName()->data());

  // find max node weight
  int64_t maxWeight = 1; // 1 to avoid div by 0
  for (auto tid : nodes()) {
    auto w = weight(tid);
    if (w > maxWeight) maxWeight = w;
  }

  // print nodes
  for (auto tid : nodes()) {
    int64_t w = weight(tid);
    uint32_t coldness  = 255 - (255 * w / maxWeight);
    Offset bcStart = profData->transStartBcOff(tid);
    Offset bcStop  = profData->transStopBcOff(tid);
    const char* shape = selected && selected->count(tid) ? "oval"
                                                         : "box";
    fprintf(file,
            "t%u [shape=%s,label=\"T: %u\\np: %" PRId64 "\\n"
            "bc: [%" PRIu32 "-%" PRIu32 ")\","
            "style=filled,fillcolor=\"#ff%02x%02x\"];\n", tid, shape, tid, w,
            bcStart, bcStop, coldness, coldness);
  }

  // print arcs
  for (auto srcId : nodes()) {
    for (auto arc : outArcs(srcId)) {
      int64_t w = arc->weight();
      fprintf(file, "t%u -> t%u [color=\"%s\",label=\"%" PRId64 "\"] ;\n",
              srcId,
              arc->dst(),
              arc->guessed() ? "red" : "green4",
              w);
    }
  }

  fprintf(file, "}\n");
  fclose(file);
}
Beispiel #6
0
void TransCFG::print(std::ostream& out, FuncId funcId,
                     const ProfData* profData) const {
  out << "digraph TransCFG { // function: "
      << Func::fromFuncId(funcId)->fullName()->data() << "\n";

  // find max node weight
  int64_t maxWeight = 1; // 1 to avoid div by 0
  for (auto tid : nodes()) {
    auto w = weight(tid);
    if (w > maxWeight) maxWeight = w;
  }

  // print nodes
  for (auto const tid : nodes()) {
    auto const w = weight(tid);
    uint32_t coldness  = 255 - (255 * w / maxWeight);
    auto const rec = profData->transRec(tid);
    auto const bcStart = rec->startBcOff();
    auto const bcStop  = rec->lastBcOff();
    auto const shape = "box";
    out << folly::sformat(
      "t{} [shape={},label=\"T: {}\\np: {}\\n"
      "bc: [{}-{})\",style=filled,fillcolor=\"#ff{:02x}{:02x}\"];\n",
      tid, shape, tid, w, bcStart, bcStop, coldness, coldness);
  }

  // print arcs
  for (auto srcId : nodes()) {
    for (auto arc : outArcs(srcId)) {
      auto const w = arc->weight();
      out << folly::sformat("t{} -> t{} [color=\"{}\",label=\"{}\"] ;\n",
                            srcId,
                            arc->dst(),
                            arc->guessed() ? "red" : "green4",
                            w);
    }
  }

  out << "}\n";
}
Beispiel #7
0
TransCFG::TransCFG(FuncId funcId,
                   const ProfData* profData,
                   bool inlining /* = false */) {
  assertx(profData);

  // add nodes
  for (auto const tid : profData->funcProfTransIDs(funcId)) {
    auto const rec = profData->transRec(tid);
    assertx(rec->region() != nullptr);
    // This will skip DV Funclets if they were already
    // retranslated w/ the prologues:
    if (inlining || !profData->optimized(rec->srcKey())) {
      int64_t weight = profData->transCounter(tid);
      addNode(tid, weight);
    }
  }

  // add arcs
  for (auto const dstId : nodes()) {
    auto const rec = profData->transRec(dstId);
    auto const dstSK = rec->srcKey();
    auto const dstBlock = rec->region()->entry();
    FTRACE(5, "TransCFG: adding incoming arcs in dstId = {}\n", dstId);
    TransIDSet predIDs = findPredTrans(dstId, profData);
    for (auto predId : predIDs) {
      if (hasNode(predId)) {
        auto const predRec = profData->transRec(predId);
        auto const predBlock = predRec->region()->blocks().back();
        auto const& postConds = predBlock->postConds();
        auto predPostConds = postConds.changed;
        predPostConds.insert(predPostConds.end(), postConds.refined.begin(),
                             postConds.refined.end());
        auto const predSK = predRec->srcKey();
        if (preCondsAreSatisfied(dstBlock, predPostConds) &&
            predSK.resumed() == dstSK.resumed()) {
          FTRACE(5, "TransCFG: adding arc {} -> {} ({} -> {})\n",
                 predId, dstId, showShort(predSK), showShort(dstSK));
          addArc(predId, dstId, TransCFG::Arc::kUnknownWeight);
        }
      }
    }
  }

  // infer arc weights
  bool changed;
  do {
    changed = false;
    for (auto const tid : nodes()) {
      auto const nodeWeight = weight(tid);
      if (inferredArcWeight(inArcs(tid),  nodeWeight)) changed = true;
      if (inferredArcWeight(outArcs(tid), nodeWeight)) changed = true;
    }
  } while (changed);

  // guess weight for non-inferred arcs
  for (auto const tid : nodes()) {
    for (auto arc : outArcs(tid)) {
      if (arc->weight() == Arc::kUnknownWeight) {
        arc->setGuessed();
        auto arcWgt = std::min(weight(arc->src()), weight(arc->dst())) / 2;
        arc->setWeight(arcWgt);
      }
    }
  }
}