Exemplo n.º 1
0
SET
setXIntersect(SET A,SET B)
{
    SET set;
    void *e;

    if (! (A->cmp && B->cmp) )
	return NULL;		/* Both need a compare function */

    /* Create new set */
    if (! (set = setNew(A->cmp,A->ed,A->ord)))
	{ XLOG(set); return NULL; }

    /* Add elements of A only */
    for (e = setFirst(A); e; e = setNext(A))
	if (!setContains(B,e))
	    setAdd(set,e);

    /* Add elements of B only */
    for (e = setFirst(B); e; e = setNext(B))
	if (!setContains(A,e))
	    setAdd(set,e);

    return set;
}
Exemplo n.º 2
0
Arquivo: hp.cpp Projeto: kavon/SALSA
// Goes over the list of nodes that needs to be freed
// and frees them if no HP points at them.
void scan(HPLocal localData) {
	int i;
	//Stage 1: scan HP list and insert non-null values to plist
	Set plist = localData->plist;
	setReset(plist);
	HPRecord* curr = localData->HPRecHead;
	while (curr != NULL) {
		for (i = 0; i < localData->hpData->HP_COUNT; i++) {
			if (curr->hp[i] != NULL) {
				setAdd(plist, (long) (curr->hp[i]));
			}
		}
		curr = curr->next;
	}
	//Stage 2: search plist
	//uses two stacks instead of allocating a new one each time scan() is called
	SwapStacks(&localData->rlist, &localData->temp);
	stackReset(localData->rlist);
	ReclaimationData* recData = stackPop(localData->temp);
	while (recData != NULL) {
		if (setContains(plist, (long) recData->address)) {
			stackPush(localData->rlist, recData->address,
					recData->reclaimationFunc);
		} else {
				(*((ReclaimationFunc*)recData->reclaimationFunc))(recData->address);
		}
		recData = stackPop(localData->temp);
	}
	setReset(plist);
}
Exemplo n.º 3
0
int DecideNextNode(int currentNodeID){

    vertexNode* v = searchNode(currentNodeID);
    //Found the vertex node

    //Create a temp head edgeNode
    edgeNode* temp_head = v->head; 
    
    if(lastPostionSeen ==Left)
    {

        while(temp_head!=NULL)  //Traverse the edge nodes and check if the id matches
                                // and return true
        {
            if(temp_head->turn == lastPostionSeen)
                {
                    lastPostionSeen = Straight;
                    return temp_head->id;         
                }
            temp_head = temp_head->next;
        }
    }
    else if(lastPostionSeen == Right)
    {

        while(temp_head!=NULL)  //Traverse the edge nodes and check if the id matches
                                // and return true
        {
            if(temp_head->turn == lastPostionSeen)
                {
                    lastPostionSeen = Straight;
                    return temp_head->id;         
                }
            temp_head = temp_head->next;
        }
    }

    else
    {

        while(temp_head!=NULL)  //Traverse the edge nodes and check if the id matches
                                // and return true
        {
        /*    if(markedNodes.find(temp_head->id) !=markedNodes.end())
                return temp_head->id;
        */
           if(setContains(markedNodes,temp_head->id) == 0)
            {
                return temp_head->id;
            }
        
            temp_head = temp_head->next;
        }

    }  

    return 0;  
}
Exemplo n.º 4
0
static bool allArcsCovered(const TransCFG::ArcPtrVec& arcs,
                           const TransCFG::ArcPtrSet& coveredArcs) {
  for (auto arc : arcs) {
    if (!setContains(coveredArcs, arc)) {
      return false;
    }
  }
  return true;
}
Exemplo n.º 5
0
void SearchOptions::setToDefault()
{
  setContains();
  setMatchAsString();
  setCaseSensitive(false);
  setWrap(true);
  setBackwards(false);
  setAllColumns(false);
  m_isReplace = false;
  setIsReplaceAll(false);
}
Exemplo n.º 6
0
/**
 * Add to sets coveredNodes and coveredArcs the cfg arcs that are now
 * covered given the new region containing the translations in
 * selectedVec.
 */
