gcc源代码分析emit_call_insn()函数

来源:互联网 发布:王者荣耀地狱火优化 编辑:程序博客网 时间:2024/05/19 12:40

/* Build a function call to function FUNCTION with parameters PARAMS.
   PARAMS is a list--a chain of TREE_LIST nodes--in which the
   TREE_VALUE of each node is a parameter-expression.
   FUNCTION's data type may be a function type or a pointer-to-function.  */

tree
build_function_call (function, params)
     tree function, params;
{
  register tree fntype;
  register tree value_type;
  register tree coerced_params;
  tree name = NULL_TREE;
  tree actualparameterlist ();

  /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
     Strip such NOP_EXPRs, since FUNCTION is used in non-lvalue context.  */
  if (TREE_CODE (function) == NOP_EXPR
      && TREE_TYPE (function) == TREE_TYPE (TREE_OPERAND (function, 0)))
    function = TREE_OPERAND (function, 0);

  /* Convert anything with function type to a pointer-to-function.  */
  if (TREE_CODE (function) == FUNCTION_DECL)
    {
      name = DECL_NAME (function);
      /* Differs from default_conversion by not setting TREE_ADDRESSABLE
     (because calling an inline function does not mean the function
     needs to be separately compiled).  */
      function = build (ADDR_EXPR, build_pointer_type (TREE_TYPE (function)),
            function);
    }
  else
    function = default_conversion (function);

  fntype = TREE_TYPE (function);

  if (TREE_CODE (fntype) == ERROR_MARK)
    return error_mark_node;

  if (!(TREE_CODE (fntype) == POINTER_TYPE
    && TREE_CODE (TREE_TYPE (fntype)) == FUNCTION_TYPE))
    {
      error ("called object is not a function");
      return error_mark_node;
    }

  /* fntype now gets the type of function pointed to.  */
  fntype = TREE_TYPE (fntype);

  /* Convert the parameters to the types declared in the
     function prototype, or apply default promotions.  */

  coerced_params = actualparameterlist (TYPE_ARG_TYPES (fntype), params, name);

  /* Recognize certain built-in functions so we can make tree-codes
     other than CALL_EXPR.  We do this when it enables fold-const.c
     to do something useful.  */

  if (TREE_CODE (function) == ADDR_EXPR
      && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL)
    switch (DECL_FUNCTION_CODE (TREE_OPERAND (function, 0)))
      {
      case BUILT_IN_ABS:
      case BUILT_IN_LABS:
      case BUILT_IN_FABS:
    if (coerced_params == 0)
      return integer_zero_node;
    return build_unary_op (ABS_EXPR, TREE_VALUE (coerced_params), 0);
      }

  value_type = TREE_TYPE (fntype) ? TREE_TYPE (fntype) : void_type_node;
 
  {
    register tree result =
      build (CALL_EXPR, value_type, function, coerced_params, NULL_TREE);

    TREE_VOLATILE (result) = 1;
    if (value_type == void_type_node)
      return result;
    return require_complete_type (result);
  }
}



extern tree build ();

声明在tree.h中,定义在tree.c中


上面是建立语法树中和函数调用有关的代码。


下面是emit_rtl.c中处理rtl的部分

rtx

emit_call_insn (pattern)
     rtx pattern;
{
  if (GET_CODE (pattern) == SEQUENCE)
    return emit_insn (pattern);
  else
    {
      register rtx insn = make_insn_raw (pattern, NULL);
      add_insn (insn);
      PUT_CODE (insn, CALL_INSN);
      return insn;
    }

}



/* Emit the rtl pattern X as an appropriate kind of insn.
   If X is a label, it is simply added into the insn chain.  */

void
emit (x)
     rtx x;
{
  enum rtx_code code = classify_insn (x);

  if (code == CODE_LABEL)
    emit_label (x);
  else if (code == INSN)
    emit_insn (x);
  else if (code == JUMP_INSN)
    {
      register rtx insn = emit_jump_insn (x);
      if (simplejump_p (insn) || GET_CODE (x) == RETURN)
    emit_barrier ();
    }
  else if (code == CALL_INSN)
    emit_call_insn (x);

}

//在hello.c编译过程中这个函数没有被用到。
0 0
原创粉丝点击