diff gcc/go/gofrontend/statements.h @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
line wrap: on
line diff
--- a/gcc/go/gofrontend/statements.h	Thu Oct 25 07:37:49 2018 +0900
+++ b/gcc/go/gofrontend/statements.h	Thu Feb 13 11:34:05 2020 +0900
@@ -15,6 +15,8 @@
 class Block;
 class Function;
 class Unnamed_label;
+class Export_function_body;
+class Import_function_body;
 class Assignment_statement;
 class Temporary_statement;
 class Variable_declaration_statement;
@@ -22,6 +24,7 @@
 class Block_statement;
 class Return_statement;
 class Thunk_statement;
+class Defer_statement;
 class Goto_statement;
 class Goto_unnamed_statement;
 class Label_statement;
@@ -185,7 +188,7 @@
 
   // Make a block statement from a Block.  This is an embedded list of
   // statements which may also include variable definitions.
-  static Statement*
+  static Block_statement*
   make_block_statement(Block*, Location);
 
   // Make an increment statement.
@@ -326,6 +329,27 @@
   check_types(Gogo* gogo)
   { this->do_check_types(gogo); }
 
+  // Return the cost of this statement for inlining purposes.
+  int
+  inlining_cost()
+  { return this->do_inlining_cost(); }
+
+  // Export data for this statement to BODY.
+  void
+  export_statement(Export_function_body* efb)
+  { this->do_export_statement(efb); }
+
+  // Make implicit type conversions explicit.
+  void
+  add_conversions()
+  { this->do_add_conversions(); }
+
+  // Read a statement from export data.  The location should be used
+  // for the returned statement.  Errors should be reported using the
+  // Import_function_body's location method.
+  static Statement*
+  import_statement(Import_function_body*, Location);
+
   // Return whether this is a block statement.
   bool
   is_block_statement() const
@@ -380,6 +404,11 @@
   Thunk_statement*
   thunk_statement();
 
+  // If this is a defer statement, return it.  Otherwise return NULL.
+  Defer_statement*
+  defer_statement()
+  { return this->convert<Defer_statement, STATEMENT_DEFER>(); }
+
   // If this is a goto statement, return it.  Otherwise return NULL.
   Goto_statement*
   goto_statement()
@@ -488,6 +517,20 @@
   do_check_types(Gogo*)
   { }
 
+  // Implemented by child class: return the cost of this statement for
+  // inlining.  The default cost is high, so we only need to define
+  // this method for statements that can be inlined.
+  virtual int
+  do_inlining_cost()
+  { return 0x100000; }
+
+  // Implemented by child class: write export data for this statement
+  // to the string.  This need only be implemented by classes that
+  // implement do_inlining_cost with a reasonable value.
+  virtual void
+  do_export_statement(Export_function_body*)
+  { go_unreachable(); }
+
   // Implemented by child class: return true if this statement may
   // fall through.
   virtual bool
@@ -502,6 +545,11 @@
   virtual void
   do_dump_statement(Ast_dump_context*) const = 0;
 
+  // Implemented by child class: make implicit conversions explicit.
+  virtual void
+  do_add_conversions()
+  { }
+
   // Traverse an expression in a statement.
   int
   traverse_expression(Traverse*, Expression**);
@@ -597,6 +645,13 @@
   void
   do_check_types(Gogo*);
 
+  int
+  do_inlining_cost()
+  { return 1; }
+
+  void
+  do_export_statement(Export_function_body*);
+
   Statement*
   do_flatten(Gogo*, Named_object*, Block*, Statement_inserter*);
 
@@ -606,6 +661,9 @@
   void
   do_dump_statement(Ast_dump_context*) const;
 
+  void
+  do_add_conversions();
+
  private:
   // Left hand side--the lvalue.
   Expression* lhs_;
@@ -623,7 +681,7 @@
   Temporary_statement(Type* type, Expression* init, Location location)
     : Statement(STATEMENT_TEMPORARY, location),
       type_(type), init_(init), bvariable_(NULL), is_address_taken_(false),
-      value_escapes_(false)
+      value_escapes_(false), assigned_(false), uses_(0)
   { }
 
   // Return the type of the temporary variable.
@@ -635,6 +693,17 @@
   init() const
   { return this->init_; }
 
+  // Set the initializer.
+  void
+  set_init(Expression* expr)
+  { this->init_ = expr; }
+
+  // Whether something takes the address of this temporary
+  // variable.
+  bool
+  is_address_taken()
+  { return this->is_address_taken_; }
+
   // Record that something takes the address of this temporary
   // variable.
   void
@@ -651,11 +720,35 @@
   set_value_escapes()
   { this->value_escapes_ = true; }
 