static void markCovered(const TransCFG& cfg, const TransIDVec selectedVec,
                        const TransIDSet heads, TransIDSet& coveredNodes,
                        TransCFG::ArcPtrSet& coveredArcs) {
  assert(selectedVec.size() > 0);
  TransID newHead = selectedVec[0];

  // Mark all region's nodes as covered.
  coveredNodes.insert(selectedVec.begin(), selectedVec.end());

  // Mark all incoming arcs into newHead from covered nodes as covered.
  for (auto arc : cfg.inArcs(newHead)) {
    TransID src = arc->src();
    if (setContains(coveredNodes, src)) {
      coveredArcs.insert(arc);
    }
  }

  // Mark all arcs between consecutive region nodes as covered.
  for (size_t i = 0; i < selectedVec.size() - 1; i++) {
    TransID node = selectedVec[i];
    TransID next = selectedVec[i + 1];
    bool foundArc = false;
    for (auto arc : cfg.outArcs(node)) {
      if (arc->dst() == next) {
        coveredArcs.insert(arc);
        foundArc = true;
      }
    }
    always_assert(foundArc);
  }

  // Mark all outgoing arcs from the region to a head node as covered.
  for (auto node : selectedVec) {
    for (auto arc : cfg.outArcs(node)) {
      if (setContains(heads, arc->dst())) {
        coveredArcs.insert(arc);
      }
    }
  }
}
Exemplo n.º 7
0
void SearchOptions::deserializeSettings(const QString allOptions)
{
  setMatchEntireString();
  setMatchAsString();
  setCaseSensitive(false);
  setBackwards(false);
  setAllColumns(false);
  setWrap(false);
  setIsReplace(false);
  setIsReplaceAll(false);
  QStringList list = allOptions.split(",");
  for (int i=0; i<list.count(); ++i) {
    QString s = list.at(i);
    if (s.compare("MatchEntireString", Qt::CaseInsensitive) == 0) {
      setMatchEntireString();
    } else if (s.compare("Contains", Qt::CaseInsensitive) == 0) {
      setContains();
    } else if (s.compare("StartsWith", Qt::CaseInsensitive) == 0) {
      setStartsWith();
    } else if (s.compare("EndsWith", Qt::CaseInsensitive) == 0) {
      setEndsWith();
    } else if (s.compare("AsString", Qt::CaseInsensitive) == 0) {
      setMatchAsString();
    } else if (s.compare("RegExp", Qt::CaseInsensitive) == 0) {
      setRegularExpression();
    } else if (s.compare("Wildcard", Qt::CaseInsensitive) == 0) {
      setWildCard();
    } else if (s.compare("CaseSensitive", Qt::CaseInsensitive) == 0) {
      setCaseSensitive();
    } else if (s.compare("CaseInSensitive", Qt::CaseInsensitive) == 0) {
      setCaseSensitive(false);
    } else if (s.compare("Wrap", Qt::CaseInsensitive) == 0) {
      setWrap(true);
    } else if (s.compare("NoWrap", Qt::CaseInsensitive) == 0) {
      setWrap(false);
    } else if (s.compare("Backward", Qt::CaseInsensitive) == 0) {
      setBackwards(true);
    } else if (s.compare("Forward", Qt::CaseInsensitive) == 0) {
      setBackwards(false);
    } else if (s.compare("AllColumns", Qt::CaseInsensitive) == 0) {
      setAllColumns(true);
    } else if (s.compare("OneColumn", Qt::CaseInsensitive) == 0) {
      setAllColumns(false);
    } else if (s.compare("Replace", Qt::CaseInsensitive) == 0) {
      setIsReplace(true);
    } else if (s.compare("ReplaceAll", Qt::CaseInsensitive) == 0) {
      setIsReplaceAll(true);
    }
  }
}
Exemplo n.º 8
0
/*----------------------------------------------------------------------*
 * Add/Remove								*
 *----------------------------------------------------------------------*/
int
setAdd(SET set,void *data)
{
    /* An ordered set uses the avl tree routines. */
    if (SET_Ord(set))
	return avlInsert(set->telts,data,data);

    /* A non-ordered set uses the disjoint flag to check if it needs to 
     * exclude double elements */
    if (SET_IsSET(set) && setContains(set,data))
	return -1;

    /* Else, or if BAG, add the element to the queue */
    return - !qAdd(set->qelts,data);
}
Exemplo n.º 9
0
/** 
 * Adds the value to the Set; specifically inserts the value at current index and increments index.
 * @param S the set to add the value to
 * @param value the value to add
 * @return 1 if add was successful or the value was already in the Set; or 0 if there's no more room.
 */
