Commit 567e560d by Nicolas Capens Committed by Nicolas Capens

Eliminate duplicate LLVM contexts

The LLVMContext object is used for caching LLVM types, eliminating duplicate constants, and things like handling diagnostics information. Previously we created one for the JITBuilder as well as the JITRoutine. While having multiple ones is mostly benign from a correctness point of view, it adds unnecessary overhead. This change reuses the context created for the JITBuilder object (which is used during IR construction), for the JITRoutine (which uses it for actual compilation). Bug: b/177024837 Change-Id: Iefbbd7fbeb53e67ab41914fad471dd94d9755311 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/51568 Kokoro-Result: kokoro <noreply+kokoro@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarAntonio Maiorano <amaiorano@google.com>
parent 0985120b
...@@ -627,13 +627,13 @@ class JITRoutine : public rr::Routine ...@@ -627,13 +627,13 @@ class JITRoutine : public rr::Routine
llvm::orc::RTDyldObjectLinkingLayer objectLayer; llvm::orc::RTDyldObjectLinkingLayer objectLayer;
llvm::orc::IRCompileLayer compileLayer; llvm::orc::IRCompileLayer compileLayer;
llvm::orc::MangleAndInterner mangle; llvm::orc::MangleAndInterner mangle;
llvm::orc::ThreadSafeContext ctx;
llvm::orc::JITDylib &dylib; llvm::orc::JITDylib &dylib;
std::vector<const void *> addresses; std::vector<const void *> addresses;
public: public:
JITRoutine( JITRoutine(
std::unique_ptr<llvm::Module> module, std::unique_ptr<llvm::Module> module,
std::unique_ptr<llvm::LLVMContext> context,
const char *name, const char *name,
llvm::Function **funcs, llvm::Function **funcs,
size_t count, size_t count,
...@@ -645,11 +645,9 @@ public: ...@@ -645,11 +645,9 @@ public:
}) })
, compileLayer(session, objectLayer, std::make_unique<llvm::orc::ConcurrentIRCompiler>(JITGlobals::get()->getTargetMachineBuilder(config.getOptimization().getLevel()))) , compileLayer(session, objectLayer, std::make_unique<llvm::orc::ConcurrentIRCompiler>(JITGlobals::get()->getTargetMachineBuilder(config.getOptimization().getLevel())))
, mangle(session, JITGlobals::get()->getDataLayout()) , mangle(session, JITGlobals::get()->getDataLayout())
, ctx(std::make_unique<llvm::LLVMContext>())
, dylib(Unwrap(session.createJITDylib("<routine>"))) , dylib(Unwrap(session.createJITDylib("<routine>")))
, addresses(count) , addresses(count)
{ {
#ifdef ENABLE_RR_DEBUG_INFO #ifdef ENABLE_RR_DEBUG_INFO
// TODO(b/165000222): Update this on next LLVM roll. // TODO(b/165000222): Update this on next LLVM roll.
// https://github.com/llvm/llvm-project/commit/98f2bb4461072347dcca7d2b1b9571b3a6525801 // https://github.com/llvm/llvm-project/commit/98f2bb4461072347dcca7d2b1b9571b3a6525801
...@@ -698,7 +696,7 @@ public: ...@@ -698,7 +696,7 @@ public:
// after this point. // after this point.
funcs = nullptr; funcs = nullptr;
llvm::cantFail(compileLayer.add(dylib, llvm::orc::ThreadSafeModule(std::move(module), ctx))); llvm::cantFail(compileLayer.add(dylib, llvm::orc::ThreadSafeModule(std::move(module), std::move(context))));
// Resolve the function addresses. // Resolve the function addresses.
for(size_t i = 0; i < count; i++) for(size_t i = 0; i < count; i++)
...@@ -736,8 +734,9 @@ namespace rr { ...@@ -736,8 +734,9 @@ namespace rr {
JITBuilder::JITBuilder(const rr::Config &config) JITBuilder::JITBuilder(const rr::Config &config)
: config(config) : config(config)
, module(new llvm::Module("", context)) , context(new llvm::LLVMContext())
, builder(new llvm::IRBuilder<>(context)) , module(new llvm::Module("", *context))
, builder(new llvm::IRBuilder<>(*context))
{ {
module->setTargetTriple(LLVM_DEFAULT_TARGET_TRIPLE); module->setTargetTriple(LLVM_DEFAULT_TARGET_TRIPLE);
module->setDataLayout(JITGlobals::get()->getDataLayout()); module->setDataLayout(JITGlobals::get()->getDataLayout());
...@@ -787,7 +786,7 @@ void JITBuilder::optimize(const rr::Config &cfg) ...@@ -787,7 +786,7 @@ void JITBuilder::optimize(const rr::Config &cfg)
std::shared_ptr<rr::Routine> JITBuilder::acquireRoutine(const char *name, llvm::Function **funcs, size_t count, const rr::Config &cfg) std::shared_ptr<rr::Routine> JITBuilder::acquireRoutine(const char *name, llvm::Function **funcs, size_t count, const rr::Config &cfg)
{ {
ASSERT(module); ASSERT(module);
return std::make_shared<JITRoutine>(std::move(module), name, funcs, count, cfg); return std::make_shared<JITRoutine>(std::move(module), std::move(context), name, funcs, count, cfg);
} }
} // namespace rr } // namespace rr
...@@ -642,7 +642,7 @@ Value *Nucleus::allocateStackVariable(Type *type, int arraySize) ...@@ -642,7 +642,7 @@ Value *Nucleus::allocateStackVariable(Type *type, int arraySize)
BasicBlock *Nucleus::createBasicBlock() BasicBlock *Nucleus::createBasicBlock()
{ {
return B(llvm::BasicBlock::Create(jit->context, "", jit->function)); return B(llvm::BasicBlock::Create(*jit->context, "", jit->function));
} }
BasicBlock *Nucleus::getInsertBlock() BasicBlock *Nucleus::getInsertBlock()
...@@ -664,10 +664,10 @@ void Nucleus::createFunction(Type *ReturnType, const std::vector<Type *> &Params ...@@ -664,10 +664,10 @@ void Nucleus::createFunction(Type *ReturnType, const std::vector<Type *> &Params
jit->function = rr::createFunction("", T(ReturnType), T(Params)); jit->function = rr::createFunction("", T(ReturnType), T(Params));
#ifdef ENABLE_RR_DEBUG_INFO #ifdef ENABLE_RR_DEBUG_INFO
jit->debugInfo = std::make_unique<DebugInfo>(jit->builder.get(), &jit->context, jit->module.get(), jit->function); jit->debugInfo = std::make_unique<DebugInfo>(jit->builder.get(), jit->context.get(), jit->module.get(), jit->function);
#endif // ENABLE_RR_DEBUG_INFO #endif // ENABLE_RR_DEBUG_INFO
jit->builder->SetInsertPoint(llvm::BasicBlock::Create(jit->context, "", jit->function)); jit->builder->SetInsertPoint(llvm::BasicBlock::Create(*jit->context, "", jit->function));
} }
Value *Nucleus::getArgument(unsigned int index) Value *Nucleus::getArgument(unsigned int index)
...@@ -906,7 +906,7 @@ Value *Nucleus::createLoad(Value *ptr, Type *type, bool isVolatile, unsigned int ...@@ -906,7 +906,7 @@ Value *Nucleus::createLoad(Value *ptr, Type *type, bool isVolatile, unsigned int
// above, but certain backends cannot deal with this. // above, but certain backends cannot deal with this.
// Load as an integer and bitcast. See b/136037244. // Load as an integer and bitcast. See b/136037244.
auto size = jit->module->getDataLayout().getTypeStoreSize(elTy); auto size = jit->module->getDataLayout().getTypeStoreSize(elTy);
auto elAsIntTy = llvm::IntegerType::get(jit->context, size * 8); auto elAsIntTy = llvm::IntegerType::get(*jit->context, size * 8);
auto ptrCast = jit->builder->CreatePointerCast(V(ptr), elAsIntTy->getPointerTo()); auto ptrCast = jit->builder->CreatePointerCast(V(ptr), elAsIntTy->getPointerTo());
auto load = jit->builder->CreateAlignedLoad(ptrCast, alignment, isVolatile); auto load = jit->builder->CreateAlignedLoad(ptrCast, alignment, isVolatile);
load->setAtomic(atomicOrdering(atomic, memoryOrder)); load->setAtomic(atomicOrdering(atomic, memoryOrder));
...@@ -917,11 +917,11 @@ Value *Nucleus::createLoad(Value *ptr, Type *type, bool isVolatile, unsigned int ...@@ -917,11 +917,11 @@ Value *Nucleus::createLoad(Value *ptr, Type *type, bool isVolatile, unsigned int
{ {
// More exotic types require falling back to the extern: // More exotic types require falling back to the extern:
// void __atomic_load(size_t size, void *ptr, void *ret, int ordering) // void __atomic_load(size_t size, void *ptr, void *ret, int ordering)
auto sizetTy = llvm::IntegerType::get(jit->context, sizeof(size_t) * 8); auto sizetTy = llvm::IntegerType::get(*jit->context, sizeof(size_t) * 8);
auto intTy = llvm::IntegerType::get(jit->context, sizeof(int) * 8); auto intTy = llvm::IntegerType::get(*jit->context, sizeof(int) * 8);
auto i8Ty = llvm::Type::getInt8Ty(jit->context); auto i8Ty = llvm::Type::getInt8Ty(*jit->context);
auto i8PtrTy = i8Ty->getPointerTo(); auto i8PtrTy = i8Ty->getPointerTo();
auto voidTy = llvm::Type::getVoidTy(jit->context); auto voidTy = llvm::Type::getVoidTy(*jit->context);
auto funcTy = llvm::FunctionType::get(voidTy, { sizetTy, i8PtrTy, i8PtrTy, intTy }, false); auto funcTy = llvm::FunctionType::get(voidTy, { sizetTy, i8PtrTy, i8PtrTy, intTy }, false);
auto func = jit->module->getOrInsertFunction("__atomic_load", funcTy); auto func = jit->module->getOrInsertFunction("__atomic_load", funcTy);
auto size = jit->module->getDataLayout().getTypeStoreSize(elTy); auto size = jit->module->getDataLayout().getTypeStoreSize(elTy);
...@@ -976,10 +976,10 @@ Value *Nucleus::createStore(Value *value, Value *ptr, Type *type, bool isVolatil ...@@ -976,10 +976,10 @@ Value *Nucleus::createStore(Value *value, Value *ptr, Type *type, bool isVolatil
{ {
// Mark all memory writes as initialized by calling __msan_unpoison // Mark all memory writes as initialized by calling __msan_unpoison
// void __msan_unpoison(const volatile void *a, size_t size) // void __msan_unpoison(const volatile void *a, size_t size)
auto voidTy = llvm::Type::getVoidTy(jit->context); auto voidTy = llvm::Type::getVoidTy(*jit->context);
auto i8Ty = llvm::Type::getInt8Ty(jit->context); auto i8Ty = llvm::Type::getInt8Ty(*jit->context);
auto voidPtrTy = i8Ty->getPointerTo(); auto voidPtrTy = i8Ty->getPointerTo();
auto sizetTy = llvm::IntegerType::get(jit->context, sizeof(size_t) * 8); auto sizetTy = llvm::IntegerType::get(*jit->context, sizeof(size_t) * 8);
auto funcTy = llvm::FunctionType::get(voidTy, { voidPtrTy, sizetTy }, false); auto funcTy = llvm::FunctionType::get(voidTy, { voidPtrTy, sizetTy }, false);
auto func = jit->module->getOrInsertFunction("__msan_unpoison", funcTy); auto func = jit->module->getOrInsertFunction("__msan_unpoison", funcTy);
auto size = jit->module->getDataLayout().getTypeStoreSize(elTy); auto size = jit->module->getDataLayout().getTypeStoreSize(elTy);
...@@ -1005,7 +1005,7 @@ Value *Nucleus::createStore(Value *value, Value *ptr, Type *type, bool isVolatil ...@@ -1005,7 +1005,7 @@ Value *Nucleus::createStore(Value *value, Value *ptr, Type *type, bool isVolatil
// above, but certain backends cannot deal with this. // above, but certain backends cannot deal with this.
// Store as an bitcast integer. See b/136037244. // Store as an bitcast integer. See b/136037244.
auto size = jit->module->getDataLayout().getTypeStoreSize(elTy); auto size = jit->module->getDataLayout().getTypeStoreSize(elTy);
auto elAsIntTy = llvm::IntegerType::get(jit->context, size * 8); auto elAsIntTy = llvm::IntegerType::get(*jit->context, size * 8);
auto valCast = jit->builder->CreateBitCast(V(value), elAsIntTy); auto valCast = jit->builder->CreateBitCast(V(value), elAsIntTy);
auto ptrCast = jit->builder->CreatePointerCast(V(ptr), elAsIntTy->getPointerTo()); auto ptrCast = jit->builder->CreatePointerCast(V(ptr), elAsIntTy->getPointerTo());
auto store = jit->builder->CreateAlignedStore(valCast, ptrCast, alignment, isVolatile); auto store = jit->builder->CreateAlignedStore(valCast, ptrCast, alignment, isVolatile);
...@@ -1015,11 +1015,11 @@ Value *Nucleus::createStore(Value *value, Value *ptr, Type *type, bool isVolatil ...@@ -1015,11 +1015,11 @@ Value *Nucleus::createStore(Value *value, Value *ptr, Type *type, bool isVolatil
{ {
// More exotic types require falling back to the extern: // More exotic types require falling back to the extern:
// void __atomic_store(size_t size, void *ptr, void *val, int ordering) // void __atomic_store(size_t size, void *ptr, void *val, int ordering)
auto sizetTy = llvm::IntegerType::get(jit->context, sizeof(size_t) * 8); auto sizetTy = llvm::IntegerType::get(*jit->context, sizeof(size_t) * 8);
auto intTy = llvm::IntegerType::get(jit->context, sizeof(int) * 8); auto intTy = llvm::IntegerType::get(*jit->context, sizeof(int) * 8);
auto i8Ty = llvm::Type::getInt8Ty(jit->context); auto i8Ty = llvm::Type::getInt8Ty(*jit->context);
auto i8PtrTy = i8Ty->getPointerTo(); auto i8PtrTy = i8Ty->getPointerTo();
auto voidTy = llvm::Type::getVoidTy(jit->context); auto voidTy = llvm::Type::getVoidTy(*jit->context);
auto funcTy = llvm::FunctionType::get(voidTy, { sizetTy, i8PtrTy, i8PtrTy, intTy }, false); auto funcTy = llvm::FunctionType::get(voidTy, { sizetTy, i8PtrTy, i8PtrTy, intTy }, false);
auto func = jit->module->getOrInsertFunction("__atomic_store", funcTy); auto func = jit->module->getOrInsertFunction("__atomic_store", funcTy);
auto size = jit->module->getDataLayout().getTypeStoreSize(elTy); auto size = jit->module->getDataLayout().getTypeStoreSize(elTy);
...@@ -1049,8 +1049,8 @@ Value *Nucleus::createMaskedLoad(Value *ptr, Type *elTy, Value *mask, unsigned i ...@@ -1049,8 +1049,8 @@ Value *Nucleus::createMaskedLoad(Value *ptr, Type *elTy, Value *mask, unsigned i
ASSERT(V(mask)->getType()->isVectorTy()); ASSERT(V(mask)->getType()->isVectorTy());
auto numEls = llvm::cast<llvm::VectorType>(V(mask)->getType())->getNumElements(); auto numEls = llvm::cast<llvm::VectorType>(V(mask)->getType())->getNumElements();
auto i1Ty = llvm::Type::getInt1Ty(jit->context); auto i1Ty = llvm::Type::getInt1Ty(*jit->context);
auto i32Ty = llvm::Type::getInt32Ty(jit->context); auto i32Ty = llvm::Type::getInt32Ty(*jit->context);
auto elVecTy = llvm::VectorType::get(T(elTy), numEls, false); auto elVecTy = llvm::VectorType::get(T(elTy), numEls, false);
auto elVecPtrTy = elVecTy->getPointerTo(); auto elVecPtrTy = elVecTy->getPointerTo();
auto i8Mask = jit->builder->CreateIntCast(V(mask), llvm::VectorType::get(i1Ty, numEls, false), false); // vec<int, int, ...> -> vec<bool, bool, ...> auto i8Mask = jit->builder->CreateIntCast(V(mask), llvm::VectorType::get(i1Ty, numEls, false), false); // vec<int, int, ...> -> vec<bool, bool, ...>
...@@ -1069,8 +1069,8 @@ void Nucleus::createMaskedStore(Value *ptr, Value *val, Value *mask, unsigned in ...@@ -1069,8 +1069,8 @@ void Nucleus::createMaskedStore(Value *ptr, Value *val, Value *mask, unsigned in
ASSERT(V(mask)->getType()->isVectorTy()); ASSERT(V(mask)->getType()->isVectorTy());
auto numEls = llvm::cast<llvm::VectorType>(V(mask)->getType())->getNumElements(); auto numEls = llvm::cast<llvm::VectorType>(V(mask)->getType())->getNumElements();
auto i1Ty = llvm::Type::getInt1Ty(jit->context); auto i1Ty = llvm::Type::getInt1Ty(*jit->context);
auto i32Ty = llvm::Type::getInt32Ty(jit->context); auto i32Ty = llvm::Type::getInt32Ty(*jit->context);
auto elVecTy = V(val)->getType(); auto elVecTy = V(val)->getType();
auto elVecPtrTy = elVecTy->getPointerTo(); auto elVecPtrTy = elVecTy->getPointerTo();
auto i1Mask = jit->builder->CreateIntCast(V(mask), llvm::VectorType::get(i1Ty, numEls, false), false); // vec<int, int, ...> -> vec<bool, bool, ...> auto i1Mask = jit->builder->CreateIntCast(V(mask), llvm::VectorType::get(i1Ty, numEls, false), false); // vec<int, int, ...> -> vec<bool, bool, ...>
...@@ -1082,9 +1082,9 @@ void Nucleus::createMaskedStore(Value *ptr, Value *val, Value *mask, unsigned in ...@@ -1082,9 +1082,9 @@ void Nucleus::createMaskedStore(Value *ptr, Value *val, Value *mask, unsigned in
{ {
// Mark memory writes as initialized by calling __msan_unpoison // Mark memory writes as initialized by calling __msan_unpoison
// void __msan_unpoison(const volatile void *a, size_t size) // void __msan_unpoison(const volatile void *a, size_t size)
auto voidTy = llvm::Type::getVoidTy(jit->context); auto voidTy = llvm::Type::getVoidTy(*jit->context);
auto voidPtrTy = voidTy->getPointerTo(); auto voidPtrTy = voidTy->getPointerTo();
auto sizetTy = llvm::IntegerType::get(jit->context, sizeof(size_t) * 8); auto sizetTy = llvm::IntegerType::get(*jit->context, sizeof(size_t) * 8);
auto funcTy = llvm::FunctionType::get(voidTy, { voidPtrTy, sizetTy }, false); auto funcTy = llvm::FunctionType::get(voidTy, { voidPtrTy, sizetTy }, false);
auto func = jit->module->getOrInsertFunction("__msan_unpoison", funcTy); auto func = jit->module->getOrInsertFunction("__msan_unpoison", funcTy);
auto size = jit->module->getDataLayout().getTypeStoreSize(llvm::cast<llvm::VectorType>(elVecTy)->getElementType()); auto size = jit->module->getDataLayout().getTypeStoreSize(llvm::cast<llvm::VectorType>(elVecTy)->getElementType());
...@@ -1093,8 +1093,8 @@ void Nucleus::createMaskedStore(Value *ptr, Value *val, Value *mask, unsigned in ...@@ -1093,8 +1093,8 @@ void Nucleus::createMaskedStore(Value *ptr, Value *val, Value *mask, unsigned in
{ {
// Check mask for this element // Check mask for this element
auto idx = llvm::ConstantInt::get(i32Ty, i); auto idx = llvm::ConstantInt::get(i32Ty, i);
auto thenBlock = llvm::BasicBlock::Create(jit->context, "", jit->function); auto thenBlock = llvm::BasicBlock::Create(*jit->context, "", jit->function);
auto mergeBlock = llvm::BasicBlock::Create(jit->context, "", jit->function); auto mergeBlock = llvm::BasicBlock::Create(*jit->context, "", jit->function);
jit->builder->CreateCondBr(jit->builder->CreateExtractElement(i1Mask, idx), thenBlock, mergeBlock); jit->builder->CreateCondBr(jit->builder->CreateExtractElement(i1Mask, idx), thenBlock, mergeBlock);
jit->builder->SetInsertPoint(thenBlock); jit->builder->SetInsertPoint(thenBlock);
...@@ -1116,9 +1116,9 @@ static llvm::Value *createGather(llvm::Value *base, llvm::Type *elTy, llvm::Valu ...@@ -1116,9 +1116,9 @@ static llvm::Value *createGather(llvm::Value *base, llvm::Type *elTy, llvm::Valu
ASSERT(mask->getType()->isVectorTy()); ASSERT(mask->getType()->isVectorTy());
auto numEls = llvm::cast<llvm::VectorType>(mask->getType())->getNumElements(); auto numEls = llvm::cast<llvm::VectorType>(mask->getType())->getNumElements();
auto i1Ty = llvm::Type::getInt1Ty(jit->context); auto i1Ty = llvm::Type::getInt1Ty(*jit->context);
auto i32Ty = llvm::Type::getInt32Ty(jit->context); auto i32Ty = llvm::Type::getInt32Ty(*jit->context);
auto i8Ty = llvm::Type::getInt8Ty(jit->context); auto i8Ty = llvm::Type::getInt8Ty(*jit->context);
auto i8PtrTy = i8Ty->getPointerTo(); auto i8PtrTy = i8Ty->getPointerTo();
auto elPtrTy = elTy->getPointerTo(); auto elPtrTy = elTy->getPointerTo();
auto elVecTy = llvm::VectorType::get(elTy, numEls, false); auto elVecTy = llvm::VectorType::get(elTy, numEls, false);
...@@ -1182,9 +1182,9 @@ static void createScatter(llvm::Value *base, llvm::Value *val, llvm::Value *offs ...@@ -1182,9 +1182,9 @@ static void createScatter(llvm::Value *base, llvm::Value *val, llvm::Value *offs
ASSERT(mask->getType()->isVectorTy()); ASSERT(mask->getType()->isVectorTy());
auto numEls = llvm::cast<llvm::VectorType>(mask->getType())->getNumElements(); auto numEls = llvm::cast<llvm::VectorType>(mask->getType())->getNumElements();
auto i1Ty = llvm::Type::getInt1Ty(jit->context); auto i1Ty = llvm::Type::getInt1Ty(*jit->context);
auto i32Ty = llvm::Type::getInt32Ty(jit->context); auto i32Ty = llvm::Type::getInt32Ty(*jit->context);
auto i8Ty = llvm::Type::getInt8Ty(jit->context); auto i8Ty = llvm::Type::getInt8Ty(*jit->context);
auto i8PtrTy = i8Ty->getPointerTo(); auto i8PtrTy = i8Ty->getPointerTo();
auto elVecTy = val->getType(); auto elVecTy = val->getType();
auto elTy = llvm::cast<llvm::VectorType>(elVecTy)->getElementType(); auto elTy = llvm::cast<llvm::VectorType>(elVecTy)->getElementType();
...@@ -1212,8 +1212,8 @@ static void createScatter(llvm::Value *base, llvm::Value *val, llvm::Value *offs ...@@ -1212,8 +1212,8 @@ static void createScatter(llvm::Value *base, llvm::Value *val, llvm::Value *offs
{ {
// Check mask for this element // Check mask for this element
auto idx = llvm::ConstantInt::get(i32Ty, i); auto idx = llvm::ConstantInt::get(i32Ty, i);
auto thenBlock = llvm::BasicBlock::Create(jit->context, "", jit->function); auto thenBlock = llvm::BasicBlock::Create(*jit->context, "", jit->function);
auto mergeBlock = llvm::BasicBlock::Create(jit->context, "", jit->function); auto mergeBlock = llvm::BasicBlock::Create(*jit->context, "", jit->function);
jit->builder->CreateCondBr(jit->builder->CreateExtractElement(i1Mask, idx), thenBlock, mergeBlock); jit->builder->CreateCondBr(jit->builder->CreateExtractElement(i1Mask, idx), thenBlock, mergeBlock);
jit->builder->SetInsertPoint(thenBlock); jit->builder->SetInsertPoint(thenBlock);
...@@ -1598,7 +1598,7 @@ Value *Nucleus::createShuffleVector(Value *v1, Value *v2, const int *select) ...@@ -1598,7 +1598,7 @@ Value *Nucleus::createShuffleVector(Value *v1, Value *v2, const int *select)
for(int i = 0; i < size; i++) for(int i = 0; i < size; i++)
{ {
swizzle[i] = llvm::ConstantInt::get(llvm::Type::getInt32Ty(jit->context), select[i]); swizzle[i] = llvm::ConstantInt::get(llvm::Type::getInt32Ty(*jit->context), select[i]);
} }
llvm::Value *shuffle = llvm::ConstantVector::get(llvm::ArrayRef<llvm::Constant *>(swizzle, size)); llvm::Value *shuffle = llvm::ConstantVector::get(llvm::ArrayRef<llvm::Constant *>(swizzle, size));
...@@ -1622,7 +1622,7 @@ void Nucleus::addSwitchCase(SwitchCases *switchCases, int label, BasicBlock *bra ...@@ -1622,7 +1622,7 @@ void Nucleus::addSwitchCase(SwitchCases *switchCases, int label, BasicBlock *bra
{ {
RR_DEBUG_INFO_UPDATE_LOC(); RR_DEBUG_INFO_UPDATE_LOC();
llvm::SwitchInst *sw = reinterpret_cast<llvm::SwitchInst *>(switchCases); llvm::SwitchInst *sw = reinterpret_cast<llvm::SwitchInst *>(switchCases);
sw->addCase(llvm::ConstantInt::get(llvm::Type::getInt32Ty(jit->context), label, true), B(branch)); sw->addCase(llvm::ConstantInt::get(llvm::Type::getInt32Ty(*jit->context), label, true), B(branch));
} }
void Nucleus::createUnreachable() void Nucleus::createUnreachable()
...@@ -1648,7 +1648,7 @@ Type *Nucleus::getPointerType(Type *ElementType) ...@@ -1648,7 +1648,7 @@ Type *Nucleus::getPointerType(Type *ElementType)
static llvm::Type *getNaturalIntType() static llvm::Type *getNaturalIntType()
{ {
return llvm::Type::getIntNTy(jit->context, sizeof(int) * 8); return llvm::Type::getIntNTy(*jit->context, sizeof(int) * 8);
} }
Type *Nucleus::getPrintfStorageType(Type *valueType) Type *Nucleus::getPrintfStorageType(Type *valueType)
...@@ -1660,7 +1660,7 @@ Type *Nucleus::getPrintfStorageType(Type *valueType) ...@@ -1660,7 +1660,7 @@ Type *Nucleus::getPrintfStorageType(Type *valueType)
} }
if(valueTy->isFloatTy()) if(valueTy->isFloatTy())
{ {
return T(llvm::Type::getDoubleTy(jit->context)); return T(llvm::Type::getDoubleTy(*jit->context));
} }
UNIMPLEMENTED_NO_BUG("getPrintfStorageType: add more cases as needed"); UNIMPLEMENTED_NO_BUG("getPrintfStorageType: add more cases as needed");
...@@ -1676,49 +1676,49 @@ Value *Nucleus::createNullValue(Type *Ty) ...@@ -1676,49 +1676,49 @@ Value *Nucleus::createNullValue(Type *Ty)
Value *Nucleus::createConstantLong(int64_t i) Value *Nucleus::createConstantLong(int64_t i)
{ {
RR_DEBUG_INFO_UPDATE_LOC(); RR_DEBUG_INFO_UPDATE_LOC();
return V(llvm::ConstantInt::get(llvm::Type::getInt64Ty(jit->context), i, true)); return V(llvm::ConstantInt::get(llvm::Type::getInt64Ty(*jit->context), i, true));
} }
Value *Nucleus::createConstantInt(int i) Value *Nucleus::createConstantInt(int i)
{ {
RR_DEBUG_INFO_UPDATE_LOC(); RR_DEBUG_INFO_UPDATE_LOC();
return V(llvm::ConstantInt::get(llvm::Type::getInt32Ty(jit->context), i, true)); return V(llvm::ConstantInt::get(llvm::Type::getInt32Ty(*jit->context), i, true));
} }
Value *Nucleus::createConstantInt(unsigned int i) Value *Nucleus::createConstantInt(unsigned int i)
{ {
RR_DEBUG_INFO_UPDATE_LOC(); RR_DEBUG_INFO_UPDATE_LOC();
return V(llvm::ConstantInt::get(llvm::Type::getInt32Ty(jit->context), i, false)); return V(llvm::ConstantInt::get(llvm::Type::getInt32Ty(*jit->context), i, false));
} }
Value *Nucleus::createConstantBool(bool b) Value *Nucleus::createConstantBool(bool b)
{ {
RR_DEBUG_INFO_UPDATE_LOC(); RR_DEBUG_INFO_UPDATE_LOC();
return V(llvm::ConstantInt::get(llvm::Type::getInt1Ty(jit->context), b)); return V(llvm::ConstantInt::get(llvm::Type::getInt1Ty(*jit->context), b));
} }
Value *Nucleus::createConstantByte(signed char i) Value *Nucleus::createConstantByte(signed char i)
{ {
RR_DEBUG_INFO_UPDATE_LOC(); RR_DEBUG_INFO_UPDATE_LOC();
return V(llvm::ConstantInt::get(llvm::Type::getInt8Ty(jit->context), i, true)); return V(llvm::ConstantInt::get(llvm::Type::getInt8Ty(*jit->context), i, true));
} }
Value *Nucleus::createConstantByte(unsigned char i) Value *Nucleus::createConstantByte(unsigned char i)
{ {
RR_DEBUG_INFO_UPDATE_LOC(); RR_DEBUG_INFO_UPDATE_LOC();
return V(llvm::ConstantInt::get(llvm::Type::getInt8Ty(jit->context), i, false)); return V(llvm::ConstantInt::get(llvm::Type::getInt8Ty(*jit->context), i, false));
} }
Value *Nucleus::createConstantShort(short i) Value *Nucleus::createConstantShort(short i)
{ {
RR_DEBUG_INFO_UPDATE_LOC(); RR_DEBUG_INFO_UPDATE_LOC();
return V(llvm::ConstantInt::get(llvm::Type::getInt16Ty(jit->context), i, true)); return V(llvm::ConstantInt::get(llvm::Type::getInt16Ty(*jit->context), i, true));
} }
Value *Nucleus::createConstantShort(unsigned short i) Value *Nucleus::createConstantShort(unsigned short i)
{ {
RR_DEBUG_INFO_UPDATE_LOC(); RR_DEBUG_INFO_UPDATE_LOC();
return V(llvm::ConstantInt::get(llvm::Type::getInt16Ty(jit->context), i, false)); return V(llvm::ConstantInt::get(llvm::Type::getInt16Ty(*jit->context), i, false));
} }
Value *Nucleus::createConstantFloat(float x) Value *Nucleus::createConstantFloat(float x)
...@@ -1776,32 +1776,32 @@ Value *Nucleus::createConstantString(const char *v) ...@@ -1776,32 +1776,32 @@ Value *Nucleus::createConstantString(const char *v)
Type *Void::type() Type *Void::type()
{ {
return T(llvm::Type::getVoidTy(jit->context)); return T(llvm::Type::getVoidTy(*jit->context));
} }
Type *Bool::type() Type *Bool::type()
{ {
return T(llvm::Type::getInt1Ty(jit->context)); return T(llvm::Type::getInt1Ty(*jit->context));
} }
Type *Byte::type() Type *Byte::type()
{ {
return T(llvm::Type::getInt8Ty(jit->context)); return T(llvm::Type::getInt8Ty(*jit->context));
} }
Type *SByte::type() Type *SByte::type()
{ {
return T(llvm::Type::getInt8Ty(jit->context)); return T(llvm::Type::getInt8Ty(*jit->context));
} }
Type *Short::type() Type *Short::type()
{ {
return T(llvm::Type::getInt16Ty(jit->context)); return T(llvm::Type::getInt16Ty(*jit->context));
} }
Type *UShort::type() Type *UShort::type()
{ {
return T(llvm::Type::getInt16Ty(jit->context)); return T(llvm::Type::getInt16Ty(*jit->context));
} }
Type *Byte4::type() Type *Byte4::type()
...@@ -2338,12 +2338,12 @@ RValue<Int> RoundInt(RValue<Float> cast) ...@@ -2338,12 +2338,12 @@ RValue<Int> RoundInt(RValue<Float> cast)
Type *Int::type() Type *Int::type()
{ {
return T(llvm::Type::getInt32Ty(jit->context)); return T(llvm::Type::getInt32Ty(*jit->context));
} }
Type *Long::type() Type *Long::type()
{ {
return T(llvm::Type::getInt64Ty(jit->context)); return T(llvm::Type::getInt64Ty(*jit->context));
} }
UInt::UInt(RValue<Float> cast) UInt::UInt(RValue<Float> cast)
...@@ -2404,7 +2404,7 @@ const UInt &operator--(UInt &val) // Pre-decrement ...@@ -2404,7 +2404,7 @@ const UInt &operator--(UInt &val) // Pre-decrement
Type *UInt::type() Type *UInt::type()
{ {
return T(llvm::Type::getInt32Ty(jit->context)); return T(llvm::Type::getInt32Ty(*jit->context));
} }
// Int2::Int2(RValue<Int> cast) // Int2::Int2(RValue<Int> cast)
...@@ -2836,7 +2836,7 @@ Type *UInt4::type() ...@@ -2836,7 +2836,7 @@ Type *UInt4::type()
Type *Half::type() Type *Half::type()
{ {
return T(llvm::Type::getInt16Ty(jit->context)); return T(llvm::Type::getInt16Ty(*jit->context));
} }
RValue<Float> Rcp_pp(RValue<Float> x, bool exactAtPow2) RValue<Float> Rcp_pp(RValue<Float> x, bool exactAtPow2)
...@@ -3032,7 +3032,7 @@ RValue<Float> Ceil(RValue<Float> x) ...@@ -3032,7 +3032,7 @@ RValue<Float> Ceil(RValue<Float> x)
Type *Float::type() Type *Float::type()
{ {
return T(llvm::Type::getFloatTy(jit->context)); return T(llvm::Type::getFloatTy(*jit->context));
} }
Type *Float2::type() Type *Float2::type()
...@@ -3445,7 +3445,7 @@ RValue<UInt> Ctlz(RValue<UInt> v, bool isZeroUndef) ...@@ -3445,7 +3445,7 @@ RValue<UInt> Ctlz(RValue<UInt> v, bool isZeroUndef)
RR_DEBUG_INFO_UPDATE_LOC(); RR_DEBUG_INFO_UPDATE_LOC();
auto func = llvm::Intrinsic::getDeclaration(jit->module.get(), llvm::Intrinsic::ctlz, { T(UInt::type()) }); auto func = llvm::Intrinsic::getDeclaration(jit->module.get(), llvm::Intrinsic::ctlz, { T(UInt::type()) });
return RValue<UInt>(V(jit->builder->CreateCall(func, { V(v.value()), return RValue<UInt>(V(jit->builder->CreateCall(func, { V(v.value()),
isZeroUndef ? llvm::ConstantInt::getTrue(jit->context) : llvm::ConstantInt::getFalse(jit->context) }))); isZeroUndef ? llvm::ConstantInt::getTrue(*jit->context) : llvm::ConstantInt::getFalse(*jit->context) })));
} }
RValue<UInt4> Ctlz(RValue<UInt4> v, bool isZeroUndef) RValue<UInt4> Ctlz(RValue<UInt4> v, bool isZeroUndef)
...@@ -3453,7 +3453,7 @@ RValue<UInt4> Ctlz(RValue<UInt4> v, bool isZeroUndef) ...@@ -3453,7 +3453,7 @@ RValue<UInt4> Ctlz(RValue<UInt4> v, bool isZeroUndef)
RR_DEBUG_INFO_UPDATE_LOC(); RR_DEBUG_INFO_UPDATE_LOC();
auto func = llvm::Intrinsic::getDeclaration(jit->module.get(), llvm::Intrinsic::ctlz, { T(UInt4::type()) }); auto func = llvm::Intrinsic::getDeclaration(jit->module.get(), llvm::Intrinsic::ctlz, { T(UInt4::type()) });
return RValue<UInt4>(V(jit->builder->CreateCall(func, { V(v.value()), return RValue<UInt4>(V(jit->builder->CreateCall(func, { V(v.value()),
isZeroUndef ? llvm::ConstantInt::getTrue(jit->context) : llvm::ConstantInt::getFalse(jit->context) }))); isZeroUndef ? llvm::ConstantInt::getTrue(*jit->context) : llvm::ConstantInt::getFalse(*jit->context) })));
} }
RValue<UInt> Cttz(RValue<UInt> v, bool isZeroUndef) RValue<UInt> Cttz(RValue<UInt> v, bool isZeroUndef)
...@@ -3461,7 +3461,7 @@ RValue<UInt> Cttz(RValue<UInt> v, bool isZeroUndef) ...@@ -3461,7 +3461,7 @@ RValue<UInt> Cttz(RValue<UInt> v, bool isZeroUndef)
RR_DEBUG_INFO_UPDATE_LOC(); RR_DEBUG_INFO_UPDATE_LOC();
auto func = llvm::Intrinsic::getDeclaration(jit->module.get(), llvm::Intrinsic::cttz, { T(UInt::type()) }); auto func = llvm::Intrinsic::getDeclaration(jit->module.get(), llvm::Intrinsic::cttz, { T(UInt::type()) });
return RValue<UInt>(V(jit->builder->CreateCall(func, { V(v.value()), return RValue<UInt>(V(jit->builder->CreateCall(func, { V(v.value()),
isZeroUndef ? llvm::ConstantInt::getTrue(jit->context) : llvm::ConstantInt::getFalse(jit->context) }))); isZeroUndef ? llvm::ConstantInt::getTrue(*jit->context) : llvm::ConstantInt::getFalse(*jit->context) })));
} }
RValue<UInt4> Cttz(RValue<UInt4> v, bool isZeroUndef) RValue<UInt4> Cttz(RValue<UInt4> v, bool isZeroUndef)
...@@ -3469,7 +3469,7 @@ RValue<UInt4> Cttz(RValue<UInt4> v, bool isZeroUndef) ...@@ -3469,7 +3469,7 @@ RValue<UInt4> Cttz(RValue<UInt4> v, bool isZeroUndef)
RR_DEBUG_INFO_UPDATE_LOC(); RR_DEBUG_INFO_UPDATE_LOC();
auto func = llvm::Intrinsic::getDeclaration(jit->module.get(), llvm::Intrinsic::cttz, { T(UInt4::type()) }); auto func = llvm::Intrinsic::getDeclaration(jit->module.get(), llvm::Intrinsic::cttz, { T(UInt4::type()) });
return RValue<UInt4>(V(jit->builder->CreateCall(func, { V(v.value()), return RValue<UInt4>(V(jit->builder->CreateCall(func, { V(v.value()),
isZeroUndef ? llvm::ConstantInt::getTrue(jit->context) : llvm::ConstantInt::getFalse(jit->context) }))); isZeroUndef ? llvm::ConstantInt::getTrue(*jit->context) : llvm::ConstantInt::getFalse(*jit->context) })));
} }
RValue<Int> MinAtomic(RValue<Pointer<Int>> x, RValue<Int> y, std::memory_order memoryOrder) RValue<Int> MinAtomic(RValue<Pointer<Int>> x, RValue<Int> y, std::memory_order memoryOrder)
...@@ -3510,7 +3510,7 @@ RValue<Pointer<Byte>> ConstantPointer(void const *ptr) ...@@ -3510,7 +3510,7 @@ RValue<Pointer<Byte>> ConstantPointer(void const *ptr)
RR_DEBUG_INFO_UPDATE_LOC(); RR_DEBUG_INFO_UPDATE_LOC();
// Note: this should work for 32-bit pointers as well because 'inttoptr' // Note: this should work for 32-bit pointers as well because 'inttoptr'
// is defined to truncate (and zero extend) if necessary. // is defined to truncate (and zero extend) if necessary.
auto ptrAsInt = llvm::ConstantInt::get(llvm::Type::getInt64Ty(jit->context), reinterpret_cast<uintptr_t>(ptr)); auto ptrAsInt = llvm::ConstantInt::get(llvm::Type::getInt64Ty(*jit->context), reinterpret_cast<uintptr_t>(ptr));
return RValue<Pointer<Byte>>(V(jit->builder->CreateIntToPtr(ptrAsInt, T(Pointer<Byte>::type())))); return RValue<Pointer<Byte>>(V(jit->builder->CreateIntToPtr(ptrAsInt, T(Pointer<Byte>::type()))));
} }
...@@ -3923,8 +3923,8 @@ RValue<Int4> pmovsxwd(RValue<Short8> x) ...@@ -3923,8 +3923,8 @@ RValue<Int4> pmovsxwd(RValue<Short8> x)
#ifdef ENABLE_RR_PRINT #ifdef ENABLE_RR_PRINT
void VPrintf(const std::vector<Value *> &vals) void VPrintf(const std::vector<Value *> &vals)
{ {
auto i32Ty = llvm::Type::getInt32Ty(jit->context); auto i32Ty = llvm::Type::getInt32Ty(*jit->context);
auto i8PtrTy = llvm::Type::getInt8PtrTy(jit->context); auto i8PtrTy = llvm::Type::getInt8PtrTy(*jit->context);
auto funcTy = llvm::FunctionType::get(i32Ty, { i8PtrTy }, true); auto funcTy = llvm::FunctionType::get(i32Ty, { i8PtrTy }, true);
auto func = jit->module->getOrInsertFunction("rr::DebugPrintf", funcTy); auto func = jit->module->getOrInsertFunction("rr::DebugPrintf", funcTy);
jit->builder->CreateCall(func, V(vals)); jit->builder->CreateCall(func, V(vals));
...@@ -3933,7 +3933,7 @@ void VPrintf(const std::vector<Value *> &vals) ...@@ -3933,7 +3933,7 @@ void VPrintf(const std::vector<Value *> &vals)
void Nop() void Nop()
{ {
auto voidTy = llvm::Type::getVoidTy(jit->context); auto voidTy = llvm::Type::getVoidTy(*jit->context);
auto funcTy = llvm::FunctionType::get(voidTy, {}, false); auto funcTy = llvm::FunctionType::get(voidTy, {}, false);
auto func = jit->module->getOrInsertFunction("nop", funcTy); auto func = jit->module->getOrInsertFunction("nop", funcTy);
jit->builder->CreateCall(func); jit->builder->CreateCall(func);
...@@ -3989,11 +3989,11 @@ void promoteFunctionToCoroutine() ...@@ -3989,11 +3989,11 @@ void promoteFunctionToCoroutine()
ASSERT(jit->coroutine.id == nullptr); ASSERT(jit->coroutine.id == nullptr);
// Types // Types
auto voidTy = llvm::Type::getVoidTy(jit->context); auto voidTy = llvm::Type::getVoidTy(*jit->context);
auto i1Ty = llvm::Type::getInt1Ty(jit->context); auto i1Ty = llvm::Type::getInt1Ty(*jit->context);
auto i8Ty = llvm::Type::getInt8Ty(jit->context); auto i8Ty = llvm::Type::getInt8Ty(*jit->context);
auto i32Ty = llvm::Type::getInt32Ty(jit->context); auto i32Ty = llvm::Type::getInt32Ty(*jit->context);
auto i8PtrTy = llvm::Type::getInt8PtrTy(jit->context); auto i8PtrTy = llvm::Type::getInt8PtrTy(*jit->context);
auto promiseTy = jit->coroutine.yieldType; auto promiseTy = jit->coroutine.yieldType;
auto promisePtrTy = promiseTy->getPointerTo(); auto promisePtrTy = promiseTy->getPointerTo();
...@@ -4036,9 +4036,9 @@ void promoteFunctionToCoroutine() ...@@ -4036,9 +4036,9 @@ void promoteFunctionToCoroutine()
auto args = jit->coroutine.await->arg_begin(); auto args = jit->coroutine.await->arg_begin();
auto handle = args++; auto handle = args++;
auto outPtr = args++; auto outPtr = args++;
jit->builder->SetInsertPoint(llvm::BasicBlock::Create(jit->context, "co_await", jit->coroutine.await)); jit->builder->SetInsertPoint(llvm::BasicBlock::Create(*jit->context, "co_await", jit->coroutine.await));
auto doneBlock = llvm::BasicBlock::Create(jit->context, "done", jit->coroutine.await); auto doneBlock = llvm::BasicBlock::Create(*jit->context, "done", jit->coroutine.await);
auto resumeBlock = llvm::BasicBlock::Create(jit->context, "resume", jit->coroutine.await); auto resumeBlock = llvm::BasicBlock::Create(*jit->context, "resume", jit->coroutine.await);
auto done = jit->builder->CreateCall(coro_done, { handle }, "done"); auto done = jit->builder->CreateCall(coro_done, { handle }, "done");
jit->builder->CreateCondBr(done, doneBlock, resumeBlock); jit->builder->CreateCondBr(done, doneBlock, resumeBlock);
...@@ -4064,7 +4064,7 @@ void promoteFunctionToCoroutine() ...@@ -4064,7 +4064,7 @@ void promoteFunctionToCoroutine()
// //
{ {
auto handle = jit->coroutine.destroy->arg_begin(); auto handle = jit->coroutine.destroy->arg_begin();
jit->builder->SetInsertPoint(llvm::BasicBlock::Create(jit->context, "", jit->coroutine.destroy)); jit->builder->SetInsertPoint(llvm::BasicBlock::Create(*jit->context, "", jit->coroutine.destroy));
jit->builder->CreateCall(coro_destroy, { handle }); jit->builder->CreateCall(coro_destroy, { handle });
jit->builder->CreateRetVoid(); jit->builder->CreateRetVoid();
} }
...@@ -4103,12 +4103,12 @@ void promoteFunctionToCoroutine() ...@@ -4103,12 +4103,12 @@ void promoteFunctionToCoroutine()
// //
#ifdef ENABLE_RR_DEBUG_INFO #ifdef ENABLE_RR_DEBUG_INFO
jit->debugInfo = std::make_unique<rr::DebugInfo>(jit->builder.get(), &jit->context, jit->module.get(), jit->function); jit->debugInfo = std::make_unique<rr::DebugInfo>(jit->builder.get(), jit->context.get(), jit->module.get(), jit->function);
#endif // ENABLE_RR_DEBUG_INFO #endif // ENABLE_RR_DEBUG_INFO
jit->coroutine.suspendBlock = llvm::BasicBlock::Create(jit->context, "suspend", jit->function); jit->coroutine.suspendBlock = llvm::BasicBlock::Create(*jit->context, "suspend", jit->function);
jit->coroutine.endBlock = llvm::BasicBlock::Create(jit->context, "end", jit->function); jit->coroutine.endBlock = llvm::BasicBlock::Create(*jit->context, "end", jit->function);
jit->coroutine.destroyBlock = llvm::BasicBlock::Create(jit->context, "destroy", jit->function); jit->coroutine.destroyBlock = llvm::BasicBlock::Create(*jit->context, "destroy", jit->function);
jit->builder->SetInsertPoint(jit->coroutine.entryBlock, jit->coroutine.entryBlock->begin()); jit->builder->SetInsertPoint(jit->coroutine.entryBlock, jit->coroutine.entryBlock->begin());
jit->coroutine.promise = jit->builder->CreateAlloca(promiseTy, nullptr, "promise"); jit->coroutine.promise = jit->builder->CreateAlloca(promiseTy, nullptr, "promise");
...@@ -4130,7 +4130,7 @@ void promoteFunctionToCoroutine() ...@@ -4130,7 +4130,7 @@ void promoteFunctionToCoroutine()
// Build the end block // Build the end block
jit->builder->SetInsertPoint(jit->coroutine.endBlock); jit->builder->SetInsertPoint(jit->coroutine.endBlock);
auto action = jit->builder->CreateCall(coro_suspend, { auto action = jit->builder->CreateCall(coro_suspend, {
llvm::ConstantTokenNone::get(jit->context), llvm::ConstantTokenNone::get(*jit->context),
llvm::ConstantInt::get(i1Ty, 1), // final: true llvm::ConstantInt::get(i1Ty, 1), // final: true
}); });
auto switch_ = jit->builder->CreateSwitch(action, jit->coroutine.suspendBlock, 3); auto switch_ = jit->builder->CreateSwitch(action, jit->coroutine.suspendBlock, 3);
...@@ -4156,9 +4156,9 @@ void Nucleus::createCoroutine(Type *YieldType, const std::vector<Type *> &Params ...@@ -4156,9 +4156,9 @@ void Nucleus::createCoroutine(Type *YieldType, const std::vector<Type *> &Params
// Coroutines are initially created as a regular function. // Coroutines are initially created as a regular function.
// Upon the first call to Yield(), the function is promoted to a true // Upon the first call to Yield(), the function is promoted to a true
// coroutine. // coroutine.
auto voidTy = llvm::Type::getVoidTy(jit->context); auto voidTy = llvm::Type::getVoidTy(*jit->context);
auto i1Ty = llvm::Type::getInt1Ty(jit->context); auto i1Ty = llvm::Type::getInt1Ty(*jit->context);
auto i8PtrTy = llvm::Type::getInt8PtrTy(jit->context); auto i8PtrTy = llvm::Type::getInt8PtrTy(*jit->context);
auto handleTy = i8PtrTy; auto handleTy = i8PtrTy;
auto boolTy = i1Ty; auto boolTy = i1Ty;
auto promiseTy = T(YieldType); auto promiseTy = T(YieldType);
...@@ -4168,7 +4168,7 @@ void Nucleus::createCoroutine(Type *YieldType, const std::vector<Type *> &Params ...@@ -4168,7 +4168,7 @@ void Nucleus::createCoroutine(Type *YieldType, const std::vector<Type *> &Params
jit->coroutine.await = rr::createFunction("coroutine_await", boolTy, { handleTy, promisePtrTy }); jit->coroutine.await = rr::createFunction("coroutine_await", boolTy, { handleTy, promisePtrTy });
jit->coroutine.destroy = rr::createFunction("coroutine_destroy", voidTy, { handleTy }); jit->coroutine.destroy = rr::createFunction("coroutine_destroy", voidTy, { handleTy });
jit->coroutine.yieldType = promiseTy; jit->coroutine.yieldType = promiseTy;
jit->coroutine.entryBlock = llvm::BasicBlock::Create(jit->context, "function", jit->function); jit->coroutine.entryBlock = llvm::BasicBlock::Create(*jit->context, "function", jit->function);
jit->builder->SetInsertPoint(jit->coroutine.entryBlock); jit->builder->SetInsertPoint(jit->coroutine.entryBlock);
} }
...@@ -4202,19 +4202,19 @@ void Nucleus::yield(Value *val) ...@@ -4202,19 +4202,19 @@ void Nucleus::yield(Value *val)
Variable::materializeAll(); Variable::materializeAll();
// Types // Types
auto i1Ty = llvm::Type::getInt1Ty(jit->context); auto i1Ty = llvm::Type::getInt1Ty(*jit->context);
auto i8Ty = llvm::Type::getInt8Ty(jit->context); auto i8Ty = llvm::Type::getInt8Ty(*jit->context);
// Intrinsics // Intrinsics
auto coro_suspend = llvm::Intrinsic::getDeclaration(jit->module.get(), llvm::Intrinsic::coro_suspend); auto coro_suspend = llvm::Intrinsic::getDeclaration(jit->module.get(), llvm::Intrinsic::coro_suspend);
// Create a block to resume execution. // Create a block to resume execution.
auto resumeBlock = llvm::BasicBlock::Create(jit->context, "resume", jit->function); auto resumeBlock = llvm::BasicBlock::Create(*jit->context, "resume", jit->function);
// Store the promise (yield value) // Store the promise (yield value)
jit->builder->CreateStore(V(val), jit->coroutine.promise); jit->builder->CreateStore(V(val), jit->coroutine.promise);
auto action = jit->builder->CreateCall(coro_suspend, { auto action = jit->builder->CreateCall(coro_suspend, {
llvm::ConstantTokenNone::get(jit->context), llvm::ConstantTokenNone::get(*jit->context),
llvm::ConstantInt::get(i1Ty, 0), // final: true llvm::ConstantInt::get(i1Ty, 0), // final: true
}); });
auto switch_ = jit->builder->CreateSwitch(action, jit->coroutine.suspendBlock, 3); auto switch_ = jit->builder->CreateSwitch(action, jit->coroutine.suspendBlock, 3);
...@@ -4239,10 +4239,10 @@ std::shared_ptr<Routine> Nucleus::acquireCoroutine(const char *name, const Confi ...@@ -4239,10 +4239,10 @@ std::shared_ptr<Routine> Nucleus::acquireCoroutine(const char *name, const Confi
// handle. // handle.
jit->builder->CreateRet(llvm::Constant::getNullValue(jit->function->getReturnType())); jit->builder->CreateRet(llvm::Constant::getNullValue(jit->function->getReturnType()));
// The 'coroutine_await' function always returns false (coroutine done). // The 'coroutine_await' function always returns false (coroutine done).
jit->builder->SetInsertPoint(llvm::BasicBlock::Create(jit->context, "", jit->coroutine.await)); jit->builder->SetInsertPoint(llvm::BasicBlock::Create(*jit->context, "", jit->coroutine.await));
jit->builder->CreateRet(llvm::Constant::getNullValue(jit->coroutine.await->getReturnType())); jit->builder->CreateRet(llvm::Constant::getNullValue(jit->coroutine.await->getReturnType()));
// The 'coroutine_destroy' does nothing, returns void. // The 'coroutine_destroy' does nothing, returns void.
jit->builder->SetInsertPoint(llvm::BasicBlock::Create(jit->context, "", jit->coroutine.destroy)); jit->builder->SetInsertPoint(llvm::BasicBlock::Create(*jit->context, "", jit->coroutine.destroy));
jit->builder->CreateRetVoid(); jit->builder->CreateRetVoid();
} }
......
...@@ -95,7 +95,7 @@ public: ...@@ -95,7 +95,7 @@ public:
std::shared_ptr<rr::Routine> acquireRoutine(const char *name, llvm::Function **funcs, size_t count, const rr::Config &cfg); std::shared_ptr<rr::Routine> acquireRoutine(const char *name, llvm::Function **funcs, size_t count, const rr::Config &cfg);
const Config config; const Config config;
llvm::LLVMContext context; std::unique_ptr<llvm::LLVMContext> context;
std::unique_ptr<llvm::Module> module; std::unique_ptr<llvm::Module> module;
std::unique_ptr<llvm::IRBuilder<>> builder; std::unique_ptr<llvm::IRBuilder<>> builder;
llvm::Function *function = nullptr; llvm::Function *function = nullptr;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment