Example #1
0
 void InvalidateWithChildren(Block *New) { // TODO: rename New
   BlockList ToInvalidate; // Being in the list means you need to be invalidated
   ToInvalidate.push_back(New);
   while (ToInvalidate.size() > 0) {
     Block *Invalidatee = ToInvalidate.front();
     ToInvalidate.pop_front();
     Block *Owner = Ownership[Invalidatee];
     if (IndependentGroups.find(Owner) != IndependentGroups.end()) { // Owner may have been invalidated, do not add to IndependentGroups!
       IndependentGroups[Owner].erase(Invalidatee);
     }
     if (Ownership[Invalidatee]) { // may have been seen before and invalidated already
       Ownership[Invalidatee] = NULL;
       for (BlockBranchMap::iterator iter = Invalidatee->BranchesOut.begin(); iter != Invalidatee->BranchesOut.end(); iter++) {
         Block *Target = iter->first;
         BlockBlockMap::iterator Known = Ownership.find(Target);
         if (Known != Ownership.end()) {
           Block *TargetOwner = Known->second;
           if (TargetOwner) {
             ToInvalidate.push_back(Target);
           }
         }
       }
     }
   }
 }
Example #2
0
DomChildren findDomChildren(const BlockList& blocks) {
  IdomVector idom = findDominators(blocks);
  DomChildren children(blocks.size(), BlockList());
  for (Block* block : blocks) {
    int idom_id = idom[block->postId()];
    if (idom_id != -1) children[idom_id].push_back(block);
  }
  return children;
}
Example #3
0
File: Line.C Project: USP/wtcpp
void Line::moveToNextPage(BlockList& floats, double minX, double maxX,
			  const WTextRenderer& renderer)
{
  for (unsigned i = 0; i < blocks_.size(); ++i) {
    Block *b = blocks_[i];

    if (b->isFloat())
      Utils::erase(floats, b);
  }

  PageState ps;
  ps.floats = floats;
  ps.page = page_;
  Block::clearFloats(ps);
  page_ = ps.page;
  floats = ps.floats;

  double oldY = y_;
  y_ = 0;
  x_ = minX;
  ++page_;

  BlockList blocks = blocks_;
  blocks_.clear();

  Range rangeX(x_, maxX);
  Block::adjustAvailableWidth(y_, page_, floats, rangeX);
  x_ = rangeX.start;
  maxX = rangeX.end;

  for (unsigned i = 0; i < blocks.size(); ++i) {
    Block *b = blocks[i];

    if (b->isFloat()) {
      b->layoutFloat(y_, page_, floats, x_, height_, minX, maxX,
		     false, renderer);
      reflow(b);
    } else {
      for (unsigned j = 0; j < b->inlineLayout.size(); ++j) {
	InlineBox& ib = b->inlineLayout[j];

	if (ib.y == oldY && ib.page == page_ - 1) {
	  if (ib.x != LEFT_MARGIN_X) {
	    ib.x = x_;
	    x_ += ib.width;
	  }

	  ib.page = page_;
	  ib.y = y_;
	}
      }
    }

    blocks_.push_back(b);
  }
}
Example #4
0
BlockList rpoSortCfg(const IRUnit& unit) {
  BlockList blocks;
  blocks.reserve(unit.numBlocks());
  postorderWalk(unit,
    [&](Block* block) {
      blocks.push_back(block);
    });

  std::reverse(blocks.begin(), blocks.end());
  assert(blocks.size() <= unit.numBlocks());
  return blocks;
}
Example #5
0
 void FindLive(Block *Root) {
   BlockList ToInvestigate;
   ToInvestigate.push_back(Root);
   while (ToInvestigate.size() > 0) {
     Block *Curr = ToInvestigate.front();
     ToInvestigate.pop_front();
     if (Live.find(Curr) != Live.end()) continue;
     Live.insert(Curr);
     for (BlockBranchMap::iterator iter = Curr->BranchesOut.begin(); iter != Curr->BranchesOut.end(); iter++) {
       ToInvestigate.push_back(iter->first);
     }
   }
 }