uint8_t addToSet(set* S, uint16_t value)
{
    if ((setContains(S, value)) == 1)   // First see if this value is already in the list
    {
        return 1;                       // Stop now; value is already in the list so we don't need to insert it
    }
        
    if (setIsFull(S))                   // Check to see if there is room in the Set for a new entry
    {
        return 0;                       // No room at the inn
    }
    
    S->values[S->size] = value;             // Add the value to the Set
    S->size++;                              // And increment the setSize
    return 1;
}
Exemplo n.º 10
0
/** 
* Utility function only used when displaying the network topology.
* Recursively iterates through the network and displays the children of a node and then the children
* of those children, and then the children of those children, etc. using recursion.
* @param shortAddress the root at which to start getting the topology. Use 0000 for the Coordinator.
* @note does not retrieve children for the same node twice. Uses a Set to keep track of which nodes
* have been searched. This is done because occasionally two nodes will list the same child.
* @see http://en.wikipedia.org/wiki/Recursion_%28computer_science%29
* @return the number of children
* @todo handle case where starting index != 0. We will have to keep track of which nodes had
* additional children, and then call zdoRequestIeeeAddress() for the next group.
*/
static uint8_t displayChildren(uint16_t shortAddress)
{
    printf("Device %04X has ", shortAddress);
    
    moduleResult_t result = zdoRequestIeeeAddress(shortAddress, INCLUDE_ASSOCIATED_DEVICES, 0);
#define MAX_CHILDREN 5  // Max of 20 from Z-Stack. Of these 20, 7 can be routers, the rest end devices. 
                        // We reduce to fit in RAM on the LaunchPad since this is called recursively
    uint8_t childCount = 0;
    uint16_t children[MAX_CHILDREN];
    
    if (result == MODULE_SUCCESS)
    {
        if (!(addToSet(&searchedSet, shortAddress)))
        {
            printf("[addToSet failed for 0x%04X\r\n]", shortAddress);
        }
        
        childCount = zmBuf[SRSP_PAYLOAD_START + ZDO_IEEE_ADDR_RSP_NUMBER_OF_ASSOCIATED_DEVICES_FIELD];
        
        if (childCount > 0)
        {
            printf("%u children, starting with #%u:", childCount, zmBuf[SRSP_PAYLOAD_START + ZDO_IEEE_ADDR_RSP_START_INDEX_FIELD]);
            int i=0;
            int j;
            for (j = 0; j < (childCount*2) - 1; j += 2) // Iterate through all the children. Each is a 2B integer
            {
                children[i] = CONVERT_TO_INT(zmBuf[(j + SRSP_PAYLOAD_START + ZDO_IEEE_ADDR_RSP_ASSOCIATED_DEVICE_FIELD_START)], zmBuf[( j + SRSP_PAYLOAD_START + ZDO_IEEE_ADDR_RSP_ASSOCIATED_DEVICE_FIELD_START + 1)]);
                printf("<%04X> ", children[i]);
                i++;
            }
            printf("\r\n");
            
            for (i=0; i<childCount; i++)                     // Iterate through all children
            {
                if (!setContains(&searchedSet, children[i])) // Don't process the same short address twice!
                {
                    displayChildren(children[i]);            // Note use of recursion here
                }
            }
        } else {
            printf("no children\r\n");
        }
    } else {
        printf("Could not locate that device (Error Code 0x%02X)\r\n", result);
    }
    return childCount;
}
Exemplo n.º 11
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 && setContains(*selected, tid) ? "oval"
                                                                : "box";
    fprintf(file,
            "t%u [shape=%s,label=\"T: %u\\np: %" PRId64 "\\nbc: [0x%x-0x%x)\","
            "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);
}
Exemplo n.º 12
0
void addNeigbourNodesToFrontier(int id){
    vertexNode* v = searchNode(id);
    //Found the vertex node

    //Create a temp head edgeNode
    edgeNode* temp_head = v->head; 
    while(temp_head!=NULL)  //Traverse and add all ids into the frontier
    {

        /*if(markedNodes.find(temp_head->astPosid) != markedNodes.end())
            frontierNodes.insert(temp_head->id);
        */
          //change
        if(setContains(markedNodes,temp_head->id) == 0)
            addToSet(&frontierNodes,temp_head->id);
        
        temp_head = temp_head-> next;
    }

}
Exemplo n.º 13
0
SET
setDifference(SET A,SET B)
{
    SET set;
    void *e;

    if ( ! B->cmp)
	return NULL;		/* B needs a compare function */

    /* Create the resulting set */
    set = setNew(A->cmp,A->ed,A->ord);

    if (!set)
	{ XLOG(set); return NULL; }

    for (e = setFirst(A); e; e = setNext(A))
	if (!setContains(B,e))
	    setAdd(set,e);

    return set;
}
Exemplo n.º 14
0
/** Print a tokens in a set
	@param name  The name of the token set (First, Follow, Contains)
	@param items The set to be printed

	The routine takes a line length of 80 characthers into account.
*/
static void printSet(const char *name, set items) {
	int lineFill, i;
	bool first = true;
	
	printIndent(); lineFill = 8 * indent;
	indent++;
	fprintf(printRuleOutput, ">> %s {", name); lineFill += strlen(name) + 5;
	/* Loop over all used tokens, and print the ones in the set */
	for (i = 0; i < condensedNumber; i++) {
		if (setContains(items, i)) {
			size_t textLength;
			const char *text;
			if (!first)
				fputc(' ', printRuleOutput);
			else
				first = false;
			if (condensedToTerminal[i].flags & CONDENSED_ISTOKEN) {
				text = condensedToTerminal[i].uToken->token[0]->text;
				textLength = strlen(text) + 1;
			} else if (i == 0) {
				text = "EOFILE";
				textLength = 7;
			} else {
				/* Note: this is a Q&D hack, to access the default symbol table. */
				text = LLgetSymbol(condensedToTerminal[i].uLiteral);
				textLength = strlen(text) + 1;
			}
			if (lineFill + textLength + 1 > 79) {
				fputc('\n', printRuleOutput);
				printIndent(); lineFill = 8 * indent;
			}
			fputs(text, printRuleOutput);
			lineFill += textLength;
		}
	}
	fputs("}\n", printRuleOutput);
	indent--;
}
Exemplo n.º 15
0
void SearchOptions::setMatchFlags(const Qt::MatchFlags flags)
{
  if ((flags & Qt::MatchWildcard) == Qt::MatchWildcard) {
      setWildCard();
  } else if ((flags & Qt::MatchRegExp) == Qt::MatchRegExp) {
      setRegularExpression();
  } else {
    setMatchAsString();
  }

  if ((flags & Qt::MatchEndsWith) == Qt::MatchEndsWith) {
      setEndsWith();
  } else if ((flags & Qt::MatchStartsWith) == Qt::MatchStartsWith) {
    setStartsWith();
  } else if ((flags & Qt::MatchContains) == Qt::MatchContains) {
    setContains();
  } else {
    setMatchEntireString();
  }

  setCaseSensitive((flags & Qt::MatchCaseSensitive) == Qt::MatchCaseSensitive);
  setWrap((flags & Qt::MatchWrap) == Qt::MatchWrap);
}
Exemplo n.º 16
0
/**
@description: 
    Checks if neighbor node exists in the frontier
    Returns bool
*/
int checkIfNeighborExistsInFrontier(int nodeID) 
{
    vertexNode* v = searchNode(nodeID);
    //Found the vertex node

    //Create a temp head edgeNode
    edgeNode* temp_head = v->head; 

    while(temp_head!=NULL)  //Traverse the edge nodes and check if the id matches
                            // and return true
    {
        /*
        if(frontierNodes.find(temp_head->id) != frontierNodes.end())
            return 1;
       */
        if(setContains(frontierNodes,temp_head->id) == 1)
            return 1;
            
        temp_head = temp_head-> next;
    }
    return 0;

}
Exemplo n.º 17
0
SET
setIntersect(SET s1,SET s2)
{
    SET set;
    void *e;

    /* At least one of the sets must have a compare function */
    if ( ! (s1->cmp || s2->cmp) )
	return NULL;

    /* Create a disjoint set */
    set = setNew(s1->cmp ? s1->cmp : s2->cmp,1,s1->ord);

    if (!set)
	{ XLOG(set); return NULL; }

    for (e = setFirst(s1); e; e = setNext(s1))
    {
	if (setContains(s2,e))
	    setAdd(set,e);
    }

    return set;
}
Exemplo n.º 18
0
/**
 * Sorts the regions vector in a linear order to be used for
 * translation.  The goal is to obtain an order that improves locality
 * when the function is executed.
 */
