1 /* 2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef COMPILER_COMPILER_OPTIONS_H 17 #define COMPILER_COMPILER_OPTIONS_H 18 19 #include "utils/pandargs.h" 20 #include "libpandabase/utils/arch.h" 21 #include "cpu_features.h" 22 #include "compiler_options_gen.h" 23 24 #include <regex> 25 26 namespace ark::compiler { 27 28 #include "cpu_features.inc" 29 30 enum CpuFeature : uint8_t { 31 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 32 #define DEF(COMPONENT, ...) COMPONENT, 33 CPU_FEATURE(DEF) 34 #undef DEF 35 CPU_FEATURES_NUM 36 }; 37 38 class CompilerOptions; 39 extern CompilerOptions g_options; 40 41 /** 42 * Extends `compiler::Options`, which may be not sufficient to provide the desired functionality 43 * (e.g. store an option-related variable) 44 */ 45 class CompilerOptions : public Options { 46 public: CompilerOptions(const std::string & exePath)47 explicit CompilerOptions(const std::string &exePath) : Options(exePath) {} 48 NO_MOVE_SEMANTIC(CompilerOptions); 49 NO_COPY_SEMANTIC(CompilerOptions); 50 ~CompilerOptions() = default; 51 52 /** 53 * `--compiler-regex` extension. 54 * The purpose of this extension is to avoid unnecessary construction of std::regex from 55 * `Options::GetCompilerRegex()` on every call to `MatchesRegex()`. 56 * 57 * Static local variable doesn't suit as soon as `Options::SetCompilerRegex()` is used (e.g. in 58 * tests). 59 */ SetCompilerRegex(const std::string & newRegexPattern)60 void SetCompilerRegex(const std::string &newRegexPattern) 61 { 62 Options::SetCompilerRegex(newRegexPattern); 63 regex_ = newRegexPattern; 64 } 65 template <typename T> MatchesRegex(const T & methodName)66 bool MatchesRegex(const T &methodName) 67 { 68 if (!WasSetCompilerRegex()) { 69 return true; 70 } 71 if (!regexInitialized_) { 72 regex_ = GetCompilerRegex(); 73 regexInitialized_ = true; 74 } 75 return std::regex_match(methodName, regex_); 76 } 77 AdjustCpuFeatures(bool crossCompilation)78 void AdjustCpuFeatures(bool crossCompilation) 79 { 80 ParseEnabledCpuFeatures(); 81 if (crossCompilation || WasSetCompilerCpuFeatures()) { 82 return; 83 } 84 switch (RUNTIME_ARCH) { 85 case Arch::AARCH64: { 86 if (CpuFeaturesHasCrc32()) { 87 EnableCpuFeature(CRC32); 88 } 89 if (CpuFeaturesHasJscvt()) { 90 EnableCpuFeature(JSCVT); 91 } 92 if (CpuFeaturesHasAtomics()) { 93 EnableCpuFeature(ATOMICS); 94 } 95 break; 96 } 97 case Arch::AARCH32: 98 break; 99 case Arch::X86: 100 break; 101 case Arch::X86_64: 102 break; 103 case Arch::NONE: 104 default: 105 break; 106 } 107 } 108 IsCpuFeatureEnabled(CpuFeature feature)109 bool IsCpuFeatureEnabled(CpuFeature feature) const 110 { 111 return features_.test(feature); 112 } 113 114 private: EnableCpuFeature(CpuFeature feature)115 void EnableCpuFeature(CpuFeature feature) 116 { 117 features_.set(feature); 118 } 119 ParseEnabledCpuFeatures()120 void ParseEnabledCpuFeatures() 121 { 122 for (const auto &arg : GetCompilerCpuFeatures()) { 123 if (arg == "none") { 124 features_.reset(); 125 break; 126 } 127 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 128 #define CONTINUE_DEF(FEATURE, NAME) \ 129 if ((NAME) == arg) { \ 130 EnableCpuFeature(FEATURE); \ 131 continue; \ 132 } 133 CPU_FEATURE(CONTINUE_DEF) 134 #undef CONTINUE_DEF 135 136 UNREACHABLE(); 137 } 138 } 139 140 // `--compiler-regex`: 141 std::regex regex_; 142 bool regexInitialized_ {false}; 143 std::bitset<CPU_FEATURES_NUM> features_; 144 }; 145 146 } // namespace ark::compiler 147 #endif // COMPILER_COMPILER_OPTIONS_H 148