Example #6
0
/*
 * Find the immediate dominator of each block using Cooper, Harvey, and
 * Kennedy's "A Simple, Fast Dominance Algorithm", returned as a vector
 * of postorder ids, indexed by postorder id.
 */
IdomVector findDominators(const BlockList& blocks) {
  assert(isRPOSorted(blocks));

  // Calculate immediate dominators with the iterative two-finger algorithm.
  // When it terminates, idom[post-id] will contain the post-id of the
  // immediate dominator of each block.  idom[start] will be -1.  This is
  // the general algorithm but it will only loop twice for loop-free graphs.
  auto const num_blocks = blocks.size();
  IdomVector idom(num_blocks, -1);
  auto start = blocks.begin();
  int start_id = (*start)->postId();
  idom[start_id] = start_id;
  start++;
  for (bool changed = true; changed; ) {
    changed = false;
    // for each block after start, in reverse postorder
    for (auto it = start; it != blocks.end(); it++) {
      Block* block = *it;
      int b = block->postId();
      // new_idom = any already-processed predecessor
      auto edge_it = block->preds().begin();
      int new_idom = edge_it->from()->postId();
      while (idom[new_idom] == -1) new_idom = (++edge_it)->from()->postId();
      // for all other already-processed predecessors p of b
      for (auto& edge : block->preds()) {
        auto p = edge.from()->postId();
        if (p != new_idom && idom[p] != -1) {
          // find earliest common predecessor of p and new_idom
          // (higher postIds are earlier in flow and in dom-tree).
          int b1 = p, b2 = new_idom;
          do {
            while (b1 < b2) b1 = idom[b1];
            while (b2 < b1) b2 = idom[b2];
          } while (b1 != b2);
          new_idom = b1;
        }
      }
      if (idom[b] != new_idom) {
        idom[b] = new_idom;
        changed = true;
      }
    }
  }
  idom[start_id] = -1; // start has no idom.
  return idom;
}
Example #7
0
BlockList rpoSortCfg(IRTrace* trace, const IRFactory& factory) {
  assert(trace->isMain());
  BlockList blocks;
  blocks.reserve(factory.numBlocks());
  unsigned next_id = 0;
  postorderWalk(
    [&](Block* block) {
      block->setPostId(next_id++);
      blocks.push_back(block);
    },
    factory.numBlocks(),
    trace->front()
  );
  std::reverse(blocks.begin(), blocks.end());
  assert(blocks.size() <= factory.numBlocks());
  assert(next_id <= factory.numBlocks());
  return blocks;
}
Example #8
0
    // For each entry, find the independent group reachable by it. The independent group is
    // the entry itself, plus all the blocks it can reach that cannot be directly reached by another entry. Note that we
    // ignore directly reaching the entry itself by another entry.
    void FindIndependentGroups(BlockSet &Blocks, BlockSet &Entries, BlockBlockSetMap& IndependentGroups) {
      typedef std::map<Block*, Block*> BlockBlockMap;

      struct HelperClass {
        BlockBlockSetMap& IndependentGroups;
        BlockBlockMap Ownership; // For each block, which entry it belongs to. We have reached it from there.

        HelperClass(BlockBlockSetMap& IndependentGroupsInit) : IndependentGroups(IndependentGroupsInit) {}
        void InvalidateWithChildren(Block *New) { // TODO: rename New
          BlockList ToInvalidate; // Being in the list means you need to be invalidated
          ToInvalidate.push_back(New);
          while (ToInvalidate.size() > 0) {
            Block *Invalidatee = ToInvalidate.front();
            ToInvalidate.pop_front();
            Block *Owner = Ownership[Invalidatee];
            if (IndependentGroups.find(Owner) != IndependentGroups.end()) { // Owner may have been invalidated, do not add to IndependentGroups!
              IndependentGroups[Owner].erase(Invalidatee);
            }
            if (Ownership[Invalidatee]) { // may have been seen before and invalidated already
              Ownership[Invalidatee] = NULL;
              for (BlockBranchMap::iterator iter = Invalidatee->BranchesOut.begin(); iter != Invalidatee->BranchesOut.end(); iter++) {
                Block *Target = iter->first;
                BlockBlockMap::iterator Known = Ownership.find(Target);
                if (Known != Ownership.end()) {
                  Block *TargetOwner = Known->second;
                  if (TargetOwner) {
                    ToInvalidate.push_back(Target);
                  }
                }
              }
            }
          }
        }
      };
      HelperClass Helper(IndependentGroups);

      // We flow out from each of the entries, simultaneously.
      // When we reach a new block, we add it as belonging to the one we got to it from.
      // If we reach a new block that is already marked as belonging to someone, it is reachable by
      // two entries and is not valid for any of them. Remove it and all it can reach that have been
      // visited.

      BlockList Queue; // Being in the queue means we just added this item, and we need to add its children
      for (BlockSet::iterator iter = Entries.begin(); iter != Entries.end(); iter++) {
        Block *Entry = *iter;
        Helper.Ownership[Entry] = Entry;
        IndependentGroups[Entry].insert(Entry);
        Queue.push_back(Entry);
      }
      while (Queue.size() > 0) {
        Block *Curr = Queue.front();
        Queue.pop_front();
        Block *Owner = Helper.Ownership[Curr]; // Curr must be in the ownership map if we are in the queue
        if (!Owner) continue; // we have been invalidated meanwhile after being reached from two entries
        // Add all children
        for (BlockBranchMap::iterator iter = Curr->BranchesOut.begin(); iter != Curr->BranchesOut.end(); iter++) {
          Block *New = iter->first;
          BlockBlockMap::iterator Known = Helper.Ownership.find(New);
          if (Known == Helper.Ownership.end()) {
            // New node. Add it, and put it in the queue
            Helper.Ownership[New] = Owner;
            IndependentGroups[Owner].insert(New);
            Queue.push_back(New);
            continue;
          }
          Block *NewOwner = Known->second;
          if (!NewOwner) continue; // We reached an invalidated node
          if (NewOwner != Owner) {
            // Invalidate this and all reachable that we have seen - we reached this from two locations
            Helper.InvalidateWithChildren(New);
          }
          // otherwise, we have the same owner, so do nothing
        }
      }

      // Having processed all the interesting blocks, we remain with just one potential issue:
      // If a->b, and a was invalidated, but then b was later reached by someone else, we must
      // invalidate b. To check for this, we go over all elements in the independent groups,
      // if an element has a parent which does *not* have the same owner, we must remove it
      // and all its children.

      for (BlockSet::iterator iter = Entries.begin(); iter != Entries.end(); iter++) {
        BlockSet &CurrGroup = IndependentGroups[*iter];
        BlockList ToInvalidate;
        for (BlockSet::iterator iter = CurrGroup.begin(); iter != CurrGroup.end(); iter++) {
          Block *Child = *iter;
          for (BlockBranchMap::iterator iter = Child->BranchesIn.begin(); iter != Child->BranchesIn.end(); iter++) {
            Block *Parent = iter->first;
            if (Helper.Ownership[Parent] != Helper.Ownership[Child]) {
              ToInvalidate.push_back(Child);
            }
          }
        }
        while (ToInvalidate.size() > 0) {
          Block *Invalidatee = ToInvalidate.front();
          ToInvalidate.pop_front();
          Helper.InvalidateWithChildren(Invalidatee);
        }
      }

      // Remove empty groups
      for (BlockSet::iterator iter = Entries.begin(); iter != Entries.end(); iter++) {
        if (IndependentGroups[*iter].size() == 0) {
          IndependentGroups.erase(*iter);
        }
      }

#if DEBUG
      PrintDebug("Investigated independent groups:\n");
      for (BlockBlockSetMap::iterator iter = IndependentGroups.begin(); iter != IndependentGroups.end(); iter++) {
        DebugDump(iter->second, " group: ");
      }
#endif
    }
 unsigned int NBlocks(void) const { return blocks.size(); }