+  // Whether this temporary variable is assigned (after initialization).
+  bool
+  assigned()
+  { return this->assigned_; }
+
+  // Record that this temporary variable is assigned.
+  void
+  set_assigned()
+  { this->assigned_ = true; }
+
+  // Number of uses of this temporary variable.
+  int
+  uses()
+  { return this->uses_; }
+
+  // Add one use of this temporary variable.
+  void
+  add_use()
+  { this->uses_++; }
+
   // Return the temporary variable.  This should not be called until
   // after the statement itself has been converted.
   Bvariable*
   get_backend_variable(Translate_context*) const;
 
+  // Import the declaration of a temporary.
+  static Statement*
+  do_import(Import_function_body*, Location);
+
  protected:
   int
   do_traverse(Traverse*);
@@ -669,6 +762,13 @@
   void
   do_check_types(Gogo*);
 
+  int
+  do_inlining_cost()
+  { return 1; }
+
+  void
+  do_export_statement(Export_function_body*);
+
   Statement*
   do_flatten(Gogo*, Named_object*, Block*, Statement_inserter*);
 
@@ -678,6 +778,9 @@
   void
   do_dump_statement(Ast_dump_context*) const;
 
+  void
+  do_add_conversions();
+
  private:
   // The type of the temporary variable.
   Type* type_;
@@ -690,6 +793,10 @@
   // True if the value assigned to this temporary variable escapes.
   // This is used for select statements.
   bool value_escapes_;
+  // True if this temporary variable is assigned (after initialization).
+  bool assigned_;
+  // Number of uses of this temporary variable.
+  int uses_;
 };
 
 // A variable declaration.  This marks the point in the code where a
@@ -705,6 +812,10 @@
   var()
   { return this->var_; }
 
+  // Import a variable declaration.
+  static Statement*
+  do_import(Import_function_body*, Location);
+
  protected:
   int
   do_traverse(Traverse*);
@@ -715,6 +826,13 @@
   Statement*
   do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
 
+  int
+  do_inlining_cost()
+  { return 1; }
+
+  void
+  do_export_statement(Export_function_body*);
+
   Statement*
   do_flatten(Gogo*, Named_object*, Block*, Statement_inserter*);
 
@@ -724,6 +842,9 @@
   void
   do_dump_statement(Ast_dump_context*) const;
 
+  void
+  do_add_conversions();
+
  private:
   Named_object* var_;
 };
@@ -758,6 +879,13 @@
   do_may_fall_through() const
   { return false; }
 
+  int
+  do_inlining_cost()
+  { return 1; }
+
+  void
+  do_export_statement(Export_function_body*);
+
   Bstatement*
   do_get_backend(Translate_context*);
 
@@ -796,6 +924,13 @@
   bool
   do_may_fall_through() const;
 
+  int
+  do_inlining_cost()
+  { return 0; }
+
+  void
+  do_export_statement(Export_function_body*);
+
   Bstatement*
   do_get_backend(Translate_context* context);
 
@@ -819,6 +954,11 @@
       block_(block), is_lowered_for_statement_(false)
   { }
 
+  // Return the actual block.
+  Block*
+  block() const
+  { return this->block_; }
+
   void
   set_is_lowered_for_statement()
   { this->is_lowered_for_statement_ = true; }
@@ -827,6 +967,16 @@
   is_lowered_for_statement()
   { return this->is_lowered_for_statement_; }
 
+  // Export a block for a block statement.
+  static void
+  export_block(Export_function_body*, Block*, bool is_lowered_for_statement);
+
+  // Import a block statement, returning the block.
+  // *IS_LOWERED_FOR_STATEMENT reports whether this block statement
+  // was lowered from a for statement.
+  static Block*
+  do_import(Import_function_body*, Location, bool* is_lowered_for_statement);
+
  protected:
   int
   do_traverse(Traverse* traverse)
@@ -836,6 +986,13 @@
   do_determine_types()
   { this->block_->determine_types(); }
 
+  int
+  do_inlining_cost()
+  { return 0; }
+
+  void
+  do_export_statement(Export_function_body*);
+
   bool
   do_may_fall_through() const
   { return this->block_->may_fall_through(); }
@@ -890,6 +1047,9 @@
   void
   do_dump_statement(Ast_dump_context*) const;
 
+  void
+  do_add_conversions();
+
  private:
   // The channel on which to send the value.
   Expression* channel_;
@@ -914,7 +1074,7 @@
   // for the variable to set, and CLOSED is either NULL or a
   // Var_expression to set to whether the channel is closed.  If VAL
   // is NULL, VAR may be a variable to be initialized with the
-  // received value, and CLOSEDVAR ma be a variable to be initialized
+  // received value, and CLOSEDVAR may be a variable to be initialized
   // with whether the channel is closed.  IS_DEFAULT is true if this
   // is the default clause.  STATEMENTS is the list of statements to
   // execute.
@@ -963,7 +1123,6 @@
   void
   dump_clauses(Ast_dump_context*) const;
 
- private:
   // A single clause.
   class Select_clause
   {
@@ -1019,8 +1178,30 @@
       return this->is_send_;
     }
 
