Exemplo n.º 1
0
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void IndirectCallPromotion::MergeReturnedValues(BlockList& callBlocks, 
                                                Block* continuationBlock,
                                                CallInstr* instr) {
    // If the call returns 'void' or the result is not used
    // there are no values to merge.
    if(instr->IsVoid() || (instr->HasDestinationOp() == false)) {
        return;
    }

    auto unit = callBlocks[0]->ParentFunction()->ParentUnit();
    auto& references = unit->References();

    // Create the 'phi' that merges the returned values.
    auto phiResultOp = Temporary::GetTemporary(instr->ResultOp()->GetType());
    auto phiInstr = PhiInstr::GetPhi(phiResultOp, callBlocks.Count());
    continuationBlock->InsertInstructionFirst(phiInstr);

    // Now add the incoming operands.
    for(int i = 0; i < callBlocks.Count(); i++) {
        auto beforeGoto = callBlocks[i]->LastInstruction()->PreviousInstruction();
        auto callInstr = beforeGoto->As<CallInstr>();
        
        DebugValidator::IsNotNull(callInstr);
        DebugValidator::IsNotNull(callInstr->ResultOp());

        auto blockRef = references.GetBlockRef(callBlocks[i]);
        phiInstr->AddOperand(callInstr->ResultOp(), blockRef);
    }

    // The original returned value is replaced by the 'phi' result.
    instr->ResultOp()->ReplaceWith(phiResultOp);
}
Exemplo n.º 2
0
bool isRPOSorted(const BlockList& blocks) {
  int id = 0;
  for (auto it = blocks.rbegin(); it != blocks.rend(); ++it) {
    if ((*it)->postId() != id++) return false;
  }
  return true;
}
Exemplo n.º 3
0
void LinearScan::allocRegsToTrace() {
  ExitTraceMap etm;

  numberInstructions(m_blocks);

  if (HPHP::Trace::moduleEnabled(HPHP::Trace::hhir, 5)) {
    std::stringstream s;
    s << "RPO: ";
    for (auto& b : m_blocks) {
      s << folly::format("{}{} ",
                         b->isMain() ? "M" : "E",
                         b->id());
    }
    s << "\n";
    HPHP::Trace::traceRelease("%s\n", s.str().c_str());
  }

  BlockList::iterator it = m_blocks.begin();
  while (it != m_blocks.end()) {
    allocRegsOneTrace(it, etm);
  }

  for (it = m_blocks.begin(); it != m_blocks.end();) {
    if ((*it)->isMain()) {
      ++it;
      continue;
    }
    allocRegsOneTrace(it, etm);
  }
}
Exemplo n.º 4
0
/* Acquire one blob from the pool.
 */
