Updating an old (c. 2013) project to use latest LLVM, some things have changed, need advice on the new way

Hi there. A long time ago (2013) I was playing around with LLVM, and, based on the Kaleidoscope tutorial, implemented a little language that used LLVM to generate bitcode that called back into the hosting (macOS) application to do its work.

The project has gathered dust since then, but I’ve long wanted to resurrect it. I just opened it up in Xcode 14.1, and of course all the references to llvm libraries have broken. I’ve since reinstalled LLVM 15.0.5 via brew, and most of the libraries are still there, but a few aren’t found:

  1. libLLVMJIT.a (and “llvm/ExecutionEngine/JIT.h”)
  2. libLLVMX86AsmPrinter
  3. libLLVMX86Utils

I also had to update the clang language version. I chose c11 and c++20, and that seems to work, but I have a couple dozen warnings about implicit conversion losing integer precision, and “/opt/homebrew/opt/llvm/include/llvm/Support/PointerLikeTypeTraits.h:42:63 Possible misuse of comma operator here”

If I comment out including the missing files, I run into more compilation issues, like: PDCodeGenPass.mm:131:31 No viable conversion from ‘int’ to ‘llvm::Align’ in this code. This one I figured out easy enough (use llvm::Align(8)). But this one is a bit more; where do I find the appropriate Type* to pass in (in the last line of this code)? Is it the classStructPtrType I declared near the top? That feels redundant.

	//	Allocate a pointer to the class type…
	
	llvm::StructType* classStructType = static_cast<llvm::StructType*>(packetClassSym->llvmType());
	llvm::PointerType* classStructPtrType = llvm::PointerType::get(classStructType, 0);
	llvm::AllocaInst* classStructPtr = builder().CreateAlloca(classStructPtrType, 0, "packet");
	classStructPtr->setAlignment(llvm::Align(8));
	
	llvm::Value* structSize = llvmValueOfSizeOf(classStructType);
	llvm::Value* packetPtr = buildCall("malloc", structSize);
	//	TODO: check for successful alloc?
	
	llvm::Value* mallocedStructPtr = builder().CreateBitCast(packetPtr, classStructPtrType);
	llvm::StoreInst* storeInst = builder().CreateAlignedStore(mallocedStructPtr, classStructPtr, llvm::MaybeAlign(8));
	
	//
	//	Implement a kind of constructor for our defined packet…
	//
	
	//	Store the passed-in completion proc pointer in the class…
	
	llvm::LoadInst* loadedPacketPtr = builder().CreateAlignedLoad(classStructPtr, 8);

Anyway, most of my issues right now are around needing to pass a Type* argument that I didn’t have to before. Hopefully once I solve those, there won’t be too many other changes I have to make!

TIA!

The Type* things are due to the transition from typed to opaque pointers.
See e.g.
Opaque Pointers — LLVM 16.0.0git documentation
Short short version: Pointers in IR are just “ptr” now, not “i32*” etc. Therefore you sometimes need to explicitly provide a pointee type since that cannot be derived from the pointer type itself.

2 Likes

Does that mean the following code:

	llvm::StructType* classStructType = static_cast<llvm::StructType*>(packetClassSym->llvmType());
	llvm::PointerType* classStructPtrType = llvm::PointerType::get(classStructType, 0);
	llvm::AllocaInst* classStructPtr = builder().CreateAlloca(classStructPtrType, 0, "packet");
	classStructPtr->setAlignment(llvm::Align(8));
	llvm::LoadInst* loadedPacketPtr = builder().CreateAlignedLoad(classStructPtr, 8);  // <-- error

should become this?

	llvm::StructType* classStructType = static_cast<llvm::StructType*>(packetClassSym->llvmType());
	llvm::PointerType* classStructPtrType = llvm::PointerType::get(classStructType, 0);
	llvm::AllocaInst* classStructPtr = builder().CreateAlloca(classStructPtrType, 0, "packet");
	classStructPtr->setAlignment(llvm::Align(8));
	llvm::LoadInst* loadedPacketPtr = builder().CreateAlignedLoad(classStructPtrType, classStructPtr, llvm::MaybeAlign(8));