Esempio n. 1
0
static tree
create_pseudo_type_info (const char *real_name, int ident, ...)
{
  tree pseudo_type;
  char *pseudo_name;
  tree fields;
  tree field_decl;
  tree result;
  va_list ap;

  va_start (ap, ident);

  /* Generate the pseudo type name.  */
  pseudo_name = alloca (strlen (real_name) + 30);
  strcpy (pseudo_name, real_name);
  strcat (pseudo_name, "_pseudo");
  if (ident)
    sprintf (pseudo_name + strlen (pseudo_name), "%d", ident);
  
  /* First field is the pseudo type_info base class.  */
  fields = build_decl (FIELD_DECL, NULL_TREE, ti_desc_type_node);
  
  /* Now add the derived fields.  */
  while ((field_decl = va_arg (ap, tree)))
    {
      TREE_CHAIN (field_decl) = fields;
      fields = field_decl;
    }
  
  /* Create the pseudo type.  */
  pseudo_type = make_aggr_type (RECORD_TYPE);
  finish_builtin_struct (pseudo_type, pseudo_name, fields, NULL_TREE);
  CLASSTYPE_AS_BASE (pseudo_type) = pseudo_type;

  result = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE);
  TINFO_REAL_NAME (result) = get_identifier (real_name);
  TINFO_PSEUDO_TYPE (result) =
    cp_build_qualified_type (pseudo_type, TYPE_QUAL_CONST);
  
  va_end (ap);
  return result;
}
Esempio n. 2
0
static void
create_tinfo_types (void)
{
  gcc_assert (!ti_desc_type_node);

  push_nested_namespace (abi_node);
  
  /* Create the internal type_info structure. This is used as a base for
     the other structures.  */
  {
    tree field, fields;

    ti_desc_type_node = make_aggr_type (RECORD_TYPE);
    field = build_decl (FIELD_DECL, NULL_TREE, const_ptr_type_node);
    fields = field;
    
    field = build_decl (FIELD_DECL, NULL_TREE, const_string_type_node);
    TREE_CHAIN (field) = fields;
    fields = field;
    
    finish_builtin_struct (ti_desc_type_node, "__type_info_pseudo",
			   fields, NULL_TREE);
    TYPE_HAS_CONSTRUCTOR (ti_desc_type_node) = 1;
  }
  
  /* Fundamental type_info */
  bltn_desc_type_node = create_pseudo_type_info
      ("__fundamental_type_info", 0,
       NULL);

  /* Array, function and enum type_info. No additional fields.  */
  ary_desc_type_node = create_pseudo_type_info
      ("__array_type_info", 0,
       NULL);
  func_desc_type_node = create_pseudo_type_info
       ("__function_type_info", 0,
        NULL);
  enum_desc_type_node = create_pseudo_type_info
       ("__enum_type_info", 0,
        NULL);
  
  /* Class type_info. Add a flags field.  */
  class_desc_type_node = create_pseudo_type_info
        ("__class_type_info", 0,
         NULL);
  
  /* Single public non-virtual base class. Add pointer to base class. 
     This is really a descendant of __class_type_info.  */
  si_class_desc_type_node = create_pseudo_type_info
           ("__si_class_type_info", 0,
            build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
            NULL);
  
  /* Base class internal helper. Pointer to base type, offset to base,
     flags.  */
  {
    tree field, fields;
    
    field = build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type);
    fields = field;
    
    field = build_decl (FIELD_DECL, NULL_TREE, integer_types[itk_long]);
    TREE_CHAIN (field) = fields;
    fields = field;
  
    base_desc_type_node = make_aggr_type (RECORD_TYPE);
    finish_builtin_struct (base_desc_type_node, "__base_class_type_info_pseudo",
			   fields, NULL_TREE);
    TYPE_HAS_CONSTRUCTOR (base_desc_type_node) = 1;
  }
  
  /* General hierarchy is created as necessary in this vector.  */
  vmi_class_desc_type_node = make_tree_vec (10);
  
  /* Pointer type_info. Adds two fields, qualification mask
     and pointer to the pointed to type.  This is really a descendant of
     __pbase_type_info.  */
  ptr_desc_type_node = create_pseudo_type_info
      ("__pointer_type_info", 0,
       build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
       build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
       NULL);

  /* Pointer to member data type_info.  Add qualifications flags,
     pointer to the member's type info and pointer to the class.
     This is really a descendant of __pbase_type_info.  */
  ptm_desc_type_node = create_pseudo_type_info
       ("__pointer_to_member_type_info", 0,
        build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
        build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
        build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
        NULL);

  pop_nested_namespace (abi_node);
}
Esempio n. 3
0
void
cilk_init_builtins (void)
{
  /* Now build the following __cilkrts_pedigree struct:
     struct __cilkrts_pedigree {
        uint64_t rank;
        struct __cilkrts_pedigree *parent;
      }  */

  tree pedigree_type = lang_hooks.types.make_type (RECORD_TYPE);
  tree pedigree_ptr  = build_pointer_type (pedigree_type);
  tree field = add_field ("rank", uint64_type_node, NULL_TREE);
  cilk_trees[CILK_TI_PEDIGREE_RANK] = field;
  field = add_field ("parent", pedigree_ptr, field);
  cilk_trees[CILK_TI_PEDIGREE_PARENT] = field;
  finish_builtin_struct (pedigree_type, "__cilkrts_pedigree_GCC", field,
			 NULL_TREE);
  lang_hooks.types.register_builtin_type (pedigree_type,
					  "__cilkrts_pedigree_t");
  cilk_pedigree_type_decl = pedigree_type; 

  /* Build the Cilk Stack Frame:
     struct __cilkrts_stack_frame {
       uint32_t flags;
       uint32_t size;
       struct __cilkrts_stack_frame *call_parent;
       __cilkrts_worker *worker;
       void *except_data;
       void *ctx[4];
       uint32_t mxcsr;
       uint16_t fpcsr;
       uint16_t reserved;
       __cilkrts_pedigree pedigree;
     };  */

  tree frame = lang_hooks.types.make_type (RECORD_TYPE);
  tree frame_ptr = build_pointer_type (frame);
  tree worker_type = lang_hooks.types.make_type (RECORD_TYPE);
  tree worker_ptr = build_pointer_type (worker_type);
  tree s_type_node = build_int_cst (size_type_node, 4);

  tree flags = add_field ("flags", uint32_type_node, NULL_TREE);
  tree size = add_field ("size", uint32_type_node, flags);
  tree parent = add_field ("call_parent", frame_ptr, size);
  tree worker = add_field ("worker", worker_ptr, parent);
  tree except = add_field ("except_data", frame_ptr, worker);
  tree context = add_field ("ctx",
			    build_array_type (ptr_type_node,
					      build_index_type (s_type_node)),
			    except);
  tree mxcsr = add_field ("mxcsr", uint32_type_node, context);
  tree fpcsr = add_field ("fpcsr", uint16_type_node, mxcsr);
  tree reserved = add_field ("reserved", uint16_type_node, fpcsr);
  tree pedigree = add_field ("pedigree", pedigree_type, reserved);
  
  /* Now add them to a common structure whose fields are #defined to something
     that is used at a later stage.  */
  cilk_trees[CILK_TI_FRAME_FLAGS] = flags;
  cilk_trees[CILK_TI_FRAME_PARENT] = parent;
  cilk_trees[CILK_TI_FRAME_WORKER] = worker;
  cilk_trees[CILK_TI_FRAME_EXCEPTION] = except;
  cilk_trees[CILK_TI_FRAME_CONTEXT] = context;
  /* We don't care about reserved, so no need to store it in cilk_trees.  */
  cilk_trees[CILK_TI_FRAME_PEDIGREE] = pedigree;
  TREE_ADDRESSABLE (frame) = 1;

  finish_builtin_struct (frame, "__cilkrts_st_frame_GCC", pedigree, NULL_TREE);
  cilk_frame_type_decl = frame;
  lang_hooks.types.register_builtin_type (frame, "__cilkrts_frame_t");

  cilk_frame_ptr_type_decl = build_qualified_type (frame_ptr,
						   TYPE_QUAL_VOLATILE);
  /* Now let's do the following worker struct:

     struct __cilkrts_worker {
       __cilkrts_stack_frame *volatile *volatile tail;
       __cilkrts_stack_frame *volatile *volatile head;
       __cilkrts_stack_frame *volatile *volatile exc;
       __cilkrts_stack_frame *volatile *volatile protected_tail;
       __cilkrts_stack_frame *volatile *ltq_limit;
       int32_t self;
       global_state_t *g;
       local_state *l;
       cilkred_map *reducer_map;
       __cilkrts_stack_frame *current_stack_frame;
       void *reserved;
       __cilkrts_worker_sysdep_state *sysdep;
       __cilkrts_pedigree pedigree;
    }   */

  tree fptr_volatil_type = build_qualified_type (frame_ptr, TYPE_QUAL_VOLATILE);
  tree fptr_volatile_ptr = build_pointer_type (fptr_volatil_type);
  tree fptr_vol_ptr_vol = build_qualified_type (fptr_volatile_ptr,
						TYPE_QUAL_VOLATILE);
  tree g = lang_hooks.types.make_type (RECORD_TYPE);
  finish_builtin_struct (g, "__cilkrts_global_state", NULL_TREE, NULL_TREE);
  tree l = lang_hooks.types.make_type (RECORD_TYPE);
  finish_builtin_struct (l, "__cilkrts_local_state", NULL_TREE, NULL_TREE);
  tree sysdep_t = lang_hooks.types.make_type (RECORD_TYPE);
  finish_builtin_struct (sysdep_t, "__cilkrts_worker_sysdep_state", NULL_TREE,
			 NULL_TREE);

  field = add_field ("tail", fptr_vol_ptr_vol, NULL_TREE);
  cilk_trees[CILK_TI_WORKER_TAIL] = field;
  field = add_field ("head", fptr_vol_ptr_vol, field);
  field  = add_field ("exc", fptr_vol_ptr_vol, field);
  field = add_field ("protected_tail", fptr_vol_ptr_vol, field);
  field = add_field ("ltq_limit", fptr_volatile_ptr, field);
  field = add_field ("self", integer_type_node, field);
  field = add_field ("g", build_pointer_type (g), field);
  field = add_field ("l", build_pointer_type (g), field);
  field = add_field ("reducer_map", ptr_type_node, field);
  field = add_field ("current_stack_frame", frame_ptr, field);
  cilk_trees[CILK_TI_WORKER_CUR] = field;
  field = add_field ("saved_protected_tail", fptr_volatile_ptr, field);
  field = add_field ("sysdep", build_pointer_type (sysdep_t), field);
  field = add_field ("pedigree", pedigree_type, field);
  cilk_trees[CILK_TI_WORKER_PEDIGREE] = field;
  finish_builtin_struct (worker_type, "__cilkrts_worker_GCC", field,
			 NULL_TREE);

  tree fptr_arglist = tree_cons (NULL_TREE, frame_ptr, void_list_node);
  tree fptr_fun = build_function_type (void_type_node, fptr_arglist);

  /* void __cilkrts_enter_frame_1 (__cilkrts_stack_frame *);  */
  cilk_enter_fndecl = install_builtin ("__cilkrts_enter_frame_1", fptr_fun,
				       BUILT_IN_CILK_ENTER_FRAME, false);

  /* void __cilkrts_enter_frame_fast_1 (__cilkrts_stack_frame *);  */
  cilk_enter_fast_fndecl = 
    install_builtin ("__cilkrts_enter_frame_fast_1", fptr_fun,
		     BUILT_IN_CILK_ENTER_FRAME_FAST, false);

  /* void __cilkrts_pop_frame (__cilkrts_stack_frame *);  */
  cilk_pop_fndecl = install_builtin ("__cilkrts_pop_frame", fptr_fun,
				     BUILT_IN_CILK_POP_FRAME, false);

  /* void __cilkrts_leave_frame (__cilkrts_stack_frame *);  */
  cilk_leave_fndecl = install_builtin ("__cilkrts_leave_frame", fptr_fun,
				       BUILT_IN_CILK_LEAVE_FRAME, false);

  /* void __cilkrts_sync (__cilkrts_stack_frame *);  */
  cilk_sync_fndecl = install_builtin ("__cilkrts_sync", fptr_fun,
				      BUILT_IN_CILK_SYNC, false);

  /* void __cilkrts_detach (__cilkrts_stack_frame *);  */
  cilk_detach_fndecl = install_builtin ("__cilkrts_detach", fptr_fun,
					BUILT_IN_CILK_DETACH, false);

  /* __cilkrts_rethrow (struct stack_frame *);  */
  cilk_rethrow_fndecl = install_builtin ("__cilkrts_rethrow", fptr_fun,
					 BUILT_IN_CILK_RETHROW, false);
  TREE_NOTHROW (cilk_rethrow_fndecl) = 0;

  /* __cilkrts_save_fp_ctrl_state (__cilkrts_stack_frame *);  */
  cilk_save_fp_fndecl = install_builtin ("__cilkrts_save_fp_ctrl_state",
					 fptr_fun, BUILT_IN_CILK_SAVE_FP,
					 false);
  /* __cilkrts_cilk_for_32 (...);  */
  cilk_for_32_fndecl = declare_cilk_for_builtin ("__cilkrts_cilk_for_32",
						 unsigned_intSI_type_node,
						 BUILT_IN_CILK_FOR_32);
  /* __cilkrts_cilk_for_64 (...);  */
  cilk_for_64_fndecl = declare_cilk_for_builtin ("__cilkrts_cilk_for_64",
						 unsigned_intDI_type_node,
						 BUILT_IN_CILK_FOR_64);
}