From 269c230fbd8ad1e524abe169af88fadc405e5056 Mon Sep 17 00:00:00 2001 From: Yang Rong Date: Wed, 20 Sep 2017 16:17:50 +0800 Subject: GBE: enable llvm5.0 support. 1. getOrInsertFunction without nullptr. 2. handle f16 rounding. 3. remove llvm value dump. 4. handle AddrSpaceCastInst when parsing block info. V2: use stripPointerCasts instead of BitCast and AddrSpaceCast. Signed-off-by: Yang Rong Reviewed-by: Ruiling Song --- backend/src/llvm/PromoteIntegers.cpp | 5 ++++ backend/src/llvm/llvm_barrier_nodup.cpp | 4 +++ backend/src/llvm/llvm_device_enqueue.cpp | 42 +++++++++++++++++--------------- backend/src/llvm/llvm_gen_backend.cpp | 41 +++++++++++++++++++++++-------- backend/src/llvm/llvm_profiling.cpp | 20 ++++++++++++--- backend/src/llvm/llvm_sampler_fix.cpp | 8 ++++++ 6 files changed, 87 insertions(+), 33 deletions(-) diff --git a/backend/src/llvm/PromoteIntegers.cpp b/backend/src/llvm/PromoteIntegers.cpp index a500311b..d433771e 100644 --- a/backend/src/llvm/PromoteIntegers.cpp +++ b/backend/src/llvm/PromoteIntegers.cpp @@ -605,8 +605,13 @@ static void convertInstruction(Instruction *Inst, ConversionState &State) { for (SwitchInst::CaseIt I = Switch->case_begin(), E = Switch->case_end(); I != E; ++I) { +#if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 50 + NewInst->addCase(cast(convertConstant(I->getCaseValue())), + I->getCaseSuccessor()); +#else NewInst->addCase(cast(convertConstant(I.getCaseValue())), I.getCaseSuccessor()); +#endif } Switch->eraseFromParent(); } else { diff --git a/backend/src/llvm/llvm_barrier_nodup.cpp b/backend/src/llvm/llvm_barrier_nodup.cpp index a7d0d1ad..b8ffdf41 100644 --- a/backend/src/llvm/llvm_barrier_nodup.cpp +++ b/backend/src/llvm/llvm_barrier_nodup.cpp @@ -74,7 +74,11 @@ namespace gbe { if (F.hasFnAttribute(Attribute::NoDuplicate)) { auto attrs = F.getAttributes(); F.setAttributes(attrs.removeAttribute(M.getContext(), +#if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 50 + AttributeList::FunctionIndex, +#else AttributeSet::FunctionIndex, +#endif Attribute::NoDuplicate)); changed = true; } diff --git a/backend/src/llvm/llvm_device_enqueue.cpp b/backend/src/llvm/llvm_device_enqueue.cpp index 9a0fb46f..58aa6817 100644 --- a/backend/src/llvm/llvm_device_enqueue.cpp +++ b/backend/src/llvm/llvm_device_enqueue.cpp @@ -29,6 +29,7 @@ namespace gbe { BitCastInst* bt = dyn_cast(I); if (bt == NULL) return NULL; +//bt->dump(); Type* type = bt->getOperand(0)->getType(); if(!type->isPointerTy()) @@ -112,7 +113,8 @@ namespace gbe { ValueToValueMapTy VMap; for (Function::arg_iterator I = Fn->arg_begin(), E = Fn->arg_end(); I != E; ++I) { PointerType *ty = dyn_cast(I->getType()); - if(ty && ty->getAddressSpace() == 0) //Foce set the address space to global + //Foce set the address space to global + if(ty && (ty->getAddressSpace() == 0 || ty->getAddressSpace() == 4)) ty = PointerType::get(ty->getPointerElementType(), 1); ParamTys.push_back(ty); } @@ -252,12 +254,13 @@ namespace gbe { if(gep == NULL) continue; - BitCastInst* fnPointer = dyn_cast(gep->getOperand(0)); - if(fnPointer == NULL) + Value *fnPointer = gep->getOperand(0)->stripPointerCasts(); + + if(fnPointer == gep->getOperand(0)) continue; - if(BitCastInst* bt = dyn_cast(fnPointer->getOperand(0))) { - std::string fnName = blocks[bt->getOperand(0)]; + if(blocks.find(fnPointer) != blocks.end()) { + std::string fnName = blocks[fnPointer]; Function* f = mod->getFunction(fnName); CallInst *newCI = builder.CreateCall(f, args); CI->replaceAllUsesWith(newCI); @@ -266,7 +269,7 @@ namespace gbe { } //the function is global variable - if(GlobalVariable* gv = dyn_cast(fnPointer->getOperand(0))) { + if(GlobalVariable* gv = dyn_cast(fnPointer)) { Constant *c = gv->getInitializer(); ConstantExpr *expr = dyn_cast(c->getOperand(3)); BitCastInst *bt = dyn_cast(expr->getAsInstruction()); @@ -277,7 +280,7 @@ namespace gbe { continue; } - ld = dyn_cast(fnPointer->getOperand(0)); + ld = dyn_cast(fnPointer); if(ld == NULL) continue; @@ -304,9 +307,7 @@ namespace gbe { User *theUser = iter->getUser(); #endif if(StoreInst *st = dyn_cast(theUser)) { - bt = dyn_cast(st->getValueOperand()); - if(bt) - v = bt->getOperand(0); + v = st->getValueOperand()->stripPointerCasts(); } } if(blocks.find(v) == blocks.end()) { @@ -339,9 +340,7 @@ namespace gbe { Type *type = CI->getArgOperand(block_index)->getType(); if(type->isIntegerTy()) block_index = 6; - Value *block = CI->getArgOperand(block_index); - while(isa(block)) - block = dyn_cast(block)->getOperand(0); + Value *block = CI->getArgOperand(block_index)->stripPointerCasts(); LoadInst *ld = dyn_cast(block); Value *v = NULL; if(ld) { @@ -353,9 +352,7 @@ namespace gbe { User *theUser = iter->getUser(); #endif if(StoreInst *st = dyn_cast(theUser)) { - BitCastInst *bt = dyn_cast(st->getValueOperand()); - if(bt) - v = bt->getOperand(0); + v = st->getValueOperand()->stripPointerCasts(); } } if(blocks.find(v) == blocks.end()) { @@ -378,15 +375,20 @@ namespace gbe { if( fn->isVarArg() ) { //enqueue function with slm, convert to __gen_enqueue_kernel_slm call //store the slm information to a alloca address. - int start = block_index + 1; + int start = block_index + 1 + 1; //the first is count, skip int count = CI->getNumArgOperands() - start; Type *intTy = IntegerType::get(mod->getContext(), 32); + Type *int64Ty = IntegerType::get(mod->getContext(), 64); AllocaInst *AI = builder.CreateAlloca(intTy, ConstantInt::get(intTy, count)); for(uint32_t i = start; i < CI->getNumArgOperands(); i++) { Value *ptr = builder.CreateGEP(AI, ConstantInt::get(intTy, i-start)); - builder.CreateStore(CI->getArgOperand(i), ptr); + Value *argSize = CI->getArgOperand(i); + if (argSize->getType() == int64Ty) { + argSize = builder.CreateTrunc(argSize, intTy); + } + builder.CreateStore(argSize, ptr); } SmallVector args(CI->op_begin(), CI->op_begin() + 3); args.push_back(CI->getArgOperand(block_index)); @@ -394,8 +396,8 @@ namespace gbe { args.push_back(AI); std::vector ParamTys; - for (Value** I = args.begin(); I != args.end(); ++I) - ParamTys.push_back((*I)->getType()); + for (Value** iter = args.begin(); iter != args.end(); ++iter) + ParamTys.push_back((*iter)->getType()); CallInst* newCI = builder.CreateCall(cast(mod->getOrInsertFunction( "__gen_enqueue_kernel_slm", FunctionType::get(intTy, ParamTys, false))), args); CI->replaceAllUsesWith(newCI); diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp index a9df6525..c552c914 100644 --- a/backend/src/llvm/llvm_gen_backend.cpp +++ b/backend/src/llvm/llvm_gen_backend.cpp @@ -740,6 +740,8 @@ namespace gbe DECL_VISIT_FN(AtomicCmpXchgInst, AtomicCmpXchgInst); #undef DECL_VISIT_FN + // Emit rounding instructions from gen native function + void emitRoundingCallInst(CallInst &I, CallSite &CS, ir::Opcode opcode); // Emit unary instructions from gen native function void emitUnaryCallInst(CallInst &I, CallSite &CS, ir::Opcode opcode, ir::Type = ir::TYPE_FLOAT); // Emit unary instructions from gen native function @@ -973,7 +975,7 @@ namespace gbe CallInst *ci = dyn_cast(theUser); pointer = ci ? ci->getArgOperand(0) : NULL; } else { - theUser->dump(); + //theUser->dump(); GBE_ASSERT(0 && "Unknown instruction operating on pointers\n"); } @@ -1121,7 +1123,7 @@ namespace gbe pointerBaseMap.insert(std::make_pair(ptr, basePhi)); return basePhi; } else { - ptr->dump(); + //ptr->dump(); GBE_ASSERT(0 && "Unhandled instruction in getPointerBase\n"); return ptr; } @@ -1202,7 +1204,7 @@ namespace gbe BtiValueMap.insert(std::make_pair(Val, btiPhi)); return btiPhi; } else { - Val->dump(); + //Val->dump(); GBE_ASSERT(0 && "Unhandled instruction in getBtiRegister\n"); return Val; } @@ -1656,7 +1658,7 @@ namespace gbe } default: { - c->dump(); + //c->dump(); NOT_IMPLEMENTED; } } @@ -1908,7 +1910,7 @@ namespace gbe ir::ImmediateIndex GenWriter::processConstantImmIndex(Constant *CPV, int32_t index) { if (dyn_cast(CPV) == NULL) return processConstantImmIndexImpl(CPV, index); - CPV->dump(); + //CPV->dump(); GBE_ASSERT(0 && "unsupported constant.\n"); return ctx.newImmediate((uint32_t)0); } @@ -4172,6 +4174,21 @@ namespace gbe }; } + void GenWriter::emitRoundingCallInst(CallInst &I, CallSite &CS, ir::Opcode opcode) { + if (I.getType()->isHalfTy()) { + const ir::Register src = this->getRegister(I.getOperand(0)); + const ir::Register srcFloat = ctx.reg(ir::FAMILY_DWORD); + const ir::Register dstFloat = ctx.reg(ir::FAMILY_DWORD); + const ir::Register dst = this->getRegister(&I); + ctx.F16TO32(ir::TYPE_FLOAT, ir::TYPE_U16, srcFloat, src); + ctx.ALU1(opcode, ir::TYPE_FLOAT, dstFloat, srcFloat); + ctx.F32TO16(ir::TYPE_U16, ir::TYPE_FLOAT, dst, dstFloat); + } else { + GBE_ASSERT(I.getType()->isFloatTy()); + this->emitUnaryCallInst(I,CS,opcode); + } + } + void GenWriter::emitUnaryCallInst(CallInst &I, CallSite &CS, ir::Opcode opcode, ir::Type type) { CallSite::arg_iterator AI = CS.arg_begin(); #if GBE_DEBUG @@ -4838,10 +4855,10 @@ namespace gbe } break; case Intrinsic::sqrt: this->emitUnaryCallInst(I,CS,ir::OP_SQR); break; - case Intrinsic::ceil: this->emitUnaryCallInst(I,CS,ir::OP_RNDU); break; - case Intrinsic::trunc: this->emitUnaryCallInst(I,CS,ir::OP_RNDZ); break; - case Intrinsic::rint: this->emitUnaryCallInst(I,CS,ir::OP_RNDE); break; - case Intrinsic::floor: this->emitUnaryCallInst(I,CS,ir::OP_RNDD); break; + case Intrinsic::ceil: this->emitRoundingCallInst(I,CS,ir::OP_RNDU); break; + case Intrinsic::trunc: this->emitRoundingCallInst(I,CS,ir::OP_RNDZ); break; + case Intrinsic::rint: this->emitRoundingCallInst(I,CS,ir::OP_RNDE); break; + case Intrinsic::floor: this->emitRoundingCallInst(I,CS,ir::OP_RNDD); break; case Intrinsic::sin: this->emitUnaryCallInst(I,CS,ir::OP_SIN); break; case Intrinsic::cos: this->emitUnaryCallInst(I,CS,ir::OP_COS); break; case Intrinsic::log2: this->emitUnaryCallInst(I,CS,ir::OP_LOG); break; @@ -5698,9 +5715,13 @@ namespace gbe case GEN_OCL_ENQUEUE_SET_NDRANGE_INFO: { GBE_ASSERT(AI != AE); + Value *dstValue; + if(I.hasStructRetAttr()) + dstValue = *AI++; + else + dstValue = &I; Value *srcValue = *AI; ++AI; - Value *dstValue = &I; regTranslator.newValueProxy(srcValue, dstValue); break; } diff --git a/backend/src/llvm/llvm_profiling.cpp b/backend/src/llvm/llvm_profiling.cpp index f7e4cc53..2d2ee119 100644 --- a/backend/src/llvm/llvm_profiling.cpp +++ b/backend/src/llvm/llvm_profiling.cpp @@ -162,12 +162,19 @@ namespace gbe /* Add the timestamp store function call. */ // __gen_ocl_store_timestamp(int nth, int type); Value *Args[2] = {ConstantInt::get(intTy, pointNum++), ConstantInt::get(intTy, profilingType)}; +#if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 50 builder->CreateCall(cast(module->getOrInsertFunction( "__gen_ocl_calc_timestamp", Type::getVoidTy(module->getContext()), IntegerType::getInt32Ty(module->getContext()), + IntegerType::getInt32Ty(module->getContext()))), + ArrayRef(Args)); +#else + builder->CreateCall(cast(module->getOrInsertFunction( + "__gen_ocl_calc_timestamp", Type::getVoidTy(module->getContext()), IntegerType::getInt32Ty(module->getContext()), - NULL)), + IntegerType::getInt32Ty(module->getContext()), nullptr)), ArrayRef(Args)); +#endif } /* We insert one store_profiling at the end of the last block to hold the place. */ llvm::Function::iterator BE = F.end(); @@ -177,12 +184,19 @@ namespace gbe builder->SetInsertPoint(&*retInst); Value *Args2[2] = {profilingBuf, ConstantInt::get(intTy, profilingType)}; +#if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 50 builder->CreateCall(cast(module->getOrInsertFunction( "__gen_ocl_store_profiling", Type::getVoidTy(module->getContext()), ptrTy, - IntegerType::getInt32Ty(module->getContext()), - NULL)), + IntegerType::getInt32Ty(module->getContext()))), ArrayRef(Args2)); +#else + builder->CreateCall(cast(module->getOrInsertFunction( + "__gen_ocl_store_profiling", Type::getVoidTy(module->getContext()), + ptrTy, + IntegerType::getInt32Ty(module->getContext()), nullptr)), + ArrayRef(Args2)); +#endif delete builder; return changed; diff --git a/backend/src/llvm/llvm_sampler_fix.cpp b/backend/src/llvm/llvm_sampler_fix.cpp index c2497558..c9ec8175 100644 --- a/backend/src/llvm/llvm_sampler_fix.cpp +++ b/backend/src/llvm/llvm_sampler_fix.cpp @@ -81,7 +81,11 @@ namespace gbe { #if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 40 Module *M = I->getParent()->getParent()->getParent(); +#if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 50 + Value* samplerCvt = M->getOrInsertFunction("__gen_ocl_sampler_to_int", i32Ty, I->getOperand(0)->getType()); +#else Value* samplerCvt = M->getOrInsertFunction("__gen_ocl_sampler_to_int", i32Ty, I->getOperand(0)->getType(), nullptr); +#endif Value *samplerVal = Builder.CreateCall(samplerCvt, {I->getOperand(0)}); #else Value *samplerVal = I->getOperand(0); @@ -119,7 +123,11 @@ namespace gbe { Builder.SetInsertPoint(I); #if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 40 Module *M = I->getParent()->getParent()->getParent(); +#if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 50 + Value* samplerCvt = M->getOrInsertFunction("__gen_ocl_sampler_to_int", i32Ty, I->getOperand(0)->getType()); +#else Value* samplerCvt = M->getOrInsertFunction("__gen_ocl_sampler_to_int", i32Ty, I->getOperand(0)->getType(), nullptr); +#endif Value *samplerVal = Builder.CreateCall(samplerCvt, {I->getOperand(0)}); #else Value *samplerVal = I->getOperand(0); -- cgit v1.2.1