예제 #1
0
// The weight on each edge is the increment required along any path that
// contains that edge.
void BallLarusDag::calculatePathNumbersFrom(BallLarusNode* node) {
  if(node == getExit())
    // The Exit node must be base case
    node->setNumberPaths(1);
  else {
    unsigned sumPaths = 0;
    BallLarusNode* succNode;

    for(BLEdgeIterator succ = node->succBegin(), end = node->succEnd();
        succ != end; succ++) {
      if( (*succ)->getType() == BallLarusEdge::BACKEDGE ||
          (*succ)->getType() == BallLarusEdge::SPLITEDGE )
        continue;

      (*succ)->setWeight(sumPaths);
      succNode = (*succ)->getTarget();

      if( !succNode->getNumberPaths() )
        return;
      sumPaths += succNode->getNumberPaths();
    }

    node->setNumberPaths(sumPaths);
  }
}
예제 #2
0
// Process an edge in the CFG for DAG building.
void BallLarusDag::buildEdge(BLBlockNodeMap& inDag, std::stack<BallLarusNode*>&
                             dfsStack, BallLarusNode* currentNode,
                             BasicBlock* succBB, unsigned duplicateCount) {
  BallLarusNode* succNode = inDag[succBB];

  if(succNode && succNode->getColor() == BallLarusNode::BLACK) {
    // visited node and forward edge
    addEdge(currentNode, succNode, duplicateCount);
  } else if(succNode && succNode->getColor() == BallLarusNode::GRAY) {
    // visited node and back edge
    DEBUG(dbgs() << "Backedge detected.\n");
    addBackedge(currentNode, succNode, duplicateCount);
  } else {
    BallLarusNode* childNode;
    // not visited node and forward edge
    if(succNode) // an unvisited node that is child of a gray node
      childNode = succNode;
    else { // an unvisited node that is a child of a an unvisted node
      childNode = addNode(succBB);
      inDag[succBB] = childNode;
    }
    addEdge(currentNode, childNode, duplicateCount);
    dfsStack.push(childNode);
  }
}
예제 #3
0
BasicBlock* ProfilePath::getFirstBlockInPath() const {
    BallLarusNode* root = _ppi->_currentDag->getRoot();
    BallLarusEdge* edge = getNextEdge(root, _number);

    if( edge && (edge->getType() == BallLarusEdge::BACKEDGE_PHONY ||
                 edge->getType() == BallLarusEdge::SPLITEDGE_PHONY) )
        return edge->getTarget()->getBlock();

    return root->getBlock();
}
예제 #4
0
// Processes one node and its imediate edges for building the DAG.
void BallLarusDag::buildNode(BLBlockNodeMap& inDag, BLNodeStack& dfsStack) {
  BallLarusNode* currentNode = dfsStack.top();
  BasicBlock* currentBlock = currentNode->getBlock();

  if(currentNode->getColor() != BallLarusNode::WHITE) {
    // we have already visited this node
    dfsStack.pop();
    currentNode->setColor(BallLarusNode::BLACK);
  } else {
    // are there any external procedure calls?
    if( ProcessEarlyTermination ) {
      for( BasicBlock::iterator bbCurrent = currentNode->getBlock()->begin(),
             bbEnd = currentNode->getBlock()->end(); bbCurrent != bbEnd;
           bbCurrent++ ) {
        Instruction& instr = *bbCurrent;
        if( instr.getOpcode() == Instruction::Call ) {
          BallLarusEdge* callEdge = addEdge(currentNode, getExit(), 0);
          callEdge->setType(BallLarusEdge::CALLEDGE_PHONY);
          break;
        }
      }
    }

    TerminatorInst* terminator = currentNode->getBlock()->getTerminator();
    if(isa<ReturnInst>(terminator) || isa<UnreachableInst>(terminator)
       || isa<UnwindInst>(terminator))
      addEdge(currentNode, getExit(),0);

    currentNode->setColor(BallLarusNode::GRAY);
    inDag[currentBlock] = currentNode;

    BasicBlock* oldSuccessor = 0;
    unsigned duplicateNumber = 0;

    // iterate through this node's successors
    for(succ_iterator successor = succ_begin(currentBlock),
          succEnd = succ_end(currentBlock); successor != succEnd;
        oldSuccessor = *successor, ++successor ) {
      BasicBlock* succBB = *successor;

      // is this edge a duplicate?
      if (oldSuccessor == succBB)
        duplicateNumber++;
      else
        duplicateNumber = 0;

      buildEdge(inDag, dfsStack, currentNode, succBB, duplicateNumber);
    }
  }
}
예제 #5
0
ProfilePathBlockVector* ProfilePath::getPathBlocks() const {
    BallLarusNode* currentNode = _ppi->_currentDag->getRoot ();
    unsigned int increment = _number;
    ProfilePathBlockVector* pbv = new ProfilePathBlockVector;

    while (currentNode != _ppi->_currentDag->getExit()) {
        BallLarusEdge* next = getNextEdge(currentNode, increment);
        increment -= next->getWeight();

        // add block to the block list if it is a real edge
        if( next->getType() == BallLarusEdge::NORMAL)
            pbv->push_back (currentNode->getBlock());
        // make the back edge the last edge since we are at the end
        else if( next->getTarget() == _ppi->_currentDag->getExit() ) {
            pbv->push_back (currentNode->getBlock());
            pbv->push_back (next->getRealEdge()->getTarget()->getBlock());
        }

        // set the new node
        currentNode = next->getTarget();
    }

    return pbv;
}
예제 #6
0
// Calculate the path numbers by assigning edge increments as prescribed
// in Ball-Larus path profiling.
void BallLarusDag::calculatePathNumbers() {
  BallLarusNode* node;
  std::queue<BallLarusNode*> bfsQueue;
  bfsQueue.push(getExit());

  while(bfsQueue.size() > 0) {
    node = bfsQueue.front();

    DEBUG(dbgs() << "calculatePathNumbers on " << node->getName() << "\n");

    bfsQueue.pop();
    unsigned prevPathNumber = node->getNumberPaths();
    calculatePathNumbersFrom(node);

    // Check for DAG splitting
    if( node->getNumberPaths() > 100000000 && node != getRoot() ) {
      // Add new phony edge from the split-node to the DAG's exit
      BallLarusEdge* exitEdge = addEdge(node, getExit(), 0);
      exitEdge->setType(BallLarusEdge::SPLITEDGE_PHONY);

      // Counters to handle the possibility of a multi-graph
      BasicBlock* oldTarget = 0;
      unsigned duplicateNumber = 0;

      // Iterate through each successor edge, adding phony edges
      for( BLEdgeIterator succ = node->succBegin(), end = node->succEnd();
           succ != end; oldTarget = (*succ)->getTarget()->getBlock(), succ++ ) {

        if( (*succ)->getType() == BallLarusEdge::NORMAL ) {
          // is this edge a duplicate?
          if( oldTarget != (*succ)->getTarget()->getBlock() )
            duplicateNumber = 0;

          // create the new phony edge: root -> succ
          BallLarusEdge* rootEdge =
            addEdge(getRoot(), (*succ)->getTarget(), duplicateNumber++);
          rootEdge->setType(BallLarusEdge::SPLITEDGE_PHONY);
          rootEdge->setRealEdge(*succ);

          // split on this edge and reference it's exit/root phony edges
          (*succ)->setType(BallLarusEdge::SPLITEDGE);
          (*succ)->setPhonyRoot(rootEdge);
          (*succ)->setPhonyExit(exitEdge);
          (*succ)->setWeight(0);
        }
      }

      calculatePathNumbersFrom(node);
    }

    DEBUG(dbgs() << "prev, new number paths " << prevPathNumber << ", "
          << node->getNumberPaths() << ".\n");

    if(prevPathNumber == 0 && node->getNumberPaths() != 0) {
      DEBUG(dbgs() << "node ready : " << node->getName() << "\n");
      for(BLEdgeIterator pred = node->predBegin(), end = node->predEnd();
          pred != end; pred++) {
        if( (*pred)->getType() == BallLarusEdge::BACKEDGE ||
            (*pred)->getType() == BallLarusEdge::SPLITEDGE )
          continue;

        BallLarusNode* nextNode = (*pred)->getSource();
        // not yet visited?
        if(nextNode->getNumberPaths() == 0)
          bfsQueue.push(nextNode);
      }
    }
  }

  DEBUG(dbgs() << "\tNumber of paths: " << getRoot()->getNumberPaths() << "\n");
}