示例#1
0
/* Print all ipcp_lattices of all functions to F.  */
static void
ipcp_print_all_lattices (FILE * f)
{
  struct cgraph_node *node;
  int i, count;

  fprintf (f, "\nLattice:\n");
  for (node = cgraph_nodes; node; node = node->next)
    {
      struct ipa_node_params *info;

      if (!node->analyzed)
	continue;
      info = IPA_NODE_REF (node);
      fprintf (f, "  Node: %s:\n", cgraph_node_name (node));
      count = ipa_get_param_count (info);
      for (i = 0; i < count; i++)
	{
	  struct ipcp_lattice *lat = ipcp_get_lattice (info, i);

	  fprintf (f, "    param [%d]: ", i);
	  if (lat->type == IPA_CONST_VALUE)
	    {
	      tree cst = lat->constant;
	      fprintf (f, "type is CONST ");
	      print_generic_expr (f, cst, 0);
	      if (TREE_CODE (cst) == ADDR_EXPR
		  && TREE_CODE (TREE_OPERAND (cst, 0)) == CONST_DECL)
		{
		  fprintf (f, " -> ");
		  print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (cst, 0)),
						       0);
		}
	    }
	  else if (lat->type == IPA_TOP)
	    fprintf (f, "type is TOP");
	  else
	    fprintf (f, "type is BOTTOM");
	  if (ipa_param_cannot_devirtualize_p (info, i))
	    fprintf (f, " - cannot_devirtualize set\n");
	  else if (ipa_param_types_vec_empty (info, i))
	    fprintf (f, " - type list empty\n");
	  else
	    fprintf (f, "\n");
	}
    }
}
示例#2
0
static tree build_junk_fn(unsigned id)
{
    char fnname[32] = {0};
    tree decl, resdecl, initial, proto;

    /* Func decl */
    snprintf(fnname, 31, "__func%d", id);
    proto = build_varargs_function_type_list(void_type_node, NULL_TREE);
    decl = build_fn_decl(fnname, proto);
    SET_DECL_ASSEMBLER_NAME(decl, get_identifier(fnname));
    
    printf(TAG "Creating junk function: %s\n", fnname);
   
    /* Result */ 
    resdecl=build_decl(BUILTINS_LOCATION,RESULT_DECL,NULL_TREE,void_type_node);
    DECL_ARTIFICIAL(resdecl) = 1;
    DECL_CONTEXT(resdecl) = decl;
    DECL_RESULT(decl) = resdecl;
    
    /* Initial */
    initial = make_node(BLOCK);
    TREE_USED(initial) = 1;
    DECL_INITIAL(decl) = initial;
    DECL_UNINLINABLE(decl) = 1;
    DECL_EXTERNAL(decl) = 0;
    DECL_PRESERVE_P(decl) = 1;

    /* Func decl */
    TREE_USED(decl) = 1;
    TREE_PUBLIC(decl) = 1;
    TREE_STATIC(decl) = 1;
    DECL_ARTIFICIAL(decl) = 1;

    /* Make the function */
    push_struct_function(decl);
    /* DECL_SAVED_TREE(decl) = gen_junk(); */
    cfun->function_end_locus = BUILTINS_LOCATION;
    gimplify_function_tree(decl);

    /* Update */
    cgraph_add_new_function(decl, false);
    cgraph_mark_needed_node(cgraph_node(decl));
    current_function_decl = NULL_TREE;
    pop_cfun();

    return decl;
}
示例#3
0
文件: method.c 项目: Fokycnuk/gcc
static tree
make_alias_for_thunk (tree function)
{
  tree alias;
  char buf[256];

#if defined (TARGET_IS_PE_COFF)
  if (DECL_ONE_ONLY (function))
    return function;
#endif

  ASM_GENERATE_INTERNAL_LABEL (buf, "LTHUNK", thunk_labelno);
  thunk_labelno++;
  alias = build_decl (FUNCTION_DECL, get_identifier (buf),
		      TREE_TYPE (function));
  DECL_LANG_SPECIFIC (alias) = DECL_LANG_SPECIFIC (function);
  cxx_dup_lang_specific_decl (alias);
  DECL_CONTEXT (alias) = NULL;
  TREE_READONLY (alias) = TREE_READONLY (function);
  TREE_THIS_VOLATILE (alias) = TREE_THIS_VOLATILE (function);
  TREE_PUBLIC (alias) = 0;
  DECL_INTERFACE_KNOWN (alias) = 1;
  DECL_NOT_REALLY_EXTERN (alias) = 1;
  DECL_THIS_STATIC (alias) = 1;
  DECL_SAVED_FUNCTION_DATA (alias) = NULL;
  DECL_DESTRUCTOR_P (alias) = 0;
  DECL_CONSTRUCTOR_P (alias) = 0;
  DECL_CLONED_FUNCTION (alias) = NULL_TREE;
  DECL_EXTERNAL (alias) = 0;
  DECL_ARTIFICIAL (alias) = 1;
  DECL_NO_STATIC_CHAIN (alias) = 1;
  DECL_PENDING_INLINE_P (alias) = 0;
  DECL_INLINE (alias) = 0;
  DECL_DECLARED_INLINE_P (alias) = 0;
  DECL_DEFERRED_FN (alias) = 0;
  DECL_USE_TEMPLATE (alias) = 0;
  DECL_TEMPLATE_INSTANTIATED (alias) = 0;
  DECL_TEMPLATE_INFO (alias) = NULL;
  DECL_INITIAL (alias) = error_mark_node;
  TREE_ADDRESSABLE (alias) = 1;
  TREE_USED (alias) = 1;
  SET_DECL_ASSEMBLER_NAME (alias, DECL_NAME (alias));
  TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (alias)) = 1;
  if (!flag_syntax_only)
    assemble_alias (alias, DECL_ASSEMBLER_NAME (function));
  return alias;
}
示例#4
0
文件: cilk.c 项目: Distrotech/gcc
static tree
create_cilk_helper_decl (struct wrapper_data *wd)
{
  char name[20];
  if (wd->type == CILK_BLOCK_FOR)
    sprintf (name, "_cilk_for_" HOST_WIDE_INT_PRINT_DEC, cilk_wrapper_count++);
  else if (wd->type == CILK_BLOCK_SPAWN)
    sprintf (name, "_cilk_spn_" HOST_WIDE_INT_PRINT_DEC, cilk_wrapper_count++);
  else
    gcc_unreachable (); 
  
  clean_symbol_name (name);

  tree fndecl = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
			    FUNCTION_DECL, get_identifier (name), wd->fntype);

  TREE_PUBLIC (fndecl) = 0;
  TREE_STATIC (fndecl) = 1;
  TREE_USED (fndecl) = 1;
  DECL_ARTIFICIAL (fndecl) = 0;
  DECL_IGNORED_P (fndecl) = 0;
  DECL_EXTERNAL (fndecl) = 0;

  DECL_CONTEXT (fndecl) = wd->context; 
  tree block = make_node (BLOCK);
  DECL_INITIAL (fndecl) = block;
  TREE_USED (block) = 1;
  BLOCK_SUPERCONTEXT (block) = fndecl;
  gcc_assert (!DECL_SAVED_TREE (fndecl));

  /* Inlining would defeat the purpose of this wrapper.
     Either it secretly switches stack frames or it allocates
     a stable stack frame to hold function arguments even if
     the parent stack frame is stolen.  */
  DECL_UNINLINABLE (fndecl) = 1;

  tree result_decl = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, 
				 void_type_node);
  DECL_ARTIFICIAL (result_decl) = 0;
  DECL_IGNORED_P (result_decl) = 1;
  DECL_CONTEXT (result_decl) = fndecl;
  DECL_RESULT (fndecl) = result_decl;
  
  return fndecl;
}
示例#5
0
文件: varpool.c 项目: palves/gcc
/* Remove node from the varpool.  */
void
varpool_remove_node (varpool_node *node)
{
  tree init;
  varpool_call_node_removal_hooks (node);
  symtab_unregister_node (node);

  /* Because we remove references from external functions before final compilation,
     we may end up removing useful constructors.
     FIXME: We probably want to trace boundaries better.  */
  if (cgraph_state == CGRAPH_LTO_STREAMING)
    ;
  else if ((init = ctor_for_folding (node->decl)) == error_mark_node)
    varpool_remove_initializer (node);
  else
    DECL_INITIAL (node->decl) = init;
  ggc_free (node);
}
示例#6
0
static void search_local_strs(bool initexit)
{
	unsigned int i;
	tree var;

	FOR_EACH_LOCAL_DECL(cfun, i, var) {
		tree str, init_val = DECL_INITIAL(var);

		if (init_val == NULL_TREE)
			continue;
		if (strcmp(DECL_NAME_POINTER(var), "__func__"))
			continue;

		str = get_string_cst(init_val);
		gcc_assert(str);

		if (set_init_exit_section(var, initexit) && verbose)
			inform(DECL_SOURCE_LOCATION(var), "initified local var: %s: %s", DECL_NAME_POINTER(current_function_decl), TREE_STRING_POINTER(str));
	}
示例#7
0
文件: treetree.c 项目: aosm/gccfast
/* Wrapup a function contained in file FILENAME, ending at line LINENO.  */
void 
tree_code_create_function_wrapup (unsigned char* filename,
                                 int lineno)
{
  tree block;
  tree fn_decl;

  fn_decl = current_function_decl;
  
  emit_line_note ((const char *)filename, lineno); /* Output the line number information.  */

  /* Get completely built level from debugger symbol table.  */
  
  block = (*lang_hooks.decls.poplevel) (1, 0, 0);
  
  /* Emit rtl for end of scope.  */
  
  expand_end_bindings (block, 0, 1);
  
  /* Emit rtl for end of function.  */
  
  expand_function_end ((const char *)filename, lineno, 0, fn_decl);
  
  /* Pop the level.  */

  block = (*lang_hooks.decls.poplevel) (1, 0, 1);

  /* And attach it to the function.  */
  
  DECL_INITIAL (fn_decl) = block;
  
  /* Emit rtl for end of scope.  */
  
  expand_end_bindings (block, 0, 1);
  
  /* Call optimization and convert optimized rtl to assembly code.  */
  
  rest_of_compilation (fn_decl);
  
  /* We are not inside of any scope now.  */
  
  current_function_decl = NULL_TREE;
}
示例#8
0
static void
build_function (tree fndecl, tree stmts, tree block)
{
    DECL_INITIAL(fndecl) = block;
    DECL_SAVED_TREE (fndecl) = stmts ;

    tree resdecl = build_decl(input_location,RESULT_DECL, NULL_TREE, integer_type_node);
    DECL_CONTEXT (resdecl) = fndecl;
    DECL_RESULT(fndecl) = resdecl;
    current_function_decl = fndecl;

    if (DECL_STRUCT_FUNCTION(fndecl) == NULL)
        push_struct_function(fndecl);
    else
		push_cfun(DECL_STRUCT_FUNCTION(fndecl));

    cfun->function_end_locus = BUILTINS_LOCATION;

}
示例#9
0
static tree
ubsan_walk_array_refs_r (tree *tp, int *walk_subtrees, void *data)
{
  hash_set<tree> *pset = (hash_set<tree> *) data;

  if (TREE_CODE (*tp) == BIND_EXPR)
    {
      /* Since walk_tree doesn't call the callback function on the decls
	 in BIND_EXPR_VARS, we have to walk them manually, so we can avoid
	 instrumenting DECL_INITIAL of TREE_STATIC vars.  */
      *walk_subtrees = 0;
      for (tree decl = BIND_EXPR_VARS (*tp); decl; decl = DECL_CHAIN (decl))
	{
	  if (TREE_STATIC (decl))
	    continue;
	  walk_tree (&DECL_INITIAL (decl), ubsan_walk_array_refs_r, pset,
		     pset);
	  walk_tree (&DECL_SIZE (decl), ubsan_walk_array_refs_r, pset, pset);
	  walk_tree (&DECL_SIZE_UNIT (decl), ubsan_walk_array_refs_r, pset,
		     pset);
	}
      walk_tree (&BIND_EXPR_BODY (*tp), ubsan_walk_array_refs_r, pset, pset);
    }
  else if (TREE_CODE (*tp) == ADDR_EXPR
	   && TREE_CODE (TREE_OPERAND (*tp, 0)) == ARRAY_REF)
    {
      ubsan_maybe_instrument_array_ref (&TREE_OPERAND (*tp, 0), true);
      /* Make sure ubsan_maybe_instrument_array_ref is not called again
	 on the ARRAY_REF, the above call might not instrument anything
	 as the index might be constant or masked, so ensure it is not
	 walked again and walk its subtrees manually.  */
      tree aref = TREE_OPERAND (*tp, 0);
      pset->add (aref);
      *walk_subtrees = 0;
      walk_tree (&TREE_OPERAND (aref, 0), ubsan_walk_array_refs_r, pset, pset);
      walk_tree (&TREE_OPERAND (aref, 1), ubsan_walk_array_refs_r, pset, pset);
      walk_tree (&TREE_OPERAND (aref, 2), ubsan_walk_array_refs_r, pset, pset);
      walk_tree (&TREE_OPERAND (aref, 3), ubsan_walk_array_refs_r, pset, pset);
    }
  else if (TREE_CODE (*tp) == ARRAY_REF)
    ubsan_maybe_instrument_array_ref (tp, false);
  return NULL_TREE;
}
示例#10
0
/* Dump given cgraph node.  */
void
dump_varpool_node (FILE *f, varpool_node *node)
{
  dump_symtab_base (f, node);
  fprintf (f, "  Availability: %s\n",
	   cgraph_function_flags_ready
	   ? cgraph_availability_names[cgraph_variable_initializer_availability (node)]
	   : "not-ready");
  fprintf (f, "  Varpool flags:");
  if (DECL_INITIAL (node->decl))
    fprintf (f, " initialized");
  if (node->output)
    fprintf (f, " output");
  if (TREE_READONLY (node->decl))
    fprintf (f, " read-only");
  if (ctor_for_folding (node->decl) != error_mark_node)
    fprintf (f, " const-value-known");
  fprintf (f, "\n");
}
示例#11
0
文件: varpool.c 项目: Lao16/gcc
/* Dump given cgraph node.  */
void
dump_varpool_node (FILE *f, struct varpool_node *node)
{
  dump_symtab_base (f, (symtab_node)node);
  fprintf (f, "  Availability: %s\n",
	   cgraph_function_flags_ready
	   ? cgraph_availability_names[cgraph_variable_initializer_availability (node)]
	   : "not-ready");
  fprintf (f, "  Varpool flags:");
  if (DECL_INITIAL (node->symbol.decl))
    fprintf (f, " initialized");
  if (node->analyzed)
    fprintf (f, " analyzed");
  if (node->finalized)
    fprintf (f, " finalized");
  if (node->output)
    fprintf (f, " output");
  fprintf (f, "\n");
}
示例#12
0
文件: varpool.c 项目: Lao16/gcc
void
varpool_analyze_node (struct varpool_node *node)
{
  tree decl = node->symbol.decl;

  /* When reading back varpool at LTO time, we re-construct the queue in order
     to have "needed" list right by inserting all needed nodes into varpool.
     We however don't want to re-analyze already analyzed nodes.  */
  if (!node->analyzed)
    {
      gcc_assert (!in_lto_p || cgraph_function_flags_ready);
      /* Compute the alignment early so function body expanders are
	 already informed about increased alignment.  */
      align_variable (decl, 0);
    }
  if (node->alias && node->alias_of)
    {
      struct varpool_node *tgt = varpool_node_for_decl (node->alias_of);
      struct varpool_node *n;

      for (n = tgt; n && n->alias;
	   n = n->analyzed ? varpool_alias_aliased_node (n) : NULL)
	if (n == node)
	  {
	    error ("variable %q+D part of alias cycle", node->symbol.decl);
	    node->alias = false;
	    continue;
	  }
      if (!vec_safe_length (node->symbol.ref_list.references))
	ipa_record_reference ((symtab_node)node, (symtab_node)tgt, IPA_REF_ALIAS, NULL);
      if (node->extra_name_alias)
	{
	  DECL_WEAK (node->symbol.decl) = DECL_WEAK (node->alias_of);
	  DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (node->alias_of);
	  DECL_VISIBILITY (node->symbol.decl) = DECL_VISIBILITY (node->alias_of);
	  fixup_same_cpp_alias_visibility ((symtab_node) node,
					   (symtab_node) tgt, node->alias_of);
	}
    }
  else if (DECL_INITIAL (decl))
    record_references_in_initializer (decl, node->analyzed);
  node->analyzed = true;
}
示例#13
0
static tree
build_trivial_generic_function ()
{
  auto_vec <tree> param_types;
  tree fndecl = make_fndecl (integer_type_node,
			     "test_fn",
			     param_types);
  ASSERT_TRUE (fndecl != NULL);

  /* Populate the function.  */
  tree retval = build_decl (UNKNOWN_LOCATION, RESULT_DECL,
			    NULL_TREE, integer_type_node);
  DECL_ARTIFICIAL (retval) = 1;
  DECL_IGNORED_P (retval) = 1;
  DECL_RESULT (fndecl) = retval;

  /* Create a BIND_EXPR, and within it, a statement list.  */
  tree stmt_list = alloc_stmt_list ();
  tree_stmt_iterator stmt_iter = tsi_start (stmt_list);
  tree block = make_node (BLOCK);
  tree bind_expr
    = build3 (BIND_EXPR, void_type_node, NULL, stmt_list, block);

  tree modify_retval = build2 (MODIFY_EXPR,
			       integer_type_node,
			       retval,
			       build_int_cst (integer_type_node, 42));
  tree return_stmt = build1 (RETURN_EXPR,
			     integer_type_node,
			     modify_retval);
  tsi_link_after (&stmt_iter, return_stmt, TSI_CONTINUE_LINKING);

  DECL_INITIAL (fndecl) = block;

  /* how to add to function? the following appears to be how to
     set the body of a fndecl: */
  DECL_SAVED_TREE(fndecl) = bind_expr;

  /* Ensure that locals appear in the debuginfo.  */
  BLOCK_VARS (block) = BIND_EXPR_VARS (bind_expr);

  return fndecl;
}
void
compile_resource_data (const char *name, const char *buffer, int length)
{
  tree rtype, field = NULL_TREE, data_type, rinit, data, decl;
  char buf[60];

  data_type = build_prim_array_type (unsigned_byte_type_node,
				     strlen (name) + length);
  rtype = make_node (RECORD_TYPE);
  PUSH_FIELD (rtype, field, "name_length", unsigned_int_type_node);
  PUSH_FIELD (rtype, field, "resource_length", unsigned_int_type_node);
  PUSH_FIELD (rtype, field, "data", data_type);
  FINISH_RECORD (rtype);
  START_RECORD_CONSTRUCTOR (rinit, rtype);
  PUSH_FIELD_VALUE (rinit, "name_length", 
		    build_int_cst (NULL_TREE, strlen (name)));
  PUSH_FIELD_VALUE (rinit, "resource_length", 
		    build_int_cst (NULL_TREE, length));
  data = build_string (strlen(name) + length, buffer);
  TREE_TYPE (data) = data_type;
  PUSH_FIELD_VALUE (rinit, "data", data);
  FINISH_RECORD_CONSTRUCTOR (rinit);
  TREE_CONSTANT (rinit) = 1;
  TREE_INVARIANT (rinit) = 1;

  /* Generate a unique-enough identifier.  */
  sprintf (buf, "_Jr%d", ++Jr_count);

  decl = build_decl (VAR_DECL, get_identifier (buf), rtype);
  TREE_STATIC (decl) = 1;
  DECL_ARTIFICIAL (decl) = 1;
  DECL_IGNORED_P (decl) = 1;
  TREE_READONLY (decl) = 1;
  TREE_THIS_VOLATILE (decl) = 0;
  DECL_INITIAL (decl) = rinit;
  layout_decl (decl, 0);
  pushdecl (decl);
  rest_of_decl_compilation (decl, global_bindings_p (), 0);
  make_decl_rtl (decl);
  assemble_variable (decl, 1, 0, 0);

  resources = tree_cons (NULL_TREE, decl, resources);
}
示例#15
0
void
compile_resource_data (const char *name, const char *buffer, int length)
{
  tree rtype, field = NULL_TREE, data_type, rinit, data, decl;
  VEC(constructor_elt,gc) *v = NULL;

  data_type = build_prim_array_type (unsigned_byte_type_node,
				     strlen (name) + length);
  rtype = make_node (RECORD_TYPE);
  PUSH_FIELD (input_location,
	      rtype, field, "name_length", unsigned_int_type_node);
  PUSH_FIELD (input_location,
	      rtype, field, "resource_length", unsigned_int_type_node);
  PUSH_FIELD (input_location, rtype, field, "data", data_type);
  FINISH_RECORD (rtype);
  START_RECORD_CONSTRUCTOR (v, rtype);
  PUSH_FIELD_VALUE (v, "name_length", 
		    build_int_cst (NULL_TREE, strlen (name)));
  PUSH_FIELD_VALUE (v, "resource_length", 
		    build_int_cst (NULL_TREE, length));
  data = build_string (strlen(name) + length, buffer);
  TREE_TYPE (data) = data_type;
  PUSH_FIELD_VALUE (v, "data", data);
  FINISH_RECORD_CONSTRUCTOR (rinit, v, rtype);
  TREE_CONSTANT (rinit) = 1;

  decl = build_decl (input_location,
		     VAR_DECL, java_mangle_resource_name (name), rtype);
  TREE_STATIC (decl) = 1;
  TREE_PUBLIC (decl) = 1;
  java_hide_decl (decl);
  DECL_ARTIFICIAL (decl) = 1;
  DECL_IGNORED_P (decl) = 1;
  TREE_READONLY (decl) = 1;
  TREE_THIS_VOLATILE (decl) = 0;
  DECL_INITIAL (decl) = rinit;
  layout_decl (decl, 0);
  pushdecl (decl);
  rest_of_decl_compilation (decl, global_bindings_p (), 0);
  varpool_finalize_decl (decl);

  VEC_safe_push (tree, gc, resources, decl);
}
static void
build_one_array (gimple swtch, int num, tree arr_index_type, gimple phi,
		 tree tidx)
{
  tree array_type, ctor, decl, value_type, name, fetch;
  gimple load;
  gimple_stmt_iterator gsi;

  gcc_assert (info.default_values[num]);
  value_type = TREE_TYPE (info.default_values[num]);
  array_type = build_array_type (value_type, arr_index_type);

  ctor = build_constructor (array_type, info.constructors[num]);
  TREE_CONSTANT (ctor) = true;

  decl = build_decl (VAR_DECL, NULL_TREE, array_type);
  TREE_STATIC (decl) = 1;
  DECL_INITIAL (decl) = ctor;

  DECL_NAME (decl) = create_tmp_var_name ("CSWTCH");
  DECL_ARTIFICIAL (decl) = 1;
  TREE_CONSTANT (decl) = 1;
  add_referenced_var (decl);
  varpool_mark_needed_node (varpool_node (decl));
  varpool_finalize_decl (decl);
  mark_sym_for_renaming (decl);

  name = make_ssa_name (SSA_NAME_VAR (PHI_RESULT (phi)), NULL);
  info.target_inbound_names[num] = name;

  fetch = build4 (ARRAY_REF, value_type, decl, tidx, NULL_TREE,
		  NULL_TREE);
  load = gimple_build_assign (name, fetch);
  SSA_NAME_DEF_STMT (name) = load;

  gsi = gsi_for_stmt (swtch);
  gsi_insert_before (&gsi, load, GSI_SAME_STMT);
  mark_symbols_for_renaming (load);

  info.arr_ref_last = load;
}
static void
lto_input_ts_block_tree_pointers (struct lto_input_block *ib,
				  struct data_in *data_in, tree expr)
{
  /* Do not stream BLOCK_SOURCE_LOCATION.  We cannot handle debug information
     for early inlining so drop it on the floor instead of ICEing in
     dwarf2out.c.  */
  BLOCK_VARS (expr) = streamer_read_chain (ib, data_in);

  /* Do not stream BLOCK_NONLOCALIZED_VARS.  We cannot handle debug information
     for early inlining so drop it on the floor instead of ICEing in
     dwarf2out.c.  */

  BLOCK_SUPERCONTEXT (expr) = stream_read_tree (ib, data_in);

  /* Do not stream BLOCK_ABSTRACT_ORIGIN.  We cannot handle debug information
     for early inlining so drop it on the floor instead of ICEing in
     dwarf2out.c.  */
  BLOCK_FRAGMENT_ORIGIN (expr) = stream_read_tree (ib, data_in);
  BLOCK_FRAGMENT_CHAIN (expr) = stream_read_tree (ib, data_in);

  /* We re-compute BLOCK_SUBBLOCKS of our parent here instead
     of streaming it.  For non-BLOCK BLOCK_SUPERCONTEXTs we still
     stream the child relationship explicitly.  */
  if (BLOCK_SUPERCONTEXT (expr)
      && TREE_CODE (BLOCK_SUPERCONTEXT (expr)) == BLOCK)
    {
      BLOCK_CHAIN (expr) = BLOCK_SUBBLOCKS (BLOCK_SUPERCONTEXT (expr));
      BLOCK_SUBBLOCKS (BLOCK_SUPERCONTEXT (expr)) = expr;
    }

  /* The global block is rooted at the TU decl.  Hook it here to
     avoid the need to stream in this block during WPA time.  */
  else if (BLOCK_SUPERCONTEXT (expr)
	   && TREE_CODE (BLOCK_SUPERCONTEXT (expr)) == TRANSLATION_UNIT_DECL)
    DECL_INITIAL (BLOCK_SUPERCONTEXT (expr)) = expr;

  /* The function-level block is connected at the time we read in
     function bodies for the same reason.  */
}
示例#18
0
/* Walk the decls we marked as necessary and see if they reference new
   variables or functions and add them into the worklists.  */
bool
varpool_analyze_pending_decls (void)
{
  bool changed = false;

  timevar_push (TV_VARPOOL);
  while (varpool_first_unanalyzed_node)
    {
      struct varpool_node *node = varpool_first_unanalyzed_node, *next;
      tree decl = node->decl;
      bool analyzed = node->analyzed;

      varpool_first_unanalyzed_node->analyzed = true;

      varpool_first_unanalyzed_node = varpool_first_unanalyzed_node->next_needed;

      /* When reading back varpool at LTO time, we re-construct the queue in order
         to have "needed" list right by inserting all needed nodes into varpool.
	 We however don't want to re-analyze already analyzed nodes.  */
      if (!analyzed)
	{
	  gcc_assert (!in_lto_p || cgraph_function_flags_ready);
          /* Compute the alignment early so function body expanders are
	     already informed about increased alignment.  */
          align_variable (decl, 0);
	}
      if (DECL_INITIAL (decl))
	record_references_in_initializer (decl, analyzed);
      if (node->same_comdat_group)
	{
	  for (next = node->same_comdat_group;
	       next != node;
	       next = next->same_comdat_group)
	    varpool_mark_needed_node (next);
	}
      changed = true;
    }
  timevar_pop (TV_VARPOOL);
  return changed;
}
示例#19
0
文件: varpool.c 项目: palves/gcc
void
varpool_analyze_node (varpool_node *node)
{
  tree decl = node->decl;

  /* When reading back varpool at LTO time, we re-construct the queue in order
     to have "needed" list right by inserting all needed nodes into varpool.
     We however don't want to re-analyze already analyzed nodes.  */
  if (!node->analyzed)
    {
      gcc_assert (!in_lto_p || cgraph_function_flags_ready);
      /* Compute the alignment early so function body expanders are
	 already informed about increased alignment.  */
      align_variable (decl, 0);
    }
  if (node->alias)
    symtab_resolve_alias
       (node, varpool_get_node (node->alias_target));
  else if (DECL_INITIAL (decl))
    record_references_in_initializer (decl, node->analyzed);
  node->analyzed = true;
}
示例#20
0
tree
make_alias_for (tree target, tree newid)
{
  tree alias = build_decl (DECL_SOURCE_LOCATION (target),
			   TREE_CODE (target), newid, TREE_TYPE (target));
  DECL_LANG_SPECIFIC (alias) = DECL_LANG_SPECIFIC (target);
  cxx_dup_lang_specific_decl (alias);
  DECL_CONTEXT (alias) = NULL;
  TREE_READONLY (alias) = TREE_READONLY (target);
  TREE_THIS_VOLATILE (alias) = TREE_THIS_VOLATILE (target);
  TREE_PUBLIC (alias) = 0;
  DECL_INTERFACE_KNOWN (alias) = 1;
  if (DECL_LANG_SPECIFIC (alias))
    {
      DECL_NOT_REALLY_EXTERN (alias) = 1;
      DECL_USE_TEMPLATE (alias) = 0;
      DECL_TEMPLATE_INFO (alias) = NULL;
    }
  DECL_EXTERNAL (alias) = 0;
  DECL_ARTIFICIAL (alias) = 1;
  DECL_TEMPLATE_INSTANTIATED (alias) = 0;
  if (TREE_CODE (alias) == FUNCTION_DECL)
    {
      DECL_SAVED_FUNCTION_DATA (alias) = NULL;
      DECL_DESTRUCTOR_P (alias) = 0;
      DECL_CONSTRUCTOR_P (alias) = 0;
      DECL_PENDING_INLINE_P (alias) = 0;
      DECL_DECLARED_INLINE_P (alias) = 0;
      DECL_INITIAL (alias) = error_mark_node;
      DECL_ARGUMENTS (alias) = copy_list (DECL_ARGUMENTS (target));
    }
  else
    TREE_STATIC (alias) = 1;
  TREE_ADDRESSABLE (alias) = 1;
  TREE_USED (alias) = 1;
  SET_DECL_ASSEMBLER_NAME (alias, DECL_NAME (alias));
  TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (alias)) = 1;
  return alias;
}
示例#21
0
static tree
start_handler_array ()
{
  tree handler_array_type, decl;

  push_obstacks_nochange ();
  end_temporary_allocation ();
  handler_array_type = build_array_type (handler_element_type, NULL_TREE);
  decl = build_lang_decl (VAR_DECL,
			  get_unique_identifier ("handler_table"),
			  handler_array_type);

/*  TREE_TYPE (decl) = handler_array_type;*/
  TREE_READONLY (decl) = 1;
  TREE_STATIC (decl) = 1;
  DECL_INITIAL (decl) = error_mark_node;
  
  pushdecl (decl);
  make_decl_rtl (decl, NULL_PTR, 0);
  current_handler->handler_array_decl = decl;
  return decl;
}
/* Dump given cgraph node.  */
void
dump_varpool_node (FILE *f, struct varpool_node *node)
{
  fprintf (f, "%s:", varpool_node_name (node));
  fprintf (f, " availability:%s",
	   cgraph_function_flags_ready
	   ? cgraph_availability_names[cgraph_variable_initializer_availability (node)]
	   : "not-ready");
  if (DECL_INITIAL (node->decl))
    fprintf (f, " initialized");
  if (node->needed)
    fprintf (f, " needed");
  if (node->analyzed)
    fprintf (f, " analyzed");
  if (node->finalized)
    fprintf (f, " finalized");
  if (node->output)
    fprintf (f, " output");
  if (node->externally_visible)
    fprintf (f, " externally_visible");
  fprintf (f, "\n");
}
/// ValidateRegisterVariable - Check that a static "asm" variable is
/// well-formed.  If not, emit error messages and return true.  If so, return
/// false.
bool ValidateRegisterVariable(tree decl) {
  const char *Name = IDENTIFIER_POINTER(DECL_ASSEMBLER_NAME(decl));
  int RegNumber = decode_reg_name(Name);
  const Type *Ty = ConvertType(TREE_TYPE(decl));

  // If this has already been processed, don't emit duplicate error messages.
  if (DECL_LLVM_SET_P(decl)) {
    // Error state encoded into DECL_LLVM.
    return cast<ConstantInt>(DECL_LLVM(decl))->getZExtValue();
  }
  
  /* Detect errors in declaring global registers.  */
  if (RegNumber == -1)
    error("%Jregister name not specified for %qD", decl, decl);
  else if (RegNumber < 0)
    error("%Jinvalid register name for %qD", decl, decl);
  else if (TYPE_MODE(TREE_TYPE(decl)) == BLKmode)
    error("%Jdata type of %qD isn%'t suitable for a register", decl, decl);
#if 0 // FIXME: enable this.
  else if (!HARD_REGNO_MODE_OK(RegNumber, TYPE_MODE(TREE_TYPE(decl))))
    error("%Jregister specified for %qD isn%'t suitable for data type",
          decl, decl);
#endif
  else if (DECL_INITIAL(decl) != 0 && TREE_STATIC(decl))
    error("global register variable has initial value");
  else if (!Ty->isFirstClassType())
    sorry("%JLLVM cannot handle register variable %qD, report a bug",
          decl, decl);
  else {
    if (TREE_THIS_VOLATILE(decl))
      warning("volatile register variables don%'t work as you might wish");
    
    SET_DECL_LLVM(decl, ConstantInt::getFalse());
    return false;  // Everything ok.
  }
  SET_DECL_LLVM(decl, ConstantInt::getTrue());
  return true;
}
示例#24
0
文件: symtab.c 项目: Roffi/gcc
symtab_node
symtab_nonoverwritable_alias (symtab_node node)
{
  tree new_decl;
  symtab_node new_node = NULL;
  symtab_for_node_and_aliases (node, symtab_nonoverwritable_alias_1,
		               (void *)&new_node, true);
  if (new_node)
    return new_node;

  new_decl = copy_node (node->symbol.decl);
  DECL_NAME (new_decl) = clone_function_name (node->symbol.decl, "localalias");
  if (TREE_CODE (new_decl) == FUNCTION_DECL)
    DECL_STRUCT_FUNCTION (new_decl) = NULL;
  DECL_INITIAL (new_decl) = NULL;
  SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
  SET_DECL_RTL (new_decl, NULL);

  /* Update the properties.  */
  DECL_EXTERNAL (new_decl) = 0;
  if (DECL_ONE_ONLY (node->symbol.decl))
    DECL_SECTION_NAME (new_decl) = NULL;
  DECL_COMDAT_GROUP (new_decl) = 0;
  TREE_PUBLIC (new_decl) = 0;
  DECL_COMDAT (new_decl) = 0;
  DECL_WEAK (new_decl) = 0;
  DECL_VIRTUAL_P (new_decl) = 0;
  if (TREE_CODE (new_decl) == FUNCTION_DECL)
    {
      DECL_STATIC_CONSTRUCTOR (new_decl) = 0;
      DECL_STATIC_DESTRUCTOR (new_decl) = 0;
      new_node = (symtab_node) cgraph_create_function_alias (new_decl, node->symbol.decl);
    }
  else
    new_node = (symtab_node) varpool_create_variable_alias (new_decl, node->symbol.decl);
  symtab_resolve_alias (new_node, node);  
  return new_node;
}
示例#25
0
/*
 *	Create a DECL_... node of code CODE, name NAME
 *	and data type TYPE. We do NOT enter this node
 *	in any sort of symbol table.
 *
 *	layout_decl is used to set up the decl's storage layout.
 *	Other slots are initialized to 0 or null pointers.
 */