static void sortRegion(RegionVec&                  regions,
                       const Func*                 func,
                       const TransCFG&             cfg,
                       const ProfData*             profData,
                       const TransIDToRegionMap&   headToRegion,
                       const RegionToTransIDsMap&  regionToTransIds) {
  RegionVec sorted;
  RegionSet selected;

  // First, pick the region for the function body entry.  There may be
  // multiple translations of the function body, so pick the one with
  // largest profile weight.
  RegionDescPtr entryRegion = nullptr;
  int64_t    maxEntryWeight = -1;
  for (const auto& pair : regionToTransIds) {
    auto  r    = pair.first;
    auto& tids = pair.second;
    for (auto tid : tids) {
      if (profData->transSrcKey(tid).offset() == func->base()) {
        int64_t weight = cfg.weight(tid);
        if (weight > maxEntryWeight) {
          entryRegion    = r;
          maxEntryWeight = weight;
        }
      }
    }
  }

  assert(entryRegion);
  sorted.push_back(entryRegion);
  selected.insert(entryRegion);

  RegionDescPtr region = entryRegion;
  // Select the remaining regions, iteratively picking the most likely
  // region to execute next.
  for (auto i = 1; i < regions.size(); i++) {
    int64_t      maxWeight = -1;
    int64_t  maxHeadWeight = -1;
    RegionDescPtr bestNext = nullptr;
    auto    regionTransIds = getRegionTransIDVec(regionToTransIds, region);
    for (auto next : regions) {
      if (setContains(selected, next)) continue;
      auto nextTransIds = getRegionTransIDVec(regionToTransIds, next);
      int64_t weight = interRegionWeight(regionTransIds, nextTransIds[0], cfg);
      int64_t headWeight = cfg.weight(nextTransIds[0]);
      if ((weight >  maxWeight) ||
          (weight == maxWeight && headWeight > maxHeadWeight)) {
        maxWeight     = weight;
        maxHeadWeight = headWeight;
        bestNext      = next;
      }
    }
    assert(bestNext);
    sorted.push_back(bestNext);
    selected.insert(bestNext);
    region = bestNext;
  }

  assert(sorted.size() == regions.size());
  regions = sorted;

  if (debug && Trace::moduleEnabled(HPHP::Trace::pgo, 5)) {
    for (size_t i = 0; i < regions.size(); i++) {
      auto r = regions[i];
      auto tids = getRegionTransIDVec(regionToTransIds, r);
      std::string transIds = folly::join(", ", tids);
      FTRACE(6, "sortRegion: region[{}]: {}\n", i, transIds);
    }
  }
}
Exemplo n.º 19
0
RegionDescPtr selectHotTrace(TransID triggerId,
                             const ProfData* profData,
                             TransCFG& cfg,
                             TransIDSet& selectedSet) {
  JIT::RegionDescPtr region = smart::make_unique<JIT::RegionDesc>();
  TransID tid    = triggerId;
  TransID prevId = InvalidID;
  selectedSet.clear();

  while (!setContains(selectedSet, tid)) {

    RegionDesc::BlockPtr block = profData->transBlock(tid);
    if (block == nullptr) break;

    // If the debugger is attached, only allow single-block regions.
    if (prevId != InvalidID && isDebuggerAttachedProcess()) {
      FTRACE(5, "selectHotRegion: breaking region at Translation {} "
             "because of debugger is attached\n", tid);
      break;
    }

    // Break if block is not the first and requires reffiness checks.
    // Task #2589970: fix translateRegion to support mid-region reffiness checks
    if (prevId != InvalidID) {
      auto nRefDeps = block->reffinessPreds().size();
      if (nRefDeps > 0) {
        FTRACE(5, "selectHotRegion: breaking region because of refDeps ({}) at "
               "Translation {}\n", nRefDeps, tid);
        break;
      }
    }

    // Break trace if translation tid cannot follow the execution of
    // the entire translation prevTd.  This can only happen if the
    // execution of prevId takes a side exit that leads to the
    // execution of tid.
    if (prevId != InvalidID) {
      Op* lastInstr = profData->transLastInstr(prevId);
      const Unit* unit = profData->transFunc(prevId)->unit();
      OffsetSet succOffs = findSuccOffsets(lastInstr, unit);
      if (!setContains(succOffs, profData->transSrcKey(tid).offset())) {
        if (HPHP::Trace::moduleEnabled(HPHP::Trace::pgo, 5)) {
          FTRACE(5, "selectHotTrace: WARNING: Breaking region @: {}\n",
                 JIT::show(*region));
          FTRACE(5, "selectHotTrace: next translation selected: tid = {}\n{}\n",
                 tid, JIT::show(*block));
          std::string succStr("succOffs = ");
          for (auto succ : succOffs) {
            succStr += lexical_cast<std::string>(succ);
          }
          FTRACE(5, "\n{}\n", succStr);
        }
        break;
      }
    }
    region->blocks.emplace_back(block);
    selectedSet.insert(tid);

    Op lastOp = *(profData->transLastInstr(tid));
    if (breaksRegion(lastOp)) {
      FTRACE(5, "selectHotTrace: breaking region because of last instruction "
             "in Translation {}: {}\n", tid, opcodeToName(lastOp));
      break;
    }

    auto outArcs = cfg.outArcs(tid);
    if (outArcs.size() == 0) {
      FTRACE(5, "selectHotTrace: breaking region because there's no successor "
             "for Translation {}\n", tid);
      break;
    }

    auto maxWeight = std::numeric_limits<int64_t>::min();
    TransCFG::Arc* maxArc = nullptr;
    for (auto arc : outArcs) {
      if (arc->weight() >= maxWeight) {
        maxWeight = arc->weight();
        maxArc = arc;
      }
    }
    assert(maxArc != nullptr);

    prevId = tid;
    tid = maxArc->dst();
  }

  return region;
}
Exemplo n.º 20
0
/**
 * Sorts the regions vector in a linear order to be used for
 * translation.  The goal is to obtain an order that improves locality
 * when the function is executed.
 */
