📄 tasking.c
字号:
args = tree_cons (NULL_TREE, TREE_TYPE (parammode), NULL_TREE); } /* start the function */ push_chill_function_context (); if (! start_chill_function (wrapper, void_type_node, args, NULL_TREE, NULL_TREE)) return; /* to avoid granting */ DECL_SOURCE_LINE (current_function_decl) = 0; if (! ignoring) { /* make the call to the PROCESS */ tree wrk; tree x = lookup_name (get_identifier ("x")); /* no need to check this pointer to be NULL */ tree indref = build_chill_indirect_ref (x, NULL_TREE, 0); args = NULL_TREE; wrk = TYPE_FIELDS (TREE_TYPE (TREE_TYPE (x))); while (wrk != NULL_TREE) { args = tree_cons (NULL_TREE, build_component_ref (indref, DECL_NAME (wrk)), args); wrk = TREE_CHAIN (wrk); } CH_DECL_PROCESS (func) = 0; expand_expr_stmt ( build_chill_function_call (func, nreverse (args))); CH_DECL_PROCESS (func) = 1; } add_taskstuff_to_list (code_decl, "_TT_Process", process_type, func, current_function_decl); /* finish the function */ finish_chill_function (); pop_chill_function_context (); }/* Generate errors for INOUT, OUT parameters. "Only if LOC is specified may the mode have the non-value property" */voidvalidate_process_parameters (parms) tree parms ATTRIBUTE_UNUSED;{}/* * build the tree for a start process action. Loop through the * actual parameters, making a constructor list, which we use to * initialize the argument structure. NAME is the process' name. * COPYNUM is its copy number, whatever that is. EXPRLIST is the * list of actual parameters passed by the start call. They must * match. EXPRLIST must still be in reverse order; we'll reverse it here. * * Note: the OPTSET name is not now used - it's here for * possible future support for the optional 'SET instance-var' * clause. */voidbuild_start_process (process_name, copynum, exprlist, optset) tree process_name, copynum, exprlist, optset;{ tree process_decl = NULL_TREE, struct_type_node = NULL_TREE; tree result; tree valtail, typetail; tree tuple = NULL_TREE, actuallist = NULL_TREE; tree typelist; int parmno = 2; tree args; tree filename, linenumber; if (exprlist != NULL_TREE && TREE_CODE (exprlist) == ERROR_MARK) process_decl = NULL_TREE; else if (! ignoring) { process_decl = lookup_name (process_name); if (process_decl == NULL_TREE) error ("process name %s never declared", IDENTIFIER_POINTER (process_name)); else if (TREE_CODE (process_decl) != FUNCTION_DECL || ! CH_DECL_PROCESS (process_decl)) { error ("You may only START a process, not a proc"); process_decl = NULL_TREE; } else if (DECL_EXTERNAL (process_decl)) { args = TYPE_ARG_TYPES (TREE_TYPE (process_decl)); if (TREE_VALUE (args) != void_type_node) struct_type_node = TREE_TYPE (TREE_VALUE (args)); else struct_type_node = NULL_TREE; } else { tree debug_type = lookup_name ( get_struct_debug_type_name (DECL_NAME (process_decl))); if (debug_type == NULL_TREE) /* no debug type, no arguments */ struct_type_node = NULL_TREE; else struct_type_node = TREE_TYPE (debug_type); } } /* begin a new name scope */ pushlevel (1); clear_last_expr (); push_momentary (); if (pass == 2) expand_start_bindings (0); if (! ignoring && process_decl != NULL_TREE) { if (optset == NULL_TREE) ; else if (!CH_REFERABLE (optset)) { error ("SET expression not a location."); optset = NULL_TREE; } else if (!CH_IS_INSTANCE_MODE (TREE_TYPE (optset))) { error ("SET location must be INSTANCE mode"); optset = NULL_TREE; } if (optset) optset = force_addr_of (optset); else optset = convert (ptr_type_node, integer_zero_node); if (struct_type_node != NULL_TREE) { typelist = TYPE_FIELDS (struct_type_node); for (valtail = nreverse (exprlist), typetail = typelist; valtail != NULL_TREE && typetail != NULL_TREE; parmno++, valtail = TREE_CHAIN (valtail), typetail = TREE_CHAIN (typetail)) { register tree actual = valtail ? TREE_VALUE (valtail) : 0; register tree type = typetail ? TREE_TYPE (typetail) : 0; char place[30]; sprintf (place, "signal field %d", parmno); actual = chill_convert_for_assignment (type, actual, place); actuallist = tree_cons (NULL_TREE, actual, actuallist); } tuple = build_nt (CONSTRUCTOR, NULL_TREE, nreverse (actuallist)); } else { valtail = NULL_TREE; typetail = NULL_TREE; } if (valtail != 0 && TREE_VALUE (valtail) != void_type_node) { char *errstr = "too many arguments to process"; if (process_name) error ("%s `%s'", errstr, IDENTIFIER_POINTER (process_name)); else error (errstr); } else if (typetail != 0 && TREE_VALUE (typetail) != void_type_node) { char *errstr = "too few arguments to process"; if (process_name) error ("%s `%s'", errstr, IDENTIFIER_POINTER (process_name)); else error (errstr); } else { tree process_decl = lookup_name (process_name); tree process_type = (tree)DECL_TASKING_CODE_DECL (process_decl); tree struct_size, struct_pointer; if (struct_type_node != NULL_TREE) { result = decl_temp1 (get_unique_identifier ("START_ARG"), struct_type_node, 0, tuple, 0, 0); /* prevent granting of this type */ DECL_SOURCE_LINE (result) = 0; mark_addressable (result); struct_pointer = build1 (ADDR_EXPR, build_chill_pointer_type (struct_type_node), result); struct_size = size_in_bytes (struct_type_node); } else { struct_size = integer_zero_node; struct_pointer = null_pointer_node; } filename = force_addr_of (get_chill_filename ()); linenumber = get_chill_linenumber (); expand_expr_stmt ( build_chill_function_call (lookup_name (get_identifier ("__start_process")), tree_cons (NULL_TREE, process_type, tree_cons (NULL_TREE, convert (integer_type_node, copynum), tree_cons (NULL_TREE, struct_size, tree_cons (NULL_TREE, struct_pointer, tree_cons (NULL_TREE, optset, tree_cons (NULL_TREE, filename, build_tree_list (NULL_TREE, linenumber))))))))); } } /* end of scope */ if (pass == 2) expand_end_bindings (getdecls (), kept_level_p (), 0); poplevel (kept_level_p (), 0, 0); pop_momentary ();}/* * A CHILL SET which represents all of the possible tasking * elements. */static treebuild_tasking_enum (){ tree result, decl1; tree enum1; tree list = NULL_TREE; tree value = integer_zero_node; enum1 = start_enum (NULL_TREE); result = build_enumerator (get_identifier ("_TT_UNUSED"), value); list = chainon (result, list); value = fold (build (PLUS_EXPR, integer_type_node, value, integer_one_node)); result = build_enumerator (get_identifier ("_TT_Process"), value); list = chainon (result, list); value = fold (build (PLUS_EXPR, integer_type_node, value, integer_one_node)); result = build_enumerator (get_identifier ("_TT_Signal"), value); list = chainon (result, list); value = fold (build (PLUS_EXPR, integer_type_node, value, integer_one_node)); result = build_enumerator (get_identifier ("_TT_Buffer"), value); list = chainon (result, list); value = fold (build (PLUS_EXPR, integer_type_node, value, integer_one_node)); result = build_enumerator (get_identifier ("_TT_Event"), value); list = chainon (result, list); value = fold (build (PLUS_EXPR, integer_type_node, value, integer_one_node)); result = build_enumerator (get_identifier ("_TT_Synonym"), value); list = chainon (result, list); value = fold (build (PLUS_EXPR, integer_type_node, value, integer_one_node)); result = build_enumerator (get_identifier ("_TT_Exception"), value); list = chainon (result, list); value = fold (build (PLUS_EXPR, integer_type_node, value, integer_one_node)); result = finish_enum (enum1, list); decl1 = build_decl (TYPE_DECL, get_identifier ("__tmp_TaskingEnum"), result); pushdecl (decl1); satisfy_decl (decl1, 0); return decl1;}treebuild_tasking_struct (){ tree listbase, decl1, decl2, result; tree enum_type = TREE_TYPE (build_tasking_enum ()); /* We temporarily reset the maximum_field_alignment to zero so the compiler's init data structures can be compatible with the run-time system, even when we're compiling with -fpack. */ extern int maximum_field_alignment; int save_maximum_field_alignment = maximum_field_alignment; maximum_field_alignment = 0; decl1 = build_decl (FIELD_DECL, get_identifier ("TaskName"), build_chill_pointer_type (char_type_node)); DECL_INITIAL (decl1) = NULL_TREE; listbase = decl1; decl2 = build_decl (FIELD_DECL, get_identifier ("TaskValue"), build_chill_pointer_type (chill_taskingcode_type_node)); TREE_CHAIN (decl1) = decl2; DECL_INITIAL (decl2) = NULL_TREE; decl1 = decl2; decl2 = build_decl (FIELD_DECL, get_identifier ("TaskValueDefined"), integer_type_node); TREE_CHAIN (decl1) = decl2; DECL_INITIAL (decl2) = NULL_TREE; decl1 = decl2; decl2 = build_decl (FIELD_DECL, get_identifier ("TaskEntry"), build_chill_pointer_type (void_ftype_void)); TREE_CHAIN (decl1) = decl2; DECL_INITIAL (decl2) = NULL_TREE; decl1 = decl2; decl2 = build_decl (FIELD_DECL, get_identifier ("TaskType"), enum_type); TREE_CHAIN (decl1) = decl2; DECL_INITIAL (decl2) = NULL_TREE; decl1 = decl2; TREE_CHAIN (decl2) = NULL_TREE; result = build_chill_struct_type (listbase); satisfy_decl (result, 0); maximum_field_alignment = save_maximum_field_alignment; return result;}/* * build data structures describing each task/signal, etc. * in current module. */voidtasking_setup (){ tree tasknode; tree struct_type; if (pass == 1) return; struct_type = TREE_TYPE (lookup_name ( get_identifier ("__tmp_TaskingStruct"))); for (tasknode = tasking_list; tasknode != NULL_TREE; tasknode = TREE_CHAIN (tasknode)) { /* This is the tasking_code_variable's decl */ tree stuffnumber = TASK_INFO_STUFF_NUM (tasknode); tree code_decl = TASK_INFO_CODE_DECL (tasknode); tree proc_decl = TASK_INFO_PDECL (tasknode); tree entry = TASK_INFO_ENTRY (tasknode); tree name = DECL_NAME (proc_decl); char *init_struct = (char *) alloca (IDENTIFIER_LENGTH(name) + 20); /* take care of zero termination */ tree task_name; /* these are the fields of the struct, in declaration order */ tree init_flag = (stuffnumber == NULL_TREE) ? integer_zero_node : integer_one_node; tree type = DECL_INITIAL (TASK_INFO_STUFF_TYPE (tasknode)); tree int_addr; tree entry_point; tree name_ptr; tree decl; tree struct_id; tree initializer; if (TREE_CODE (proc_decl) == FUNCTION_DECL && CH_DECL_PROCESS (proc_decl) && ! DECL_EXTERNAL (proc_decl)) { if (entry == NULL_TREE) entry = proc_decl; mark_addressable (entry); entry_point = build1 (ADDR_EXPR, build_chill_pointer_type (void_ftype_void), entry); } else entry_point = build1 (NOP_EXPR, build_chill_pointer_type (void_ftype_void), null_pointer_node); /* take care of zero termination */ task_name = build_chill_string (IDENTIFIER_LENGTH (name) + 1, IDENTIFIER_POINTER (name)); mark_addressable (code_decl); int_addr = build1 (ADDR_EXPR, build_chill_pointer_type (chill_integer_type_node), code_decl); mark_addressable (task_name); name_ptr = build1 (ADDR_EXPR, build_chill_pointer_type (char_type_node), task_name); sprintf (init_struct, "__tmp_%s_struct", IDENTIFIER_POINTER (name)); struct_id = get_identifier (init_struct); initializer = build (CONSTRUCTOR, struct_type, NULL_TREE, tree_cons (NULL_TREE, name_ptr, tree_cons (NULL_TREE, int_addr, tree_cons (NULL_TREE, init_flag, tree_cons (NULL_TREE, entry_point, tree_cons (NULL_TREE, type, NULL_TREE)))))); TREE_CONSTANT (initializer) = 1; decl = decl_temp1 (struct_id, struct_type, 1, initializer, 0, 0); /* prevent granting of this type */ DECL_SOURCE_LINE (decl) = 0; /* pass the decl to tasking_registry() in the symbol table */ IDENTIFIER_LOCAL_VALUE (struct_id) = decl; }}/* * Generate code to register the tasking-related stuff * with the runtime. Only in pass 2.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -