diff --git a/docs/COMPILER_CLI.md b/docs/COMPILER_CLI.md index 1d412863..b067eebd 100644 --- a/docs/COMPILER_CLI.md +++ b/docs/COMPILER_CLI.md @@ -324,6 +324,8 @@ OPTIONS: --dry Dry run: only generate C++ code, skip compilation and linking --lto Enable Link Time Optimization (-flto) --format Enable clang-format code formatting (disabled by default) + --cxx-std C++ standard version (c++17, c++20, etc., default: c++17) + --march Target CPU instruction set (e.g. native, x86-64-v3, armv8-a) -l, --link-lib Link against a library (repeatable, e.g. -lcurl) -L, --link-path Add a library search path (repeatable, e.g. -L/usr/local/lib) --build-dir Specify build directory for generated C++ code @@ -565,6 +567,41 @@ EXAMPLES: --- +### 18. `--march ` - 目标 CPU 指令集 + +**类型**: 单值参数 + +指定编译器生成针对特定 CPU 架构优化的代码。等价于 GCC/Clang 的 `-march=` 选项。 + +**常用值**: +| 值 | 说明 | +|---|---| +| `native` | 自动检测并优化当前 CPU 支持的指令集 | +| `x86-64-v3` | x86-64 微架构级别 3 (AVX, AVX2, BMI1, BMI2, F16C, FMA, LZCNT, MOVBE, XSAVE) | +| `x86-64-v4` | x86-64 微架构级别 4 (AVX512F, AVX512BW, AVX512CD, AVX512DQ, AVX512VL) | +| `armv8-a` | ARMv8-A 基础架构 | +| `armv8.1-a` | ARMv8.1-A | +| `armv8.2-a` | ARMv8.2-A | +| `armv9-a` | ARMv9-A | + +> **⚠️ 注意**: `--march` 仅适用于 GCC/Clang 编译器。MSVC 不支持此选项,请使用 `--cxx-flags /arch:AVX2` 等方式。 + +**示例**: +```bash +# 优化当前机器运行的 CPU +./bin/compiler.php app.php --march=native -O2 + +# 特定目标架构 +./bin/compiler.php app.php --march=x86-64-v3 -O2 + +# ARM 平台 +./bin/compiler.php app.php --march=armv8-a -O2 +``` + +**与 GCC/Clang 等价**: `--march=` 直接传递给编译器的 `-march=` 选项。 + +--- + ## 🔧 编译器选择 ### 默认编译器 diff --git a/src/Php/Backend/Clang.php b/src/Php/Backend/Clang.php index a7717ca0..7e1d6c8c 100644 --- a/src/Php/Backend/Clang.php +++ b/src/Php/Backend/Clang.php @@ -307,6 +307,11 @@ class Clang extends CompilerBackend $cmd .= ' -std=' . $options['cpp_std']; } + // 目标 CPU 指令集 + if (!empty($options['march'])) { + $cmd .= ' -march=' . $options['march']; + } + // Sanitizer if (!empty($options['sanitize'])) { $cmd .= ' -fsanitize=' . $options['sanitize']; @@ -398,6 +403,11 @@ class Clang extends CompilerBackend $cmd .= ' -std=' . $config['cpp_std']; } + // 目标 CPU 指令集 + if (!empty($config['march'])) { + $cmd .= ' -march=' . $config['march']; + } + // PIC (Position Independent Code) if ((!empty($config['build_mode']) && $config['build_mode'] === 'ext') || !empty($config['pic'])) { if ($this->platform instanceof \PhpAot\Php\Platform\Windows) { diff --git a/src/Php/Backend/Gcc.php b/src/Php/Backend/Gcc.php index 452ab1b4..40c5c643 100644 --- a/src/Php/Backend/Gcc.php +++ b/src/Php/Backend/Gcc.php @@ -214,6 +214,11 @@ class Gcc extends CompilerBackend $cmd .= ' -std=' . $options['cpp_std']; } + // 目标 CPU 指令集 + if (!empty($options['march'])) { + $cmd .= ' -march=' . $options['march']; + } + // Sanitizer if (!empty($options['sanitize'])) { $cmd .= ' -fsanitize=' . $options['sanitize']; @@ -284,6 +289,11 @@ class Gcc extends CompilerBackend $cmd .= ' -std=' . $config['cpp_std']; } + // 目标 CPU 指令集 + if (!empty($config['march'])) { + $cmd .= ' -march=' . $config['march']; + } + // PIC (Position Independent Code) if ((!empty($config['build_mode']) && $config['build_mode'] === 'ext') || !empty($config['pic'])) { $cmd .= ' -fPIC'; diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 6e7cb76b..13be2ff5 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -241,6 +241,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected string $buildMode = self::BUILD_MODE_BIN; protected string $cxxFlags = ''; protected string $cxxStd = 'c++17'; + protected string $march = ''; // --march: target CPU instruction set (e.g. native, x86-64-v3) protected string $ldflags = ''; protected array $linkLibs = []; // --link-lib / -l: user-specified libraries to link protected array $linkPaths = []; // --link-path / -L: user-specified library search paths @@ -773,6 +774,11 @@ class CompilerBase extends \PhpAot\Core\Translator return $this->linkPaths; } + public function getMarch(): string + { + return $this->march; + } + public function getRelativePath($path, $cwd = ''): string { $cwd = $cwd ?: getcwd(); diff --git a/src/Php/Constants.php b/src/Php/Constants.php index decf8b04..69b9c790 100644 --- a/src/Php/Constants.php +++ b/src/Php/Constants.php @@ -163,6 +163,12 @@ class Constants 'required' => false, 'defaultValue' => 'c++17', ], + 'march' => [ + 'longPrefix' => 'march', + 'description' => 'Target CPU instruction set for code generation (e.g. native, x86-64-v3, armv8-a)', + 'required' => false, + 'defaultValue' => '', + ], 'build-dir' => [ 'longPrefix' => 'build-dir', 'description' => 'Specify the build directory for generated C++ code', diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 4a01ea6d..4dfa9b6f 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -227,6 +227,8 @@ class Translator extends Preprocessor $climate->tab()->out('-D, --define Define a preprocessor macro (repeatable, e.g. -D FOO=bar)'); $climate->tab()->out('--lto Enable Link Time Optimization (-flto)'); $climate->tab()->out('--format Enable clang-format code formatting (disabled by default)'); + $climate->tab()->out('--cxx-std C++ standard version (c++17, c++20, etc., default: c++17)'); + $climate->tab()->out('--march Target CPU instruction set (e.g. native, x86-64-v3, armv8-a)'); $climate->tab()->out('-l, --link-lib Link against a library (repeatable, e.g. -lcurl)'); $climate->tab()->out('-L, --link-path Add a library search path (repeatable, e.g. -L/usr/local/lib)'); $climate->br(); @@ -240,6 +242,8 @@ class Translator extends Preprocessor $climate->tab()->out($cmd . ' gui-app.php --no-console (Windows GUI app, no console)'); $climate->tab()->out($cmd . ' app.php --sanitize=address (Enable AddressSanitizer)'); $climate->tab()->out($cmd . ' app.php --cxx-std=c++17 (Use C++17 standard)'); + $climate->tab()->out($cmd . ' app.php --march=native -O2 (Optimize for host CPU)'); + $climate->tab()->out($cmd . ' app.php --march=x86-64-v3 -O2 (Target x86-64-v3 instructions)'); $climate->tab()->out($cmd . ' app.php --no-literal-strings (Disable string optimization)'); $climate->tab()->out($cmd . ' app.php -r -O2 -- --flag1 value1'); $climate->tab()->out($cmd . ' hello.php --dry (only generate C++ code, skip compilation)'); @@ -307,6 +311,11 @@ class Translator extends Preprocessor $this->cxxStd = $this->climate->arguments->get('cxx-std'); } + // 目标 CPU 指令集 + if ($this->climate->arguments->defined('march')) { + $this->march = $this->climate->arguments->get('march'); + } + // 构建目录 if ($this->climate->arguments->defined('build-dir')) { $buildDir = $this->climate->arguments->get('build-dir'); @@ -1398,6 +1407,7 @@ CODE; 'debug' => $this->debug, 'sanitize' => $this->sanitize, 'cpp_std' => $this->cxxStd, + 'march' => $this->march, 'is_zts' => $this->isPhpZts, 'build_mode' => $this->buildMode, 'enable_profiler' => $this->enableProfiler, @@ -1436,6 +1446,7 @@ CODE; 'build_mode' => $this->buildMode, 'enable_profiler' => $this->enableProfiler, 'suppressed_warnings' => Constants::MSVC_SUPPRESSED_WARNINGS ?? [], + 'march' => $this->march, ]; } @@ -1881,6 +1892,12 @@ CODE; $this->cxxStd = $cxxStd; } + // 读取 march(目标 CPU 指令集) + $march = $cfg['march'] ?? null; + if (!empty($march)) { + $this->march = $march; + } + // 读取 ld-flags $ldflags = $cfg['ld-flags'] ?? null; if (!empty($ldflags)) {