Mercurial > hg > CbC > CbC_gcc
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. */ |