diff options
author | SimplyTheOther <simplytheother@gmail.com> | 2020-09-08 19:43:37 +0800 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2020-11-28 21:13:20 +0000 |
commit | daedbe3476556f0b39f595debeea6979382d296b (patch) | |
tree | 66fb0606ad0337b4cd7650055b6f69a980d4c40d /gcc | |
parent | 8a633e3ca4d151d6bbee849a1ef2d265d95bc2a7 (diff) | |
download | gcc-daedbe3476556f0b39f595debeea6979382d296b.zip gcc-daedbe3476556f0b39f595debeea6979382d296b.tar.gz gcc-daedbe3476556f0b39f595debeea6979382d296b.tar.bz2 |
Potential modifications to buffered_queue to move when resizing instead of copying - test if works properly
Added messages to buffered_queue to debug assertion failure
Attempt to fix the buffered_queue issue
Removed some debug in buffered_queue
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/lex/rust-lex.cc | 26 | ||||
-rw-r--r-- | gcc/rust/rust-buffered-queue.h | 62 | ||||
-rw-r--r-- | gcc/rust/rust-system.h | 87 |
3 files changed, 60 insertions, 115 deletions
diff --git a/gcc/rust/lex/rust-lex.cc b/gcc/rust/lex/rust-lex.cc index ac174ad..632d5fe 100644 --- a/gcc/rust/lex/rust-lex.cc +++ b/gcc/rust/lex/rust-lex.cc @@ -97,9 +97,10 @@ is_whitespace (char character) // this compiles fine, so any intellisense saying otherwise is fake news Lexer::Lexer (const char *filename, RAIIFile file_input, Linemap *linemap) - : input (std::move (file_input)), current_line (1), current_column (1), line_map (linemap), + : input (std::move (file_input)), current_line (1), current_column (1), + line_map (linemap), /*input_source (input.get_raw ()), */ - input_queue {InputSource (input.get_raw ())}, + input_queue{InputSource (input.get_raw ())}, /*token_source (this),*/ token_queue (TokenSource (this)) { @@ -160,13 +161,14 @@ Lexer::replace_current_token (TokenPtr replacement) { token_queue.replace_current_value (replacement); - fprintf(stderr, "called 'replace_current_token' - this is deprecated"); + fprintf (stderr, "called 'replace_current_token' - this is deprecated"); } /* shitty anonymous namespace that can only be accessed inside the compilation - * unit - used for classify_keyword Binary search in sorted array of keywords + * unit - used for classify_keyword binary search in sorted array of keywords * created with x-macros. */ namespace { +// TODO: make constexpr when update to c++20 const std::string keyword_index[] = { #define RS_TOKEN(x, y) #define RS_TOKEN_KEYWORD(name, keyword) keyword, @@ -175,7 +177,7 @@ const std::string keyword_index[] = { #undef RS_TOKEN }; -TokenId keyword_keys[] = { +constexpr TokenId keyword_keys[] = { #define RS_TOKEN(x, y) #define RS_TOKEN_KEYWORD(name, keyword) name, RS_TOKEN_LIST @@ -183,7 +185,7 @@ TokenId keyword_keys[] = { #undef RS_TOKEN }; -const int num_keywords = sizeof (keyword_index) / sizeof (*keyword_index); +constexpr int num_keywords = sizeof (keyword_index) / sizeof (*keyword_index); } // namespace /* Determines whether the string passed in is a keyword or not. If it is, it @@ -1988,7 +1990,7 @@ Lexer::parse_char_or_lifetime (Location loc) { rust_error_at (get_current_location (), "expected ' after character constant in char literal"); - return nullptr; + return nullptr; } } } @@ -2296,10 +2298,12 @@ Lexer::test_peek_codepoint_input (int n) }*/ } -void -Lexer::split_current_token (TokenId new_left, TokenId new_right) { - // TODO: assert that this TokenId is a "simple token" like punctuation and not like "IDENTIFIER"? - Location current_loc = peek_token ()->get_locus(); +void +Lexer::split_current_token (TokenId new_left, TokenId new_right) +{ + // TODO: assert that this TokenId is a "simple token" like punctuation and not + // like "IDENTIFIER"? + Location current_loc = peek_token ()->get_locus (); TokenPtr new_left_tok = Token::make (new_left, current_loc); TokenPtr new_right_tok = Token::make (new_right, current_loc + 1); diff --git a/gcc/rust/rust-buffered-queue.h b/gcc/rust/rust-buffered-queue.h index ac9ffa1..ae002c0 100644 --- a/gcc/rust/rust-buffered-queue.h +++ b/gcc/rust/rust-buffered-queue.h @@ -2,10 +2,9 @@ #define RUST_BUFFERED_QUEUE_H #include <vector> +#include <utility> -#include "config.h" -#include "system.h" -// order: config, system +#include "rust-system.h" namespace Rust { /* Buffered queue implementation. Items are of type T, queue source is of type @@ -32,7 +31,7 @@ public: T peek (int n) { // n should not be behind - gcc_assert (n >= 0); + rust_assert (n >= 0); int num_queued_items = end - start; int num_items_required = n + 1; @@ -50,20 +49,39 @@ public: int new_size = (buffer.size () + num_items_to_read); new_size += (new_size >> 1); - // create new queue buffer with new size - std::vector<T> new_queue (new_size); - std::copy (buffer.begin () + start, buffer.begin () + end, - new_queue.begin ()); + // old method: + /* + // create new queue buffer with new size + std::vector<T> new_queue (new_size); + std::copy (buffer.begin () + start, buffer.begin () + end, + new_queue.begin ()); + start = 0; + end = num_queued_items; + // TODO: would move be better here? optimisation for move with + // shared pointer? + + // swap member buffer and new queue buffer + std::swap (buffer, new_queue); + */ + + // TODO: determine overhead of this approach vs copy. Should be lower. + std::vector<T> new_queue; + new_queue.reserve (new_size); + new_queue.insert (new_queue.begin (), + std::make_move_iterator (buffer.begin () + start), + std::make_move_iterator (buffer.begin () + end)); start = 0; end = num_queued_items; - // TODO: would move be better here? optimisation for move with - // shared pointer? + // fill up rest of vector with junk so that indexing can work + new_queue.insert (new_queue.begin () + end, new_size - new_queue.size(), T ()); - // swap member buffer and new queue buffer - std::swap (buffer, new_queue); + buffer = std::move (new_queue); + /* this should be best method - std::move(range) would have + * allocation problems; initial construction would require + * reallocation upon resizing */ // validate that buffer is large enough now - gcc_assert (end + num_queued_items < (int) buffer.size ()); + rust_assert (end + num_queued_items < (int) buffer.size ()); } /* iterate through buffer and invoke operator () on source on values @@ -75,11 +93,11 @@ public: end += num_items_to_read; } - gcc_assert (0 <= start); - gcc_assert (start <= end); - gcc_assert (end <= (int) buffer.size ()); + rust_assert (0 <= start); + rust_assert (start <= end); + rust_assert (end <= (int) buffer.size ()); - gcc_assert (start + n < end); + rust_assert (start + n < end); // return value at start + n in buffer return buffer[start + n]; @@ -96,14 +114,14 @@ public: // Clear queue values from start to n (inclusive). for (int i = 0; i < (n + 1); i++) - buffer[start + i] = T (); + buffer[start + i] = T (); // Move start forward by n + 1. start += (n + 1); // Ensure start is not impossible somehow - gcc_assert (0 <= start); - gcc_assert (start <= end); + rust_assert (0 <= start); + rust_assert (start <= end); // Compact buffer if empty if (start == end) @@ -125,12 +143,12 @@ public: } // Insert at arbitrary position (attempt) - void insert (int index, T elem_to_insert) + void insert (int index, T elem_to_insert) { // TODO: test as this may not work properly // n should not be behind - gcc_assert (index >= 0); + rust_assert (index >= 0); // call peek to ensure that the items behind this (at least) are in queue if (index >= 1) diff --git a/gcc/rust/rust-system.h b/gcc/rust/rust-system.h index da2454a..a711fdc 100644 --- a/gcc/rust/rust-system.h +++ b/gcc/rust/rust-system.h @@ -41,91 +41,14 @@ #include <deque> #include <functional> -/* TODO: strictly speaking, as AST move semantics make frontend C++11-and-up - * only, unordered map should always be definable (i.e. don't have to resort to - * tr1 like in C++03), so don't need to have this macro switch - just include - * <unordered_map> and <unordered_set>. */ -#if defined(HAVE_UNORDERED_MAP) - +// Rust frontend requires C++11 minimum, so will have unordered_map and set #include <unordered_map> #include <unordered_set> -#define Unordered_map(KEYTYPE, VALTYPE) std::unordered_map<KEYTYPE, VALTYPE> - -#define Unordered_map_hash(KEYTYPE, VALTYPE, HASHFN, EQFN) \ - std::unordered_map<KEYTYPE, VALTYPE, HASHFN, EQFN> - -#define Unordered_set(KEYTYPE) std::unordered_set<KEYTYPE> - -#define Unordered_set_hash(KEYTYPE, HASHFN, EQFN) \ - std::unordered_set<KEYTYPE, HASHFN, EQFN> - -#elif defined(HAVE_TR1_UNORDERED_MAP) - -#include <tr1/unordered_map> -#include <tr1/unordered_set> - -#define Unordered_map(KEYTYPE, VALTYPE) \ - std::tr1::unordered_map<KEYTYPE, VALTYPE> - -#define Unordered_map_hash(KEYTYPE, VALTYPE, HASHFN, EQFN) \ - std::tr1::unordered_map<KEYTYPE, VALTYPE, HASHFN, EQFN> - -#define Unordered_set(KEYTYPE) std::tr1::unordered_set<KEYTYPE> - -#define Unordered_set_hash(KEYTYPE, HASHFN, EQFN) \ - std::tr1::unordered_set<KEYTYPE, HASHFN, EQFN> - -#elif defined(HAVE_EXT_HASH_MAP) - -#include <ext/hash_map> -#include <ext/hash_set> - -#define Unordered_map(KEYTYPE, VALTYPE) __gnu_cxx::hash_map<KEYTYPE, VALTYPE> - -#define Unordered_map_hash(KEYTYPE, VALTYPE, HASHFN, EQFN) \ - __gnu_cxx::hash_map<KEYTYPE, VALTYPE, HASHFN, EQFN> - -#define Unordered_set(KEYTYPE) __gnu_cxx::hash_set<KEYTYPE> - -#define Unordered_set_hash(KEYTYPE, HASHFN, EQFN) \ - __gnu_cxx::hash_set<KEYTYPE, HASHFN, EQFN> - -// Provide hash functions for strings and pointers. - -namespace __gnu_cxx { - -template <> struct hash<std::string> -{ - size_t operator() (std::string s) const - { - return __stl_hash_string (s.c_str ()); - } -}; - -template <typename T> struct hash<T *> -{ - size_t operator() (T *p) const { return reinterpret_cast<size_t> (p); } -}; - -} // namespace __gnu_cxx - -#else - -#define Unordered_map(KEYTYPE, VALTYPE) std::map<KEYTYPE, VALTYPE> - -#define Unordered_set(KEYTYPE) std::set<KEYTYPE> - -// We could make this work by writing an adapter class which -// implemented operator< in terms of the hash function. -#error "requires hash table type" - -#endif - -// We don't really need iostream, but some versions of gmp.h include -// it when compiled with C++, which means that we need to include it -// before the macro magic of safe-ctype.h, which is included by -// system.h. +/* We don't really need iostream, but some versions of gmp.h include + * it when compiled with C++, which means that we need to include it + * before the macro magic of safe-ctype.h, which is included by + * system.h. */ #include <iostream> #include "system.h" |