1/** 2 * Copyright (c) 2021-2022 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 26namespace panda::compiler { 27 28#include "cpu_features.inc" 29 30enum 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 38class CompilerOptions; 39extern CompilerOptions 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 */ 45class CompilerOptions : public Options { 46public: 47 explicit CompilerOptions(const std::string &exe_path) : Options(exe_path) {} 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 */ 60 void SetCompilerRegex(const std::string &new_regex_pattern) 61 { 62 Options::SetCompilerRegex(new_regex_pattern); 63 regex_ = new_regex_pattern; 64 } 65 template <typename T> 66 bool MatchesRegex(const T &method_name) 67 { 68 if (!WasSetCompilerRegex()) { 69 return true; 70 } 71 if (!regex_initialized_) { 72 regex_ = GetCompilerRegex(); 73 regex_initialized_ = true; 74 } 75 return std::regex_match(method_name, regex_); 76 } 77 78 void AdjustCpuFeatures(bool cross_compilation) 79 { 80 ParseEnabledCpuFeatures(); 81 if (cross_compilation || WasSetCompilerCpuFeatures()) { 82 return; 83 } 84 switch (RUNTIME_ARCH) { 85 case Arch::AARCH64: { 86 if (CpuFeaturesHasCrc32()) { 87 EnableCpuFeature(CRC32); 88 } 89 break; 90 } 91 case Arch::AARCH32: 92 break; 93 case Arch::X86: 94 break; 95 case Arch::X86_64: 96 break; 97 case Arch::NONE: 98 break; 99 default: 100 break; 101 } 102 } 103 104 bool IsCpuFeatureEnabled(CpuFeature feature) const 105 { 106 return features_.test(feature); 107 } 108 109private: 110 void EnableCpuFeature(CpuFeature feature) 111 { 112 features_.set(feature); 113 } 114 115 void ParseEnabledCpuFeatures() 116 { 117 for (const auto &arg : GetCompilerCpuFeatures()) { 118 if (arg == "none") { 119 features_.reset(); 120 break; 121 } 122// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 123#define DEF(FEATURE, NAME) \ 124 if (NAME == arg) { \ 125 EnableCpuFeature(FEATURE); \ 126 continue; \ 127 } 128 CPU_FEATURE(DEF) 129#undef DEF 130 131 UNREACHABLE(); 132 } 133 } 134 135 // `--compiler-regex`: 136 std::regex regex_; 137 bool regex_initialized_ {false}; 138 std::bitset<CPU_FEATURES_NUM> features_; 139}; 140 141} // namespace panda::compiler 142 143#endif // COMPILER_COMPILER_OPTIONS_H 144