From 4e7e7a49b760bc46bf0ade36c25a7d8e088b6dea Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 6 May 2011 20:06:29 +0000 Subject: [PATCH] More uses of backend interface for types. From-SVN: r173507 --- gcc/go/gofrontend/types.cc | 154 ++++++++++++++++++------------------------- gcc/go/gofrontend/types.h | 5 -- libgo/runtime/channel.h | 3 + libgo/runtime/go-map-index.c | 6 +- libgo/runtime/go-map-len.c | 2 +- libgo/runtime/go-map-range.c | 2 +- libgo/runtime/go-new-map.c | 4 +- libgo/runtime/map.h | 11 ++-- 8 files changed, 79 insertions(+), 108 deletions(-) diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index fe96741..b89cb63 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -845,7 +845,7 @@ Type::get_tree(Gogo* gogo) if (this->forward_declaration_type() != NULL || this->named_type() != NULL) - return this->get_tree_without_hash(gogo); + return type_to_tree(this->get_btype_without_hash(gogo)); if (this->is_error_type()) return error_mark_node; @@ -865,7 +865,7 @@ Type::get_tree(Gogo* gogo) return ins.first->second; } - tree t = this->get_tree_without_hash(gogo); + tree t = type_to_tree(this->get_btype_without_hash(gogo)); if (ins.first->second == NULL_TREE) ins.first->second = t; @@ -884,43 +884,33 @@ Type::get_tree(Gogo* gogo) return t; } -// Return a tree for a type without looking in the hash table for -// identical types. This is used for named types, since there is no -// point to looking in the hash table for them. +// Return the backend representation for a type without looking in the +// hash table for identical types. This is used for named types, +// since a named type is never identical to any other type. -tree -Type::get_tree_without_hash(Gogo* gogo) +Btype* +Type::get_btype_without_hash(Gogo* gogo) { if (this->tree_ == NULL_TREE) { - tree t = this->do_get_tree(gogo); + Btype* bt = tree_to_type(this->do_get_tree(gogo)); // For a recursive function or pointer type, we will temporarily // return a circular pointer type during the recursion. We // don't want to record that for a forwarding type, as it may // confuse us later. if (this->forward_declaration_type() != NULL - && gogo->backend()->is_circular_pointer_type(tree_to_type(t))) - return t; + && gogo->backend()->is_circular_pointer_type(bt)) + return bt; if (gogo == NULL || !gogo->named_types_are_converted()) - return t; + return bt; + tree t = type_to_tree(bt); this->tree_ = t; - go_preserve_from_gc(t); } - return this->tree_; -} - -// Return the backend representation for a type without looking in the -// hash table for identical types. This is used for named types, -// since a named type is never identical to any other type. - -Btype* -Type::get_btype_without_hash(Gogo* gogo) -{ - return tree_to_type(this->get_tree_without_hash(gogo)); + return tree_to_type(this->tree_); } // Return a tree representing a zero initialization for this type. @@ -1596,8 +1586,8 @@ class Error_type : public Type protected: tree - do_get_tree(Gogo*) - { return error_mark_node; } + do_get_tree(Gogo* gogo) + { return type_to_tree(gogo->backend()->error_type()); } tree do_get_init_tree(Gogo*, tree, bool) @@ -3228,8 +3218,11 @@ class Nil_type : public Type protected: tree - do_get_tree(Gogo*) - { return ptr_type_node; } + do_get_tree(Gogo* gogo) + { + Btype* bt = gogo->backend()->pointer_type(gogo->backend()->void_type()); + return type_to_tree(bt); + } tree do_get_init_tree(Gogo*, tree type_tree, bool is_clear) @@ -5064,61 +5057,44 @@ Map_type::do_check_make_expression(Expression_list* args, return true; } -// Get a tree for a map type. A map type is represented as a pointer -// to a struct. The struct is __go_map in libgo/map.h. +// Get the backend representation for a map type. A map type is +// represented as a pointer to a struct. The struct is __go_map in +// libgo/map.h. tree Map_type::do_get_tree(Gogo* gogo) { - static tree type_tree; - if (type_tree == NULL_TREE) + static Btype* backend_map_type; + if (backend_map_type == NULL) { - tree struct_type = make_node(RECORD_TYPE); - - tree map_descriptor_type = gogo->map_descriptor_type(); - tree const_map_descriptor_type = - build_qualified_type(map_descriptor_type, TYPE_QUAL_CONST); - tree name = get_identifier("__descriptor"); - tree field = build_decl(BUILTINS_LOCATION, FIELD_DECL, name, - build_pointer_type(const_map_descriptor_type)); - DECL_CONTEXT(field) = struct_type; - TYPE_FIELDS(struct_type) = field; - tree last_field = field; + std::vector bfields(4); - name = get_identifier("__element_count"); - field = build_decl(BUILTINS_LOCATION, FIELD_DECL, name, sizetype); - DECL_CONTEXT(field) = struct_type; - DECL_CHAIN(last_field) = field; - last_field = field; - - name = get_identifier("__bucket_count"); - field = build_decl(BUILTINS_LOCATION, FIELD_DECL, name, sizetype); - DECL_CONTEXT(field) = struct_type; - DECL_CHAIN(last_field) = field; - last_field = field; + Type* pdt = Type::make_type_descriptor_ptr_type(); + bfields[0].name = "__descriptor"; + bfields[0].btype = tree_to_type(pdt->get_tree(gogo)); + bfields[0].location = BUILTINS_LOCATION; - name = get_identifier("__buckets"); - field = build_decl(BUILTINS_LOCATION, FIELD_DECL, name, - build_pointer_type(ptr_type_node)); - DECL_CONTEXT(field) = struct_type; - DECL_CHAIN(last_field) = field; + Type* uintptr_type = Type::lookup_integer_type("uintptr"); + bfields[1].name = "__element_count"; + bfields[1].btype = tree_to_type(uintptr_type->get_tree(gogo)); + bfields[1].location = BUILTINS_LOCATION; - layout_type(struct_type); + bfields[2].name = "__bucket_count"; + bfields[2].btype = bfields[1].btype; + bfields[2].location = BUILTINS_LOCATION; - // Give the struct a name for better debugging info. - name = get_identifier("__go_map"); - tree type_decl = build_decl(BUILTINS_LOCATION, TYPE_DECL, name, - struct_type); - DECL_ARTIFICIAL(type_decl) = 1; - TYPE_NAME(struct_type) = type_decl; - go_preserve_from_gc(type_decl); - rest_of_decl_compilation(type_decl, 1, 0); + Btype* bvt = gogo->backend()->void_type(); + Btype* bpvt = gogo->backend()->pointer_type(bvt); + Btype* bppvt = gogo->backend()->pointer_type(bpvt); + bfields[3].name = "__buckets"; + bfields[3].btype = bppvt; + bfields[3].location = BUILTINS_LOCATION; - type_tree = build_pointer_type(struct_type); - go_preserve_from_gc(type_tree); + Btype *bt = gogo->backend()->struct_type(bfields); + bt = gogo->backend()->named_type("__go_map", bt, BUILTINS_LOCATION); + backend_map_type = gogo->backend()->pointer_type(bt); } - - return type_tree; + return type_to_tree(backend_map_type); } // Initialize a map. @@ -5354,19 +5330,17 @@ Channel_type::do_check_make_expression(Expression_list* args, // libgo/runtime/channel.h. tree -Channel_type::do_get_tree(Gogo*) +Channel_type::do_get_tree(Gogo* gogo) { - static tree type_tree; - if (type_tree == NULL_TREE) + static Btype* backend_channel_type; + if (backend_channel_type == NULL) { - tree ret = make_node(RECORD_TYPE); - TYPE_NAME(ret) = get_identifier("__go_channel"); - TYPE_STUB_DECL(ret) = build_decl(BUILTINS_LOCATION, TYPE_DECL, NULL_TREE, - ret); - type_tree = build_pointer_type(ret); - go_preserve_from_gc(type_tree); + std::vector bfields; + Btype* bt = gogo->backend()->struct_type(bfields); + bt = gogo->backend()->named_type("__go_channel", bt, BUILTINS_LOCATION); + backend_channel_type = gogo->backend()->pointer_type(bt); } - return type_tree; + return type_to_tree(backend_channel_type); } // Initialize a channel variable. @@ -8433,7 +8407,7 @@ Forward_declaration_type::do_traverse(Traverse* traverse) return TRAVERSE_CONTINUE; } -// Get a tree for the type. +// Get the backend representation for the type. tree Forward_declaration_type::do_get_tree(Gogo* gogo) @@ -8445,15 +8419,13 @@ Forward_declaration_type::do_get_tree(Gogo* gogo) return error_mark_node; // We represent an undefined type as a struct with no fields. That - // should work fine for the middle-end, since the same case can - // arise in C. - Named_object* no = this->named_object(); - tree type_tree = make_node(RECORD_TYPE); - tree id = no->get_id(gogo); - tree decl = build_decl(no->location(), TYPE_DECL, id, type_tree); - TYPE_NAME(type_tree) = decl; - layout_type(type_tree); - return type_tree; + // should work fine for the backend, since the same case can arise + // in C. + std::vector fields; + Btype* bt = gogo->backend()->struct_type(fields); + bt = gogo->backend()->named_type(this->name(), bt, + this->named_object()->location()); + return type_to_tree(bt); } // Build a type descriptor for a forwarded type. diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h index d8a0f71..a76b653 100644 --- a/gcc/go/gofrontend/types.h +++ b/gcc/go/gofrontend/types.h @@ -1098,11 +1098,6 @@ class Type bool* is_method, bool* found_pointer_method, std::string* ambig1, std::string* ambig2); - // Get a tree for a type without looking in the hash table for - // identical types. - tree - get_tree_without_hash(Gogo*); - // Get the backend representation for a type without looking in the // hash table for identical types. Btype* diff --git a/libgo/runtime/channel.h b/libgo/runtime/channel.h index ac79174..9dcaf7f 100644 --- a/libgo/runtime/channel.h +++ b/libgo/runtime/channel.h @@ -74,6 +74,9 @@ struct __go_channel uint64_t data[]; }; +/* Try to link up with the structure generated by the frontend. */ +typedef struct __go_channel __go_channel; + /* The mutex used to control access to the value pointed to by the __go_channel_select selected field. No additional mutexes may be acquired while this mutex is held. */ diff --git a/libgo/runtime/go-map-index.c b/libgo/runtime/go-map-index.c index 1561c97..02a0f73 100644 --- a/libgo/runtime/go-map-index.c +++ b/libgo/runtime/go-map-index.c @@ -21,11 +21,11 @@ __go_map_rehash (struct __go_map *map) size_t key_offset; size_t key_size; size_t (*hashfn) (const void *, size_t); - size_t old_bucket_count; + uintptr_t old_bucket_count; void **old_buckets; - size_t new_bucket_count; + uintptr_t new_bucket_count; void **new_buckets; - size_t i; + uintptr_t i; descriptor = map->__descriptor; diff --git a/libgo/runtime/go-map-len.c b/libgo/runtime/go-map-len.c index 01df5b4..a8922b9 100644 --- a/libgo/runtime/go-map-len.c +++ b/libgo/runtime/go-map-len.c @@ -18,6 +18,6 @@ __go_map_len (struct __go_map *map) { if (map == NULL) return 0; - __go_assert (map->__element_count == (size_t) (int) map->__element_count); + __go_assert (map->__element_count == (uintptr_t) (int) map->__element_count); return map->__element_count; } diff --git a/libgo/runtime/go-map-range.c b/libgo/runtime/go-map-range.c index 364cda9..54444bc 100644 --- a/libgo/runtime/go-map-range.c +++ b/libgo/runtime/go-map-range.c @@ -34,7 +34,7 @@ __go_mapiternext (struct __go_hash_iter *it) if (entry == NULL) { const struct __go_map *map; - size_t bucket; + uintptr_t bucket; map = it->map; bucket = it->bucket; diff --git a/libgo/runtime/go-new-map.c b/libgo/runtime/go-new-map.c index 73e8d7d..3a47129 100644 --- a/libgo/runtime/go-new-map.c +++ b/libgo/runtime/go-new-map.c @@ -73,8 +73,8 @@ static const unsigned long prime_list[] = /* 256 + 1 or 256 + 48 + 1 */ /* Return the next number from PRIME_LIST >= N. */ -unsigned long -__go_map_next_prime (unsigned long n) +uintptr_t +__go_map_next_prime (uintptr_t n) { size_t low; size_t high; diff --git a/libgo/runtime/map.h b/libgo/runtime/map.h index 9c3fda2..40c31f8 100644 --- a/libgo/runtime/map.h +++ b/libgo/runtime/map.h @@ -1,10 +1,11 @@ /* map.h -- the map type for Go. - Copyright 2009, 2010 The Go Authors. All rights reserved. + Copyright 2009 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ #include +#include #include "go-type.h" @@ -38,10 +39,10 @@ struct __go_map const struct __go_map_descriptor *__descriptor; /* The number of elements in the hash table. */ - size_t __element_count; + uintptr_t __element_count; /* The number of entries in the __buckets array. */ - size_t __bucket_count; + uintptr_t __bucket_count; /* Each bucket is a pointer to a linked list of map entries. */ void **__buckets; @@ -64,13 +65,13 @@ struct __go_hash_iter all the entries in the current bucket. */ const void *next_entry; /* The bucket index of the current and next entry. */ - size_t bucket; + uintptr_t bucket; }; extern struct __go_map *__go_new_map (const struct __go_map_descriptor *, uintptr_t); -extern unsigned long __go_map_next_prime (unsigned long); +extern uintptr_t __go_map_next_prime (uintptr_t); extern void *__go_map_index (struct __go_map *, const void *, _Bool); -- 2.7.4