tree
build_decl (enum tree_code code, tree name, tree type)
{
	register tree	t;

	t = make_node (code);

#if (0)	/*************************************/
	/*
	 *	That is not done, deliberately, so that
	 *	having error_mark_node as the type can
	 *	suppress useless errors in the use of
	 *	this variable.
	 */
	if (type == error_mark_node)
		type = integer_type_node;
#endif	/*************************************/

	DECL_NAME (t) = name;

	if (name)
	{
		DECL_PRINT_NAME (t) = IDENTIFIER_POINTER (name);
		DECL_ASSEMBLER_NAME (t) = IDENTIFIER_POINTER (name);
	}

	TREE_TYPE (t) = type;
	DECL_ARGUMENTS (t) = NULL_TREE;
	DECL_INITIAL (t) = NULL_TREE;

	if (code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL)
		layout_decl (t, 0);
	elif (code == FUNCTION_DECL)
		DECL_MODE (t) = FUNCTION_MODE;

	return (t);

}	/* end build_decl */
示例#26
0
/* Return lexical scope block insn belong to.  */
static tree
insn_scope (rtx insn)
{
  int max = VARRAY_ACTIVE_SIZE (block_locators_locs);
  int min = 0;
  int loc = INSN_LOCATOR (insn);

  /* When block_locators_locs was initialized, the pro- and epilogue
     insns didn't exist yet and can therefore not be found this way.
     But we know that they belong to the outer most block of the
     current function.
     Without this test, the prologue would be put inside the block of
     the first valid instruction in the function and when that first
     insn is part of an inlined function then the low_pc of that
     inlined function is messed up.  Likewise for the epilogue and
     the last valid instruction.  */
  if (loc == prologue_locator || loc == epilogue_locator)
    return DECL_INITIAL (cfun->decl);

  if (!max || !loc)
    return NULL;
  while (1)
    {
      int pos = (min + max) / 2;
      int tmp = VARRAY_INT (block_locators_locs, pos);

      if (tmp <= loc && min != pos)
	min = pos;
      else if (tmp > loc && max != pos)
	max = pos;
      else
	{
	  min = pos;
	  break;
	}
    }
   return VARRAY_TREE (block_locators_blocks, min);
}
示例#27
0
/* Dump given cgraph node.  */
void
dump_varpool_node (FILE *f, struct varpool_node *node)
{
  fprintf (f, "%s:", varpool_node_name (node));
  fprintf (f, " availability:%s",
	   cgraph_function_flags_ready
	   ? cgraph_availability_names[cgraph_variable_initializer_availability (node)]
	   : "not-ready");
  if (DECL_ASSEMBLER_NAME_SET_P (node->decl))
    fprintf (f, " (asm: %s)", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl)));
  if (DECL_INITIAL (node->decl))
    fprintf (f, " initialized");
  if (TREE_ASM_WRITTEN (node->decl))
    fprintf (f, " (asm written)");
  if (node->needed)
    fprintf (f, " needed");
  if (node->analyzed)
    fprintf (f, " analyzed");
  if (node->finalized)
    fprintf (f, " finalized");
  if (node->output)
    fprintf (f, " output");
  if (node->externally_visible)
    fprintf (f, " externally_visible");
  if (node->resolution != LDPR_UNKNOWN)
    fprintf (f, " %s",
 	     ld_plugin_symbol_resolution_names[(int)node->resolution]);
  if (node->in_other_partition)
    fprintf (f, " in_other_partition");
  else if (node->used_from_other_partition)
    fprintf (f, " used_from_other_partition");
  fprintf (f, "\n");
  fprintf (f, "  References: ");
  ipa_dump_references (f, &node->ref_list);
  fprintf (f, "  Refering this var: ");
  ipa_dump_refering (f, &node->ref_list);
}
示例#28
0
tree visit_fun(tree *decl, int *subtrees, void *dummy)
{
    (void)subtrees;
    (void)dummy;
    enum tree_code code = TREE_CODE(*decl);
    tree var = NULL_TREE;
    
    if(code == BIND_EXPR)
    {
        for(var = BIND_EXPR_VARS(*decl); var; var = TREE_CHAIN(var))
        {
            if(TREE_CODE(var) == VAR_DECL)
            {
                if(auto_var_in_fn_p(var, current_function_decl) &&
                   !DECL_ARTIFICIAL(var))
                {
                    if(!DECL_INITIAL(var))
                    {
                        tree init_var = walk_tree_without_duplicates(decl, walk_init, var);

                        if(init_var == NULL_TREE)
                        {
                            // don't check classes initialization (too complicated)
                            if(!(TREE_CODE(TREE_TYPE(var)) == RECORD_TYPE &&
                                 CLASSTYPE_DECLARED_CLASS(TREE_TYPE(var))))
                            {
                                WARNING_DECL(*decl, "uninititialized auto var %qD", var);
                            }
                        }
                    }
                }
            }
        }
    }

    return NULL_TREE;
}
示例#29
0
void
lto_symtab_register_decl (tree decl,
			  ld_plugin_symbol_resolution_t resolution,
			  struct lto_file_decl_data *file_data)
{
  lto_symtab_entry_t new_entry;
  void **slot;

