From 95e715febd528646b46fce422dc660599674490b Mon Sep 17 00:00:00 2001 From: Chris Tate Date: Tue, 27 Oct 2026 20:11:44 -0500 Subject: [PATCH] Optimize the speed runtime units with a committed runtime profile The LLVM helper's runtime-unit now optimizes a unit itself (--opt-level), with IR instrumentation (--profile-generate) or a profile (--profile-use), through the same pipeline as program code. The Linux x64 pack's speed units are compiled to unoptimized bitcode and optimized there with packages/runtime-pack-common/profiles/linux-x64-gnu.profdata.gz, so one LLVM writes and reads every profile. Release and library flavors are unchanged. The pack manifest records how the profile matched the units. Code the runtime profile finds cold is optimized for speed, not size: a runtime function the training programs rarely call can be hot in another program. scr_message.c is optimized without the profile. scripts/refresh-runtime-profile.mjs trains the profile on the runtime benchmark workloads and, optionally, a tsc-ts checkout, and keeps only the records of functions the instrumented runtime units define (merge-profiles --keep-functions). Tests check that the profile still matches the runtime and names only runtime functions. --- native/llvm-codegen/src/emit.cpp | 38 ++++ native/llvm-codegen/src/emit.h | 29 +++ native/llvm-codegen/src/main.cpp | 8 +- native/llvm-codegen/src/profile.cpp | 49 ++++- native/llvm-codegen/src/profile.h | 11 +- native/llvm-codegen/src/runtime-unit.cpp | 83 +++++++- .../profiles/linux-x64-gnu.profdata.gz | Bin 0 -> 88863 bytes .../runtime-pack-common/scripts/build.mjs | 77 ++++++- .../scripts/runtime-unit.mjs | 39 +++- .../test/runtime-profile.test.ts | 98 +++++++++ scripts/bench-runtime.mjs | 31 ++- scripts/refresh-runtime-profile.mjs | 188 ++++++++++++++++++ 12 files changed, 631 insertions(+), 20 deletions(-) create mode 100644 packages/runtime-pack-common/profiles/linux-x64-gnu.profdata.gz create mode 100644 packages/runtime-pack-common/test/runtime-profile.test.ts create mode 100644 scripts/refresh-runtime-profile.mjs diff --git a/native/llvm-codegen/src/emit.cpp b/native/llvm-codegen/src/emit.cpp index 98e07e9ce..6a2574538 100644 --- a/native/llvm-codegen/src/emit.cpp +++ b/native/llvm-codegen/src/emit.cpp @@ -1340,6 +1340,44 @@ emitSplitCodegen(const EmitOptions &Options, Module &M, TargetMachine &Machine, } // namespace +std::optional optimizeModule(Module &M, TargetMachine &Machine, + const std::string &OptLevel, + bool Instrument, + const std::string &ProfileGenerate, + const std::string &ProfileUse, + ModuleProfileMatch &Result) { + OptimizationLevel Level = optimizationLevel(OptLevel); + std::optional Profile; + if (Instrument) { + Profile = PGOOptions(ProfileGenerate, "", "", "", PGOOptions::IRInstr); + } else if (!ProfileUse.empty()) { + EmitOptions Inspected; + Inspected.ProfileUse = ProfileUse; + if (std::optional Failure = inspectProfile(Inspected)) + return Failure->Message; + reportMissingProfiles(); + Profile = PGOOptions(ProfileUse, "", "", "", PGOOptions::IRUse); + } + bool Annotating = Profile && Profile->Action == PGOOptions::IRUse; + ProfileMatch Match; + if (Annotating) + M.getContext().setDiagnosticHandler( + std::make_unique(Match)); + { + Pipeline P(Machine, Level, std::move(Profile)); + if (Annotating) + P.countAnnotated(Match.Annotated); + P.PB.buildPerModuleDefaultPipeline(Level).run(M, P.MAM); + } + Result.Annotated = Match.Annotated.load(); + Result.Mismatched = Match.Mismatched.load(); + Result.Missing = Match.Missing.load(); + if (std::optional Failure = + verify(M, "post_optimization_verification_failed")) + return Failure->Message; + return std::nullopt; +} + int emit(const EmitOptions &Options) { if (!supportsTarget(Options.Target)) return reportError("unsupported_target", diff --git a/native/llvm-codegen/src/emit.h b/native/llvm-codegen/src/emit.h index 1bdc578df..dd02cfd98 100644 --- a/native/llvm-codegen/src/emit.h +++ b/native/llvm-codegen/src/emit.h @@ -1,9 +1,15 @@ #pragma once +#include #include #include #include +namespace llvm { +class Module; +class TargetMachine; +} // namespace llvm + namespace scriptc { struct EmitOptions { @@ -36,4 +42,27 @@ struct EmitOptions { std::optional parseEmitOptions(int Argc, char **Argv); int emit(const EmitOptions &Options); +// How a profile matched the functions of one optimized module: functions +// that received its counts, functions whose control flow changed since it +// was collected, and functions it has no record of. +struct ModuleProfileMatch { + uint64_t Annotated = 0; + uint64_t Mismatched = 0; + uint64_t Missing = 0; +}; + +// Optimizes `M` with the per-module default pipeline at `OptLevel`, as `emit` +// does for a whole program, with IR instrumentation when `Instrument` is set +// or annotation from the indexed `ProfileUse` profile. Instrumentation writes +// raw profiles to the `ProfileGenerate` pattern; an empty pattern names no +// file, so the program that links the module names it. Returns an error +// message, or nothing on success. +std::optional optimizeModule(llvm::Module &M, + llvm::TargetMachine &Machine, + const std::string &OptLevel, + bool Instrument, + const std::string &ProfileGenerate, + const std::string &ProfileUse, + ModuleProfileMatch &Match); + } // namespace scriptc diff --git a/native/llvm-codegen/src/main.cpp b/native/llvm-codegen/src/main.cpp index 57416106a..d9481395d 100644 --- a/native/llvm-codegen/src/main.cpp +++ b/native/llvm-codegen/src/main.cpp @@ -58,6 +58,9 @@ int version(int Argc, char **Argv) { {"supported_targets", std::move(SupportedTargets)}, {"default_target", scriptc::DefaultTarget}, {"data_layout", Machine->createDataLayout().getStringRepresentation()}, + // Commands and options added within one protocol version, for callers + // that also run against older helpers. + {"features", json::Array{"runtime-unit-profile", "profile-functions"}}, }; outs() << formatv("{0}\n", json::Value(std::move(Response))); return 0; @@ -80,6 +83,8 @@ int main(int Argc, char **Argv) { return scriptc::pruneImport(Argc, Argv); if (Argc >= 2 && StringRef(Argv[1]) == "merge-profiles") return scriptc::mergeProfiles(Argc, Argv); + if (Argc >= 2 && StringRef(Argv[1]) == "profile-functions") + return scriptc::profileFunctions(Argc, Argv); if (Argc >= 2 && StringRef(Argv[1]) == "emit") { std::optional Options = scriptc::parseEmitOptions(Argc, Argv); @@ -95,5 +100,6 @@ int main(int Argc, char **Argv) { } return scriptc::reportError("usage", "expected 'version --format=json', 'emit', 'runtime-unit', " - "'prune-import', or 'merge-profiles'"); + "'prune-import', 'merge-profiles', or " + "'profile-functions'"); } diff --git a/native/llvm-codegen/src/profile.cpp b/native/llvm-codegen/src/profile.cpp index b7df1445d..e06d051c9 100644 --- a/native/llvm-codegen/src/profile.cpp +++ b/native/llvm-codegen/src/profile.cpp @@ -2,10 +2,14 @@ #include "diagnostics.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringSet.h" #include "llvm/ADT/StringRef.h" #include "llvm/ProfileData/InstrProfReader.h" #include "llvm/ProfileData/InstrProfWriter.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/JSON.h" +#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" @@ -19,6 +23,7 @@ namespace scriptc { int mergeProfiles(int Argc, char **Argv) { std::string Output; bool Sparse = false; + std::string KeepFunctions; std::vector Inputs; for (int I = 2; I < Argc; ++I) { StringRef Arg(Argv[I]); @@ -26,17 +31,35 @@ int mergeProfiles(int Argc, char **Argv) { Output = Argv[++I]; else if (Arg == "--sparse") Sparse = true; + else if (Arg == "--keep-functions" && I + 1 < Argc) + KeepFunctions = Argv[++I]; else if (!Arg.starts_with("--")) Inputs.push_back(Arg.str()); else return reportError("usage", "merge-profiles requires --output " "and one or more input profiles, and " - "accepts --sparse"); + "accepts --sparse and --keep-functions " + ""); } if (Output.empty() || Inputs.empty()) return reportError("usage", "merge-profiles requires --output and " "one or more input profiles"); + // --keep-functions names the functions to keep, one profile name per + // line; the records of every other function are left out. + StringSet<> Kept; + if (!KeepFunctions.empty()) { + ErrorOr> List = + MemoryBuffer::getFile(KeepFunctions); + if (!List) + return reportError("profile_read_failed", + KeepFunctions + ": " + List.getError().message()); + SmallVector Names; + (*List)->getBuffer().split(Names, '\n', -1, /*KeepEmpty=*/false); + for (StringRef Name : Names) + Kept.insert(Name); + } + // Sparse profiles leave out the functions that never ran, which then // optimize as without a profile instead of as cold. InstrProfWriter Writer(Sparse); @@ -52,6 +75,8 @@ int mergeProfiles(int Argc, char **Argv) { Path + ": " + toString(std::move(E))); std::string RecordError; for (NamedInstrProfRecord &Record : **Reader) { + if (!KeepFunctions.empty() && !Kept.contains(Record.Name)) + continue; Writer.addRecord(std::move(Record), /*Weight=*/1, [&](Error E) { if (RecordError.empty()) RecordError = toString(std::move(E)); @@ -100,4 +125,26 @@ int mergeProfiles(int Argc, char **Argv) { return 0; } +int profileFunctions(int Argc, char **Argv) { + if (Argc != 4 || StringRef(Argv[2]) != "--input") + return reportError("usage", + "profile-functions requires --input "); + std::string Path = Argv[3]; + IntrusiveRefCntPtr FS = vfs::getRealFileSystem(); + Expected> Reader = + InstrProfReader::create(Path, *FS); + if (!Reader) + return reportError("profile_read_failed", + Path + ": " + toString(Reader.takeError())); + json::Array Functions; + for (const NamedInstrProfRecord &Record : **Reader) + Functions.push_back(Record.Name.str()); + if ((*Reader)->hasError()) + return reportError("profile_read_failed", + Path + ": " + toString((*Reader)->getError())); + json::Object Response{{"ok", true}, {"functions", std::move(Functions)}}; + outs() << formatv("{0}\n", json::Value(std::move(Response))); + return 0; +} + } // namespace scriptc diff --git a/native/llvm-codegen/src/profile.h b/native/llvm-codegen/src/profile.h index 1cad1c54b..8602889a3 100644 --- a/native/llvm-codegen/src/profile.h +++ b/native/llvm-codegen/src/profile.h @@ -2,9 +2,14 @@ namespace scriptc { -// `merge-profiles --output [--sparse] ...`: merges raw -// (.profraw) or indexed (.profdata) IR profiles into one indexed profile. -// --sparse leaves out functions that never ran. +// `merge-profiles --output [--sparse] [--keep-functions +// ] ...`: merges raw (.profraw) or indexed (.profdata) IR +// profiles into one indexed profile. --sparse leaves out functions that never +// ran, and --keep-functions every function the file does not name. int mergeProfiles(int Argc, char **Argv); +// `profile-functions --input `: prints the names of the +// functions an indexed profile has records for, as {"ok":true,"functions":[]}. +int profileFunctions(int Argc, char **Argv); + } // namespace scriptc diff --git a/native/llvm-codegen/src/runtime-unit.cpp b/native/llvm-codegen/src/runtime-unit.cpp index e92c384ee..d97638c84 100644 --- a/native/llvm-codegen/src/runtime-unit.cpp +++ b/native/llvm-codegen/src/runtime-unit.cpp @@ -13,6 +13,7 @@ #include "runtime-unit.h" #include "diagnostics.h" +#include "emit.h" #include "runtime-import.h" #include "target.h" @@ -27,12 +28,16 @@ #include "llvm/IR/Module.h" #include "llvm/IR/Verifier.h" #include "llvm/IRReader/IRReader.h" +#include "llvm/ProfileData/InstrProf.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/JSON.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" #include "llvm/TargetParser/Triple.h" #include "llvm/Transforms/Utils/Cloning.h" +#include "llvm/Transforms/Utils/SizeOpts.h" #include #include @@ -53,6 +58,16 @@ struct UnitOptions { std::string Tag; bool FunctionSections = false; bool DataSections = false; + // When set, the input is unoptimized and the helper optimizes it at this + // level, with the profile-guided optimization below; otherwise the input + // is already optimized and is only promoted and emitted. + std::string OptLevel; + // Instruments the unit for IR profiling; raw profiles go to this pattern, + // or, when it is empty, to the file the program that links the unit names. + bool ProfileGenerate = false; + std::string ProfileGeneratePattern; + // Indexed profile (.profdata) that guides the unit's optimization. + std::string ProfileUse; }; std::optional parse(int Argc, char **Argv) { @@ -80,12 +95,26 @@ std::optional parse(int Argc, char **Argv) { Options.Target = Value.str(); else if (Arg == "--tag") Options.Tag = Value.str(); + else if (Arg == "--opt-level") + Options.OptLevel = Value.str(); + else if (Arg == "--profile-generate") { + Options.ProfileGenerate = true; + Options.ProfileGeneratePattern = Value.str(); + } else if (Arg == "--profile-use") + Options.ProfileUse = Value.str(); else return std::nullopt; } if (Options.Input.empty() || Options.Object.empty() || Options.Bitcode.empty() || Options.Target.empty() || Options.Tag.empty()) return std::nullopt; + // A profile only guides an optimization the helper runs, and a unit is + // either instrumented or annotated. + if ((Options.ProfileGenerate || !Options.ProfileUse.empty()) && + Options.OptLevel.empty()) + return std::nullopt; + if (Options.ProfileGenerate && !Options.ProfileUse.empty()) + return std::nullopt; return Options; } @@ -98,10 +127,22 @@ bool keepLocal(const GlobalValue &GV) { return false; } +// The profile's counters and per-function records (instrumented units only) +// stay private to the unit: the profile runtime finds them by section. +bool profileData(const GlobalValue &GV) { + if (const auto *Object = dyn_cast(&GV)) + if (Object->getSection().starts_with("__llvm_prf")) + return true; + return GV.getName().starts_with("__llvm_prf") || + GV.getName().starts_with("__profc_") || + GV.getName().starts_with("__profd_") || + GV.getName().starts_with("__profvp_"); +} + void promoteLocals(Module &M, StringRef Tag) { unsigned Anonymous = 0; auto Promote = [&](GlobalValue &GV) { - if (!GV.hasLocalLinkage() || keepLocal(GV)) + if (!GV.hasLocalLinkage() || keepLocal(GV) || profileData(GV)) return; std::string Base = GV.hasName() ? GV.getName().str() : ("anon." + Twine(Anonymous++)).str(); @@ -157,7 +198,9 @@ int runtimeUnit(int Argc, char **Argv) { return fail("usage", "runtime-unit requires --input --object --bitcode " "--target --tag and accepts " - "--function-sections --data-sections"); + "--function-sections --data-sections, and --opt-level " + "with either --profile-generate or --profile-use " + ""); LLVMContext Context; SMDiagnostic Diagnostic; std::unique_ptr M = parseIRFile(Options->Input, Diagnostic, Context); @@ -208,6 +251,42 @@ int runtimeUnit(int Argc, char **Argv) { if (F.getFnAttribute("probe-stack").getValueAsString() == "__chkstk_darwin") F.addFnAttr("probe-stack", "inline-asm"); + // Profiles name a unit's internal functions after its source file. The + // unit's own name keeps those names the same in every checkout, so a + // committed profile matches wherever the pack is built. + if (!Options->OptLevel.empty()) { + M->setSourceFileName(Options->Tag + ".c"); + // The runtime profile comes from a fixed set of training programs, and a + // runtime function they rarely call can be hot in another program (a + // long UTF-8 decode, a busy worker channel). Code the profile finds cold + // is therefore optimized for speed as without a profile, not for size: + // the profile still guides inlining, block layout and branch weights. + EnablePGSO.setValue(false); + // The profile names of the functions an instrumented unit defines, so + // a merged profile can keep the runtime's records and drop the + // training programs'. + json::Array Functions; + if (Options->ProfileGenerate) + for (const Function &F : *M) + if (!F.isDeclaration() && !F.hasAvailableExternallyLinkage()) + Functions.push_back(getIRPGOFuncName(F)); + ModuleProfileMatch Match; + if (std::optional Failure = optimizeModule( + *M, *Machine, Options->OptLevel, Options->ProfileGenerate, + Options->ProfileGeneratePattern, Options->ProfileUse, Match)) + return fail("optimization_failed", *Failure); + if (!Options->ProfileUse.empty()) { + json::Object Profile{{"annotated", Match.Annotated}, + {"mismatched", Match.Mismatched}, + {"missing", Match.Missing}}; + json::Object Response{{"ok", true}, {"profile", std::move(Profile)}}; + outs() << formatv("{0}\n", json::Value(std::move(Response))); + } else if (Options->ProfileGenerate) { + json::Object Response{{"ok", true}, {"functions", std::move(Functions)}}; + outs() << formatv("{0}\n", json::Value(std::move(Response))); + } + } + promoteLocals(*M, Options->Tag); std::string VerifyError; raw_string_ostream VerifyStream(VerifyError); diff --git a/packages/runtime-pack-common/profiles/linux-x64-gnu.profdata.gz b/packages/runtime-pack-common/profiles/linux-x64-gnu.profdata.gz new file mode 100644 index 0000000000000000000000000000000000000000..6d4a0d942b8fe400af980f55bd688caf8b2dc709 GIT binary patch literal 88863 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