static void sortRegion(RegionVec&                  regions,
                       const Func*                 func,
                       const TransCFG&             cfg,
                       const ProfData*             profData,
                       const TransIDToRegionMap&   headToRegion,
                       const RegionToTransIDsMap&  regionToTransIds) {
  RegionVec sorted;
  RegionSet selected;

  if (regions.size() == 0) return;

  // First, pick the region starting at the lowest bytecode offset.
  // This will normally correspond to the main function entry (for
  // normal, regular bytecode), but it may not be for irregular
  // functions written in hhas (like array_map and array_filter).  If
  // there multiple regions starting at the lowest bytecode offset,
  // pick the one with the largest profile weight.
  RegionDescPtr entryRegion = nullptr;
  int64_t    maxEntryWeight = -1;
  Offset     lowestOffset   = kInvalidOffset;
  for (const auto& pair : regionToTransIds) {
    auto  r    = pair.first;
    auto& tids = pair.second;
    TransID firstTid = tids[0];
    Offset firstOffset = profData->transSrcKey(firstTid).offset();
    int64_t weight = cfg.weight(firstTid);
    if (lowestOffset == kInvalidOffset || firstOffset < lowestOffset ||
        (firstOffset == lowestOffset && weight > maxEntryWeight)) {
      entryRegion    = r;
      maxEntryWeight = weight;
      lowestOffset   = firstOffset;
    }
  }

  assert(entryRegion);
  sorted.push_back(entryRegion);
  selected.insert(entryRegion);

  RegionDescPtr region = entryRegion;
  // Select the remaining regions, iteratively picking the most likely
  // region to execute next.
  for (auto i = 1; i < regions.size(); i++) {
    int64_t      maxWeight = -1;
    int64_t  maxHeadWeight = -1;
    RegionDescPtr bestNext = nullptr;
    auto    regionTransIds = getRegionTransIDVec(regionToTransIds, region);
    for (auto next : regions) {
      if (setContains(selected, next)) continue;
      auto nextTransIds = getRegionTransIDVec(regionToTransIds, next);
      int64_t weight = interRegionWeight(regionTransIds, nextTransIds[0], cfg);
      int64_t headWeight = cfg.weight(nextTransIds[0]);
      if ((weight >  maxWeight) ||
          (weight == maxWeight && headWeight > maxHeadWeight)) {
        maxWeight     = weight;
        maxHeadWeight = headWeight;
        bestNext      = next;
      }
    }
    assert(bestNext);
    sorted.push_back(bestNext);
    selected.insert(bestNext);
    region = bestNext;
  }

  assert(sorted.size() == regions.size());
  regions = sorted;

  if (debug && Trace::moduleEnabled(HPHP::Trace::pgo, 5)) {
    for (size_t i = 0; i < regions.size(); i++) {
      auto r = regions[i];
      auto tids = getRegionTransIDVec(regionToTransIds, r);
      std::string transIds = folly::join(", ", tids);
      FTRACE(6, "sortRegion: region[{}]: {}\n", i, transIds);
    }
  }
}
Exemplo n.º 21
0
/**
 * Regionize a func, so that each node and each arc in its TransCFG is
 * "covered".  A node is covered if any region contains it.  An arc T1->T2
 * is covered if either:
 *
 *   a) T1 and T2 are in the same region R and T2 immediately follows
 *      T1 in R.
 *   b) T2 is the head (first translation) of a region.
 *
 * Basic algorithm:
 *
 *   1) sort nodes in decreasing weight order
 *   2) for each node N:
 *      2.1) if N and all its incoming arcs are covered, then continue
 *      2.2) select a region starting at this node and mark nodes/arcs as
 *           covered appropriately
 */