+    // Return the value to send or the lvalue to receive into.
+    Expression*
+    val() const
+    { return this->val_; }
+
+    // Return the lvalue to set to whether the channel is closed
+    // on a receive.
+    Expression*
+    closed() const
+    { return this->closed_; }
+
+    // Return the variable to initialize, for "case a := <-ch".
+    Named_object*
+    var() const
+    { return this->var_; }
+
+    // Return the variable to initialize to whether the channel
+    // is closed, for "case a, c := <-ch".
+    Named_object*
+    closedvar() const
+    { return this->closedvar_; }
+
     // Return the statements.
-    const Block*
+    Block*
     statements() const
     { return this->statements_; }
 
@@ -1088,6 +1269,11 @@
     bool is_lowered_;
   };
 
+  Select_clause&
+  at(size_t i)
+  { return this->clauses_.at(i); }
+
+ private:
   typedef std::vector<Select_clause> Clauses;
 
   Clauses clauses_;
@@ -1141,6 +1327,14 @@
   do_dump_statement(Ast_dump_context*) const;
 
  private:
+  // Lower a one-case select statement.
+  Statement*
+  lower_one_case(Block*);
+
+  // Lower a two-case select statement with one defualt case.
+  Statement*
+  lower_two_case(Block*);
+
   // The select clauses.
   Select_clauses* clauses_;
   // A temporary that holds the index value returned by selectgo.
@@ -1238,15 +1432,26 @@
 {
  public:
   Defer_statement(Call_expression* call, Location location)
-    : Thunk_statement(STATEMENT_DEFER, call, location)
+    : Thunk_statement(STATEMENT_DEFER, call, location),
+      on_stack_(false)
   { }
 
+  void
+  set_on_stack()
+  { this->on_stack_ = true; }
+
  protected:
   Bstatement*
   do_get_backend(Translate_context*);
 
   void
   do_dump_statement(Ast_dump_context*) const;
+
+ private:
+  static Type*
+  defer_struct_type();
+
+  bool on_stack_;
 };
 
 // A goto statement.
@@ -1264,6 +1469,10 @@
   label() const
   { return this->label_; }
 
+  // Import a goto statement.
+  static Statement*
+  do_import(Import_function_body*, Location);
+
  protected:
   int
   do_traverse(Traverse*);
@@ -1278,6 +1487,13 @@
   Bstatement*
   do_get_backend(Translate_context*);
 
+  int
+  do_inlining_cost()
+  { return 5; }
+
+  void
+  do_export_statement(Export_function_body*);
+
   void
   do_dump_statement(Ast_dump_context*) const;
 
@@ -1310,6 +1526,13 @@
   Bstatement*
   do_get_backend(Translate_context* context);
 
+  int
+  do_inlining_cost()
+  { return 5; }
+
+  void
+  do_export_statement(Export_function_body*);
+
   void
   do_dump_statement(Ast_dump_context*) const;
 
@@ -1332,6 +1555,10 @@
   label() const
   { return this->label_; }
 
+  // Import a label or unnamed label.
+  static Statement*
+  do_import(Import_function_body*, Location);
+
  protected:
   int
   do_traverse(Traverse*);
@@ -1339,6 +1566,13 @@
   Bstatement*
   do_get_backend(Translate_context*);
 
+  int
+  do_inlining_cost()
+  { return 1; }
+
+  void
+  do_export_statement(Export_function_body*);
+
   void
   do_dump_statement(Ast_dump_context*) const;
 
@@ -1361,6 +1595,13 @@
   Bstatement*
   do_get_backend(Translate_context* context);
 
+  int
+  do_inlining_cost()
+  { return 1; }
+
+  void
+  do_export_statement(Export_function_body*);
+
   void
   do_dump_statement(Ast_dump_context*) const;
 
@@ -1384,6 +1625,18 @@
   condition() const
   { return this->cond_; }
 
+  Block*
+  then_block() const
+  { return this->then_block_; }
+
+  Block*
+  else_block() const
+  { return this->else_block_; }
+
+  // Import an if statement.
+  static Statement*
+  do_import(Import_function_body*, Location);
+
  protected:
   int
   do_traverse(Traverse*);
@@ -1394,6 +1647,13 @@
   void
   do_check_types(Gogo*);
 
+  int
+  do_inlining_cost()
+  { return 5; }
+
+  void
+  do_export_statement(Export_function_body*);
+
   bool
   do_may_fall_through() const;
 
@@ -1558,6 +1818,15 @@
 		      Temporary_statement*, Block**, Expression**, Block**,
 		      Block**);
 
+  Statement*
+  lower_map_range_clear(Type*, Block*, Expression*, Named_object*,
+                        Temporary_statement*, Location);
+
+  Statement*
+  lower_array_range_clear(Gogo*, Type*, Expression*, Block*,
+                          Named_object*, Temporary_statement*,
+                          Location);
+
   // The variable which is set to the index value.
   Expression* index_var_;
   // The variable which is set to the element value.  This may be