Files
scriptc/native/llvm-codegen/src/main.cpp
T
Malte Ubl 3467efac73 Prune runtime import bitcode to importable bodies
Program builds that import runtime bitcode parsed and merged every unit's
whole module, although the import can only ever take small bodies that
need no second copy of unit-local state. The helper now reduces a unit's
bitcode to exactly that set when the runtime pack is built: the importable
bodies within the size limit at their call distance from any public
function, and the constants they copy. Every other definition becomes a
declaration, as the import would treat it. A program's selection starts
from public functions, so it is always a subset of the pruned set, and
programs import the same bodies as before.

`runtime-unit` writes the pruned bitcode for speed units; the new
`prune-import` command prunes a unit's bitcode as compiled, for units
whose objects the runtime compiler emits itself.

Linux x64 speed bitcode shrinks from 17.0 MB to 8.6 MB. Runtime objects
are byte-identical, and import lists match the unpruned bitcode exactly.
Interleaved cold builds of 53 programs in a Linux Vercel Sandbox: speed
went from +21.4% to +12.1% over release.
2026-10-16 13:12:16 -07:00

96 lines
3.3 KiB
C++

#include "diagnostics.h"
#include "emit.h"
#include "runtime-unit.h"
#include "target.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/JSON.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/TargetParser/Host.h"
#include <optional>
#include <cstdlib>
#include <string>
using namespace llvm;
#ifndef SCRIPTC_PACKAGE_VERSION
#define SCRIPTC_PACKAGE_VERSION "0.0.0-dev"
#endif
namespace {
int version(int Argc, char **Argv) {
if (Argc != 3 || StringRef(Argv[2]) != "--format=json")
return scriptc::reportError("usage", "version requires --format=json");
std::string Error;
std::unique_ptr<TargetMachine> Machine = scriptc::createTargetMachine(
scriptc::DefaultTarget, "2", Error);
if (!Machine)
return scriptc::reportError("target_machine_failed", Error);
json::Array Targets;
StringRef Backends = scriptc::TargetBackends;
while (!Backends.empty()) {
auto Split = Backends.split(',');
Targets.push_back(Split.first);
Backends = Split.second;
}
json::Array SupportedTargets;
StringRef TargetsText = scriptc::AllowedTargets;
while (!TargetsText.empty()) {
auto Split = TargetsText.split(',');
SupportedTargets.push_back(Split.first);
TargetsText = Split.second;
}
json::Object Response{
{"ok", true},
{"protocol_version", scriptc::ProtocolVersion},
{"scriptc_package_version", SCRIPTC_PACKAGE_VERSION},
{"llvm_version", LLVM_VERSION_STRING},
{"host_triple", sys::getDefaultTargetTriple()},
{"targets", std::move(Targets)},
{"supported_targets", std::move(SupportedTargets)},
{"default_target", scriptc::DefaultTarget},
{"data_layout", Machine->createDataLayout().getStringRepresentation()},
};
outs() << formatv("{0}\n", json::Value(std::move(Response)));
return 0;
}
} // namespace
int main(int Argc, char **Argv) {
scriptc::installFatalDiagnosticHandler();
// Process-isolated test seam for the fatal handler itself. It is inert in
// every ordinary invocation and ensures a future LLVM fatal never becomes
// an unstructured abort/stack trace in the Node caller.
if (std::getenv("SCRIPTC_LLVM_TEST_FATAL") != nullptr)
report_fatal_error("scriptc LLVM fatal diagnostic self-test");
if (Argc >= 2 && StringRef(Argv[1]) == "version")
return version(Argc, Argv);
if (Argc >= 2 && StringRef(Argv[1]) == "runtime-unit")
return scriptc::runtimeUnit(Argc, Argv);
if (Argc >= 2 && StringRef(Argv[1]) == "prune-import")
return scriptc::pruneImport(Argc, Argv);
if (Argc >= 2 && StringRef(Argv[1]) == "emit") {
std::optional<scriptc::EmitOptions> Options =
scriptc::parseEmitOptions(Argc, Argv);
if (!Options)
return scriptc::reportError(
"usage",
"emit requires --input <file> --output <file> and accepts "
"--filetype <obj|asm> --target <triple> --opt-level <0|1|2|3|s|z> "
"--relocation-model pic --diagnostic-format json "
"--source-path <path> --import-bitcode <file> --cache-dir <dir>");
return scriptc::emit(*Options);
}
return scriptc::reportError("usage",
"expected 'version --format=json', 'emit', 'runtime-unit', or "
"'prune-import'");
}