void regionizeFunc(const Func*            func,
                   JIT::TranslatorX64* tx64,
                   RegionVec&             regions) {
  assert(RuntimeOption::EvalJitPGO);
  FuncId funcId = func->getFuncId();
  ProfData* profData = tx64->profData();
  TransCFG cfg(funcId, profData, tx64->getSrcDB(), tx64->getJmpToTransIDMap());

  if (Trace::moduleEnabled(HPHP::Trace::pgo, 5)) {
    string dotFileName = folly::to<string>("/tmp/func-cfg-", funcId, ".dot");
    cfg.print(dotFileName, funcId, profData, nullptr);
    FTRACE(5, "regionizeFunc: initial CFG for func {} saved to file {}\n",
           funcId, dotFileName);
  }

  TransCFG::ArcPtrVec arcs = cfg.arcs();
  vector<TransID>    nodes = cfg.nodes();

  std::sort(nodes.begin(), nodes.end(),
            [&](TransID tid1, TransID tid2) -> bool {
              if (cfg.weight(tid1) != cfg.weight(tid2)) {
                return cfg.weight(tid1) > cfg.weight(tid2);
              }
              // In case of ties, pick older translations first, in an
              // attempt to start loops at their headers.
              return tid1 < tid2;
            });

  TransCFG::ArcPtrSet coveredArcs;
  TransIDSet          coveredNodes;
  TransIDSet          heads;
  TransIDToRegionMap  headToRegion;
  RegionToTransIDsMap regionToTransIds;
  regions.clear();

  for (auto node : nodes) {
    if (!setContains(coveredNodes, node) ||
        !allArcsCovered(cfg.inArcs(node),  coveredArcs)) {
      TransID newHead = node;
      FTRACE(6, "regionizeFunc: selecting trace to cover node {}\n", newHead);
      TransIDSet selectedSet;
      TransIDVec selectedVec;
      RegionDescPtr region = selectHotTrace(newHead, profData, cfg,
                                            selectedSet, &selectedVec);
      profData->setOptimized(profData->transSrcKey(newHead));
      assert(selectedVec.size() > 0 && selectedVec[0] == newHead);
      regions.push_back(region);
      heads.insert(newHead);
      markCovered(cfg, selectedVec, heads, coveredNodes, coveredArcs);
      regionToTransIds[region] = selectedVec;
      headToRegion[newHead] = region;

      FTRACE(6, "regionizeFunc: selected trace: {}\n",
             folly::join(", ", selectedVec));
    }
  }

  assert(coveredNodes.size() == cfg.nodes().size());
  assert(coveredArcs.size() == arcs.size());

  sortRegion(regions, func, cfg, profData, headToRegion, regionToTransIds);

  if (debug && Trace::moduleEnabled(HPHP::Trace::pgo, 5)) {
    FTRACE(5, "\n--------------------------------------------\n"
           "regionizeFunc({}): computed regions:\n", funcId);
    for (auto region : regions) {
      FTRACE(5, "{}\n\n", show(*region));
    }
  }
}