# HG changeset patch # User Nobuyasu Oshiro # Date 1320946516 -32400 # Node ID 895e19fe9c2240d9492ec2187e6268d70194eaaa # Parent d8bf5c8fdea8fa30b8ffb6ceba944b342f29c74c modify calls.c diff -r d8bf5c8fdea8 -r 895e19fe9c22 gcc/c-parser.c --- a/gcc/c-parser.c Sat Sep 24 02:41:02 2011 +0900 +++ b/gcc/c-parser.c Fri Nov 11 02:35:16 2011 +0900 @@ -2113,9 +2113,11 @@ attrs = build_tree_list(attrs, NULL_TREE); declspecs_add_attrs(specs, attrs); */ - attrs = build_tree_list (get_identifier("fastcall"), NULL_TREE); - /*attrs = build_tree_list (get_identifier("noreturn"), attrs);*/ - declspecs_add_attrs(specs, attrs); + if(!TARGET_64BIT) { + attrs = build_tree_list (get_identifier("fastcall"), NULL_TREE); + /*attrs = build_tree_list (get_identifier("noreturn"), attrs);*/ + declspecs_add_attrs(specs, attrs); + } c_parser_consume_token (parser); break; diff -r d8bf5c8fdea8 -r 895e19fe9c22 gcc/calls.c --- a/gcc/calls.c Sat Sep 24 02:41:02 2011 +0900 +++ b/gcc/calls.c Fri Nov 11 02:35:16 2011 +0900 @@ -2335,7 +2335,12 @@ #endif /* Check whether the target is able to optimize the call into a sibcall. */ +#ifndef noCbC + || (!targetm.function_ok_for_sibcall (fndecl, exp) + && (!fndecl || !CbC_IS_CODE_SEGMENT (TREE_TYPE (fndecl)))) +#else || !targetm.function_ok_for_sibcall (fndecl, exp) +#endif /* Functions that do not return exactly once may not be sibcall optimized. */ || (flags & (ECF_RETURNS_TWICE | ECF_NORETURN)) @@ -2359,9 +2364,14 @@ || !lang_hooks.decls.ok_for_sibcall (fndecl)) try_tail_call = 0; + /* Check if caller and callee disagree in promotion of function return value. */ - if (try_tail_call) +#ifndef noCbC + if (try_tail_call && (!fndecl || !CbC_IS_CODE_SEGMENT (TREE_TYPE (fndecl)))) +#else + if (try_tail_call) +#endif { enum machine_mode caller_mode, caller_promoted_mode; enum machine_mode callee_mode, callee_promoted_mode; diff -r d8bf5c8fdea8 -r 895e19fe9c22 gcc/calls.c~ --- a/gcc/calls.c~ Sat Sep 24 02:41:02 2011 +0900 +++ b/gcc/calls.c~ Fri Nov 11 02:35:16 2011 +0900 @@ -99,6 +99,9 @@ word-sized pseudos we made. */ rtx *aligned_regs; int n_aligned_regs; +#ifndef noCbC +rtx exprs; +#endif }; /* A vector of one char per byte of stack space. A byte if nonzero if @@ -1893,6 +1896,10 @@ return true; } +#ifndef noCbC +#include "cbc-tree.h" +#endif + /* If X is a likely-spilled register value, copy it to a pseudo register and return that register. Return X otherwise. */ @@ -2296,8 +2303,13 @@ expanding a call, as that means we're an argument. Don't try if there's cleanups, as we know there's code to follow the call. */ + // -O2オプションがないときも末尾最適化が行われるように(Code Segmentのみ) if (currently_expanding_call++ != 0 +#ifndef noCbC + || ((!fndecl || !CbC_IS_CODE_SEGMENT (TREE_TYPE (fndecl))) && !flag_optimize_sibling_calls) +#else || !flag_optimize_sibling_calls +#endif || args_size.var || dbg_cnt (tail_call) == false) try_tail_call = 0; @@ -2323,7 +2335,12 @@ #endif /* Check whether the target is able to optimize the call into a sibcall. */ +#ifndef noCbC + || (!targetm.function_ok_for_sibcall (fndecl, exp) + && !CbC_IS_CODE_SEGMENT (TREE_TYPE (fndecl))) +#else || !targetm.function_ok_for_sibcall (fndecl, exp) +#endif /* Functions that do not return exactly once may not be sibcall optimized. */ || (flags & (ECF_RETURNS_TWICE | ECF_NORETURN)) @@ -2347,9 +2364,14 @@ || !lang_hooks.decls.ok_for_sibcall (fndecl)) try_tail_call = 0; + /* Check if caller and callee disagree in promotion of function return value. */ +#ifndef noCbC + if(0) +#else if (try_tail_call) +#endif { enum machine_mode caller_mode, caller_promoted_mode; enum machine_mode callee_mode, callee_promoted_mode; @@ -2388,6 +2410,67 @@ preferred_unit_stack_boundary = preferred_stack_boundary / BITS_PER_UNIT; +#ifndef noCbC + if ( fntype + && CbC_IS_CbC_GOTO (exp) // it's better? than CALL_EXPR_TAILCALL() + && CbC_IS_CODE_SEGMENT (TREE_TYPE (current_function_decl)) + ) + { + + args_size.constant = CbC_PRETENDED_STACK_SIZE; + // try_tail_callを矯正的に立たせて末尾最適化を必ずうように変更 + // -> expand_cbc_gotは不要に。 + /* return expand_cbc_goto(exp, target, fndecl, funtype, fntype, + * addr, ignore, flags, num_actuals, args, &args_size, + * args_so_far, + * old_stack_level, reg_parm_stack_space, old_pending_adj, + * preferred_stack_boundary, preferred_unit_stack_boundary, + * structure_value_addr, old_inhibit_defer_pop); */ + } + else if ( CbC_IS_CbC_GOTO (exp) ) + { + // TODO: 関数からコードセグメントへの遷移 + /* + if (fndecl) + { + char *name_callee = IDENTIFIER_POINTER(DECL_NAME(fndecl)); + warning(0, "no warning: code segment `%s' has been called from a function.", name_callee); + } + else + { + warning(0, "no warning: unnamed code segment has been called from a function."); + } + */ + args_size.constant = CbC_PRETENDED_STACK_SIZE; + } + else if ( fndecl && CbC_IS_CODE_SEGMENT (TREE_TYPE (fndecl)) ) + { + // 警告コードセグメントを関数呼び出し + //char *name= IDENTIFIER_POINTER(DECL_NAME(fndecl)); + //warning (0, "code segment `%s' has been \"called\" instead \"goto\".", name); + } + else if (CbC_IS_CODE_SEGMENT(TREE_TYPE (current_function_decl)) ) + { + // code segment内部からの関数呼び出し。なんも問題ない。 + //warning (0, "no warning: normal call from a code segment."); + } +#endif + + // when tail call optimization flag was down, warn about them. + // and flag it to force a tail call optimize. +#ifndef noCbC + if (fndecl && CbC_IS_CODE_SEGMENT (TREE_TYPE (fndecl)) + && CbC_IS_CODE_SEGMENT (TREE_TYPE (current_function_decl)) + && try_tail_call == 0) + { + location_t loc = EXPR_LOCATION (exp); + char *name_callee = IDENTIFIER_POINTER(DECL_NAME(fndecl)); + warning_at (loc, 0, "transition to code segment \"%s\" with CbC goto, but tail call optimization was cut.", + name_callee); + try_tail_call = 1; + } +#endif + /* We want to make two insn chains; one for a sibling call, the other for a normal call. We will select one of the two chains after initial RTL generation is complete. */ @@ -2454,16 +2537,31 @@ adjusted_args_size = args_size; /* Compute the actual size of the argument block required. The variable - and constant sizes must be combined, the size may have to be rounded, - and there may be a minimum required size. When generating a sibcall - pattern, do not round up, since we'll be re-using whatever space our - caller provided. */ + and constant sizes must be combined, the size may have to be rounded, + and there may be a minimum required size. When generating a sibcall + pattern, do not round up, since we'll be re-using whatever space our + caller provided. */ +#ifndef noCbC + if ( fntype && CbC_IS_CODE_SEGMENT(fntype) ) + { + unadjusted_args_size = args_size.constant; + adjusted_args_size.constant = CbC_PRETENDED_STACK_SIZE; + compute_argument_block_size (reg_parm_stack_space, + &adjusted_args_size, + fndecl, fntype, + (pass == 0 ? 0 + : preferred_stack_boundary)); + } + else +#endif + { unadjusted_args_size - = compute_argument_block_size (reg_parm_stack_space, - &adjusted_args_size, - fndecl, fntype, - (pass == 0 ? 0 - : preferred_stack_boundary)); + = compute_argument_block_size (reg_parm_stack_space, + &adjusted_args_size, + fndecl, fntype, + (pass == 0 ? 0 + : preferred_stack_boundary)); + } old_stack_allocated = stack_pointer_delta - pending_stack_adjust; diff -r d8bf5c8fdea8 -r 895e19fe9c22 gcc/function.c --- a/gcc/function.c Sat Sep 24 02:41:02 2011 +0900 +++ b/gcc/function.c Fri Nov 11 02:35:16 2011 +0900 @@ -65,6 +65,12 @@ #include "timevar.h" #include "vecprim.h" +#ifndef noCbC +#include "cbc-tree.h" +#define CbC_STACK_SIZE (1024 * 8) +#endif + + /* So we can assign to cfun in this file. */ #undef cfun @@ -3481,8 +3487,8 @@ } #ifndef noCbC - //if (CbC_IS_CODE_SEGMENT(TREE_TYPE(fndecl)) ) - //all.stack_args_size.constant = CbC_STACK_SIZE; + if (CbC_IS_CODE_SEGMENT(TREE_TYPE(fndecl)) ) + all.stack_args_size.constant = CbC_STACK_SIZE; #endif /* We have aligned all the args, so add space for the pretend args. */