service/method-inliner/CFGInliner.cpp
/*
 * If `insert_after`, add edges from callsite to the entry point and back from
 * the exit points to to the block after the callsite. Otherwise add edges
 * into callsite to the entry point and from the exit points to the block
 * after.
 */
If `insert_after`, add edges from callsite to the entry point and back from
the exit points to to the block after the callsite. Otherwise add edges
into callsite to the entry point and from the exit points to the block
after.
If ` insert_after ` add edges from callsite to the entry point and back from the exit points to to the block after the callsite . Otherwise add edges into callsite to the entry point and from the exit points to the block after .
void CFGInliner::connect_cfgs(bool inline_after,
                              ControlFlowGraph* cfg,
                              Block* callsite,
                              const std::vector<Block*>& callee_blocks,
                              Block* callee_entry,
                              const std::vector<Block*>& callee_exits,
                              Block* callsite_split) {
  const auto& caller_throws = callsite->get_outgoing_throws_in_order();
  if (!caller_throws.empty()) {
    add_callee_throws_to_caller(cfg, callee_blocks, caller_throws);
  }
  auto connect = [&cfg](const std::vector<Block*>& preds, Block* succ) {
    for (Block* pred : preds) {
      TRACE(CFG, 4, "connecting %zu, %zu in %s", pred->id(), succ->id(),
            SHOW(*cfg));
      cfg->add_edge(pred, succ, EDGE_GOTO);
    }
  };
  if (inline_after) {
    cfg->delete_succ_edge_if(
        callsite, [](const Edge* e) { return e->type() == EDGE_GOTO; });
    connect({callsite}, callee_entry);
  } else {
    cfg->delete_succ_edges(callsite_split);
    connect({callsite_split}, callee_entry);
  }
  if (inline_after) {
    connect(callee_exits, callsite_split);
  } else {
    cfg->delete_pred_edges(callsite);
    connect(callee_exits, callsite);
  }
}
void CFGInliner :: connect_cfgs ( bool inline_after , ControlFlowGraph * cfg , Block * callsite , const std :: vector < Block * > & callee_blocks , Block * callee_entry , const std :: vector < Block * > & callee_exits , Block * callsite_split ) { const auto & caller_throws = callsite -> get_outgoing_throws_in_order ( ) ; if ( ! caller_throws . empty ( ) ) { add_callee_throws_to_caller ( cfg , callee_blocks , caller_throws ) ; } auto connect = [ & cfg ] ( const std :: vector < Block * > & preds , Block * succ ) { for ( Block * pred : preds ) { TRACE ( CFG , 4 , " " , pred -> id ( ) , succ -> id ( ) , SHOW ( * cfg ) ) ; cfg -> add_edge ( pred , succ , EDGE_GOTO ) ; } } ; if ( inline_after ) { cfg -> delete_succ_edge_if ( callsite , [ ] ( const Edge * e ) { return e -> type ( ) == EDGE_GOTO ; } ) ; connect ( { callsite } , callee_entry ) ; } else { cfg -> delete_succ_edges ( callsite_split ) ; connect ( { callsite_split } , callee_entry ) ; } if ( inline_after ) { connect ( callee_exits , callsite_split ) ; } else { cfg -> delete_pred_edges ( callsite ) ; connect ( callee_exits , callsite ) ; } }
If `insert_after`, add edges from callsite to the entry point and back from
 the exit points to to the block after the callsite.
If ` insert_after ` add edges from callsite to the entry point and back from the exit points to to the block after the callsite .
// Add edges from callee throw sites to caller catch sites // Remove the goto between the callsite and its successor // Remove the preds into callsite, having moved them to entry // TODO: tail call optimization (if callsite_split is a return & inline_after)