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/logger.h" 20 #include "utils/pandargs.h" 21 #include "libpandabase/utils/arch.h" 22 #include "cpu_features.h" 23 #include "compiler_options_gen.h" 24 25 #include <regex> 26 27 namespace ark::compiler { 28 29 #include "cpu_features.inc" 30 31 enum CpuFeature : uint8_t { 32 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 33 #define DEF(COMPONENT, ...) COMPONENT, 34 CPU_FEATURE(DEF) 35 #undef DEF 36 CPU_FEATURES_NUM 37 }; 38 39 class CompilerOptions; 40 PANDA_PUBLIC_API extern CompilerOptions g_options; 41 42 /** 43 * Extends `compiler::Options`, which may be not sufficient to provide the desired functionality 44 * (e.g. store an option-related variable) 45 */ 46 class CompilerOptions : public Options { 47 public: CompilerOptions(const std::string & exePath)48 explicit CompilerOptions(const std::string &exePath) : Options(exePath) {} 49 NO_MOVE_SEMANTIC(CompilerOptions); 50 NO_COPY_SEMANTIC(CompilerOptions); 51 ~CompilerOptions() = default; 52 53 /** 54 * `--compiler-regex` extension. 55 * The purpose of this extension is to avoid unnecessary construction of std::regex from 56 * `Options::GetCompilerRegex()` on every call to `MatchesRegex()`. 57 * 58 * Static local variable doesn't suit as soon as `Options::SetCompilerRegex()` is used (e.g. in 59 * tests). 60 */ SetCompilerRegexWithSignature(const std::string & newRegexPattern)61 void SetCompilerRegexWithSignature([[maybe_unused]] const std::string &newRegexPattern) 62 { 63 LOG(FATAL, COMPILER) << "'SetCompilerRegexWithSignature()' is not supported."; 64 } 65 SetCompilerRegex(const std::string & newRegexPattern)66 void SetCompilerRegex(const std::string &newRegexPattern) 67 { 68 ASSERT(!WasSetCompilerRegexWithSignature()); 69 Options::SetCompilerRegex(newRegexPattern); 70 regex_ = newRegexPattern; 71 } 72 73 template <typename T> MatchesRegex(const T & methodName)74 bool MatchesRegex(const T &methodName) 75 { 76 if (!WasSetCompilerRegex() && !WasSetCompilerRegexWithSignature()) { 77 return true; 78 } 79 if (!regexInitialized_) { 80 if (WasSetCompilerRegexWithSignature() && WasSetCompilerRegex()) { 81 LOG(FATAL, COMPILER) 82 << "'--compiler-regex' and '--compiler-regex-with-signature' cannot be used together."; 83 } 84 regex_ = WasSetCompilerRegex() ? GetCompilerRegex() : GetCompilerRegexWithSignature(); 85 regexInitialized_ = true; 86 } 87 return std::regex_match(methodName, regex_); 88 } 89 AdjustCpuFeatures(bool crossCompilation)90 void AdjustCpuFeatures(bool crossCompilation) 91 { 92 ParseEnabledCpuFeatures(); 93 if (crossCompilation || WasSetCompilerCpuFeatures()) { 94 return; 95 } 96 switch (RUNTIME_ARCH) { 97 case Arch::AARCH64: { 98 if (CpuFeaturesHasCrc32()) { 99 EnableCpuFeature(CRC32); 100 } 101 if (CpuFeaturesHasJscvt()) { 102 EnableCpuFeature(JSCVT); 103 } 104 if (CpuFeaturesHasAtomics()) { 105 EnableCpuFeature(ATOMICS); 106 } 107 break; 108 } 109 case Arch::AARCH32: 110 break; 111 case Arch::X86: 112 break; 113 case Arch::X86_64: 114 break; 115 case Arch::NONE: 116 default: 117 break; 118 } 119 } 120 IsCpuFeatureEnabled(CpuFeature feature)121 bool IsCpuFeatureEnabled(CpuFeature feature) const 122 { 123 return features_.test(feature); 124 } 125 126 private: EnableCpuFeature(CpuFeature feature)127 void EnableCpuFeature(CpuFeature feature) 128 { 129 features_.set(feature); 130 } 131 ParseEnabledCpuFeatures()132 void ParseEnabledCpuFeatures() 133 { 134 for (const auto &arg : GetCompilerCpuFeatures()) { 135 if (arg == "none") { 136 features_.reset(); 137 break; 138 } 139 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 140 #define CONTINUE_DEF(FEATURE, NAME) \ 141 if ((NAME) == arg) { \ 142 EnableCpuFeature(FEATURE); \ 143 continue; \ 144 } 145 CPU_FEATURE(CONTINUE_DEF) 146 #undef CONTINUE_DEF 147 148 UNREACHABLE(); 149 } 150 } 151 152 // `--compiler-regex`: 153 std::regex regex_; 154 bool regexInitialized_ {false}; 155 std::bitset<CPU_FEATURES_NUM> features_; 156 }; 157 158 } // namespace ark::compiler 159 #endif // COMPILER_COMPILER_OPTIONS_H 160