# HG changeset patch # User Shinji KONO # Date 1542883533 -32400 # Node ID c83ff0b5a2edcab19352a4d7962e615a16810d87 # Parent ce508c72660fd5e6b03c9fb343056773cf53040f# Parent ae07388db63799994dd5f8b21af7411b46b680a8 merge diff -r ae07388db637 -r c83ff0b5a2ed CbC-examples/c-next.c diff -r ae07388db637 -r c83ff0b5a2ed gcc/c/c-parser.c --- a/gcc/c/c-parser.c Mon Nov 12 17:01:46 2018 +0900 +++ b/gcc/c/c-parser.c Thu Nov 22 19:45:33 2018 +0900 @@ -5418,12 +5418,9 @@ c_parser_statement_after_labels (parser, if_p, NULL); } -/* Parse a statement, other than a labeled statement. CHAIN is a vector - of if-else-if conditions. - - IF_P is used to track whether there's a (possibly labeled) if statement - which is not enclosed in braces and has an else clause. This is used to - implement -Wparentheses. */ +/* + * To avoid complication, compute argments and function pointer before tail call + */ static tree cbc_replace_arguments (location_t loc, tree call) @@ -5438,7 +5435,12 @@ if ( TREE_CODE (fn)==PARM_DECL || !TREE_CONSTANT (fn) ) { tmp_decl = build_decl (loc, VAR_DECL, NULL_TREE, TREE_TYPE(fn)); + DECL_SOURCE_LOCATION (tmp_decl) = loc; + DECL_ARTIFICIAL (tmp_decl) = 1; + TREE_USED (tmp_decl) = 1; + DECL_CONTEXT (tmp_decl) = current_function_decl; pushdecl (tmp_decl); + finish_decl (tmp_decl, loc, NULL_TREE, NULL_TREE, NULL_TREE); add_stmt (build_modify_expr (loc, tmp_decl, NULL_TREE, NOP_EXPR, loc, fn, NULL_TREE)); CALL_EXPR_FN (call) = tmp_decl; @@ -5446,11 +5448,15 @@ FOR_EACH_CALL_EXPR_ARG (arg, iter, call) { - /* if ( !CONSTANT_CLASS_P (arg) && !VAR_OR_FUNCTION_DECL_P (arg) ) */ if ( TREE_CODE (arg)==PARM_DECL || !TREE_CONSTANT (arg) ) { tmp_decl = build_decl (loc, VAR_DECL, NULL_TREE, TREE_TYPE(arg)); + DECL_SOURCE_LOCATION (tmp_decl) = loc; + DECL_ARTIFICIAL (tmp_decl) = 1; + TREE_USED (tmp_decl) = 1; + DECL_CONTEXT (tmp_decl) = current_function_decl; pushdecl (tmp_decl); + finish_decl (tmp_decl, loc, NULL_TREE, NULL_TREE, NULL_TREE); add_stmt (build_modify_expr (loc, tmp_decl, NULL_TREE, NOP_EXPR, loc, arg, NULL_TREE)); CALL_EXPR_ARG (call, i) = tmp_decl; @@ -5461,6 +5467,13 @@ return call; } +/* Parse a statement, other than a labeled statement. CHAIN is a vector + of if-else-if conditions. + + IF_P is used to track whether there's a (possibly labeled) if statement + which is not enclosed in braces and has an else clause. This is used to + implement -Wparentheses. */ + static void c_parser_statement_after_labels (c_parser *parser, bool *if_p, vec *chain) @@ -5531,17 +5544,15 @@ { tree id = c_parser_peek_token (parser)->value; location_t loc = c_parser_peek_token (parser)->location; - /** build_external_ref (id,RID_CbC_CODE , loc); **/ build_external_ref (loc, id, RID_CbC_CODE, &expr.original_type); } expr = c_parser_expr_no_commas (parser, NULL); if (TREE_CODE(expr.value) == CALL_EXPR ) { location_t loc = c_parser_peek_token (parser)->location; - cbc_replace_arguments (loc, expr.value); + // cbc_replace_arguments (loc, expr.value); TREE_TYPE(expr.value) = void_type_node; - /*tree env = NULL_TREE;**/ CbC_IS_CbC_GOTO (expr.value) = 1; CALL_EXPR_TAILCALL (expr.value) = 1; add_stmt(expr.value); @@ -5549,7 +5560,7 @@ bool flag_isoc99_save = flag_isoc99; warn_return_type = false; flag_isoc99 = false; - stmt = c_finish_return(loc, NULL_TREE, NULL_TREE); /* stmt = c_finish_return (0); */ + stmt = c_finish_return(loc, NULL_TREE, NULL_TREE); warn_return_type = warn_return_type_save; flag_isoc99 = flag_isoc99_save; } @@ -7980,7 +7991,7 @@ add_stmt (build_stmt (loc, LABEL_EXPR, tlab)); /* add_stmt (RETURN_EXPR) */ - tree ret = c_finish_return (loc, retval, retval); + /*tree ret = */ c_finish_return (loc, retval, retval); DECL_READ_P(retval) = 1; // (NODE)->decl_common.decl_read_flag = 1; // TREE_USED(ret) = 1; tree stmt_body = c_end_compound_stmt (loc, stmt, true); @@ -8001,6 +8012,7 @@ TREE_USED (retval) = 1; } + static tree cbc_finish_nested_function (location_t loc, tree label, tree retval_decl) { @@ -8069,7 +8081,7 @@ tree cstmt = c_begin_compound_stmt (true); add_stmt (build_modify_expr (loc, retval_decl, NULL_TREE, NOP_EXPR, loc, _retval_decl, NULL_TREE)); - tree stmt = c_finish_goto_label (loc, label); + /*tree stmt = */ c_finish_goto_label (loc, label); /* end compound statement. */ fnbody = c_end_compound_stmt (loc, cstmt, true); diff -r ae07388db637 -r c83ff0b5a2ed gcc/c/cbc-tree.h --- a/gcc/c/cbc-tree.h Mon Nov 12 17:01:46 2018 +0900 +++ b/gcc/c/cbc-tree.h Thu Nov 22 19:45:33 2018 +0900 @@ -3,11 +3,10 @@ /* Set if the fntype is code segment on CbC language. */ /* flag3,5,6 has been used by c-tree.h */ -#define CbC_IS_CODE_SEGMENT(TYPE) TYPE_LANG_FLAG_5 ( FUNCTION_TYPE_CHECK(TYPE)) +#define CbC_IS_CODE_SEGMENT(TYPE) (TYPE_LANG_FLAG_5 ( FUNCTION_TYPE_CHECK(TYPE))) /* Set if the CALL_EXPR NODE is goto statement on CbC language. */ -#define CbC_IS_CbC_GOTO(NODE) TREE_LANG_FLAG_5 (CALL_EXPR_CHECK(NODE)) -#define CALL_EXPR_CbC_GOTO(NODE) TREE_LANG_FLAG_5 (CALL_EXPR_CHECK(NODE)) +#define CbC_IS_CbC_GOTO(NODE) (TREE_LANG_FLAG_5 (CALL_EXPR_CHECK(NODE))) extern tree cbc_return_f; extern tree cbc_env; diff -r ae07388db637 -r c83ff0b5a2ed gcc/calls.c --- a/gcc/calls.c Mon Nov 12 17:01:46 2018 +0900 +++ b/gcc/calls.c Thu Nov 22 19:45:33 2018 +0900 @@ -119,9 +119,6 @@ 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 @@ -3618,7 +3615,7 @@ 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のみ) + // in case of __code do tail call even if no -O2 if (currently_expanding_call++ != 0 #ifndef noCbC @@ -3695,53 +3692,23 @@ 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() - //&& CALL_EXPR_TAILCALL(exp) - && 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."); - } - */ - // treat goto codesegments in normall function call as a function call - // this behavale same as llvm - //args_size.constant = CbC_PRETENDED_STACK_SIZE; - try_tail_call = 0; - } - 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."); - } + if (CbC_IS_CbC_GOTO (exp)) { + if (CbC_IS_CODE_SEGMENT (TREE_TYPE (current_function_decl))) { + // fix stack size to force tail call + args_size.constant = CbC_PRETENDED_STACK_SIZE; + } else { + // treat goto codesegments in normall function call as a function call + // this behavale same as llvm + //args_size.constant = CbC_PRETENDED_STACK_SIZE; + try_tail_call = 0; + } + } else if ( fndecl && CbC_IS_CODE_SEGMENT (TREE_TYPE (fndecl)) ) { + // __code is called as function + if (CbC_IS_CODE_SEGMENT(TREE_TYPE (current_function_decl)) ) { + const char *name= IDENTIFIER_POINTER(DECL_NAME(fndecl)); + warning (0, "code segment `%s' has been \"called\" instead \"goto\".", name); + } + } #endif // when tail call optimization flag was down, warn about them. diff -r ae07388db637 -r c83ff0b5a2ed gcc/cfgexpand.c --- a/gcc/cfgexpand.c Mon Nov 12 17:01:46 2018 +0900 +++ b/gcc/cfgexpand.c Thu Nov 22 19:45:33 2018 +0900 @@ -2680,6 +2680,9 @@ if (gimple_no_warning_p (stmt)) TREE_NO_WARNING (exp) = 1; +#ifndef noCbC + CbC_IS_CbC_GOTO (exp) = gimple_call_cbc_goto_p(stmt); +#endif CALL_EXPR_TAILCALL (exp) = gimple_call_tail_p (stmt); CALL_EXPR_MUST_TAIL_CALL (exp) = gimple_call_must_tail_p (stmt); CALL_EXPR_RETURN_SLOT_OPT (exp) = gimple_call_return_slot_opt_p (stmt); diff -r ae07388db637 -r c83ff0b5a2ed gcc/function.c --- a/gcc/function.c Mon Nov 12 17:01:46 2018 +0900 +++ b/gcc/function.c Thu Nov 22 19:45:33 2018 +0900 @@ -3696,7 +3696,7 @@ #ifndef noCbC if (CbC_IS_CODE_SEGMENT(TREE_TYPE(fndecl)) ) - all.stack_args_size.constant = CbC_PRETENDED_STACK_SIZE; + all.stack_args_size.constant = CbC_PRETENDED_STACK_SIZE; #endif /* We have aligned all the args, so add space for the pretend args. */ diff -r ae07388db637 -r c83ff0b5a2ed gcc/gimple.c --- a/gcc/gimple.c Mon Nov 12 17:01:46 2018 +0900 +++ b/gcc/gimple.c Thu Nov 22 19:45:33 2018 +0900 @@ -387,7 +387,7 @@ gimple_call_set_nothrow (call, TREE_NOTHROW (t)); gimple_call_set_by_descriptor (call, CALL_EXPR_BY_DESCRIPTOR (t)); #ifndef noCbC - gimple_call_set_cbc_goto (call, CALL_EXPR_CbC_GOTO (t)); + gimple_call_set_cbc_goto (call, CbC_IS_CbC_GOTO (t)); #endif gimple_set_no_warning (call, TREE_NO_WARNING (t)); diff -r ae07388db637 -r c83ff0b5a2ed gcc/gimplify.c --- a/gcc/gimplify.c Mon Nov 12 17:01:46 2018 +0900 +++ b/gcc/gimplify.c Thu Nov 22 19:45:33 2018 +0900 @@ -1513,9 +1513,7 @@ || ( ret_expr && TREE_CODE(ret_expr)==CALL_EXPR && CbC_IS_CbC_GOTO(ret_expr) - //&& !CbC_IS_CODE_SEGMENT(TREE_TYPE(current_function_decl))) && !(current_function_decl&&CbC_IS_CODE_SEGMENT(TREE_TYPE(current_function_decl)))) - //&& !(current_function_decl&&CbC_IS_CODE_SEGMENT(current_function_decl))) #endif ) result_decl = NULL_TREE; diff -r ae07388db637 -r c83ff0b5a2ed gcc/tree-ssa-operands.c --- a/gcc/tree-ssa-operands.c Mon Nov 12 17:01:46 2018 +0900 +++ b/gcc/tree-ssa-operands.c Thu Nov 22 19:45:33 2018 +0900 @@ -30,9 +30,6 @@ #include "stmt.h" #include "print-tree.h" #include "dumpfile.h" -#ifndef noCbC - #include "c/cbc-tree.h" -#endif /* This file contains the code required to manage the operands cache of the SSA optimizer. For every stmt, we maintain an operand cache in the stmt