wI(f9S(tqSRX*Am7X5IkrehE-9! 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.profdata.gz), or instruments for + // scripts/refresh-runtime-profile.mjs (SCRIPTC_RUNTIME_PROFILE_GENERATE=1). + // The runtime compiler then emits their bitcode unoptimized, and one LLVM, + // the helper's, instruments, annotates and optimizes every profiled unit. + // Release and library flavors keep the runtime compiler's optimization. + const committedProfile = join( + repoRoot, + "packages", + "runtime-pack-common", + "profiles", + `${config.target.name}.profdata.gz`, + ); + // The committed profile is unpacked into the build directory once it exists. + const unpackedProfile = join(buildRoot, "runtime.profdata"); + // Without a helper that optimizes units itself, speed units are built as + // before, without the profile. + const unitProfiles = unitHelper?.features.includes("runtime-unit-profile") === true; + if (process.env.SCRIPTC_RUNTIME_PROFILE_GENERATE === "1" && !unitProfiles) + throw new Error( + "SCRIPTC_RUNTIME_PROFILE_GENERATE=1 needs an LLVM helper with runtime-unit profiles", + ); + const speedProfile = !unitProfiles + ? null + : process.env.SCRIPTC_RUNTIME_PROFILE_GENERATE === "1" + ? { args: ["--opt-level", "2", "--profile-generate", ""] } + : existsSync(committedProfile) + ? { args: ["--opt-level", "2", "--profile-use", unpackedProfile], unpack: true } + : null; + // Speed units the helper optimizes without the profile (at the same level). + // scr_message.c: with the profile on its decoding, a program whose workers + // each receive many small messages ran 5% slower in its workers' own code, + // although that code and its data were unchanged; without it, the program + // runs as fast as with an unprofiled runtime. + const unprofiledUnits = new Set(["scr_message.c"]); + // The instrumented units' functions, which SCRIPTC_RUNTIME_PROFILE_FUNCTIONS + // names a file for; the refresh script keeps only their records. + const profiledFunctions = new Set(); const parallel = async (items, task) => { const width = Math.max(1, Math.min(8, availableParallelism())); return parallelMap(items, width, task); @@ -156,6 +196,8 @@ async function build() { await rm(buildRoot, { recursive: true, force: true }); try { await mkdir(stagedOutputRoot, { recursive: true }); + if (speedProfile?.unpack) + await writeFile(unpackedProfile, gunzipSync(await readFile(committedProfile))); // Zig 0.16 creates a zero-byte `a.o` in its working directory for // `zig cc --version`. Probe from a private temporary directory so a // runtime-pack build never leaves that compiler byproduct in the package. @@ -197,6 +239,7 @@ async function build() { ...(config.platform === "linux" ? ["-fomit-frame-pointer"] : []), ] : []; + const profileMatches = []; const units = await parallel( flavorSpec.runtime_units ?? matrix.runtime_units, async (unit) => { @@ -249,9 +292,10 @@ async function build() { let bitcode; const bitcodeOutput = output.replace(/\.o$/, ".bc"); if (flavor === "speed") await mkdir(dirname(output), { recursive: true }); + let unitBuild = false; if ( flavor === "speed" && - (await buildRuntimeUnit({ + (unitBuild = await buildRuntimeUnit({ helper: unitHelper, compileBitcode: (optimized) => run(compiler, [ @@ -259,12 +303,17 @@ async function build() { ...sourcePathFlags, ...unitFlags, "-g0", + ...(speedProfile === null ? [] : ["-Xclang", "-disable-llvm-passes"]), "-emit-llvm", "-c", join(runtimeSrc, unit.source), "-o", optimized, ]), + helperArgs: + speedProfile?.unpack && unprofiledUnits.has(unit.source) + ? ["--opt-level", "2"] + : (speedProfile?.args ?? []), object: output, bitcode: bitcodeOutput, triple: matrix.target.llvm_triple, @@ -275,6 +324,8 @@ async function build() { ), })) ) { + if (unitBuild.profile !== undefined) profileMatches.push(unitBuild.profile); + for (const name of unitBuild.functions ?? []) profiledFunctions.add(name); bitcode = { path: artifactPath(bitcodeOutput), sha256: await sha256(bitcodeOutput), @@ -324,7 +375,21 @@ async function build() { return { source: unit.source, predicate: unit.predicate, variants }; }, ); - flavors[flavor] = { optimization: flavorSpec.optimization, runtime_units: units }; + flavors[flavor] = { + optimization: flavorSpec.optimization, + runtime_units: units, + // How the committed runtime profile matched the units it guided + // (scripts/refresh-runtime-profile.mjs refreshes it). + ...(profileMatches.length === 0 + ? {} + : { + runtime_profile: { + annotated: profileMatches.reduce((sum, match) => sum + match.annotated, 0), + mismatched: profileMatches.reduce((sum, match) => sum + match.mismatched, 0), + missing: profileMatches.reduce((sum, match) => sum + match.missing, 0), + }, + }), + }; } const mbedtlsSources = (await readdir(join(mbedtls, "library"))) .filter((name) => !name.startsWith(".") && name.endsWith(".c")) @@ -505,6 +570,14 @@ async function build() { backupRoot: join(packageRoot, `.runtime-pack-artifacts-backup-${suffix}`), backupManifestPath: join(packageRoot, `.runtime-pack-manifest-backup-${suffix}`), }); + if (process.env.SCRIPTC_RUNTIME_PROFILE_FUNCTIONS !== undefined) + await writeFile( + process.env.SCRIPTC_RUNTIME_PROFILE_FUNCTIONS, + [...profiledFunctions] + .sort() + .map((name) => `${name}\n`) + .join(""), + ); process.stdout.write( `built ${packageManifest.name}@${packageManifest.version}: ${Object.keys(flavors).length} flavors, ${archives.length} vendor archives\n`, ); diff --git a/packages/runtime-pack-common/scripts/runtime-unit.mjs b/packages/runtime-pack-common/scripts/runtime-unit.mjs index 1d4b549b6..68bc62381 100644 --- a/packages/runtime-pack-common/scripts/runtime-unit.mjs +++ b/packages/runtime-pack-common/scripts/runtime-unit.mjs @@ -12,10 +12,13 @@ const run = promisify(execFile); * Speed units produce both artifacts from one optimized LLVM module: the * runtime compiler optimizes the C source to bitcode, and the host helper's * `runtime-unit` command promotes translation-unit-local symbols to hidden - * unit-qualified globals and emits the object and the bitcode. Release - * units keep the runtime compiler's own objects; their bitcode is the same - * compilation with -emit-llvm, which the helper's `prune-import` reduces to - * the bodies that need none of the unit's local state. Both bitcode forms + * unit-qualified globals and emits the object and the bitcode. With the + * target's committed runtime profile, the runtime compiler emits the bitcode + * unoptimized and the helper also optimizes it with the profile (build.mjs), + * so one LLVM reads and writes every profile. Release units keep the + * runtime compiler's own objects; their bitcode is the same compilation with + * -emit-llvm, which the helper's `prune-import` reduces to the bodies that + * need none of the unit's local state. Both bitcode forms * keep only what a program build can import. * * Every host helper supports every scriptc target, so packs keep building @@ -54,7 +57,15 @@ export async function resolveRuntimeUnitHelper(repoRoot, triple) { const { stdout } = await run(helper, ["version", "--format=json"]); const version = JSON.parse(stdout); if (!version.supported_targets?.includes(triple)) return null; - return { path: helper, identity: `scriptc-llvm-codegen ${version.llvm_version}` }; + return { + path: helper, + identity: `scriptc-llvm-codegen ${version.llvm_version}`, + // Commands and options newer than the protocol version, such as + // "runtime-unit-profile": `runtime-unit` takes --opt-level, + // --profile-use and --profile-generate (older helpers only promote and + // emit). + features: Array.isArray(version.features) ? version.features : [], + }; } catch { if (explicit !== undefined) throw new Error(`SCRIPTC_LLVM_CODEGEN is not usable: ${helper}`); return null; @@ -63,12 +74,19 @@ export async function resolveRuntimeUnitHelper(repoRoot, triple) { /** Compile one unit through the helper. `compileBitcode(output)` must run * the runtime compiler with the unit's exact flags plus -emit-llvm. + * `helperArgs` asks the helper to optimize the unit itself (`--opt-level`, + * with `--profile-use` or `--profile-generate`), for bitcode the runtime + * compiler emitted unoptimized. * Returns false, leaving no artifacts behind, when the helper cannot emit * this unit; the caller then compiles the object directly without bitcode, - * so a pack never fails to build because of the import path. */ + * so a pack never fails to build because of the import path. Otherwise + * returns an object, with the helper's `profile` match counts when a profile + * guided the unit, or the profile names of the unit's `functions` when it + * was instrumented. */ export async function buildRuntimeUnit({ helper, compileBitcode, + helperArgs = [], object, bitcode, triple, @@ -79,7 +97,7 @@ export async function buildRuntimeUnit({ // A runtime compiler failure is a real build error and surfaces as one. await compileBitcode(optimized); try { - await run(helper.path, [ + const { stdout } = await run(helper.path, [ "runtime-unit", "--input", optimized, @@ -92,8 +110,13 @@ export async function buildRuntimeUnit({ "--tag", tag, ...(sections ? ["--function-sections", "--data-sections"] : []), + ...helperArgs, ]); - return true; + const report = stdout.trim() === "" ? {} : JSON.parse(stdout.trim().split("\n").pop()); + return { + ...(report.profile === undefined ? {} : { profile: report.profile }), + ...(report.functions === undefined ? {} : { functions: report.functions }), + }; } catch (error) { const detail = (error.stderr || error.message || String(error)).trim().split("\n")[0]; process.stderr.write(`runtime-unit: ${tag}: emitting without import bitcode (${detail})\n`); diff --git a/packages/runtime-pack-common/test/runtime-profile.test.ts b/packages/runtime-pack-common/test/runtime-profile.test.ts new file mode 100644 index 000000000..0b2bf19a4 --- /dev/null +++ b/packages/runtime-pack-common/test/runtime-profile.test.ts @@ -0,0 +1,98 @@ +import { execFileSync } from "node:child_process"; +import { existsSync, mkdtempSync, readdirSync, readFileSync, rmSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { fileURLToPath } from "node:url"; +import { gunzipSync } from "node:zlib"; +import { expect, test } from "vitest"; +import { resolveRuntimeUnitHelper } from "../scripts/runtime-unit.mjs"; + +const repoRoot = fileURLToPath(new URL("../../..", import.meta.url)); +const committedProfile = join( + repoRoot, + "packages/runtime-pack-common/profiles/linux-x64-gnu.profdata.gz", +); +const manifestPath = join(repoRoot, "packages/runtime-linux-x64-gnu/runtime-pack.json"); +const runtimeRoot = join(repoRoot, "packages/runtime"); + +// Both tests read the committed profile through an LLVM helper new enough to +// apply it; the pack test also needs the Linux x64 pack built with it. +const helper = + process.platform === "linux" && process.arch === "x64" && existsSync(committedProfile) + ? await resolveRuntimeUnitHelper(repoRoot, "x86_64-unknown-linux-gnu") + : null; +const built = + helper?.features.includes("runtime-unit-profile") === true && existsSync(manifestPath); + +// A profile older than the runtime sources loses the counts of every function +// whose control flow changed since it was collected. More than this share of +// the functions it describes means it is due for scripts/refresh-runtime-profile.mjs. +const MAX_MISMATCHED_SHARE = 0.1; + +test.skipIf(!built)("the committed runtime profile still matches the runtime's speed units", () => { + const manifest = JSON.parse(readFileSync(manifestPath, "utf8")); + const match = manifest.flavors?.speed?.runtime_profile; + expect(match, "the speed flavor was built without the committed runtime profile").toBeDefined(); + const described = match.annotated + match.mismatched; + expect(match.annotated).toBeGreaterThan(0); + expect( + match.mismatched / described, + `${match.mismatched} of the ${described} runtime functions the profile describes changed since it was collected; run node scripts/refresh-runtime-profile.mjs`, + ).toBeLessThanOrEqual(MAX_MISMATCHED_SHARE); +}); + +// The committed profile holds the runtime's records only. Training programs' +// functions, and the source paths their names can carry, stay out of the +// repository: refresh-runtime-profile.mjs keeps the functions the +// instrumented runtime units define. +test.skipIf(helper?.features.includes("profile-functions") !== true)( + "the committed runtime profile names only runtime functions", + () => { + const profile = gunzipSync(readFileSync(committedProfile)); + const scratch = mkdtempSync(join(tmpdir(), "scriptc-runtime-profile-")); + let functions: string[]; + try { + const unpacked = join(scratch, "runtime.profdata"); + writeFileSync(unpacked, profile); + ({ functions } = JSON.parse( + execFileSync(helper!.path, ["profile-functions", "--input", unpacked], { + encoding: "utf8", + maxBuffer: 64 * 1024 * 1024, + }), + )); + } finally { + rmSync(scratch, { recursive: true, force: true }); + } + expect(functions.length).toBeGreaterThan(0); + + const sources = new Set(readdirSync(join(runtimeRoot, "src"))); + const identifiers = new Set(); + const collect = (dir: string) => { + for (const entry of readdirSync(dir, { withFileTypes: true })) { + const path = join(dir, entry.name); + if (entry.isDirectory()) collect(path); + else if (/\.(c|h|inc|def)$/.test(entry.name)) + for (const name of readFileSync(path, "latin1").match(/[A-Za-z_]\w*/g) ?? []) + identifiers.add(name); + } + }; + collect(join(runtimeRoot, "src")); + collect(join(runtimeRoot, "vendor")); + + // A unit's internal functions are named ".c;" after its + // runtime source, and its external ones by their C names, which are never + // a program's `main` or generated `sc_` symbols. + const foreign = functions.filter((name) => { + if (/[/\\]/.test(name)) return true; + const local = /^([\w-]+\.c);(.+)$/.exec(name); + if (local !== null) return !sources.has(local[1]!); + return name === "main" || name.startsWith("sc_") || !identifiers.has(name); + }); + expect(foreign, "records that are not runtime functions").toEqual([]); + + // Nor does any other part of the file hold a path, such as a checkout's. + const text = profile.toString("latin1"); + const paths = text.match(/(?:\/[\w.-]+){3,}|[A-Za-z]:\\[\w.-]+\\|\.tsx?;/g) ?? []; + expect(paths, "path strings in the committed profile").toEqual([]); + }, +); diff --git a/scripts/bench-runtime.mjs b/scripts/bench-runtime.mjs index 0845d57b8..63f3fa2d6 100644 --- a/scripts/bench-runtime.mjs +++ b/scripts/bench-runtime.mjs @@ -44,6 +44,7 @@ const { values } = parseArgs({ "candidate-target-cpu": { type: "string" }, "baseline-cpu-dispatch": { type: "boolean", default: false }, "candidate-cpu-dispatch": { type: "boolean", default: false }, + "candidate-profile-generate": { type: "string" }, json: { type: "string" }, "no-lock": { type: "boolean", default: false }, node: { type: "boolean", default: true }, @@ -57,6 +58,7 @@ if (values.help) { [--baseline-optimization=release] [--candidate-optimization=release] [--baseline-target-cpu=] [--candidate-target-cpu=] [--baseline-cpu-dispatch] [--candidate-cpu-dispatch] + [--candidate-profile-generate=] [--no-lock] [--no-node] [--keep] Each checkout must have a built CLI (packages/cli/dist/bootstrap.js) and native @@ -79,7 +81,10 @@ release. --baseline-target-cpu/--candidate-target-cpu pass --target-cpu to each contender's builds, e.g. --baseline=. --candidate-target-cpu=x86-64-v3 compares x86-64-v3 code with the baseline. --baseline-cpu-dispatch/--candidate-cpu-dispatch pass --cpu-dispatch, and SCRIPTC_CPU_LEVEL in the environment reaches every timed -run. cold_build_ms records each contender's first, uncached build.`); +run. cold_build_ms records each contender's first, uncached build. +--candidate-profile-generate builds the candidate's workloads with +--profile-generate=, so its runs write raw profiles there +(scripts/refresh-runtime-profile.mjs trains the runtime profile this way).`); process.exit(0); } const runs = Number(values.runs); @@ -448,7 +453,16 @@ function revision(root) { }); return r.stdout.trim() + (dirty.stdout.trim() ? "+dirty" : ""); } -function build(label, root, workload, layout, optimization, targetCpu, cpuDispatch) { +function build( + label, + root, + workload, + layout, + optimization, + targetCpu, + cpuDispatch, + profileGenerate, +) { const cli = cliFor(root); const out = join(work, label, layout === 0 ? workload.name : `${workload.name}.layout${layout}`); mkdirSync(dirname(out), { recursive: true }); @@ -471,6 +485,7 @@ function build(label, root, workload, layout, optimization, targetCpu, cpuDispat `--optimization=${optimization}`, ...(targetCpu === undefined ? [] : [`--target-cpu=${targetCpu}`]), ...(cpuDispatch ? ["--cpu-dispatch"] : []), + ...(profileGenerate === undefined ? [] : [`--profile-generate=${profileGenerate}`]), "-o", out, ], @@ -507,6 +522,7 @@ const contenders = [ optimization: values["candidate-optimization"], targetCpu: values["candidate-target-cpu"], cpuDispatch: values["candidate-cpu-dispatch"], + profileGenerate: values["candidate-profile-generate"], }, ]; const report = { @@ -613,7 +629,16 @@ try { entry.results[c.label] = result; result.binaries = []; for (let layout = 0; layout < layouts && result.status === undefined; layout++) { - const built = build(c.label, c.root, w, layout, c.optimization, c.targetCpu, c.cpuDispatch); + const built = build( + c.label, + c.root, + w, + layout, + c.optimization, + c.targetCpu, + c.cpuDispatch, + c.profileGenerate, + ); result.build_ms += Math.round(built.buildMs); if (layout === 0) result.cold_build_ms = Math.round(built.buildMs); if (!built.ok) { diff --git a/scripts/refresh-runtime-profile.mjs b/scripts/refresh-runtime-profile.mjs new file mode 100644 index 000000000..608abb5de --- /dev/null +++ b/scripts/refresh-runtime-profile.mjs @@ -0,0 +1,188 @@ +#!/usr/bin/env node +/* Refreshes packages/runtime-pack-common/profiles/linux-x64-gnu.profdata.gz, + * the profile that the Linux x64 runtime pack's speed units are optimized + * with (runtime-pack-common/scripts/build.mjs). The LLVM helper instruments, + * annotates and optimizes those units, so the profile is in the helper's + * format and merged by the helper's merge-profiles, like every program + * profile. + * + * Builds an instrumented runtime pack (SCRIPTC_RUNTIME_PROFILE_GENERATE=1), + * then runs the training programs built against it with --profile-generate: + * every runtime benchmark workload at --optimization=speed (through + * scripts/bench-runtime.mjs, with its inputs and load clients), and, with + * --tsc-ts, an instrumented tsc-ts checking its own sources and each + * --project. The raw profiles hold the runtime's counters beside the + * programs'; the merged profile keeps the runtime functions that ran: the + * instrumented pack lists its functions, and the programs' records are left + * out. The pack is then rebuilt with the new profile. A stale profile only + * loses part of its gain: functions whose code changed are optimized as + * without one (the pack test reports how many). + * + * node scripts/refresh-runtime-profile.mjs [--tsc-ts [--project

[:]]...] + */ +import { spawnSync } from "node:child_process"; +import { + existsSync, + mkdirSync, + mkdtempSync, + readdirSync, + readFileSync, + rmSync, + writeFileSync, +} from "node:fs"; +import { tmpdir } from "node:os"; +import { dirname, join, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; +import { parseArgs } from "node:util"; +import { constants, gzipSync } from "node:zlib"; + +const root = fileURLToPath(new URL("..", import.meta.url)); +const { values } = parseArgs({ + options: { + "tsc-ts": { type: "string" }, + project: { type: "string", multiple: true, default: [] }, + output: { + type: "string", + default: join(root, "packages/runtime-pack-common/profiles/linux-x64-gnu.profdata.gz"), + }, + work: { type: "string" }, + help: { type: "boolean", default: false }, + }, +}); +if (values.help) { + console.log( + "Usage: node scripts/refresh-runtime-profile.mjs [--tsc-ts [--project [:]]...] [--output ] [--work ]", + ); + process.exit(0); +} +if (process.platform !== "linux" || process.arch !== "x64") + throw new Error("the runtime profile is collected on Linux x64"); +if (values.project.length !== 0 && values["tsc-ts"] === undefined) + throw new Error("--project needs --tsc-ts"); +const cli = join(root, "packages/cli/dist/main.js"); +if (!existsSync(cli)) throw new Error("build the compiler first (pnpm build)"); +const helper = join(root, "packages/llvm-linux-x64-gnu/bin/scriptc-llvm-codegen"); +if (!existsSync(helper)) + throw new Error( + "build the LLVM helper first (pnpm --filter @scriptc/llvm-linux-x64-gnu build:native)", + ); +const output = resolve(values.output); +mkdirSync(dirname(output), { recursive: true }); +const work = resolve(values.work ?? mkdtempSync(join(tmpdir(), "scriptc-runtime-profile-"))); +const raw = join(work, "raw"); +rmSync(raw, { recursive: true, force: true }); +mkdirSync(raw, { recursive: true }); +const env = { ...process.env }; +delete env.SCRIPTC_LLVM_HELPER; + +const buildPack = (extra) => + run("pnpm", ["--filter", "@scriptc/runtime-linux-x64-gnu", "build:native"], { + cwd: root, + env: { ...env, ...extra }, + }); + +const functions = join(work, "runtime-functions.txt"); +console.log("building the instrumented runtime pack"); +buildPack({ SCRIPTC_RUNTIME_PROFILE_GENERATE: "1", SCRIPTC_RUNTIME_PROFILE_FUNCTIONS: functions }); +try { + console.log("training on the runtime benchmark workloads"); + run( + process.execPath, + [ + join(root, "scripts/bench-runtime.mjs"), + `--candidate=${root}`, + "--candidate-optimization=speed", + `--candidate-profile-generate=${join(raw, "bench-%m-%p.profraw")}`, + "--runs=3", + "--warmup=0", + "--no-node", + "--no-lock", + `--json=${join(work, "bench.json")}`, + ], + { cwd: root, env }, + ); + if (values["tsc-ts"] !== undefined) trainTscTs(resolve(values["tsc-ts"])); + const profiles = readdirSync(raw).map((name) => join(raw, name)); + if (profiles.length === 0) throw new Error(`no raw profiles in ${raw}`); + // `scriptc merge-profiles` runs this merge too; called directly, it keeps + // only the runtime's records, so the training programs' stay out of the repo. + const merged = join(work, "runtime.profdata"); + run( + helper, + ["merge-profiles", "--output", merged, "--sparse", "--keep-functions", functions, ...profiles], + { cwd: root, env }, + ); + writeFileSync(output, gzipSync(readFileSync(merged), { level: constants.Z_BEST_COMPRESSION })); + console.log(`wrote ${output} from ${profiles.length} raw profiles`); +} finally { + // The pack goes back to an ordinary build, now with the new profile. + console.log("rebuilding the runtime pack"); + buildPack({}); +} +if (values.work === undefined) rmSync(work, { recursive: true, force: true }); + +// An instrumented tsc-ts, built against the instrumented pack, checking its +// own sources and each --project at --checkers 1. +function trainTscTs(checkout) { + const pkg = join(checkout, "packages/tsc-ts"); + if (!existsSync(join(pkg, "src/main.ts"))) + throw new Error(`${checkout} is not a tsc-ts checkout`); + // The upstream lib files, where npm run fetch:upstream puts them (older + // tsc-ts checkouts used the second directory). + const lib = [ + "upstream/typescript-go/internal/bundled/libs", + "upstream/TypeScript/tsc/internal/bundled/libs", + ] + .map((dir) => join(checkout, dir)) + .find((dir) => existsSync(join(dir, "lib.d.ts"))); + if (lib === undefined) + throw new Error( + `no lib files in ${checkout}/upstream: run npm run fetch:upstream in the tsc-ts checkout`, + ); + const tsc = join(work, "tsc-ts"); + console.log("building an instrumented tsc-ts"); + run( + process.execPath, + [ + cli, + "build", + "src/main.ts", + "--optimization=speed", + "--detached-exit", + `--profile-generate=${join(raw, "tsc-ts-%p.profraw")}`, + "-o", + tsc, + ], + { cwd: pkg, env }, + ); + const projects = [ + { dir: pkg, config: "tsconfig.json" }, + ...values.project.map((spec) => { + const [dir, config = "tsconfig.json"] = spec.split(":"); + return { dir: resolve(dir), config }; + }), + ]; + for (const { dir, config } of projects) { + // Projects with type errors exit with 1 or 2; any other status is a failed run. + const result = spawnSync( + tsc, + ["-p", config, "--noEmit", "--incremental", "false", "--checkers", "1"], + { + cwd: dir, + stdio: "ignore", + env: { ...env, TSC_TS_LIB_DIR: lib }, + }, + ); + if (result.status === null || result.status > 2) + throw new Error( + `the instrumented tsc-ts failed on ${join(dir, config)} (${result.signal ?? result.status})`, + ); + console.log(`profiled ${join(dir, config)}`); + } +} + +function run(command, args, options) { + const result = spawnSync(command, args, { ...options, stdio: "inherit" }); + if (result.status !== 0) + throw new Error(`${command} ${args.join(" ")} exited with ${result.status}`); +}