void* blob_pool::acquire() {
    BlockList* blist;
    if(! helper::get_blist(&blist, &_pool))
        new (blist) BlockList(&_pool, BLOB_POOL_TEMPLATE_ARGS);
    void* ptr = blist->acquire(BLOB_POOL_TEMPLATE_ARGS);
    assert(_pool.validate_pointer(ptr));
    return ptr;
}
Exemplo n.º 5
0
typename MemoryManager<AllocatorType>::BlockList::iterator MemoryManager<AllocatorType>::findBlock(BlockList& blockList, Byte* address, size_t index)
{
	typename BlockList::iterator it{blockList.begin()};
	const size_t blockSize{1UL << index};
	// Loop while the address is not in the block pointed by it
	while((address < *it or address >= *it + blockSize) and it != blockList.end())
		++it;
	return it;
}
Exemplo n.º 6
0
//
// Compute the generate and kill sets for each basic block in the given
// function. The generate and kill functions are overriden by the subclass.
//
void DataFlowPass::initStates(const BlockList& blocks, BlockStates& states) {
  for (BlockList::const_iterator FI = blocks.begin(), FE = blocks.end();
      FI != FE; ++FI) {
    const BasicBlock& block = *FI;
    BlockState state;
    initState(block, state);
    states.insert(BlockStatePair(&block, state));
  }
}
Exemplo n.º 7
0
Arquivo: Line.C Projeto: 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);
  }
}
Exemplo n.º 8
0
// This function attempts to find a pre-coloring hint from two
// different sources: If tmp comes from a DefLabel, it will scan up to
// the SSATmps providing values to incoming Jmp_s to look for a
// hint. If tmp is consumed by a Jmp_, look for other incoming Jmp_s
// to its destination and see if any of them have already been given a
// register. If all of these fail, let normal register allocation
// proceed unhinted.
RegNumber LinearScan::getJmpPreColor(SSATmp* tmp, uint32_t regIndex,
                                     bool isReload) {
  IRInstruction* srcInst = tmp->inst();
  const JmpList& jmps = m_jmps[tmp];
  if (isReload && (srcInst->op() == DefLabel || !jmps.empty())) {
    // If we're precoloring a Reload of a temp that we'd normally find
    // a hint for, just return the register allocated to the spilled
    // temp.
    auto reg = m_allocInfo[tmp].reg(regIndex);
    assert(reg != reg::noreg);
    return reg;
  }

  if (srcInst->op() == DefLabel) {
    // Figure out which dst of the label is tmp
    for (unsigned i = 0, n = srcInst->numDsts(); i < n; ++i) {
      if (srcInst->dst(i) == tmp) {
        auto reg = findLabelSrcReg(m_allocInfo, srcInst, i, regIndex);
        // Until we handle loops, it's a bug to try and allocate a
        // register to a DefLabel's dest before all of its incoming
        // Jmp_s have had their srcs allocated, unless the incoming
        // block is unreachable.
        const DEBUG_ONLY bool unreachable =
          std::find(m_blocks.begin(), m_blocks.end(),
                    srcInst->block()) == m_blocks.end();
        always_assert(reg != reg::noreg || unreachable);
        return reg;
      }
    }
    not_reached();
  }

  // If srcInst wasn't a label, check if tmp is used by any Jmp_
  // instructions. If it is, trace to the Jmp_'s label and use the
  // same procedure as above.
  for (unsigned ji = 0, jn = jmps.size(); ji < jn; ++ji) {
    IRInstruction* jmp = jmps[ji];
    IRInstruction* label = jmp->taken()->front();

    // Figure out which src of the Jmp_ is tmp
    for (unsigned si = 0, sn = jmp->numSrcs(); si < sn; ++si) {
      SSATmp* src = jmp->src(si);
      if (tmp == src) {
        // For now, a DefLabel should never have a register assigned
        // to it before any of its incoming Jmp_ instructions.
        always_assert(m_allocInfo[label->dst(si)].reg(regIndex) ==
                      reg::noreg);
        auto reg = findLabelSrcReg(m_allocInfo, label, si, regIndex);
        if (reg != reg::noreg) return reg;
      }
    }
  }

  return reg::noreg;
}
Exemplo n.º 9
0
void write_bc_file(const BlockList &blockList, const std::string &file_name) {
    FILE *fp = fopen(file_name.c_str(), "wb");
    if (!fp) {
        abort_("[write_bc_file] File %s cound not be opened for writing", file_name.c_str());
    }
    cout << "Writing " << file_name << " ..." << endl;
    for (BlockList::const_iterator it=blockList.begin(); it!=blockList.end(); ++it) {
        fwrite(&it->front(), 1, it->size(), fp);
    }
    fclose(fp);
}
Exemplo n.º 10
0
//
// Called after the pass is complete.
// Show the results of the pass for each program point b/t blocks.
//
void DataFlowPass::display(const BlockList& blocks, BlockStates& states) {
  for (BlockList::const_iterator I = blocks.begin(), IE = blocks.end();
      I != IE; ++I) {
    const BasicBlock* block = &(*I);
    BlockState& state = states[block];
    if (I == blocks.begin()) {
      DataFlowUtil::print(state.in);
      cout << endl;
    }
    block->dump();
    DataFlowUtil::print(state.out);
    cout << endl;
  }
  cout << endl;
}
Exemplo n.º 11
0
void LinearScan::collectInfo(BlockList::iterator it, IRTrace* trace) {
  m_natives.clear();
  m_uses.reset(); // TODO(#2536764): serious time sink

  while (it != m_blocks.end()) {
    Block* block = *it++;
    bool offTrace = block->trace() != trace;
    if (offTrace) {
      if (!trace->isMain()) return;
      int lastId = block->trace()->data();
      for (IRInstruction& inst : *block) {
        for (auto* src : inst.srcs()) {
          if (lastId > m_uses[src].lastUse) {
            m_uses[src].lastUse = lastId;
          }
        }
      }
    } else {
      for (IRInstruction& inst : *block) {
        for (auto* src : inst.srcs()) {
          m_uses[src].lastUse = m_linear[inst];
        }
        if (inst.isNative()) m_natives.push_back(&inst);
      }

      IRInstruction* jmp = block->back();
      if (jmp->op() == Jmp_ && jmp->numSrcs() != 0) {
        for (SSATmp* src : jmp->srcs()) {
          m_jmps[src].push_back(jmp);
        }
      }
    }
  }
}
Exemplo n.º 12
0
//
// Generic helper functions for arbitrary sets of blocks
//
BlockStates DataFlowPass::runOnBlocks(const BlockList& blocks) {
  BlockStates states;
  // First pass: precompute generate and kill sets.
  initStates(blocks, states);
  // iterate for a forwards pass
  if (_direction == FORWARDS) {
    const BasicBlock* start = &(blocks.front());
    traverseForwards(start, states);
  }
  // iterate for a backwards pass
  else if (_direction == BACKWARDS) {
    const BasicBlock* start = &(blocks.back());
    traverseBackwards(start, states);
  }
  // return copy of states
  return states;
}
Exemplo n.º 13
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;
}
Exemplo n.º 14
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;
}
Exemplo n.º 15
0
/*removes the temp blocks in the current scope, then delete the scope's TempBlockStack */
void BlockManager::leave_scope() {
	BlockList* temps = temp_block_list_stack_.back();
	BlockList::iterator it;
	for (it = temps->begin(); it != temps->end(); ++it) {
		BlockId &block_id = *it;
		int array_id = block_id.array_id();

		// Cached delete for distributed/served arrays.
		// Regular delete for temp blocks.

		if (sip_tables_.is_distributed(array_id) || sip_tables_.is_served(array_id))
			cached_delete_block(*it);
		else
			delete_block(*it);
//		delete_block(*it);
	}
	temp_block_list_stack_.pop_back();
	delete temps;
}
Exemplo n.º 16
0
void reflowTypes(Block* const changed, const BlockList& blocks) {
  assert(isRPOSorted(blocks));

  auto it = rpoIteratorTo(blocks, changed);
  assert(it != blocks.end());
  for (; it != blocks.end(); ++it) {
    FTRACE(5, "reflowTypes: visiting block {}\n", (*it)->id());
    for (auto& inst : **it) visitInstruction(&inst);
  }
}
bool
UnreachableCodeElimination::enqueue(MBasicBlock *block, BlockList &list)
{
    if (block->isMarked())
        return true;

    block->mark();
    marked_++;
    return list.append(block);
}
Exemplo n.º 18
0
Arquivo: cfg.cpp Projeto: BruceZu/hhvm
/*
 * Find the immediate dominator of each block using Cooper, Harvey, and
 * Kennedy's "A Simple, Fast Dominance Algorithm", returned as a vector
 * of Block*, indexed by block.  IdomVector[b] == nullptr if b has no
 * dominator.  This is the case for the entry block and any blocks not
 * reachable from the entry block.
 */
