aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorSimplyTheOther <simplytheother@gmail.com>2020-09-08 19:43:37 +0800
committerPhilip Herron <philip.herron@embecosm.com>2020-11-28 21:13:20 +0000
commitdaedbe3476556f0b39f595debeea6979382d296b (patch)
tree66fb0606ad0337b4cd7650055b6f69a980d4c40d /gcc
parent8a633e3ca4d151d6bbee849a1ef2d265d95bc2a7 (diff)
downloadgcc-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.cc26
-rw-r--r--gcc/rust/rust-buffered-queue.h62
-rw-r--r--gcc/rust/rust-system.h87
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"