diff --git a/src/tcompiler.cpp b/src/tcompiler.cpp index abf13ac6..12e8bd79 100644 --- a/src/tcompiler.cpp +++ b/src/tcompiler.cpp @@ -270,12 +270,6 @@ int terra_inittarget(lua_State *L) { TT->next_unused_id = 0; TT->ctx = new LLVMContext(); -#if LLVM_VERSION >= 150 - // Hack: This is a workaround to avoid the opaque pointer - // transition, but we will need to deal with it eventually. - // FIXME: https://github.com/terralang/terra/issues/553 - TT->ctx->setOpaquePointers(false); -#endif std::string err; const Target *TheTarget = TargetRegistry::lookupTarget(TT->Triple, err); if (!TheTarget) { @@ -1223,14 +1217,19 @@ struct CCallingConv { assert(t1->isAggregateType()); LoadInst *l = dyn_cast(src); if ((t1->isStructTy() || (t1->isArrayTy())) && l) { - // create bitcasts of src and dest address Value *addr_src = l->getOperand(0); +#if LLVM_VERSION < 150 + // create bitcasts of src and dest address unsigned as_src = addr_src->getType()->getPointerAddressSpace(); Type *t_src = Type::getInt8PtrTy(*CU->TT->ctx, as_src); unsigned as_dst = addr_dst->getType()->getPointerAddressSpace(); Type *t_dst = Type::getInt8PtrTy(*CU->TT->ctx, as_dst); Value *addr_dest = B->CreateBitCast(addr_dst, t_dst); Value *addr_source = B->CreateBitCast(addr_src, t_src); +#else + Value *addr_dest = addr_dst; + Value *addr_source = addr_src; +#endif uint64_t size = 0; MaybeAlign a1; if (t1->isStructTy()) { @@ -1312,17 +1311,26 @@ struct CCallingConv { ++ai; break; case C_AGGREGATE_REG: { +#if LLVM_VERSION < 150 unsigned as = v->getType()->getPointerAddressSpace(); Value *dest = B->CreateBitCast(v, Ptr(p->cctype, as)); EmitEntryAggReg(B, dest, p->cctype, ai); +#else + EmitEntryAggReg(B, v, p->cctype, ai); +#endif } break; case C_ARRAY_REG: { Value *scratch = CreateAlloca(B, p->cctype); - unsigned as = scratch->getType()->getPointerAddressSpace(); emitStoreAgg(B, p->cctype, &*ai, scratch); +#if LLVM_VERSION < 150 + unsigned as = scratch->getType()->getPointerAddressSpace(); Value *casted = B->CreateBitCast(scratch, Ptr(p->type->type, as)); emitStoreAgg(B, p->type->type, B->CreateLoad(p->type->type, casted), v); +#else + emitStoreAgg(B, p->type->type, B->CreateLoad(p->type->type, scratch), + v); +#endif ++ai; } break; } @@ -1343,10 +1351,14 @@ struct CCallingConv { B->CreateRetVoid(); } else if (C_AGGREGATE_REG == kind) { Value *dest = CreateAlloca(B, info->returntype.type->type); - unsigned as = dest->getType()->getPointerAddressSpace(); emitStoreAgg(B, info->returntype.type->type, result, dest); StructType *type = cast(info->returntype.cctype); +#if LLVM_VERSION < 150 + unsigned as = dest->getType()->getPointerAddressSpace(); Value *result = B->CreateBitCast(dest, Ptr(type, as)); +#else + Value *result = dest; +#endif Type *result_type = type; if (info->returntype.GetNumberOfTypesInParamList() == 1) { do { @@ -1357,10 +1369,14 @@ struct CCallingConv { B->CreateRet(B->CreateLoad(result_type, result)); } else if (C_ARRAY_REG == kind) { Value *dest = CreateAlloca(B, info->returntype.type->type); - unsigned as = dest->getType()->getPointerAddressSpace(); emitStoreAgg(B, info->returntype.type->type, result, dest); ArrayType *result_type = cast(info->returntype.cctype); +#if LLVM_VERSION < 150 + unsigned as = dest->getType()->getPointerAddressSpace(); Value *result = B->CreateBitCast(dest, Ptr(result_type, as)); +#else + Value *result = dest; +#endif B->CreateRet(B->CreateLoad(result_type, result)); } else { assert(!"unhandled return value"); @@ -1408,17 +1424,25 @@ struct CCallingConv { } break; case C_AGGREGATE_REG: { Value *scratch = CreateAlloca(B, a->type->type); - unsigned as = scratch->getType()->getPointerAddressSpace(); emitStoreAgg(B, a->type->type, actual, scratch); +#if LLVM_VERSION < 150 + unsigned as = scratch->getType()->getPointerAddressSpace(); Value *casted = B->CreateBitCast(scratch, Ptr(a->cctype, as)); EmitCallAggReg(B, casted, a->cctype, arguments); +#else + EmitCallAggReg(B, scratch, a->cctype, arguments); +#endif } break; case C_ARRAY_REG: { Value *scratch = CreateAlloca(B, a->type->type); - unsigned as = scratch->getType()->getPointerAddressSpace(); emitStoreAgg(B, a->type->type, actual, scratch); +#if LLVM_VERSION < 150 + unsigned as = scratch->getType()->getPointerAddressSpace(); Value *casted = B->CreateBitCast(scratch, Ptr(a->cctype, as)); EmitCallAggReg(B, casted, a->cctype, arguments); +#else + EmitCallAggReg(B, scratch, a->cctype, arguments); +#endif } break; default: { assert(!"unhandled argument kind"); @@ -1427,9 +1451,13 @@ struct CCallingConv { } // emit call +#if LLVM_VERSION < 150 // function pointers are stored as &int8 to avoid calling convension issues // cast it back to the real pointer type right before calling it callee = B->CreateBitCast(callee, Ptr(info.fntype)); +#else + assert(callee->getType()->isPointerTy()); +#endif CallInst *call = B->CreateCall(info.fntype, callee, arguments); // annotate call with byval and sret AttributeFnOrCall(call, &info); @@ -1444,9 +1472,13 @@ struct CCallingConv { aggregate = arguments[0]; } else if (C_AGGREGATE_REG == info.returntype.kind) { aggregate = CreateAlloca(B, info.returntype.type->type); - unsigned as = aggregate->getType()->getPointerAddressSpace(); StructType *type = cast(info.returntype.cctype); +#if LLVM_VERSION < 150 + unsigned as = aggregate->getType()->getPointerAddressSpace(); Value *casted = B->CreateBitCast(aggregate, Ptr(type, as)); +#else + Value *casted = aggregate; +#endif if (info.returntype.GetNumberOfTypesInParamList() == 1) { do { casted = CreateConstGEP2_32(B, casted, type, 0, 0); @@ -1456,10 +1488,14 @@ struct CCallingConv { B->CreateStore(call, casted); } else if (C_ARRAY_REG == info.returntype.kind) { aggregate = CreateAlloca(B, info.returntype.type->type); - unsigned as = aggregate->getType()->getPointerAddressSpace(); ArrayType *type = cast(info.returntype.cctype); +#if LLVM_VERSION < 150 + unsigned as = aggregate->getType()->getPointerAddressSpace(); Value *casted = B->CreateBitCast(aggregate, Ptr(type, as)); emitStoreAgg(B, type, call, casted); +#else + emitStoreAgg(B, type, call, aggregate); +#endif } else { assert(!"unhandled argument kind"); } @@ -2347,13 +2383,17 @@ struct FunctionEmitter { result = B->CreateInsertElement(result, v, ConstantInt::get(integerType, i)); return result; } +#if LLVM_VERSION < 150 bool isPointerToFunction(Type *t) { return t->isPointerTy() && t->getPointerElementType()->isFunctionTy(); } +#endif Value *emitStructSelect(Obj *structType, Value *structPtr, int index, Obj *entryType) { assert(structPtr->getType()->isPointerTy()); +#if LLVM_VERSION < 150 assert(structPtr->getType()->getPointerElementType()->isStructTy()); +#endif Ty->EnsureTypeIsComplete(structType); Obj layout; @@ -2377,7 +2417,11 @@ struct FunctionEmitter { // in all cases we simply bitcast cast the resulting pointer to the expected type entry.obj("type", entryType); TType *entryTType = getType(entryType); - if (entry.boolean("inunion") || isPointerToFunction(entryTType->type)) { + if (entry.boolean("inunion") +#if LLVM_VERSION < 150 + || isPointerToFunction(entryTType->type) +#endif + ) { unsigned as = addr->getType()->getPointerAddressSpace(); Type *resultType = PointerType::get(entryTType->type, as); addr = B->CreateBitCast(addr, resultType); @@ -2390,6 +2434,7 @@ struct FunctionEmitter { LoadInst *l = dyn_cast(&*value); Type *t1 = value->getType(); if ((t1->isStructTy() || t1->isArrayTy()) && l) { +#if LLVM_VERSION < 150 unsigned as_dst = addr->getType()->getPointerAddressSpace(); // create bitcasts of src and dest address Type *t_dst = Type::getInt8PtrTy(*CU->TT->ctx, as_dst); @@ -2400,6 +2445,10 @@ struct FunctionEmitter { unsigned as_src = addr_src->getType()->getPointerAddressSpace(); Type *t_src = Type::getInt8PtrTy(*CU->TT->ctx, as_src); addr_src = B->CreateBitCast(addr_src, t_src); +#else + Value *addr_dst = addr; + Value *addr_src = l->getOperand(0); +#endif uint64_t size = 0; MaybeAlign a1; if (t1->isStructTy()) { @@ -2480,6 +2529,7 @@ struct FunctionEmitter { if (T_globalvariable == global.kind("kind")) { GlobalVariable *gv = EmitGlobalVariable(CU, &global, exp->string("name")); +#if LLVM_VERSION < 150 // Clang (as of LLVM 7) changes the types of certain globals // (like arrays). Change the type back to what we expect // here so we don't cause issues downstream in the compiler. @@ -2487,11 +2537,18 @@ struct FunctionEmitter { gv, PointerType::get(typeOfValue(exp)->type, gv->getType()->getPointerAddressSpace())); +#else + return gv; +#endif } else { +#if LLVM_VERSION < 150 // functions are represented with &int8 pointers to avoid // calling convension issues, so cast the literal to this type now return B->CreateBitCast(EmitFunction(CU, &global, fstate), typeOfValue(exp)->type); +#else + return EmitFunction(CU, &global, fstate); +#endif } } break; case T_allocvar: { @@ -2619,7 +2676,11 @@ struct FunctionEmitter { lua_pop(L, 1); mapSymbol(CU->symbols, &stringvalue, str); } +#if LLVM_VERSION < 150 return B->CreateBitCast(str, pt); +#else + return str; +#endif } else { assert(!"NYI - pointer literal"); } @@ -2709,7 +2770,11 @@ struct FunctionEmitter { Value *v = emitExp(&a); if (fromT->type->isPointerTy()) { if (toT->type->isPointerTy()) { +#if LLVM_VERSION < 150 return B->CreateBitCast(v, toT->type); +#else + return v; +#endif } else { assert(toT->type->isIntegerTy()); return B->CreatePtrToInt(v, toT->type); @@ -3614,7 +3679,10 @@ static int terra_deletefunction(lua_State *L) { VERBOSE_ONLY(CU->T) { printf("... uses not empty, removing body but keeping declaration.\n"); } +#if LLVM_VERSION < 150 + // FIXME: LLVM crashes if we attempt to delete with opaque pointers enabled func->deleteBody(); +#endif VERBOSE_ONLY(CU->T) { printf("... finish delete.\n"); } fstate->func = NULL; freecompilationunit(CU); diff --git a/tests/dgemm3.t b/tests/dgemm3.t index 1260cf73..8645b553 100644 --- a/tests/dgemm3.t +++ b/tests/dgemm3.t @@ -11,7 +11,11 @@ end local function isinteger(x) return math.floor(x) == x end -llvmprefetch = terralib.intrinsic("llvm.prefetch.p0i8",{&opaque,int,int,int} -> {}) +if terralib.llvm_version < 160 then + llvmprefetch = terralib.intrinsic("llvm.prefetch.p0i8",{&opaque,int,int,int} -> {}) +else + llvmprefetch = terralib.intrinsic("llvm.prefetch.p0",{&opaque,int,int,int} -> {}) +end local function alignedload(addr) return `terralib.attrload(addr, { align = 8 }) diff --git a/tests/dgemmpaper.t b/tests/dgemmpaper.t index d4156930..0abb1e94 100644 --- a/tests/dgemmpaper.t +++ b/tests/dgemmpaper.t @@ -7,7 +7,11 @@ function symmat(typ,name,I,...) end return r end -prefetch = terralib.intrinsic("llvm.prefetch.p0i8",{&opaque,int,int,int} -> {}) +if terralib.llvm_version < 160 then + prefetch = terralib.intrinsic("llvm.prefetch.p0i8",{&opaque,int,int,int} -> {}) +else + prefetch = terralib.intrinsic("llvm.prefetch.p0",{&opaque,int,int,int} -> {}) +end function genkernel(NB, RM, RN, V,alpha) local VT = vector(double,V) diff --git a/tests/diffuse.t b/tests/diffuse.t index 169af608..71d1d9cc 100644 --- a/tests/diffuse.t +++ b/tests/diffuse.t @@ -99,7 +99,11 @@ terra diffuse(output : &float, N : int, M : int, stride : int, x : &float, x0 : end -llvmprefetch = terralib.intrinsic("llvm.prefetch.p0i8",{&opaque,int,int,int} -> {}) +if terralib.llvm_version < 160 then + llvmprefetch = terralib.intrinsic("llvm.prefetch.p0i8",{&opaque,int,int,int} -> {}) +else + llvmprefetch = terralib.intrinsic("llvm.prefetch.p0",{&opaque,int,int,int} -> {}) +end terra diffuse2(output : &float, N : int, M : int, stride : int, x : &float, x0 : &float, a : float,xi : &float) var invD = 1.f / (1 + 4.f*a) diff --git a/tests/gemm.t b/tests/gemm.t index 19c6497a..c8e696c7 100644 --- a/tests/gemm.t +++ b/tests/gemm.t @@ -13,7 +13,11 @@ end local function isinteger(x) return math.floor(x) == x end -llvmprefetch = terralib.intrinsic("llvm.prefetch.p0i8",{&opaque,int,int,int} -> {}) +if terralib.llvm_version < 160 then + llvmprefetch = terralib.intrinsic("llvm.prefetch.p0i8",{&opaque,int,int,int} -> {}) +else + llvmprefetch = terralib.intrinsic("llvm.prefetch.p0",{&opaque,int,int,int} -> {}) +end local function unalignedload(addr) return `terralib.attrload(addr, { align = alignment }) end diff --git a/tests/sgemm3.t b/tests/sgemm3.t index 7af73a5c..aa601669 100644 --- a/tests/sgemm3.t +++ b/tests/sgemm3.t @@ -9,7 +9,11 @@ function symmat(typ,name,I,...) end -llvmprefetch = terralib.intrinsic("llvm.prefetch.p0i8",{&opaque,int,int,int} -> {}) +if terralib.llvm_version < 160 then + llvmprefetch = terralib.intrinsic("llvm.prefetch.p0i8",{&opaque,int,int,int} -> {}) +else + llvmprefetch = terralib.intrinsic("llvm.prefetch.p0",{&opaque,int,int,int} -> {}) +end