changeset 142:c83ff0b5a2ed

merge
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Thu, 22 Nov 2018 19:45:33 +0900
parents ce508c72660f (diff) ae07388db637 (current diff)
children 76e1cf5455ef
files CbC-examples/c-next.c
diffstat 8 files changed, 50 insertions(+), 74 deletions(-) [+]
line wrap: on
line diff
--- 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<tree> *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);
--- 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;
--- 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.
--- 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);
--- 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.  */
--- 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));
 
--- 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;
--- 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