diff -Naur /root/cell/source/spu/gcc/gcc/c-decl.c ./gcc/c-decl.c --- /root/cell/source/spu/gcc/gcc/c-decl.c 2007-11-26 19:24:26.000000000 +0100 +++ ./gcc/c-decl.c 2008-02-06 19:34:43.000000000 +0100 @@ -6139,6 +6139,9 @@ pedwarn ("%q+D is normally a non-static function", decl1); } + DECL_SPECIFIC_TARGET (decl1) = current_target; + DECL_PROCESS_NAME (decl1) = current_process_name; + /* Record the decl so that the function name is defined. If we already have a decl for this name, and it is a FUNCTION_DECL, use the old decl. */ diff -Naur /root/cell/source/spu/gcc/gcc/common.opt ./gcc/common.opt --- /root/cell/source/spu/gcc/gcc/common.opt 2007-07-30 03:39:43.000000000 +0200 +++ ./gcc/common.opt 2008-02-06 18:25:30.000000000 +0100 @@ -367,6 +367,14 @@ Common Joined RejectNegative -fdiagnostics-show-location=[once|every-line] How often to emit source location at the beginning of line-wrapped diagnostics +ftarget= +Common Joined Var(target_isa_name) +Filter code to this target architecture + +fprocess-name= +Common Joined Var(target_process_name) +Compiles SPU application pragmatized with specified name + fdiagnostics-show-option Common Amend appropriate diagnostic messages with the command line option that controls them diff -Naur /root/cell/source/spu/gcc/gcc/c-pragma.c ./gcc/c-pragma.c --- /root/cell/source/spu/gcc/gcc/c-pragma.c 2006-07-13 02:16:16.000000000 +0200 +++ ./gcc/c-pragma.c 2008-02-06 18:26:39.000000000 +0100 @@ -42,6 +42,9 @@ #define GCC_BAD2(gmsgid, arg) \ do { warning (OPT_Wpragmas, gmsgid, arg); return; } while (0) +tree current_target = NULL_TREE; +tree current_process_name = NULL_TREE; + typedef struct align_stack GTY(()) { int alignment; @@ -494,6 +497,31 @@ "#pragma extern_prefix not supported on this target"); } +/* #pragma target */ +static void +handle_pragma_target (cpp_reader * ARG_UNUSED (dummy)) +{ + tree target; + tree exec_name; + + if (c_lex (&target) == CPP_NAME) + { + current_target = target; + + if(!strcmp(IDENTIFIER_POINTER(target), "spu") + && c_lex(&exec_name) == CPP_STRING) + { + current_process_name = exec_name; + } + } + else + { + current_target = NULL_TREE; + current_process_name = NULL_TREE; + } + +} + /* Hook from the front ends to apply the results of one of the preceding pragmas that rename variables. */ @@ -706,6 +734,8 @@ c_register_pragma ("GCC", "pch_preprocess", c_common_pch_pragma); + c_register_pragma (0, "target", handle_pragma_target); + #ifdef REGISTER_TARGET_PRAGMAS REGISTER_TARGET_PRAGMAS (); #endif diff -Naur /root/cell/source/spu/gcc/gcc/passes.c ./gcc/passes.c --- /root/cell/source/spu/gcc/gcc/passes.c 2007-06-28 13:39:47.000000000 +0200 +++ ./gcc/passes.c 2008-02-06 18:58:43.000000000 +0100 @@ -104,6 +104,7 @@ int dump_flags; bool in_gimple_form; +unsigned int abort_function_compilation; /* This is called from various places for FUNCTION_DECL, VAR_DECL, and TYPE_DECL nodes. @@ -251,7 +252,10 @@ { /* Early return if there were errors. We can run afoul of our consistency checks, and there's not really much point in fixing them. */ - return !(rtl_dump_and_exit || flag_syntax_only || errorcount || sorrycount); + //if(!abort_function_compilation) + return !(rtl_dump_and_exit || flag_syntax_only || errorcount || sorrycount); + //else + // return false; } struct tree_opt_pass pass_rest_of_compilation = @@ -274,7 +278,7 @@ static bool gate_postreload (void) { - return reload_completed; + return reload_completed && !abort_function_compilation; } struct tree_opt_pass pass_postreload = @@ -294,6 +298,79 @@ 0 /* letter */ }; +static unsigned int +target_filter (void) +{ + fprintf(stderr, "Entering target_filter for %s\n", IDENTIFIER_POINTER(DECL_NAME(cfun->decl))); + + if(DECL_SPECIFIC_TARGET (cfun->decl) && DECL_SPECIFIC_TARGET (cfun->decl) != NULL_TREE + && strcmp(IDENTIFIER_POINTER(DECL_SPECIFIC_TARGET(cfun->decl)), target_isa_name)) + { + struct cgraph_node *node = cgraph_node (cfun->decl); + tree decl = cfun->decl; + + DECL_EXTERNAL (decl) = 1; + TREE_PUBLIC (decl) = 1; + DECL_ARTIFICIAL (decl) = 1; + TREE_NOTHROW (decl) = 1; + + node->needed = 0; + node->reachable = 0; + node->output = 0; + + abort_function_compilation = true; + fprintf(stderr, "Aborting compilation of function %s.\n", + IDENTIFIER_POINTER (DECL_NAME (decl))); + } + else + { + /* fprintf(stderr, "Trying to change function name\n"); */ + if(DECL_PROCESS_NAME (cfun->decl) != NULL_TREE && TREE_STRING_POINTER (DECL_PROCESS_NAME (cfun->decl))) + { + char tmp[256]; + + fprintf(stderr, "Contains process name %s\n", TREE_STRING_POINTER(DECL_PROCESS_NAME(cfun->decl))); + sprintf(tmp, "%s_main", TREE_STRING_POINTER (DECL_PROCESS_NAME (cfun->decl))); + if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (cfun->decl)), tmp)) + { + char *output_name = NULL; + fprintf (stderr, "Changing name to main.\n"); + + /* Set function name to main. */ + output_name = (char *) alloca (4 + 64); + strcpy (output_name, "main"); + + DECL_NAME (cfun->decl) = get_identifier (output_name); + + /* Create a new SYMBOL_REF rtx for the new name. */ + if (DECL_RTL (cfun->decl) != NULL) + { + XEXP (DECL_RTL (cfun->decl), 0) = + gen_rtx_SYMBOL_REF (GET_MODE (XEXP (DECL_RTL (cfun->decl), 0)), + IDENTIFIER_POINTER (DECL_NAME (cfun->decl))); + } + } + } + } + return 0; +} + +struct tree_opt_pass pass_target_filter = +{ + "target_filter", /* name */ + NULL, /* gate */ + target_filter, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_cgraph, /* todo_flags_finish */ + 0 /* letter */ +}; /* The root of the compilation pass tree, once constructed. */ @@ -644,6 +721,7 @@ NEXT_PASS (pass_sched); NEXT_PASS (pass_local_alloc); NEXT_PASS (pass_global_alloc); + NEXT_PASS (pass_target_filter); NEXT_PASS (pass_postreload); *p = NULL; @@ -860,6 +938,9 @@ if (execute_one_pass (pass) && pass->sub) execute_pass_list (pass->sub); pass = pass->next; + +// if(abort_function_compilation) +// break; } while (pass); } diff -Naur /root/cell/source/spu/gcc/gcc/tree.h ./gcc/tree.h --- /root/cell/source/spu/gcc/gcc/tree.h 2007-11-26 19:24:26.000000000 +0100 +++ ./gcc/tree.h 2008-02-06 18:59:40.000000000 +0100 @@ -2060,6 +2060,10 @@ definition. */ #define DECL_ABSTRACT_ORIGIN(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.abstract_origin) +/* ISA to which code should be compiled. */ +#define DECL_SPECIFIC_TARGET(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.specific_target) +#define DECL_PROCESS_NAME(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.process_name) + /* Like DECL_ABSTRACT_ORIGIN, but returns NODE if there's no abstract origin. This is useful when setting the DECL_ABSTRACT_ORIGIN. */ #define DECL_ORIGIN(NODE) \ @@ -2255,6 +2259,10 @@ tree initial; tree attributes; tree abstract_origin; + + /* Attributes to declarations specified by pragma target */ + tree specific_target; + tree process_name; HOST_WIDE_INT pointer_alias_set; /* Points to a structure whose details depend on the language in use. */ @@ -4199,6 +4207,9 @@ restricted to creating gimple expressions. */ extern bool in_gimple_form; +extern tree current_target; +extern tree current_process_name; + /* In tree-gimple.c. */ extern tree get_base_address (tree t); diff -Naur /root/cell/source/spu/gcc/gcc/tree-optimize.c ./gcc/tree-optimize.c --- /root/cell/source/spu/gcc/gcc/tree-optimize.c 2006-07-14 04:57:54.000000000 +0200 +++ ./gcc/tree-optimize.c 2007-12-12 19:10:17.000000000 +0100 @@ -416,6 +416,7 @@ tree_register_cfg_hooks (); /* Perform all tree transforms and optimizations. */ + abort_function_compilation = false; execute_pass_list (all_passes); bitmap_obstack_release (®_obstack); diff -Naur /root/cell/source/spu/gcc/gcc/tree-pass.h ./gcc/tree-pass.h --- /root/cell/source/spu/gcc/gcc/tree-pass.h 2007-04-05 23:40:53.000000000 +0200 +++ ./gcc/tree-pass.h 2008-02-06 19:00:17.000000000 +0100 @@ -383,4 +383,6 @@ extern void execute_pass_list (struct tree_opt_pass *); extern void execute_ipa_pass_list (struct tree_opt_pass *); +extern unsigned int abort_function_compilation; + #endif /* GCC_TREE_PASS_H */