IdomVector findDominators(const IRUnit& unit,
                          const BlockList& blocks,
                          const BlockIDs& rpoIDs) {
  // 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.
  IdomVector idom(unit, nullptr);
  auto start = blocks.begin();
  auto entry = *start;
  idom[entry] = entry;
  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;
      // p1 = any already-processed predecessor
      auto predIter = block->preds().begin();
      auto predEnd = block->preds().end();
      auto p1 = predIter->from();
      while (!idom[p1]) p1 = (++predIter)->from();
      // for all other already-processed predecessors p2 of block
      for (++predIter; predIter != predEnd; ++predIter) {
        auto p2 = predIter->from();
        if (p2 == p1 || !idom[p2]) continue;
        // find earliest common predecessor of p1 and p2
        // (lower RPO ids are earlier in flow and in dom-tree).
        do {
          while (rpoIDs[p1] < rpoIDs[p2]) p2 = idom[p2];
          while (rpoIDs[p2] < rpoIDs[p1]) p1 = idom[p1];
        } while (p1 != p2);
      }
      if (idom[block] != p1) {
        idom[block] = p1;
        changed = true;
      }
    }
  }
  idom[entry] = nullptr; // entry has no dominator.
  return idom;
}
Exemplo n.º 19
0
GlobalValueNumbering::GlobalValueNumbering(IR* ir)
  : _current_map(NULL)
  , _value_maps(ir->linear_scan_order()->length(), NULL)
  , _compilation(ir->compilation())
{
  TRACE_VALUE_NUMBERING(tty->print_cr("****** start of global value numbering"));

  ShortLoopOptimizer short_loop_optimizer(this);

  BlockList* blocks = ir->linear_scan_order();
  int num_blocks = blocks->length();

  BlockBegin* start_block = blocks->at(0);
  assert(start_block == ir->start() && start_block->number_of_preds() == 0 && start_block->dominator() == NULL, "must be start block");
  assert(start_block->next()->as_Base() != NULL && start_block->next()->next() == NULL, "start block must not have instructions");

  // method parameters are not linked in instructions list, so process them separateley
  for_each_state_value(start_block->state(), value,
     assert(value->as_Local() != NULL, "only method parameters allowed");
     set_processed(value);
  );
Exemplo n.º 20
0
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void IndirectCallPromotion::ConnectGeneratedBlocks(BlockList& testBlocks, 
                                                   BlockList& callBlocks) {
    // Connect the blocks based on the following pattern:
    // TEST_BLOCK0:
    //     t0 = ucmp targetOp, FUNCT_REF0
    //     if t0, CALL_BLOCK0, TEST_BLOCK1
    // CALL_BLOCK0:
    //     call FUNCT_REF0
    //     goto CONTINUATION_BLOCK
    // TEST_BLOCK1:
    //     t1 = ucmp targetOp, FUNCT_REF1
    //     if t1, CALL_BLOCK1, TEST_BLOCK2
    // ...
    // CALL_BLOCK_N:   // only if unpromoted targets
    //     call targetOp
    //     goto CONTINUATION_BLOCK
    // CONTINUATION_BLOCK:
    auto unit = callBlocks[0]->ParentFunction()->ParentUnit();
    auto& references = unit->References();

    for(int i = 0; i < testBlocks.Count(); i++) {
        auto testBlock = testBlocks[i];
        auto ucmpResultOp = testBlocks[i]->LastInstruction()->GetDestinationOp();
        auto trueBlockRef = references.GetBlockRef(callBlocks[i]);
        Block* falseBlock;
        
        if((i + 1) < testBlocks.Count()) {
            // There is a next target test.
            falseBlock = testBlocks[i + 1];
        }
        else {
            // Unpromoted targets exist, always do the call.
            falseBlock = callBlocks[i + 1];
        }

        auto falseBlockRef = references.GetBlockRef(falseBlock);
        auto ifInstr = IfInstr::GetIf(ucmpResultOp, trueBlockRef, falseBlockRef);
        testBlock->InsertInstruction(ifInstr);
    }
}
Exemplo n.º 21
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);
           }
         }
       }
     }
   }
 }
