comparison gcc/calls.c~ @ 82:895e19fe9c22

modify calls.c
author Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
date Fri, 11 Nov 2011 02:35:16 +0900
parents 561a7518be6b
children 6fb1a677d0b5
comparison
equal deleted inserted replaced
80:d8bf5c8fdea8 82:895e19fe9c22
97 copy in smaller-sized pieces into pseudos. These are stored in a 97 copy in smaller-sized pieces into pseudos. These are stored in a
98 block pointed to by this field. The next field says how many 98 block pointed to by this field. The next field says how many
99 word-sized pseudos we made. */ 99 word-sized pseudos we made. */
100 rtx *aligned_regs; 100 rtx *aligned_regs;
101 int n_aligned_regs; 101 int n_aligned_regs;
102 #ifndef noCbC
103 rtx exprs;
104 #endif
102 }; 105 };
103 106
104 /* A vector of one char per byte of stack space. A byte if nonzero if 107 /* A vector of one char per byte of stack space. A byte if nonzero if
105 the corresponding stack location has been used. 108 the corresponding stack location has been used.
106 This vector is used to prevent a function call within an argument from 109 This vector is used to prevent a function call within an argument from
1891 value, GEN_INT (shift), value, 1, OPTAB_WIDEN)) 1894 value, GEN_INT (shift), value, 1, OPTAB_WIDEN))
1892 gcc_unreachable (); 1895 gcc_unreachable ();
1893 return true; 1896 return true;
1894 } 1897 }
1895 1898
1899 #ifndef noCbC
1900 #include "cbc-tree.h"
1901 #endif
1902
1896 /* If X is a likely-spilled register value, copy it to a pseudo 1903 /* If X is a likely-spilled register value, copy it to a pseudo
1897 register and return that register. Return X otherwise. */ 1904 register and return that register. Return X otherwise. */
1898 1905
1899 static rtx 1906 static rtx
1900 avoid_likely_spilled_reg (rtx x) 1907 avoid_likely_spilled_reg (rtx x)
2294 /* Tail calls can make things harder to debug, and we've traditionally 2301 /* Tail calls can make things harder to debug, and we've traditionally
2295 pushed these optimizations into -O2. Don't try if we're already 2302 pushed these optimizations into -O2. Don't try if we're already
2296 expanding a call, as that means we're an argument. Don't try if 2303 expanding a call, as that means we're an argument. Don't try if
2297 there's cleanups, as we know there's code to follow the call. */ 2304 there's cleanups, as we know there's code to follow the call. */
2298 2305
2306 // -O2オプションがないときも末尾最適化が行われるように(Code Segmentのみ)
2299 if (currently_expanding_call++ != 0 2307 if (currently_expanding_call++ != 0
2308 #ifndef noCbC
2309 || ((!fndecl || !CbC_IS_CODE_SEGMENT (TREE_TYPE (fndecl))) && !flag_optimize_sibling_calls)
2310 #else
2300 || !flag_optimize_sibling_calls 2311 || !flag_optimize_sibling_calls
2312 #endif
2301 || args_size.var 2313 || args_size.var
2302 || dbg_cnt (tail_call) == false) 2314 || dbg_cnt (tail_call) == false)
2303 try_tail_call = 0; 2315 try_tail_call = 0;
2304 2316
2305 /* Rest of purposes for tail call optimizations to fail. */ 2317 /* Rest of purposes for tail call optimizations to fail. */
2321 != OUTGOING_REG_PARM_STACK_SPACE (TREE_TYPE (current_function_decl))) 2333 != OUTGOING_REG_PARM_STACK_SPACE (TREE_TYPE (current_function_decl)))
2322 || (reg_parm_stack_space != REG_PARM_STACK_SPACE (fndecl)) 2334 || (reg_parm_stack_space != REG_PARM_STACK_SPACE (fndecl))
2323 #endif 2335 #endif
2324 /* Check whether the target is able to optimize the call 2336 /* Check whether the target is able to optimize the call
2325 into a sibcall. */ 2337 into a sibcall. */
2338 #ifndef noCbC
2339 || (!targetm.function_ok_for_sibcall (fndecl, exp)
2340 && !CbC_IS_CODE_SEGMENT (TREE_TYPE (fndecl)))
2341 #else
2326 || !targetm.function_ok_for_sibcall (fndecl, exp) 2342 || !targetm.function_ok_for_sibcall (fndecl, exp)
2343 #endif
2327 /* Functions that do not return exactly once may not be sibcall 2344 /* Functions that do not return exactly once may not be sibcall
2328 optimized. */ 2345 optimized. */
2329 || (flags & (ECF_RETURNS_TWICE | ECF_NORETURN)) 2346 || (flags & (ECF_RETURNS_TWICE | ECF_NORETURN))
2330 || TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (addr))) 2347 || TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (addr)))
2331 /* If the called function is nested in the current one, it might access 2348 /* If the called function is nested in the current one, it might access
2345 TREE_TYPE (current_function_decl), 2362 TREE_TYPE (current_function_decl),
2346 crtl->args.size)) 2363 crtl->args.size))
2347 || !lang_hooks.decls.ok_for_sibcall (fndecl)) 2364 || !lang_hooks.decls.ok_for_sibcall (fndecl))
2348 try_tail_call = 0; 2365 try_tail_call = 0;
2349 2366
2367
2350 /* Check if caller and callee disagree in promotion of function 2368 /* Check if caller and callee disagree in promotion of function
2351 return value. */ 2369 return value. */
2370 #ifndef noCbC
2371 if(0)
2372 #else
2352 if (try_tail_call) 2373 if (try_tail_call)
2374 #endif
2353 { 2375 {
2354 enum machine_mode caller_mode, caller_promoted_mode; 2376 enum machine_mode caller_mode, caller_promoted_mode;
2355 enum machine_mode callee_mode, callee_promoted_mode; 2377 enum machine_mode callee_mode, callee_promoted_mode;
2356 int caller_unsignedp, callee_unsignedp; 2378 int caller_unsignedp, callee_unsignedp;
2357 tree caller_res = DECL_RESULT (current_function_decl); 2379 tree caller_res = DECL_RESULT (current_function_decl);
2386 else 2408 else
2387 preferred_stack_boundary = crtl->preferred_stack_boundary; 2409 preferred_stack_boundary = crtl->preferred_stack_boundary;
2388 2410
2389 preferred_unit_stack_boundary = preferred_stack_boundary / BITS_PER_UNIT; 2411 preferred_unit_stack_boundary = preferred_stack_boundary / BITS_PER_UNIT;
2390 2412
2413 #ifndef noCbC
2414 if ( fntype
2415 && CbC_IS_CbC_GOTO (exp) // it's better? than CALL_EXPR_TAILCALL()
2416 && CbC_IS_CODE_SEGMENT (TREE_TYPE (current_function_decl))
2417 )
2418 {
2419
2420 args_size.constant = CbC_PRETENDED_STACK_SIZE;
2421 // try_tail_callを矯正的に立たせて末尾最適化を必ずうように変更
2422 // -> expand_cbc_gotは不要に。
2423 /* return expand_cbc_goto(exp, target, fndecl, funtype, fntype,
2424 * addr, ignore, flags, num_actuals, args, &args_size,
2425 * args_so_far,
2426 * old_stack_level, reg_parm_stack_space, old_pending_adj,
2427 * preferred_stack_boundary, preferred_unit_stack_boundary,
2428 * structure_value_addr, old_inhibit_defer_pop); */
2429 }
2430 else if ( CbC_IS_CbC_GOTO (exp) )
2431 {
2432 // TODO: 関数からコードセグメントへの遷移
2433 /*
2434 if (fndecl)
2435 {
2436 char *name_callee = IDENTIFIER_POINTER(DECL_NAME(fndecl));
2437 warning(0, "no warning: code segment `%s' has been called from a function.", name_callee);
2438 }
2439 else
2440 {
2441 warning(0, "no warning: unnamed code segment has been called from a function.");
2442 }
2443 */
2444 args_size.constant = CbC_PRETENDED_STACK_SIZE;
2445 }
2446 else if ( fndecl && CbC_IS_CODE_SEGMENT (TREE_TYPE (fndecl)) )
2447 {
2448 // 警告コードセグメントを関数呼び出し
2449 //char *name= IDENTIFIER_POINTER(DECL_NAME(fndecl));
2450 //warning (0, "code segment `%s' has been \"called\" instead \"goto\".", name);
2451 }
2452 else if (CbC_IS_CODE_SEGMENT(TREE_TYPE (current_function_decl)) )
2453 {
2454 // code segment内部からの関数呼び出し。なんも問題ない。
2455 //warning (0, "no warning: normal call from a code segment.");
2456 }
2457 #endif
2458
2459 // when tail call optimization flag was down, warn about them.
2460 // and flag it to force a tail call optimize.
2461 #ifndef noCbC
2462 if (fndecl && CbC_IS_CODE_SEGMENT (TREE_TYPE (fndecl))
2463 && CbC_IS_CODE_SEGMENT (TREE_TYPE (current_function_decl))
2464 && try_tail_call == 0)
2465 {
2466 location_t loc = EXPR_LOCATION (exp);
2467 char *name_callee = IDENTIFIER_POINTER(DECL_NAME(fndecl));
2468 warning_at (loc, 0, "transition to code segment \"%s\" with CbC goto, but tail call optimization was cut.",
2469 name_callee);
2470 try_tail_call = 1;
2471 }
2472 #endif
2473
2391 /* We want to make two insn chains; one for a sibling call, the other 2474 /* We want to make two insn chains; one for a sibling call, the other
2392 for a normal call. We will select one of the two chains after 2475 for a normal call. We will select one of the two chains after
2393 initial RTL generation is complete. */ 2476 initial RTL generation is complete. */
2394 for (pass = try_tail_call ? 0 : 1; pass < 2; pass++) 2477 for (pass = try_tail_call ? 0 : 1; pass < 2; pass++)
2395 { 2478 {
2452 if (pass == 0 && crtl->stack_protect_guard) 2535 if (pass == 0 && crtl->stack_protect_guard)
2453 stack_protect_epilogue (); 2536 stack_protect_epilogue ();
2454 2537
2455 adjusted_args_size = args_size; 2538 adjusted_args_size = args_size;
2456 /* Compute the actual size of the argument block required. The variable 2539 /* Compute the actual size of the argument block required. The variable
2457 and constant sizes must be combined, the size may have to be rounded, 2540 and constant sizes must be combined, the size may have to be rounded,
2458 and there may be a minimum required size. When generating a sibcall 2541 and there may be a minimum required size. When generating a sibcall
2459 pattern, do not round up, since we'll be re-using whatever space our 2542 pattern, do not round up, since we'll be re-using whatever space our
2460 caller provided. */ 2543 caller provided. */
2544 #ifndef noCbC
2545 if ( fntype && CbC_IS_CODE_SEGMENT(fntype) )
2546 {
2547 unadjusted_args_size = args_size.constant;
2548 adjusted_args_size.constant = CbC_PRETENDED_STACK_SIZE;
2549 compute_argument_block_size (reg_parm_stack_space,
2550 &adjusted_args_size,
2551 fndecl, fntype,
2552 (pass == 0 ? 0
2553 : preferred_stack_boundary));
2554 }
2555 else
2556 #endif
2557 {
2461 unadjusted_args_size 2558 unadjusted_args_size
2462 = compute_argument_block_size (reg_parm_stack_space, 2559 = compute_argument_block_size (reg_parm_stack_space,
2463 &adjusted_args_size, 2560 &adjusted_args_size,
2464 fndecl, fntype, 2561 fndecl, fntype,
2465 (pass == 0 ? 0 2562 (pass == 0 ? 0
2466 : preferred_stack_boundary)); 2563 : preferred_stack_boundary));
2564 }
2467 2565
2468 old_stack_allocated = stack_pointer_delta - pending_stack_adjust; 2566 old_stack_allocated = stack_pointer_delta - pending_stack_adjust;
2469 2567
2470 /* The argument block when performing a sibling call is the 2568 /* The argument block when performing a sibling call is the
2471 incoming argument block. */ 2569 incoming argument block. */