  /* Check that declarations reaching this function do not have
     properties inconsistent with having external linkage.  If any of
     these asertions fail, then the object file reader has failed to
     detect these cases and issue appropriate error messages.  */
  gcc_assert (decl
	      && TREE_PUBLIC (decl)
	      && (TREE_CODE (decl) == VAR_DECL
		  || TREE_CODE (decl) == FUNCTION_DECL)
	      && DECL_ASSEMBLER_NAME_SET_P (decl));
  if (TREE_CODE (decl) == VAR_DECL
      && DECL_INITIAL (decl))
    gcc_assert (!DECL_EXTERNAL (decl)
		|| (TREE_STATIC (decl) && TREE_READONLY (decl)));
  if (TREE_CODE (decl) == FUNCTION_DECL)
    gcc_assert (!DECL_ABSTRACT (decl));

  new_entry = ggc_alloc_cleared_lto_symtab_entry_def ();
  new_entry->id = (*targetm.asm_out.mangle_assembler_name)
		  (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
  new_entry->decl = decl;
  new_entry->resolution = resolution;
  new_entry->file_data = file_data;

  lto_symtab_maybe_init_hash_table ();
  slot = htab_find_slot (lto_symtab_identifiers, new_entry, INSERT);
  new_entry->next = (lto_symtab_entry_t) *slot;
  *slot = new_entry;
}
示例#30
0
static void
create_common (gfc_common_head *com, segment_info *head, bool saw_equiv)
{
  segment_info *s, *next_s;
  tree union_type;
  tree *field_link;
  tree field;
  tree field_init = NULL_TREE;
  record_layout_info rli;
  tree decl;
  bool is_init = false;
  bool is_saved = false;

  /* Declare the variables inside the common block.
     If the current common block contains any equivalence object, then
     make a UNION_TYPE node, otherwise RECORD_TYPE. This will let the
     alias analyzer work well when there is no address overlapping for
     common variables in the current common block.  */
  if (saw_equiv)
    union_type = make_node (UNION_TYPE);
  else
    union_type = make_node (RECORD_TYPE);

  rli = start_record_layout (union_type);
  field_link = &TYPE_FIELDS (union_type);

  /* Check for overlapping initializers and replace them with a single,
     artificial field that contains all the data.  */
  if (saw_equiv)
    field = get_init_field (head, union_type, &field_init, rli);
  else
    field = NULL_TREE;

  if (field != NULL_TREE)
    {
      is_init = true;
      *field_link = field;
      field_link = &DECL_CHAIN (field);
    }

  for (s = head; s; s = s->next)
    {
      build_field (s, union_type, rli);

      /* Link the field into the type.  */
      *field_link = s->field;
      field_link = &DECL_CHAIN (s->field);

      /* Has initial value.  */
      if (s->sym->value)
        is_init = true;

      /* Has SAVE attribute.  */
      if (s->sym->attr.save)
        is_saved = true;
    }

  finish_record_layout (rli, true);

  if (com)
    decl = build_common_decl (com, union_type, is_init);
  else
    decl = build_equiv_decl (union_type, is_init, is_saved);

  if (is_init)
    {
      tree ctor, tmp;
      VEC(constructor_elt,gc) *v = NULL;

      if (field != NULL_TREE && field_init != NULL_TREE)
	CONSTRUCTOR_APPEND_ELT (v, field, field_init);
      else
	for (s = head; s; s = s->next)
	  {
	    if (s->sym->value)
	      {
		/* Add the initializer for this field.  */
		tmp = gfc_conv_initializer (s->sym->value, &s->sym->ts,
					    TREE_TYPE (s->field),
					    s->sym->attr.dimension,
					    s->sym->attr.pointer
					    || s->sym->attr.allocatable, false);

		CONSTRUCTOR_APPEND_ELT (v, s->field, tmp);
	      }
	  }

      gcc_assert (!VEC_empty (constructor_elt, v));
      ctor = build_constructor (union_type, v);
      TREE_CONSTANT (ctor) = 1;
      TREE_STATIC (ctor) = 1;
      DECL_INITIAL (decl) = ctor;

#ifdef ENABLE_CHECKING
      {
	tree field, value;
	unsigned HOST_WIDE_INT idx;
	FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), idx, field, value)
	  gcc_assert (TREE_CODE (field) == FIELD_DECL);
      }
#endif
    }

  /* Build component reference for each variable.  */
  for (s = head; s; s = next_s)
    {
      tree var_decl;

      var_decl = build_decl (s->sym->declared_at.lb->location,
			     VAR_DECL, DECL_NAME (s->field),
			     TREE_TYPE (s->field));
      TREE_STATIC (var_decl) = TREE_STATIC (decl);
      /* Mark the variable as used in order to avoid warnings about
	 unused variables.  */
      TREE_USED (var_decl) = 1;
      if (s->sym->attr.use_assoc)
	DECL_IGNORED_P (var_decl) = 1;
      if (s->sym->attr.target)
	TREE_ADDRESSABLE (var_decl) = 1;
      /* Fake variables are not visible from other translation units. */
      TREE_PUBLIC (var_decl) = 0;

      /* To preserve identifier names in COMMON, chain to procedure
         scope unless at top level in a module definition.  */
      if (com
          && s->sym->ns->proc_name
          && s->sym->ns->proc_name->attr.flavor == FL_MODULE)
	var_decl = pushdecl_top_level (var_decl);
      else
	gfc_add_decl_to_function (var_decl);

      SET_DECL_VALUE_EXPR (var_decl,
			   fold_build3_loc (input_location, COMPONENT_REF,
					    TREE_TYPE (s->field),
					    decl, s->field, NULL_TREE));
      DECL_HAS_VALUE_EXPR_P (var_decl) = 1;
      GFC_DECL_COMMON_OR_EQUIV (var_decl) = 1;

      if (s->sym->attr.assign)
	{
	  gfc_allocate_lang_decl (var_decl);
	  GFC_DECL_ASSIGN (var_decl) = 1;
	  GFC_DECL_STRING_LEN (var_decl) = GFC_DECL_STRING_LEN (s->field);
	  GFC_DECL_ASSIGN_ADDR (var_decl) = GFC_DECL_ASSIGN_ADDR (s->field);
	}

      s->sym->backend_decl = var_decl;

      next_s = s->next;
      free (s);
    }
}