build under older LLVM's, handle rust mangling
diff --git a/enzyme/Enzyme/GradientUtils.cpp b/enzyme/Enzyme/GradientUtils.cpp
index 4159e2a..43c857b 100644
--- a/enzyme/Enzyme/GradientUtils.cpp
+++ b/enzyme/Enzyme/GradientUtils.cpp
@@ -127,6 +127,10 @@
llvm::cl::opt<bool>
EnzymePrintDiffUse("enzyme-print-diffuse", cl::init(false), cl::Hidden,
cl::desc("Print differential use analysis"));
+
+llvm::cl::opt<std::string>
+ EnzymeRustDeallocName("rust-dealloc-name", cl::init(""), cl::Hidden,
+ cl::desc("Name of Rust deallocation function"));
}
SmallVector<unsigned int, 9> MD_ToCopy = {
@@ -9474,6 +9478,7 @@
GradientUtils *gutils) {
assert(isAllocationFunction(allocationfn, TLI));
+#if LLVM_VERSION_MAJOR >= 17
std::string demangledName = llvm::demangle(allocationfn);
if (demangledName == "__rustc::__rust_alloc" || demangledName == "__rustc::__rust_alloc_zeroed" ) {
Type *VoidTy = Type::getVoidTy(tofree->getContext());
@@ -9482,10 +9487,26 @@
Type *inTys[3] = {IntPtrTy, RustSz, RustSz};
auto FT = FunctionType::get(VoidTy, inTys, false);
+ if (EnzymeRustDeallocName == "") {
+ // Rust's (de)alloc names aren't stable. We expect rustc to set them
+ // for us, but if it fails to do so we instead search for it here.
+ for (auto &F : *builder.GetInsertBlock()->getParent()->getParent()) {
+ auto demangledName = llvm::demangle(F.getName());
+ if (demangledName == "__rustc::__rust_dealloc") {
+ EnzymeRustDeallocName = F.getName();
+ break;
+ }
+ }
+ if (EnzymeRustDeallocName == "") {
+ // If we can't find it, use the raw __rust_dealloc as a fallback.
+ // FIXME: Make this a hard error once we pass the right name from rustc.
+ EnzymeRustDeallocName = "__rust_dealloc";
+ }
+ }
Value *freevalue = builder.GetInsertBlock()
->getParent()
->getParent()
- ->getOrInsertFunction("__rust_dealloc", FT)
+ ->getOrInsertFunction(EnzymeRustDeallocName, FT)
.getCallee();
Value *vals[3];
vals[0] = builder.CreatePointerCast(tofree, IntPtrTy);
@@ -9509,6 +9530,7 @@
builder.Insert(freecall);
return freecall;
}
+#endif
if (allocationfn == "julia.gc_alloc_obj" ||
allocationfn == "jl_gc_alloc_typed" ||
allocationfn == "ijl_gc_alloc_typed" ||
diff --git a/enzyme/Enzyme/LibraryFuncs.h b/enzyme/Enzyme/LibraryFuncs.h
index 299d9d6..8291e0a 100644
--- a/enzyme/Enzyme/LibraryFuncs.h
+++ b/enzyme/Enzyme/LibraryFuncs.h
@@ -56,9 +56,11 @@
return true;
if (name == "__size_returning_new_experiment")
return true;
+#if LLVM_VERSION_MAJOR >= 17
std::string demangledName = llvm::demangle(name.str());
if (demangledName == "__rustc::__rust_alloc" || demangledName == "__rustc::__rust_alloc_zeroed")
return true;
+#endif
if (name == "julia.gc_alloc_obj" || name == "jl_gc_alloc_typed" ||
name == "ijl_gc_alloc_typed")
return true;
@@ -210,8 +212,12 @@
assert(isAllocationFunction(funcName, TLI));
// Don't re-zero an already-zero buffer
+#if LLVM_VERSION_MAJOR >= 17
std::string demangledName = llvm::demangle(funcName.str());
- if (funcName == "calloc" || demangledName == "__rustc::__rust_alloc_zeroed")
+ if (demangledName == "__rustc::__rust_alloc_zeroed")
+ return;
+#endif
+ if (funcName == "calloc")
return;
Value *allocSize = argValues[0];