Load when upgrading the vendored LLVM submodule in ponyc. Covers the per-version commit strategy, submodule mechanics, patch hash computation, and common API migration patterns.
Upgrade one major version at a time. Each version gets its own commit. This isolates which LLVM version introduced each breaking change and makes bisection straightforward if something breaks later.
# Reset any applied patches first
git -C lib/llvm/src checkout -- .
# Fetch and checkout the new tag
git -C lib/llvm/src fetch origin tag llvmorg-XX.Y.Z
git -C lib/llvm/src checkout llvmorg-XX.Y.Z
lib/CMakeLists.txtGet the new commit hash:
git -C lib/llvm/src rev-parse HEAD
Set LLVM_DESIRED_HASH to this value.
Check if patches in lib/llvm/patches/ still apply:
git -C lib/llvm/src apply --check -p 1 ../patches/PATCH_NAME.diff
If a patch has been upstreamed (apply fails because the changes are already present), delete the patch file.
PATCHES_DESIRED_HASHThe CMake patch hash computation (lines ~93-100 of lib/CMakeLists.txt):
"needed_if_no_patches"If no patches remain, compute: SHA256("needed_if_no_patches") = 3e16c097794cb669a8f6a0bd7600b440205ac5c29a6135750c2e83263eb16a95
To compute this value:
echo -n "needed_if_no_patches" | sha256sum
Fix compilation errors from removed/deprecated LLVM APIs. See "Common Migration Patterns" below.
The submodule pointer must be committed before building because CMake runs git submodule update --init which would revert an uncommitted pointer change.
git add lib/llvm/src lib/CMakeLists.txt src/libponyc/codegen/...
git commit -m "Upgrade LLVM XX.Y.Z → XX.Y.Z"
make cleanlibs && make libs build_flags="-j12" # Build LLVM (~30-60 min)
make # Build ponyc
make test-full-programs-release # Run full-program tests
If the build finds additional errors, assess whether they're the same class of API change already handled (fix and amend) or indicate a different migration pattern is needed (revisit step 5).
LLVMConst* → LLVMBuild* (constant expression removal)LLVM progressively removed constant expression functions. The LLVMBuild* equivalents auto-constant-fold when given constant operands, so they're drop-in replacements:
// Before:
return LLVMConstShl(l_value, r_value);
// After:
return LLVMBuildShl(c->builder, l_value, r_value, "");
Removal timeline (approximate):
LLVMConstICmp, LLVMConstFCmp, LLVMConstShlLLVMConstAdd, LLVMConstSubLLVMConstMulmake_binop NULL fallthroughIn ponyc's genoperator.c, make_binop takes a const_i function pointer. Passing NULL causes the null guard (line ~68) to fall through to the builder path, which constant-folds automatically:
// Before:
make_binop(c, left, right, NULL, LLVMConstAdd, LLVMBuildFAdd, LLVMBuildAdd);
// After:
make_binop(c, left, right, NULL, NULL, LLVMBuildFAdd, LLVMBuildAdd);
LLVMArrayType(elemTy, count) → LLVMArrayType2(elemTy, count) // uint64_t
LLVMConstArray(elemTy, vals, count) → LLVMConstArray2(elemTy, vals, count) // uint64_t
LLVMConstStringInContext(ctx, s, len) → LLVMConstStringInContext2(ctx, s, len) // size_t
LLVMGetMDKindID(name, len) → LLVMGetMDKindIDInContext(ctx, name, len)
DIBuilder::insertDeclare returns DbgInstPtr (PointerUnion) instead of Instruction*. If callers don't use the return value, change wrapper return type to void.LLVMBuildNSWNeg/LLVMBuildNUWNeg deprecated → use LLVMBuildNeg + LLVMSetNoSignedWrap/LLVMSetNoUnsignedWrap.Intrinsic::getDeclaration → Intrinsic::getOrInsertDeclaration.registerOptimizerEarlyEPCallback, registerOptimizerLastEPCallback) add ThinOrFullLTOPhase parameter to the lambda.Attribute::NoCapture → Attribute::getWithCaptureInfo(ctx, CaptureInfo::none()).LintPass() constructor requires bool AbortOnError parameter → LintPass(false).createTargetMachine takes const Triple& instead of StringRef → wrap with Triple(opt->triple).APIs used in ponyc that may break in future LLVM versions. Check during each upgrade:
| API | Location | Likely replacement |
|---|---|---|
LLVMConstNeg | genoperator.c | LLVMBuildNeg |
LLVMConstNot | genoperator.c | LLVMBuildNot |
LLVMConstXor | genoperator.c | LLVMBuildXor |
LLVMConstTrunc | genreference.c | LLVMBuildTrunc |
lib/CMakeLists.txt — LLVM_DESIRED_HASH, PATCHES_DESIRED_HASHlib/llvm/patches/ — patch files (may be added/removed)src/libponyc/codegen/genoperator.c — constant expression replacementssrc/libponyc/codegen/genreference.c — constant expression replacementssrc/libponyc/codegen/gendebug.cc / gendebug.h — debug info API changessrc/libponyc/codegen/host.cc — target machine, intrinsicssrc/libponyc/codegen/genopt.cc — optimizer pass pipelinesrc/libponyc/codegen/gendesc.c — array/descriptor constructionsrc/libponyc/codegen/codegen.c — core codegen types and helperssrc/libponyc/codegen/gencontrol.c — metadata APIs