This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Go patch committed: Use backend interface for array length


This patch by Chris Manghane changes the Go frontend to use the backend
interface for the length of an array.  Bootstrapped and ran Go testsuite
on x86_64-unknown-linux-gnu.  Committed to mainline.

Ian

diff -r f4135c695c00 go/types.cc
--- a/go/types.cc	Mon May 05 20:10:20 2014 -0400
+++ b/go/types.cc	Mon May 05 21:00:16 2014 -0400
@@ -245,7 +245,7 @@
   return ptype == NULL ? NULL : ptype->points_to();
 }
 
-// Return whether this is an open array type.
+// Return whether this is a slice type.
 
 bool
 Type::is_slice_type() const
@@ -5839,14 +5839,85 @@
   gogo->add_statement(s);
 }
 
-// Get a tree for the length of a fixed array.  The length may be
+// Get the backend representation of the fields of a slice.  This is
+// not declared in types.h so that types.h doesn't have to #include
+// backend.h.
+//
+// We use int for the count and capacity fields.  This matches 6g.
+// The language more or less assumes that we can't allocate space of a
+// size which does not fit in int.
+
+static void
+get_backend_slice_fields(Gogo* gogo, Array_type* type, bool use_placeholder,
+			 std::vector<Backend::Btyped_identifier>* bfields)
+{
+  bfields->resize(3);
+
+  Type* pet = Type::make_pointer_type(type->element_type());
+  Btype* pbet = (use_placeholder
+		 ? pet->get_backend_placeholder(gogo)
+		 : pet->get_backend(gogo));
+  Location ploc = Linemap::predeclared_location();
+
+  Backend::Btyped_identifier* p = &(*bfields)[0];
+  p->name = "__values";
+  p->btype = pbet;
+  p->location = ploc;
+
+  Type* int_type = Type::lookup_integer_type("int");
+
+  p = &(*bfields)[1];
+  p->name = "__count";
+  p->btype = int_type->get_backend(gogo);
+  p->location = ploc;
+
+  p = &(*bfields)[2];
+  p->name = "__capacity";
+  p->btype = int_type->get_backend(gogo);
+  p->location = ploc;
+}
+
+// Get a tree for the type of this array.  A fixed array is simply
+// represented as ARRAY_TYPE with the appropriate index--i.e., it is
+// just like an array in C.  A slice is a struct with three
+// fields: a data pointer, the length, and the capacity.
+
+Btype*
+Array_type::do_get_backend(Gogo* gogo)
+{
+  if (this->length_ == NULL)
+    {
+      std::vector<Backend::Btyped_identifier> bfields;
+      get_backend_slice_fields(gogo, this, false, &bfields);
+      return gogo->backend()->struct_type(bfields);
+    }
+  else
+    {
+      Btype* element = this->get_backend_element(gogo, false);
+      Bexpression* len = this->get_backend_length(gogo);
+      return gogo->backend()->array_type(element, len);
+    }
+}
+
+// Return the backend representation of the element type.
+
+Btype*
+Array_type::get_backend_element(Gogo* gogo, bool use_placeholder)
+{
+  if (use_placeholder)
+    return this->element_type_->get_backend_placeholder(gogo);
+  else
+    return this->element_type_->get_backend(gogo);
+}
+
+// Return the backend representation of the length. The length may be
 // computed using a function call, so we must only evaluate it once.
 
