From a614bdd133d2d2ebc8834f8741548511192a7cb9 Mon Sep 17 00:00:00 2001 From: Finn Wilkinson Date: Tue, 17 Sep 2024 16:56:14 +0100 Subject: [PATCH] Added SimInfo.cc to fix link time optimisation issues with static local variable in getInstance(). --- src/include/simeng/config/SimInfo.hh | 119 ++++--------------------- src/lib/CMakeLists.txt | 1 + src/lib/config/SimInfo.cc | 126 +++++++++++++++++++++++++++ 3 files changed, 146 insertions(+), 100 deletions(-) create mode 100644 src/lib/config/SimInfo.cc diff --git a/src/include/simeng/config/SimInfo.hh b/src/include/simeng/config/SimInfo.hh index 75ee342709..7e6b6df9d7 100644 --- a/src/include/simeng/config/SimInfo.hh +++ b/src/include/simeng/config/SimInfo.hh @@ -25,155 +25,74 @@ class SimInfo { public: /** A getter function to retrieve the ryml::Tree representing the underlying * model config file. */ - static ryml::ConstNodeRef getConfig() { - return getInstance()->validatedConfig_.crootref(); - } + static ryml::ConstNodeRef getConfig(); /** A setter function to set the model config file from a path to a YAML file. */ - static void setConfig(std::string path) { getInstance()->makeConfig(path); } + static void setConfig(std::string path); /** A function to add additional config values to the model config file. */ - static void addToConfig(std::string configAdditions) { - getInstance()->modelConfig_.addConfigOptions(configAdditions); - // Replace the validated config with new instance with the supplied - // additional values - getInstance()->validatedConfig_ = getInstance()->modelConfig_.getConfig(); - // Update previously extracted values from the config file - getInstance()->extractValues(); - } + static void addToConfig(std::string configAdditions); /** A function to generate a default config file based on a passed ISA. */ - static void generateDefault(ISA isa, bool force = false) { - if (isa == ISA::AArch64) - getInstance()->modelConfig_.reGenerateDefault(ISA::AArch64, force); - else if (isa == ISA::RV64) - getInstance()->modelConfig_.reGenerateDefault(ISA::RV64, force); - - // Update config path to be the default string - getInstance()->configFilePath_ = DEFAULT_STR; - - // Replace the validated config with the new default config - getInstance()->validatedConfig_ = getInstance()->modelConfig_.getConfig(); - // Update previously extracted values from the config file - getInstance()->extractValues(); - } + static void generateDefault(ISA isa, bool force = false); /** A getter function to retrieve the config file path. */ - static std::string getConfigPath() { return getInstance()->configFilePath_; } + static std::string getConfigPath(); /** A getter function to retrieve the simulation mode of the current SimEng * instance. */ - static SimulationMode getSimMode() { return getInstance()->mode_; } + static SimulationMode getSimMode(); /** A getter function to retrieve the simulation mode of the current SimEng * instance as a string. */ - static std::string getSimModeStr() { return getInstance()->modeStr_; } + static std::string getSimModeStr(); /** A getter function to retrieve which ISA the current simulation is using. */ - static ISA getISA() { return getInstance()->isa_; } + static ISA getISA(); /** A getter function to retrieve which ISA the current simulation is using in * a string format. */ - static std::string getISAString() { return getInstance()->isaString_; } + static std::string getISAString(); /** A getter function to retrieve a vector of {size, number} pairs describing * the available architectural registers. */ - static const std::vector& getArchRegStruct() { - return getInstance()->archInfo_->getArchRegStruct(); - } + static const std::vector& getArchRegStruct(); /** A getter function to retrieve a vector of {size, number} pairs describing * the available physical registers. */ - static const std::vector& getPhysRegStruct() { - return getInstance()->archInfo_->getPhysRegStruct(); - } + static const std::vector& getPhysRegStruct(); /** A getter function to retrieve a vector of uint16_t values describing * the quantities of physical registers available. */ - static const std::vector& getPhysRegQuantities() { - return getInstance()->archInfo_->getPhysRegQuantities(); - } + static const std::vector& getPhysRegQuantities(); /** A getter function to retrieve a vector of Capstone sysreg enums for * all the system registers that should be utilised in simulation. */ - static const std::vector& getSysRegVec() { - return getInstance()->archInfo_->getSysRegEnums(); - } + static const std::vector& getSysRegVec(); /** A getter function to retrieve whether or not the special files * directories should be generated. */ - static bool getGenSpecFiles() { return getInstance()->genSpecialFiles_; } + static bool getGenSpecFiles(); /** A utility function to rebuild/construct member variables/classes. For use * if the configuration used changes during simulation (e.g. during the * execution of a test suite). */ - static void reBuild() { getInstance()->extractValues(); } + static void reBuild(); private: - SimInfo() { - // Set the validated config file to be the current default config - // generated by the default constructor of ModelConfig - validatedConfig_ = modelConfig_.getConfig(); - extractValues(); - } + SimInfo(); /** Gets the static instance of the SimInfo class. */ - static std::unique_ptr& getInstance() { - static std::unique_ptr SimInfoClass = nullptr; - if (SimInfoClass == nullptr) { - SimInfoClass = std::unique_ptr(new SimInfo()); - } - return SimInfoClass; - } + static std::unique_ptr& getInstance(); /** Create a model config from a passed YAML file path. */ - void makeConfig(std::string path) { - // Recreate the model config instance from the YAML file path - modelConfig_ = ModelConfig(path); - - // Update config path to be the passed path - configFilePath_ = path; - - // Update the validated config file - validatedConfig_ = modelConfig_.getConfig(); - extractValues(); - } + void makeConfig(std::string path); /** A function to extract various values from the generated config file to * populate frequently queried model config values. */ - void extractValues() { - // Get ISA type and set the corresponding ArchInfo class - isaString_ = validatedConfig_["Core"]["ISA"].as(); - if (isaString_ == "AArch64") { - isa_ = ISA::AArch64; - archInfo_ = std::make_unique( - arch::aarch64::ArchInfo(validatedConfig_)); - } else if (isaString_ == "rv64") { - isa_ = ISA::RV64; - archInfo_ = std::make_unique( - arch::riscv::ArchInfo(validatedConfig_)); - } - - // Get Simulation mode - std::string mode = - validatedConfig_["Core"]["Simulation-Mode"].as(); - if (mode == "emulation") { - mode_ = SimulationMode::Emulation; - modeStr_ = "Emulation"; - } else if (mode == "inorderpipelined") { - mode_ = SimulationMode::InOrderPipelined; - modeStr_ = "In-Order Pipelined"; - } else if (mode == "outoforder") { - mode_ = SimulationMode::Outoforder; - modeStr_ = "Out-of-Order"; - } - - // Get if the special files directory should be created - genSpecialFiles_ = - validatedConfig_["CPU-Info"]["Generate-Special-Dir"].as(); - } + void extractValues(); /** The validated model config file represented as a ryml:Tree. */ ryml::Tree validatedConfig_; diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index ae659e2338..3690d7fd1c 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -18,6 +18,7 @@ set(SIMENG_SOURCES branchpredictors/GenericPredictor.cc branchpredictors/PerceptronPredictor.cc config/ModelConfig.cc + config/SimInfo.cc kernel/Linux.cc kernel/LinuxProcess.cc memory/FixedLatencyMemoryInterface.cc diff --git a/src/lib/config/SimInfo.cc b/src/lib/config/SimInfo.cc new file mode 100644 index 0000000000..a4136a00df --- /dev/null +++ b/src/lib/config/SimInfo.cc @@ -0,0 +1,126 @@ +#include "simeng/config/SimInfo.hh" + +namespace simeng { +namespace config { + +ryml::ConstNodeRef SimInfo::getConfig() { + return getInstance()->validatedConfig_.crootref(); +} + +void SimInfo::setConfig(std::string path) { getInstance()->makeConfig(path); } + +void SimInfo::addToConfig(std::string configAdditions) { + getInstance()->modelConfig_.addConfigOptions(configAdditions); + // Replace the validated config with new instance with the supplied + // additional values + getInstance()->validatedConfig_ = getInstance()->modelConfig_.getConfig(); + // Update previously extracted values from the config file + getInstance()->extractValues(); +} + +void SimInfo::generateDefault(ISA isa, bool force) { + if (isa == ISA::AArch64) + getInstance()->modelConfig_.reGenerateDefault(ISA::AArch64, force); + else if (isa == ISA::RV64) + getInstance()->modelConfig_.reGenerateDefault(ISA::RV64, force); + + // Update config path to be the default string + getInstance()->configFilePath_ = DEFAULT_STR; + + // Replace the validated config with the new default config + getInstance()->validatedConfig_ = getInstance()->modelConfig_.getConfig(); + // Update previously extracted values from the config file + getInstance()->extractValues(); +} + +std::string SimInfo::getConfigPath() { return getInstance()->configFilePath_; } + +SimulationMode SimInfo::getSimMode() { return getInstance()->mode_; } + +std::string SimInfo::getSimModeStr() { return getInstance()->modeStr_; } + +ISA SimInfo::getISA() { return getInstance()->isa_; } + +std::string SimInfo::getISAString() { return getInstance()->isaString_; } + +const std::vector& SimInfo::getArchRegStruct() { + return getInstance()->archInfo_->getArchRegStruct(); +} + +const std::vector& SimInfo::getPhysRegStruct() { + return getInstance()->archInfo_->getPhysRegStruct(); +} + +const std::vector& SimInfo::getPhysRegQuantities() { + return getInstance()->archInfo_->getPhysRegQuantities(); +} + +const std::vector& SimInfo::getSysRegVec() { + return getInstance()->archInfo_->getSysRegEnums(); +} + +bool SimInfo::getGenSpecFiles() { return getInstance()->genSpecialFiles_; } + +void SimInfo::reBuild() { getInstance()->extractValues(); } + +SimInfo::SimInfo() { + // Set the validated config file to be the current default config + // generated by the default constructor of ModelConfig + validatedConfig_ = modelConfig_.getConfig(); + extractValues(); +} + +std::unique_ptr& SimInfo::getInstance() { + static std::unique_ptr SimInfoClass = nullptr; + if (SimInfoClass == nullptr) { + SimInfoClass = std::unique_ptr(new SimInfo()); + } + return SimInfoClass; +} + +void SimInfo::makeConfig(std::string path) { + // Recreate the model config instance from the YAML file path + modelConfig_ = ModelConfig(path); + + // Update config path to be the passed path + configFilePath_ = path; + + // Update the validated config file + validatedConfig_ = modelConfig_.getConfig(); + extractValues(); +} + +void SimInfo::extractValues() { + // Get ISA type and set the corresponding ArchInfo class + isaString_ = validatedConfig_["Core"]["ISA"].as(); + if (isaString_ == "AArch64") { + isa_ = ISA::AArch64; + archInfo_ = std::make_unique( + arch::aarch64::ArchInfo(validatedConfig_)); + } else if (isaString_ == "rv64") { + isa_ = ISA::RV64; + archInfo_ = std::make_unique( + arch::riscv::ArchInfo(validatedConfig_)); + } + + // Get Simulation mode + std::string mode = + validatedConfig_["Core"]["Simulation-Mode"].as(); + if (mode == "emulation") { + mode_ = SimulationMode::Emulation; + modeStr_ = "Emulation"; + } else if (mode == "inorderpipelined") { + mode_ = SimulationMode::InOrderPipelined; + modeStr_ = "In-Order Pipelined"; + } else if (mode == "outoforder") { + mode_ = SimulationMode::Outoforder; + modeStr_ = "Out-of-Order"; + } + + // Get if the special files directory should be created + genSpecialFiles_ = + validatedConfig_["CPU-Info"]["Generate-Special-Dir"].as(); +} + +} // namespace config +} // namespace simeng \ No newline at end of file