mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-11-15 05:28:31 +00:00
Add support to the driver for CLI flags that select which CPU to target, which CPU to tune performance for, and which CPU features to enable. - `--target-cpu` selects the architecture of CPU to target, similar to `-march` on x86. This combines `-march` with `armv*` strings and `-mcpu` on Arm for specific CPU names. Similarly for RISC-V (if/when we support and test it), etc. Notably, `--target-cpu=native` targets the current native CPU. - `--target-cpu-tune` maps to `-mtune`. This is expected to be rarely if ever desirable, and I'm open to removing it, but if folks are relying on this for performance I didn't want to hide the option. - `--target-cpu-features` allows a "standard" (for LLVM) comma-separated list of LLVM subtarget features, including `+feature` and `-feature` syntax. These flags, when provided, establish the default baseline for CPU targeting and control how on-demand runtimes are built. They can be changed or overridden by additional Clang flags when using `--clang-arg`. A critical part of this is building runtimes on demand using these features. For that, we need to do some amount of canonicalization (re-using Clang's canonicalization to ensure consistent behavior), and extend the runtimes cache features to recognize these customizations. Note that only the top-level Carbon flags impact runtimes, any particular Clang arguments are only used by the specific compiles that receive those arguments. There is some nascent RISC-V support here, but it is incomplete and only minimally tested. Still, it seemed better to record the parts we could test than remove them. Assisted-by: Antigravity with Gemini
123 lines
4.4 KiB
C++
123 lines
4.4 KiB
C++
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
// Exceptions. See /LICENSE for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
#include "toolchain/driver/build_runtimes_subcommand.h"
|
|
|
|
#include "llvm/TargetParser/Triple.h"
|
|
#include "toolchain/driver/carbon_runtimes.h"
|
|
#include "toolchain/driver/clang_runner.h"
|
|
#include "toolchain/driver/clang_runtimes.h"
|
|
|
|
namespace Carbon {
|
|
|
|
auto BuildRuntimesOptions::Build(CommandLine::CommandBuilder& b) -> void {
|
|
b.AddStringOption(
|
|
{
|
|
.name = "output-directory",
|
|
.value_name = "DIR",
|
|
.help = R"""(
|
|
The directory to populate with runtime libraries suitable for the selected code
|
|
generation options.
|
|
)""",
|
|
},
|
|
[&](auto& arg_b) { arg_b.Set(&directory); });
|
|
|
|
b.AddFlag(
|
|
{
|
|
.name = "force",
|
|
.help = R"""(
|
|
Force re-creating the provided output path from scratch
|
|
|
|
This will **remove** the provided output path and re-create it from scratch.
|
|
)""",
|
|
},
|
|
[&](CommandLine::FlagBuilder& arg_b) { arg_b.Set(&force); });
|
|
|
|
codegen_options.Build(b);
|
|
}
|
|
|
|
static constexpr CommandLine::CommandInfo SubcommandInfo = {
|
|
.name = "build-runtimes",
|
|
.help = R"""(
|
|
Build Carbon's runtime libraries.
|
|
|
|
This subcommand builds Carbon's runtime libraries for a particular code
|
|
generation target, either in their default location or a specified one.
|
|
|
|
Running this command directly is not necessary as Carbon will build and cache
|
|
runtimes as needed when linking, but building them directly can aid in
|
|
debugging issues or allow them to be prebuilt, possibly with customized code
|
|
generation flags, and used explicitly when linking.
|
|
)""",
|
|
};
|
|
|
|
BuildRuntimesSubcommand::BuildRuntimesSubcommand()
|
|
: DriverSubcommand(SubcommandInfo) {}
|
|
|
|
auto BuildRuntimesSubcommand::Run(DriverEnv& driver_env) -> DriverResult {
|
|
// Don't run Clang when fuzzing, it is known to not be reliable under fuzzing
|
|
// due to many unfixed issues.
|
|
if (TestAndDiagnoseIfFuzzingExternalLibraries(driver_env, "clang")) {
|
|
return {.success = false};
|
|
}
|
|
|
|
// For diagnosing filesystem or other errors when building runtimes.
|
|
CARBON_DIAGNOSTIC(FailureBuildingRuntimes, Error,
|
|
"failure building runtimes: {0}", std::string);
|
|
|
|
auto run_result = RunInternal(driver_env);
|
|
if (!run_result.ok()) {
|
|
driver_env.emitter.Emit(FailureBuildingRuntimes,
|
|
run_result.error().message());
|
|
return {.success = false};
|
|
}
|
|
|
|
llvm::outs() << "Built runtimes: " << *run_result << "\n";
|
|
return {.success = true};
|
|
}
|
|
|
|
auto BuildRuntimesSubcommand::RunInternal(DriverEnv& driver_env)
|
|
-> ErrorOr<std::filesystem::path> {
|
|
ClangRunner runner(driver_env.installation, driver_env.fs,
|
|
driver_env.vlog_stream);
|
|
|
|
CARBON_ASSIGN_OR_RETURN(Runtimes::Cache::Features features,
|
|
runner.ComputeRuntimesFeatures(
|
|
options_.codegen_options, *driver_env.consumer));
|
|
|
|
bool is_cache = options_.directory.empty();
|
|
std::filesystem::path output_path = options_.directory.str();
|
|
|
|
CARBON_ASSIGN_OR_RETURN(
|
|
auto runtimes, is_cache
|
|
? driver_env.runtimes_cache.Lookup(features)
|
|
: Runtimes::Make(output_path, driver_env.vlog_stream));
|
|
|
|
if (options_.force) {
|
|
// Remove existing runtimes to force a rebuild.
|
|
CARBON_RETURN_IF_ERROR(runtimes.Remove(Runtimes::ClangResourceDir));
|
|
CARBON_RETURN_IF_ERROR(runtimes.Remove(Runtimes::LibUnwind));
|
|
CARBON_RETURN_IF_ERROR(runtimes.Remove(Runtimes::Libcxx));
|
|
CARBON_RETURN_IF_ERROR(runtimes.Remove(Runtimes::CarbonCore));
|
|
}
|
|
|
|
ClangResourceDirBuilder resource_dir_builder(&runner, driver_env.thread_pool,
|
|
&runtimes, features);
|
|
ClangArchiveRuntimesBuilder<Runtimes::LibUnwind> lib_unwind_builder(
|
|
&runner, driver_env.thread_pool, &runtimes, features);
|
|
ClangArchiveRuntimesBuilder<Runtimes::Libcxx> libcxx_builder(
|
|
&runner, driver_env.thread_pool, &runtimes, features);
|
|
CarbonPreludeBuilder prelude_builder(&driver_env, &runtimes,
|
|
&options_.codegen_options);
|
|
|
|
CARBON_RETURN_IF_ERROR(std::move(resource_dir_builder).Wait());
|
|
CARBON_RETURN_IF_ERROR(std::move(lib_unwind_builder).Wait());
|
|
CARBON_RETURN_IF_ERROR(std::move(libcxx_builder).Wait());
|
|
CARBON_RETURN_IF_ERROR(std::move(prelude_builder).Build());
|
|
|
|
return runtimes.base_path();
|
|
}
|
|
|
|
} // namespace Carbon
|