Exemplo n.º 22
0
bool ShortLoopOptimizer::process(BlockBegin* loop_header) {
  TRACE_VALUE_NUMBERING(tty->print_cr("** loop header block"));

  _too_complicated_loop = false;
  _loop_blocks.clear();
  _loop_blocks.append(loop_header);

  for (int i = 0; i < _loop_blocks.length(); i++) {
    BlockBegin* block = _loop_blocks.at(i);
    TRACE_VALUE_NUMBERING(tty->print_cr("processing loop block B%d", block->block_id()));

    if (block->is_set(BlockBegin::exception_entry_flag)) {
      // this would be too complicated
      return false;
    }

    // add predecessors to worklist
    for (int j = block->number_of_preds() - 1; j >= 0; j--) {
      BlockBegin* pred = block->pred_at(j);

      if (pred->is_set(BlockBegin::osr_entry_flag)) {
        return false;
      }

      ValueMap* pred_map = value_map_of(pred);
      if (pred_map != NULL) {
        current_map()->kill_map(pred_map);
      } else if (!_loop_blocks.contains(pred)) {
        if (_loop_blocks.length() >= ValueMapMaxLoopSize) {
          return false;
        }
        _loop_blocks.append(pred);
      }
    }

    // use the instruction visitor for killing values
    for (Value instr = block->next(); instr != NULL; instr = instr->next()) {
      instr->visit(this);
      if (_too_complicated_loop) {
        return false;
      }
    }
  }

  bool optimistic = this->_gvn->compilation()->is_optimistic();

  if (UseLoopInvariantCodeMotion && optimistic) {
    LoopInvariantCodeMotion code_motion(this, _gvn, loop_header, &_loop_blocks);
  }

  TRACE_VALUE_NUMBERING(tty->print_cr("** loop successfully optimized"));
  return true;
}
Exemplo n.º 23
0
void cloneToBlock(const BlockList& rpoBlocks,
                  IRFactory& irFactory,
                  Block::iterator const first,
                  Block::iterator const last,
                  Block* const target) {
  assert(isRPOSorted(rpoBlocks));

  StateVector<SSATmp,SSATmp*> rewriteMap(irFactory, nullptr);

  auto rewriteSources = [&] (IRInstruction* inst) {
    for (int i = 0; i < inst->numSrcs(); ++i) {
      if (auto newTmp = rewriteMap[inst->src(i)]) {
        FTRACE(5, "  rewrite: {} -> {}\n",
               inst->src(i)->toString(),
               newTmp->toString());
        inst->setSrc(i, newTmp);
      }
    }
  };

  auto targetIt = target->skipHeader();
  for (auto it = first; it != last; ++it) {
    assert(!it->isControlFlow());

    FTRACE(5, "cloneToBlock({}): {}\n", target->id(), it->toString());
    auto const newInst = irFactory.cloneInstruction(&*it);

    if (auto const numDests = newInst->numDsts()) {
      for (int i = 0; i < numDests; ++i) {
        FTRACE(5, "  add rewrite: {} -> {}\n",
               it->dst(i)->toString(),
               newInst->dst(i)->toString());
        rewriteMap[it->dst(i)] = newInst->dst(i);
      }
    }

    target->insert(targetIt, newInst);
    targetIt = ++target->iteratorTo(newInst);
  }

  auto it = rpoIteratorTo(rpoBlocks, target);
  for (; it != rpoBlocks.end(); ++it) {
    FTRACE(5, "cloneToBlock: rewriting block {}\n", (*it)->id());
    for (auto& inst : **it) {
      FTRACE(5, " rewriting {}\n", inst.toString());
      rewriteSources(&inst);
    }
  }
}
Exemplo n.º 24
0
void process_bin_file(char *file_name) {
    int seq = 0;
	FILE *fp = fopen(file_name, "rb");
	if (!fp) {
		abort_("[read_bin_file] File %s cound not be opened for reading", file_name);
	}
    fseek(fp, 0, SEEK_END);
    long file_size = ftell(fp);
    if (file_size % BLOCK_SIZE) {
        abort_("[read_bin_file] File %s bad size", file_name);
    }
    fseek(fp, 0, SEEK_SET);
    Block block;
    block.resize(BLOCK_SIZE);
    BlockList blockList;
    for (int i=0; i<file_size/BLOCK_SIZE; ++i) {
        if (BLOCK_SIZE != fread(&(block.front()), 1, BLOCK_SIZE, fp)) {
            abort_("[read_bin_file] Fild %s read error", file_name);
        }
        if (0 == memcmp(&block.front(), FCC_TEX1, 4)) {
            if (!blockList.empty()) {
                ostringstream bc_file_name;
                bc_file_name << file_name << "-" << seq << ".bc";
                write_bc_file(blockList, bc_file_name.str());
                seq ++;
                blockList.clear();
            }
            blockList.push_back(block);
        }
        else {
            blockList.push_back(block);
        }
    }
    fclose(fp);
    cout << "Done" << endl;
}
Exemplo n.º 25
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;
}
Exemplo n.º 26
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);
     }
   }
 }