-tree
-Array_type::get_length_tree(Gogo* gogo)
+Bexpression*
+Array_type::get_backend_length(Gogo* gogo)
 {
   go_assert(this->length_ != NULL);
-  if (this->length_tree_ == NULL_TREE)
+  if (this->blength_ == NULL)
     {
       Numeric_constant nc;
       mpz_t val;
@@ -5854,8 +5925,8 @@
 	{
 	  if (mpz_sgn(val) < 0)
 	    {
-	      this->length_tree_ = error_mark_node;
-	      return this->length_tree_;
+	      this->blength_ = gogo->backend()->error_expression();
+	      return this->blength_;
 	    }
 	  Type* t = nc.type();
 	  if (t == NULL)
@@ -5863,9 +5934,8 @@
 	  else if (t->is_abstract())
 	    t = t->make_non_abstract_type();
           Btype* btype = t->get_backend(gogo);
-          Bexpression* iexpr =
-              gogo->backend()->integer_constant_expression(btype, val);
-	  this->length_tree_ = expr_to_tree(iexpr);
+          this->blength_ =
+	    gogo->backend()->integer_constant_expression(btype, val);
 	  mpz_clear(val);
 	}
       else
@@ -5873,97 +5943,15 @@
 	  // Make up a translation context for the array length
 	  // expression.  FIXME: This won't work in general.
 	  Translate_context context(gogo, NULL, NULL, NULL);
-	  tree len = this->length_->get_tree(&context);
-	  if (len != error_mark_node)
-	    {
-	      Type* int_type = Type::lookup_integer_type("int");
-	      tree int_type_tree = type_to_tree(int_type->get_backend(gogo));
-	      len = convert_to_integer(int_type_tree, len);
-	      len = save_expr(len);
-	    }
-	  this->length_tree_ = len;
-	}
-    }
-  return this->length_tree_;
-}
-
-// Get the backend representation of the fields of a slice.  This is
-// not declared in types.h so that types.h doesn't have to #include
-// backend.h.
-//
-// We use int for the count and capacity fields.  This matches 6g.
-// The language more or less assumes that we can't allocate space of a
-// size which does not fit in int.
-
-static void
-get_backend_slice_fields(Gogo* gogo, Array_type* type, bool use_placeholder,
-			 std::vector<Backend::Btyped_identifier>* bfields)
-{
-  bfields->resize(3);
-
-  Type* pet = Type::make_pointer_type(type->element_type());
-  Btype* pbet = (use_placeholder
-		 ? pet->get_backend_placeholder(gogo)
-		 : pet->get_backend(gogo));
-  Location ploc = Linemap::predeclared_location();
-
-  Backend::Btyped_identifier* p = &(*bfields)[0];
-  p->name = "__values";
-  p->btype = pbet;
-  p->location = ploc;
-
-  Type* int_type = Type::lookup_integer_type("int");
-
-  p = &(*bfields)[1];
-  p->name = "__count";
-  p->btype = int_type->get_backend(gogo);
-  p->location = ploc;
-
-  p = &(*bfields)[2];
-  p->name = "__capacity";
-  p->btype = int_type->get_backend(gogo);
-  p->location = ploc;
-}
-
-// Get a tree for the type of this array.  A fixed array is simply
-// represented as ARRAY_TYPE with the appropriate index--i.e., it is
-// just like an array in C.  An open array is a struct with three
-// fields: a data pointer, the length, and the capacity.
-
-Btype*
-Array_type::do_get_backend(Gogo* gogo)
-{
-  if (this->length_ == NULL)
-    {
-      std::vector<Backend::Btyped_identifier> bfields;
-      get_backend_slice_fields(gogo, this, false, &bfields);
-      return gogo->backend()->struct_type(bfields);
-    }
-  else
-    {
-      Btype* element = this->get_backend_element(gogo, false);
-      Bexpression* len = this->get_backend_length(gogo);
-      return gogo->backend()->array_type(element, len);
-    }
-}
-
-// Return the backend representation of the element type.
-
-Btype*
-Array_type::get_backend_element(Gogo* gogo, bool use_placeholder)
-{
-  if (use_placeholder)
-    return this->element_type_->get_backend_placeholder(gogo);
-  else
-    return this->element_type_->get_backend(gogo);
-}
-
-// Return the backend representation of the length.
-
-Bexpression*
-Array_type::get_backend_length(Gogo* gogo)
-{
-  return tree_to_expr(this->get_length_tree(gogo));
+	  this->blength_ = tree_to_expr(this->length_->get_tree(&context));
+
+	  Btype* ibtype = Type::lookup_integer_type("int")->get_backend(gogo);
+	  this->blength_ =
+	    gogo->backend()->convert_expression(ibtype, this->blength_,
+						this->length_->location());
+	}
+    }
+  return this->blength_;
 }
 
 // Finish backend representation of the array.
@@ -5997,7 +5985,7 @@
                                    array->location());
     }
 
-  // Open array.
+  // Slice.
   return Expression::make_slice_info(array,
                                      Expression::SLICE_INFO_VALUE_POINTER,
                                      array->location());
@@ -6012,7 +6000,7 @@
   if (this->length_ != NULL)
     return this->length_;
 
-  // This is an open array.  We need to read the length field.
+  // This is a slice.  We need to read the length field.
   return Expression::make_slice_info(array, Expression::SLICE_INFO_LENGTH,
                                      array->location());
 }
@@ -6026,7 +6014,7 @@
   if (this->length_ != NULL)
     return this->length_;
 
-  // This is an open array.  We need to read the capacity field.
+  // This is a slice.  We need to read the capacity field.
   return Expression::make_slice_info(array, Expression::SLICE_INFO_CAPACITY,
                                      array->location());
 }
diff -r f4135c695c00 go/types.h
--- a/go/types.h	Mon May 05 20:10:20 2014 -0400
+++ b/go/types.h	Mon May 05 21:00:16 2014 -0400
@@ -2305,7 +2305,7 @@
  public:
   Array_type(Type* element_type, Expression* length)
     : Type(TYPE_ARRAY),
-      element_type_(element_type), length_(length), length_tree_(NULL)
+      element_type_(element_type), length_(length), blength_(NULL)
   { }
 
   // Return the element type.
@@ -2313,7 +2313,7 @@
   element_type() const
   { return this->element_type_; }
 
-  // Return the length.  This will return NULL for an open array.
+  // Return the length.  This will return NULL for a slice.
   Expression*
   length() const
   { return this->length_; }
@@ -2407,9 +2407,6 @@
   bool
   verify_length();
 
-  tree
-  get_length_tree(Gogo*);
-
   Expression*
   array_type_descriptor(Gogo*, Named_type*);
 
@@ -2420,8 +2417,9 @@
   Type* element_type_;
   // The number of elements.  This may be NULL.
   Expression* length_;
-  // The length as a tree.  We only want to compute this once.
-  tree length_tree_;
+  // The backend representation of the length.
+  // We only want to compute this once.
+  Bexpression* blength_;
 };
 
 // The type of a map.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]