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