From 35164f5d664775d4ece40d1c0774d5c417686e3c Mon Sep 17 00:00:00 2001 From: ISSOtm Date: Fri, 23 Aug 2024 04:18:32 +0200 Subject: [PATCH] Reduce the size of some enums and structs By removing padding, essentially. While trying to keep semantically-relevant fields together. This should bump performance slightly, simply from moving less data around (especially in the lexer, which creates a bunch of contexts all the time) --- include/asm/format.hpp | 7 ++++--- include/asm/lexer.hpp | 18 +++++++++--------- include/asm/output.hpp | 2 +- include/asm/rpn.hpp | 2 +- include/asm/symbol.hpp | 6 +++--- include/asm/warning.hpp | 2 +- include/gfx/main.hpp | 20 ++++++++++---------- include/link/main.hpp | 4 ++-- include/link/symbol.hpp | 2 +- include/linkdefs.hpp | 14 +++++++------- src/link/object.cpp | 4 ++-- src/link/output.cpp | 1 - 12 files changed, 41 insertions(+), 41 deletions(-) diff --git a/include/asm/format.hpp b/include/asm/format.hpp index 537160d17..0be41a5e0 100644 --- a/include/asm/format.hpp +++ b/include/asm/format.hpp @@ -7,7 +7,7 @@ #include #include -enum FormatState { +enum FormatState : unsigned char { FORMAT_SIGN, // expects '+' or ' ' (optional) FORMAT_PREFIX, // expects '#' (optional) FORMAT_ALIGN, // expects '-' (optional) @@ -18,17 +18,18 @@ enum FormatState { }; class FormatSpec { - FormatState state; int sign; bool prefix; bool alignLeft; bool padZero; - size_t width; bool hasFrac; size_t fracWidth; + size_t width; int type; bool valid; + FormatState state; + public: bool isEmpty() const { return !state; } bool isValid() const { return valid || state == FORMAT_DONE; } diff --git a/include/asm/lexer.hpp b/include/asm/lexer.hpp index a9abc0fe1..fdf3f78c9 100644 --- a/include/asm/lexer.hpp +++ b/include/asm/lexer.hpp @@ -21,7 +21,7 @@ static_assert(LEXER_BUF_SIZE > 1, "Lexer buffer size is too small"); // This caps the size of buffer reads, and according to POSIX, passing more than SSIZE_MAX is UB static_assert(LEXER_BUF_SIZE <= SSIZE_MAX, "Lexer buffer size is too large"); -enum LexerMode { +enum LexerMode : unsigned char { LEXER_NORMAL, LEXER_RAW, LEXER_SKIP_TO_ELIF, @@ -80,23 +80,23 @@ struct IfStackEntry { struct LexerState { std::string path; - LexerMode mode; + std::deque expansions; // Front is the innermost current expansion + size_t macroArgScanDistance; // Max distance already scanned for macro args + bool disableMacroArgs; + bool disableInterpolation; + bool expandStrings; + bool atLineStart; uint32_t lineNo; uint32_t colNo; int lastToken; - - std::deque ifStack; + LexerMode mode; bool capturing; // Whether the text being lexed should be captured size_t captureSize; // Amount of text captured std::shared_ptr> captureBuf; // Buffer to send the captured text to if set - bool disableMacroArgs; - bool disableInterpolation; - size_t macroArgScanDistance; // Max distance already scanned for macro args - bool expandStrings; - std::deque expansions; // Front is the innermost current expansion + std::deque ifStack; Either content; diff --git a/include/asm/output.hpp b/include/asm/output.hpp index 490f4448a..af7eace9f 100644 --- a/include/asm/output.hpp +++ b/include/asm/output.hpp @@ -14,7 +14,7 @@ struct Expression; struct FileStackNode; -enum StateFeature { +enum StateFeature : unsigned char { STATE_EQU, STATE_VAR, STATE_EQUS, diff --git a/include/asm/rpn.hpp b/include/asm/rpn.hpp index b5b95ba83..bd79f20e2 100644 --- a/include/asm/rpn.hpp +++ b/include/asm/rpn.hpp @@ -18,9 +18,9 @@ struct Expression { std::string // Why the expression is not known, if it isn't > data = 0; - bool isSymbol = false; // Whether the expression represents a symbol suitable for const diffing std::vector rpn{}; // Bytes serializing the RPN expression uint32_t rpnPatchSize = 0; // Size the expression will take in the object file + bool isSymbol = false; // Whether the expression represents a symbol suitable for const diffing Expression() = default; Expression(Expression &&) = default; diff --git a/include/asm/symbol.hpp b/include/asm/symbol.hpp index 15bdb477e..4259d217b 100644 --- a/include/asm/symbol.hpp +++ b/include/asm/symbol.hpp @@ -15,7 +15,7 @@ #include "asm/lexer.hpp" #include "asm/section.hpp" -enum SymbolType { +enum SymbolType : unsigned char { SYM_LABEL, SYM_EQU, SYM_VAR, @@ -29,12 +29,12 @@ bool sym_IsPC(Symbol const *sym); // For the inline `getSection` method struct Symbol { std::string name; + std::shared_ptr src; // Where the symbol was defined + uint32_t fileLine; // Line where the symbol was defined SymbolType type; bool isExported; // Whether the symbol is to be exported bool isBuiltin; // Whether the symbol is a built-in Section *section; - std::shared_ptr src; // Where the symbol was defined - uint32_t fileLine; // Line where the symbol was defined std::variant< int32_t, // If isNumeric() diff --git a/include/asm/warning.hpp b/include/asm/warning.hpp index 167de412b..f2c5ca87d 100644 --- a/include/asm/warning.hpp +++ b/include/asm/warning.hpp @@ -5,7 +5,7 @@ extern unsigned int nbErrors, maxErrors; -enum WarningState { WARNING_DEFAULT, WARNING_DISABLED, WARNING_ENABLED, WARNING_ERROR }; +enum WarningState : unsigned char { WARNING_DEFAULT, WARNING_DISABLED, WARNING_ENABLED, WARNING_ERROR }; enum WarningID { WARNING_ASSERT, // Assertions diff --git a/include/gfx/main.hpp b/include/gfx/main.hpp index 9716d4619..b963816a3 100644 --- a/include/gfx/main.hpp +++ b/include/gfx/main.hpp @@ -13,6 +13,8 @@ #include "gfx/rgba.hpp" struct Options { + std::string input{}; // positional arg + bool useColorCurve = false; // -C bool allowDedup = false; // -u bool allowMirroringX = false; // -X, -m @@ -20,15 +22,15 @@ struct Options { bool columnMajor = false; // -Z uint8_t verbosity = 0; // -v - std::string attrmap{}; // -a, -A - std::array baseTileIDs{0, 0}; // -b - enum { + enum : unsigned char { NO_SPEC, EXPLICIT, EMBEDDED, - } palSpecType = NO_SPEC; // -c + } palSpecType = NO_SPEC; // -c + uint8_t bitDepth = 2; // -d + std::string attrmap{}; // -a, -A + std::array baseTileIDs{0, 0}; // -b std::vector, 4>> palSpec{}; - uint8_t bitDepth = 2; // -d struct { uint16_t left; uint16_t top; @@ -36,16 +38,14 @@ struct Options { uint16_t height; } inputSlice{0, 0, 0, 0}; // -L (margins in clockwise order, like CSS) std::array maxNbTiles{UINT16_MAX, 0}; // -N - uint16_t nbPalettes = 8; // -n std::string output{}; // -o std::string palettes{}; // -p, -P std::string palmap{}; // -q, -Q - uint16_t reversedWidth = 0; // -r, in tiles - uint8_t nbColorsPerPal = 0; // -s; 0 means "auto" = 1 << bitDepth; std::string tilemap{}; // -t, -T uint64_t trim = 0; // -x - - std::string input{}; // positional arg + uint16_t nbPalettes = 8; // -n + uint16_t reversedWidth = 0; // -r, in tiles + uint8_t nbColorsPerPal = 0; // -s; 0 means "auto" = 1 << bitDepth; static constexpr uint8_t VERB_NONE = 0; // Normal, no extra output static constexpr uint8_t VERB_CFG = 1; // Print configuration after parsing options diff --git a/include/link/main.hpp b/include/link/main.hpp index 99327cc12..47a012bd8 100644 --- a/include/link/main.hpp +++ b/include/link/main.hpp @@ -37,16 +37,16 @@ extern bool disablePadding; } while (0) struct FileStackNode { - FileStackNodeType type; Either< std::vector, // NODE_REPT std::string // NODE_FILE, NODE_MACRO > data; + FileStackNodeType type; - FileStackNode *parent; // Line at which the parent context was exited; meaningless for the root level uint32_t lineNo; + FileStackNode *parent; // REPT iteration counts since last named node, in reverse depth order std::vector &iters() { return data.get>(); } diff --git a/include/link/symbol.hpp b/include/link/symbol.hpp index 34a36bf14..2d31b7ff1 100644 --- a/include/link/symbol.hpp +++ b/include/link/symbol.hpp @@ -24,9 +24,9 @@ struct Label { struct Symbol { // Info contained in the object files std::string name; - ExportLevel type; char const *objFileName; FileStackNode const *src; + ExportLevel type; int32_t lineNo; Either< int32_t, // Constants just have a numeric value diff --git a/include/linkdefs.hpp b/include/linkdefs.hpp index 2a18c6f43..05e119a94 100644 --- a/include/linkdefs.hpp +++ b/include/linkdefs.hpp @@ -11,9 +11,9 @@ #define RGBDS_OBJECT_VERSION_STRING "RGB9" #define RGBDS_OBJECT_REV 11U -enum AssertionType { ASSERT_WARN, ASSERT_ERROR, ASSERT_FATAL }; +enum AssertionType : unsigned char { ASSERT_WARN, ASSERT_ERROR, ASSERT_FATAL }; -enum RPNCommand { +enum RPNCommand : unsigned char { RPN_ADD = 0x00, RPN_SUB = 0x01, RPN_MUL = 0x02, @@ -62,7 +62,7 @@ enum RPNCommand { RPN_SYM = 0x81 }; -enum SectionType { +enum SectionType : unsigned char { SECTTYPE_WRAM0, SECTTYPE_VRAM, SECTTYPE_ROMX, @@ -77,7 +77,7 @@ enum SectionType { SECTTYPE_INVALID }; -enum FileStackNodeType { +enum FileStackNodeType : unsigned char { NODE_REPT, NODE_FILE, NODE_MACRO, @@ -119,13 +119,13 @@ static inline uint32_t nbbanks(SectionType type) { return sectionTypeInfo[type].lastBank - sectionTypeInfo[type].firstBank + 1; } -enum SectionModifier { SECTION_NORMAL, SECTION_UNION, SECTION_FRAGMENT }; +enum SectionModifier : unsigned char { SECTION_NORMAL, SECTION_UNION, SECTION_FRAGMENT }; extern char const * const sectionModNames[]; -enum ExportLevel { SYMTYPE_LOCAL, SYMTYPE_IMPORT, SYMTYPE_EXPORT }; +enum ExportLevel : unsigned char { SYMTYPE_LOCAL, SYMTYPE_IMPORT, SYMTYPE_EXPORT }; -enum PatchType { +enum PatchType : unsigned char { PATCHTYPE_BYTE, PATCHTYPE_WORD, PATCHTYPE_LONG, diff --git a/src/link/object.cpp b/src/link/object.cpp index 2960328d2..c7938c093 100644 --- a/src/link/object.cpp +++ b/src/link/object.cpp @@ -502,10 +502,10 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) { // Since SDCC does not provide line info, everything will be reported as coming from the // object file. It's better than nothing. nodes[fileID].push_back({ - .type = NODE_FILE, .data = Either, std::string>(fileName), - .parent = nullptr, + .type = NODE_FILE, .lineNo = 0, + .parent = nullptr, }); std::vector &fileSymbols = symbolLists.emplace_front(); diff --git a/src/link/output.cpp b/src/link/output.cpp index 9ce02b968..e2e5f243b 100644 --- a/src/link/output.cpp +++ b/src/link/output.cpp @@ -8,7 +8,6 @@ #include #include #include -#include #include "error.hpp" #include "extern/utf8decoder.hpp"