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; }
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); }
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); }