Exemplo n.º 27
0
void reflowTypes(Block* const changed, const BlockList& blocks) {
  assert(isRPOSorted(blocks));

  auto retypeDst = [&] (IRInstruction* inst, int num) {
    auto ssa = inst->dst(num);

    /*
     * The type of a tmp defined by DefLabel is the union of the
     * types of the tmps at each incoming Jmp.
     */
    if (inst->op() == DefLabel) {
      Type type = Type::Bottom;
      inst->block()->forEachSrc(num, [&](IRInstruction*, SSATmp* tmp) {
        type = Type::unionOf(type, tmp->type());
      });
      ssa->setType(type);
      return;
    }

    ssa->setType(outputType(inst, num));
  };

  auto visit = [&] (IRInstruction* inst) {
    for (int i = 0; i < inst->numDsts(); ++i) {
      auto const ssa = inst->dst(i);
      auto const oldType = ssa->type();
      retypeDst(inst, i);
      if (!ssa->type().equals(oldType)) {
        FTRACE(5, "reflowTypes: retyped {} in {}\n", oldType.toString(),
               inst->toString());
      }
    }
  };

  auto it = rpoIteratorTo(blocks, changed);
  assert(it != blocks.end());
  for (; it != blocks.end(); ++it) {
    FTRACE(5, "reflowTypes: visiting block {}\n", (*it)->id());
    for (auto& inst : **it) visit(&inst);
  }
}
Exemplo n.º 28
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;
}
Exemplo n.º 29
0
void LoopFinder::gather_loop_blocks(LoopList* loops) {
  int lng = loops->length();
  BitMap blocks_in_loop(max_blocks());
  for (int i = 0; i < lng; i++) {
    // for each loop do the following
    blocks_in_loop.clear();
    Loop* loop = loops->at(i);
    BlockList* ends = loop->ends();
    if (!loop->is_end(loop->start())) {
      GrowableArray<BlockBegin*>* stack = new GrowableArray<BlockBegin*>();
      blocks_in_loop.at_put(loop->start()->block_id(), true);
      
      // insert all the ends into the list
      for (int i = 0; i < ends->length(); i++) {
        blocks_in_loop.at_put(ends->at(i)->block_id()  , true);
        stack->push(ends->at(i));
      }
      
      while (!stack->is_empty()) {
        BlockBegin* bb = stack->pop();
        BlockLoopInfo* bli = get_block_info(bb);
        // push all predecessors that are not yet in loop
        int npreds = bli->nof_preds();
        for (int m = 0; m < npreds; m++) {
          BlockBegin* pred = bli->pred_no(m);
          if (!blocks_in_loop.at(pred->block_id())) {
            blocks_in_loop.at_put(pred->block_id(), true);
            loop->append_node(pred);
            stack->push(pred);
          }
        }
      }
      loop->append_node(loop->start());
    }
    // insert all the ends into the loop
    for (int i = 0; i < ends->length(); i++) {
      loop->append_node(ends->at(i));
    }
  }
}
Exemplo n.º 30
0
void HBlock::subdivide(BlockList& bl)
{
    bl.addBlock(this);
}