gcc 源码分析---gimple 程序流程

static void
do_compile ()
{

  .....

compile_file()

....

}

static void
compile_file (void)

{

        ...

      /* Run the actual compilation process.  */
  if (!in_lto_p)
    {
      timevar_start (TV_PHASE_OPT_GEN);
      symtab->finalize_compilation_unit ();
      timevar_stop (TV_PHASE_OPT_GEN);
    }

.....

}

void
symbol_table::finalize_compilation_unit (void)

{

        .....

/* Gimplify and lower all functions, compute reachability and
     remove unreachable nodes.  */
  analyze_functions (/*first_time=*/true);

  /* Mark alias targets necessary and emit diagnostics.  */
  handle_alias_pairs ();

  /* Gimplify and lower thunks.  */
  analyze_functions (/*first_time=*/false);

.....

}

static void
analyze_functions (bool first_time)

{
  /* Keep track of already processed nodes when called multiple times for
     intermodule optimization.  */
  cgraph_node *first_handled = first_analyzed;
  varpool_node *first_handled_var = first_analyzed_var;
  hash_set<void *> reachable_call_targets;

  symtab_node *node;
  symtab_node *next;
  int i;
  ipa_ref *ref;
  bool changed = true;
  location_t saved_loc = input_location;

  bitmap_obstack_initialize (NULL);
  symtab->state = CONSTRUCTION;
  input_location = UNKNOWN_LOCATION;

  thunk_info::process_early_thunks ();

  /* Ugly, but the fixup cannot happen at a time same body alias is created;
     C++ FE is confused about the COMDAT groups being right.  */
  if (symtab->cpp_implicit_aliases_done)
    FOR_EACH_SYMBOL (node)
      if (node->cpp_implicit_alias)
      node->fixup_same_cpp_alias_visibility (node->get_alias_target ());
  build_type_inheritance_graph ();

  if (flag_openmp && first_time)
    omp_discover_implicit_declare_target ();

  /* Analysis adds static variables that in turn adds references to new functions.
     So we need to iterate the process until it stabilize.  */
  while (changed)
    {
      changed = false;
      process_function_and_variable_attributes (first_analyzed,
                        first_analyzed_var);

      /* First identify the trivially needed symbols.  */
      for (node = symtab->first_symbol ();
       node != first_analyzed
       && node != first_analyzed_var; node = node->next)
    {
      /* Convert COMDAT group designators to IDENTIFIER_NODEs.  */
      node->get_comdat_group_id ();
      if (node->needed_p ())
        {
          enqueue_node (node);
          if (!changed && symtab->dump_file)
        fprintf (symtab->dump_file, "Trivially needed symbols:");
          changed = true;
          if (symtab->dump_file)
        fprintf (symtab->dump_file, " %s", node->dump_asm_name ());
        }
      if (node == first_analyzed
          || node == first_analyzed_var)
        break;
    }
      symtab->process_new_functions ();
      first_analyzed_var = symtab->first_variable ();
      first_analyzed = symtab->first_function ();

      if (changed && symtab->dump_file)
    fprintf (symtab->dump_file, "\n");

      /* Lower representation, build callgraph edges and references for all trivially
         needed symbols and all symbols referred by them.  */
      while (queued_nodes != &symtab_terminator)
    {
      changed = true;
      node = queued_nodes;
      queued_nodes = (symtab_node *)queued_nodes->aux;
      cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
      if (cnode && cnode->definition)
        {
          cgraph_edge *edge;
          tree decl = cnode->decl;

          /* ??? It is possible to create extern inline function
          and later using weak alias attribute to kill its body.
          See gcc.c-torture/compile/20011119-1.c  */
          if (!DECL_STRUCT_FUNCTION (decl)
          && !cnode->alias
          && !cnode->thunk
          && !cnode->dispatcher_function)
        {
          cnode->reset ();
          cnode->redefined_extern_inline = true;
          continue;
        }

          if (!cnode->analyzed)
        cnode->analyze ();

          for (edge = cnode->callees; edge; edge = edge->next_callee)
        if (edge->callee->definition
            && (!DECL_EXTERNAL (edge->callee->decl)
            /* When not optimizing, do not try to analyze extern
               inline functions.  Doing so is pointless.  */
            || opt_for_fn (edge

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GoldKey

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值