# HG changeset patch # User Nobuyasu Oshiro # Date 1321169082 -32400 # Node ID 32380d8cb035210901447e226bb669fe9ebfb617 # Parent a5786e986ad208225d8c287bdd450d7b12c671bc# Parent dbfc0d2dde362a251247c2c9bf6087d58a4b3e81 merge 83 diff -r dbfc0d2dde36 -r 32380d8cb035 CbC-examples/arg.c --- a/CbC-examples/arg.c Sat Sep 24 02:43:04 2011 +0900 +++ b/CbC-examples/arg.c Sun Nov 13 16:24:42 2011 +0900 @@ -13,13 +13,13 @@ void *exit_env; __code (*exit___code)(); -__code carg1(int arg0,int arg1,int arg2,int arg3,int arg4,__code(*exit1)(),void *env) +__code carg1(int arg0,int arg1,int arg2,int arg3,int arg4,__code(*exit1)(int, void*),void *env) { printf("#0017:arg1: %d %d %d %d %d : %x %x\n",arg0,arg1,arg2,arg3,arg4,exit1==exit___code,env==exit_env); goto carg2(arg1,arg2,arg3,arg4,arg0,exit1,env); } -__code carg2(int arg0,int arg1,int arg2,int arg3,int arg4,__code(*exit1)(),void *env) +__code carg2(int arg0,int arg1,int arg2,int arg3,int arg4,__code(*exit1)(int, void*),void *env) { struct arg args0; printf("#0024:arg1: %d %d %d %d %d : %x %x\n",arg0,arg1,arg2,arg3,arg4,exit1==exit___code,env==exit_env ); @@ -31,7 +31,7 @@ goto cargs(args0,exit1,env); } -__code cargs(struct arg args0,__code exit1(),void *env) +__code cargs(struct arg args0,__code exit1(int, void*),void *env) { printf("#0035:args: %d %d %d %d %d : %x %x\n", args0.a0,args0.a1,args0.a2,args0.a3,args0.a4, diff -r dbfc0d2dde36 -r 32380d8cb035 gcc/c-parser.c --- a/gcc/c-parser.c Sat Sep 24 02:43:04 2011 +0900 +++ b/gcc/c-parser.c Sun Nov 13 16:24:42 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; @@ -6738,7 +6740,7 @@ /* declare retval. (int retval;) */ tree decl_cond = build_decl (location, VAR_DECL, get_identifier ("retval"), - TREE_TYPE (TREE_TYPE (current_function_decl))); + TREE_TYPE (TREE_TYPE (current_function_decl))); TREE_STATIC (decl_cond) = 1; DECL_ARTIFICIAL (decl_cond) = 1; pushdecl (decl_cond); diff -r dbfc0d2dde36 -r 32380d8cb035 gcc/calls.c --- a/gcc/calls.c Sat Sep 24 02:43:04 2011 +0900 +++ b/gcc/calls.c Sun Nov 13 16:24:42 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)) @@ -2348,8 +2353,14 @@ function, we cannot change it into a sibling call. crtl->args.pretend_args_size is not part of the stack allocated by our caller. */ +#ifndef noCbC + || (args_size.constant > (crtl->args.size + - crtl->args.pretend_args_size) + && (!fndecl || !CbC_IS_CODE_SEGMENT (TREE_TYPE (fndecl)))) +#else || args_size.constant > (crtl->args.size - crtl->args.pretend_args_size) +#endif /* If the callee pops its own arguments, then it must pop exactly the same number of arguments as the current function. */ || (targetm.calls.return_pops_args (fndecl, funtype, args_size.constant) @@ -2359,9 +2370,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 dbfc0d2dde36 -r 32380d8cb035 gcc/calls.c~ --- a/gcc/calls.c~ Sat Sep 24 02:43:04 2011 +0900 +++ b/gcc/calls.c~ Sun Nov 13 16:24:42 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) + && (!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)) @@ -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. */ - 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; @@ -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 dbfc0d2dde36 -r 32380d8cb035 gcc/function.c --- a/gcc/function.c Sat Sep 24 02:43:04 2011 +0900 +++ b/gcc/function.c Sun Nov 13 16:24:42 2011 +0900 @@ -65,6 +65,8 @@ #include "timevar.h" #include "vecprim.h" + + /* So we can assign to cfun in this file. */ #undef cfun @@ -3481,8 +3483,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. */