From 91d4ae46f691c20251f746dcdc577aa05352f22e Mon Sep 17 00:00:00 2001 From: Evghenii Date: Mon, 6 Jan 2014 15:38:30 +0100 Subject: [PATCH] sort --fails --- ctx.cpp | 134 ++++-------------------- decl.cpp | 5 +- examples_ptx/rt/Makefile_gpu | 13 +++ func.cpp | 191 ++--------------------------------- ispc.cpp | 5 - module.cpp | 4 +- type.cpp | 2 - 7 files changed, 45 insertions(+), 309 deletions(-) create mode 100644 examples_ptx/rt/Makefile_gpu diff --git a/ctx.cpp b/ctx.cpp index b5ca392c..3c972f1c 100644 --- a/ctx.cpp +++ b/ctx.cpp @@ -3559,7 +3559,6 @@ FunctionEmitContext::LaunchInst(llvm::Value *callee, llvm::StructType *argStructType = static_cast(pt->getElementType()); - llvm::Function *falloc = m->module->getFunction("ISPCAlloc"); AssertPos(currentPos, falloc != NULL); llvm::Value *structSize = g->target->SizeOf(argStructType, bblock); @@ -3680,129 +3679,34 @@ FunctionEmitContext::LaunchInst(llvm::Value *callee, llvm::Value *ret = CallInst(flaunch, NULL, args, ""); return ret; } -#if 0 - { - if (callee == NULL) { - AssertPos(currentPos, m->errorCount > 0); - return NULL; - } - launchedTasks = true; - AssertPos(currentPos, llvm::isa(callee)); - - std::vector argTypes; - for (unsigned int i = 0; i < argVals.size(); i++) - argTypes.push_back(argVals[i]->getType()); - llvm::Type *st = llvm::StructType::get(*g->ctx, argTypes); - llvm::StructType *argStructType = static_cast(st); - llvm::Value *structSize = g->target->SizeOf(argStructType, bblock); - if (structSize->getType() != LLVMTypes::Int64Type) - structSize = ZExtInst(structSize, LLVMTypes::Int64Type, - "struct_size_to_64"); -#if 0 - { - std::string str; llvm::raw_string_ostream rso(str); llvm::formatted_raw_ostream fos(rso); - structSize->print(fos); - fos.flush(); fprintf(stderr, ">>> %s\n", str.c_str()); - } -#endif - int align = 8; - llvm::Function *falloc = m->module->getFunction("ISPCGetParamBuffer"); - AssertPos(currentPos, falloc != NULL); - std::vector allocArgs; - allocArgs.push_back(launchGroupHandlePtr); - allocArgs.push_back(LLVMInt64(align)); - allocArgs.push_back(structSize); - llvm::Value *voidmem = CallInst(falloc, NULL, allocArgs, "args_ptr"); - llvm::Value *voidi64 = PtrToIntInst(voidmem, "args_i64"); - llvm::BasicBlock* if_true = CreateBasicBlock("if_true"); - llvm::BasicBlock* if_false = CreateBasicBlock("if_false"); -// llvm::BasicBlock* bblock_bak = bblock; - - /* check if the pointer returned by ISPCGetParamBuffer is not NULL - * -------------- - * this is a workaround for not checking which laneIdx we are in, - * because ISPCGetParamBuffer will return NULL pointer for all laneIdx, except when laneIdx = 0 - * of course, if ISPCGetParamBuffer fails to get parameter buffer, the pointer for laneIdx = 0 - * will also be zero. - * This check must be added, and also rewrite the code to make it less opaque - */ - llvm::Value* cmp1 = CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_NE, voidi64, LLVMInt64(0), "cmp1"); - BranchInst(if_true, if_false, cmp1); - - bblock = if_true; - - // label_if_then block: - llvm::Type *pt = llvm::PointerType::getUnqual(st); - llvm::Value *argmem = BitCastInst(voidmem, pt); - for (unsigned int i = 0; i < argVals.size(); ++i) - { - llvm::Value *ptr = AddElementOffset(argmem, i, NULL, "funarg"); - // don't need to do masked store here, I think - StoreInst(argVals[i], ptr); - } - BranchInst(if_false); - - bblock = if_false; - - llvm::Value *fptr = BitCastInst(callee, LLVMTypes::VoidPointerType); - llvm::Function *flaunch = m->module->getFunction("ISPCLaunch"); - AssertPos(currentPos, flaunch != NULL); - std::vector args; - args.push_back(launchGroupHandlePtr); - args.push_back(fptr); - args.push_back(voidmem); - args.push_back(launchCount[0]); - args.push_back(launchCount[1]); - args.push_back(launchCount[2]); - return CallInst(flaunch, NULL, args, ""); - } -#endif } void FunctionEmitContext::SyncInst() { -#if 0 - if (g->target->getISA() != Target::NVPTX) - { -#endif - llvm::Value *launchGroupHandle = LoadInst(launchGroupHandlePtr); - llvm::Value *nullPtrValue = - llvm::Constant::getNullValue(LLVMTypes::VoidPointerType); - llvm::Value *nonNull = CmpInst(llvm::Instruction::ICmp, - llvm::CmpInst::ICMP_NE, - launchGroupHandle, nullPtrValue); - llvm::BasicBlock *bSync = CreateBasicBlock("call_sync"); - llvm::BasicBlock *bPostSync = CreateBasicBlock("post_sync"); - BranchInst(bSync, bPostSync, nonNull); + llvm::Value *launchGroupHandle = LoadInst(launchGroupHandlePtr); + llvm::Value *nullPtrValue = + llvm::Constant::getNullValue(LLVMTypes::VoidPointerType); + llvm::Value *nonNull = CmpInst(llvm::Instruction::ICmp, + llvm::CmpInst::ICMP_NE, + launchGroupHandle, nullPtrValue); + llvm::BasicBlock *bSync = CreateBasicBlock("call_sync"); + llvm::BasicBlock *bPostSync = CreateBasicBlock("post_sync"); + BranchInst(bSync, bPostSync, nonNull); - SetCurrentBasicBlock(bSync); - llvm::Function *fsync = m->module->getFunction("ISPCSync"); - if (fsync == NULL) - FATAL("Couldn't find ISPCSync declaration?!"); - CallInst(fsync, NULL, launchGroupHandle, ""); + SetCurrentBasicBlock(bSync); + llvm::Function *fsync = m->module->getFunction("ISPCSync"); + if (fsync == NULL) + FATAL("Couldn't find ISPCSync declaration?!"); + CallInst(fsync, NULL, launchGroupHandle, ""); - // zero out the handle so that if ISPCLaunch is called again in this - // function, it knows it's starting out from scratch - StoreInst(nullPtrValue, launchGroupHandlePtr); + // zero out the handle so that if ISPCLaunch is called again in this + // function, it knows it's starting out from scratch + StoreInst(nullPtrValue, launchGroupHandlePtr); - BranchInst(bPostSync); + BranchInst(bPostSync); - SetCurrentBasicBlock(bPostSync); -#if 0 - } - else - { - llvm::Value *launchGroupHandle = LoadInst(launchGroupHandlePtr); - llvm::Value *nullPtrValue = - llvm::Constant::getNullValue(LLVMTypes::VoidPointerType); - llvm::Function *fsync = m->module->getFunction("ISPCSync"); - if (fsync == NULL) - FATAL("Couldn't find ISPCSync declaration?!"); - CallInst(fsync, NULL, launchGroupHandle, ""); - StoreInst(nullPtrValue, launchGroupHandlePtr); - } -#endif + SetCurrentBasicBlock(bPostSync); } diff --git a/decl.cpp b/decl.cpp index 7c248f82..52848fbf 100644 --- a/decl.cpp +++ b/decl.cpp @@ -531,12 +531,9 @@ Declarator::InitFromType(const Type *baseType, DeclSpecs *ds) { returnType = returnType->ResolveUnboundVariability(Variability::Varying); bool isTask = ds && ((ds->typeQualifiers & TYPEQUAL_TASK) != 0); + /* evghenii: without this, PTX fails on some examples, like deferred */ if (isTask && g->target->getISA() == Target::NVPTX) - { -// ds->storageClass = SC_EXTERN_C; ds->typeQualifiers |= TYPEQUAL_UNMASKED; -// ds->typeQualifiers |= TYPEQUAL_INLINE; - } bool isExternC = ds && (ds->storageClass == SC_EXTERN_C); bool isExported = ds && ((ds->typeQualifiers & TYPEQUAL_EXPORT) != 0); diff --git a/examples_ptx/rt/Makefile_gpu b/examples_ptx/rt/Makefile_gpu new file mode 100644 index 00000000..80a4401e --- /dev/null +++ b/examples_ptx/rt/Makefile_gpu @@ -0,0 +1,13 @@ +PROG=rt +ISPC_SRC=rt.ispc +CU_SRC=rt.cu +CXX_SRC=rt.cpp rt_serial.cpp +PTXCC_REGMAX=32 + +LLVM_GPU=1 +NVVM_GPU=1 + +include ../common_gpu.mk + + + diff --git a/func.cpp b/func.cpp index 165c17ba..bff29e32 100644 --- a/func.cpp +++ b/func.cpp @@ -186,7 +186,6 @@ lCopyInTaskParameter(int i, llvm::Value *structArgPtr, const FunctionEmitContext *ctx) { // We expect the argument structure to come in as a poitner to a // structure. Confirm and figure out its type here. - const llvm::Type *structArgType = structArgPtr->getType(); Assert(llvm::isa(structArgType)); const llvm::PointerType *pt = llvm::dyn_cast(structArgType); @@ -346,173 +345,6 @@ Function::emitCode(FunctionEmitContext *ctx, llvm::Function *function, annotations->addOperand(llvm::MDNode::get(*g->ctx, av)); } } -#if 0 - if (type->isTask == true) { - // For tasks, we there should always be three parmeters: the - // pointer to the structure that holds all of the arguments, the - // thread index, and the thread count variables. - - if (g->target->getISA() != Target::NVPTX) - { - llvm::Function::arg_iterator argIter = function->arg_begin(); - llvm::Value *structParamPtr = argIter++; - // Copy the function parameter values from the structure into local - // storage - for (unsigned int i = 0; i < args.size(); ++i) - lCopyInTaskParameter(i, structParamPtr, args, ctx); - - if (type->isUnmasked == false) { - // Copy in the mask as well. - int nArgs = (int)args.size(); - // The mask is the last parameter in the argument structure - llvm::Value *ptr = ctx->AddElementOffset(structParamPtr, nArgs, NULL, - "task_struct_mask"); - llvm::Value *ptrval = ctx->LoadInst(ptr, "mask"); - ctx->SetFunctionMask(ptrval); - } - - llvm::Value *threadIndex = argIter++; - llvm::Value *threadCount = argIter++; - llvm::Value *taskIndex = argIter++; - llvm::Value *taskCount = argIter++; - llvm::Value *taskIndex0 = argIter++; - llvm::Value *taskIndex1 = argIter++; - llvm::Value *taskIndex2 = argIter++; - llvm::Value *taskCount0 = argIter++; - llvm::Value *taskCount1 = argIter++; - llvm::Value *taskCount2 = argIter++; - - // Copy threadIndex and threadCount into stack-allocated storage so - // that their symbols point to something reasonable. - threadIndexSym->storagePtr = ctx->AllocaInst(LLVMTypes::Int32Type, "threadIndex"); - ctx->StoreInst(threadIndex, threadIndexSym->storagePtr); - - threadCountSym->storagePtr = ctx->AllocaInst(LLVMTypes::Int32Type, "threadCount"); - ctx->StoreInst(threadCount, threadCountSym->storagePtr); - - // Copy taskIndex and taskCount into stack-allocated storage so - // that their symbols point to something reasonable. - taskIndexSym->storagePtr = ctx->AllocaInst(LLVMTypes::Int32Type, "taskIndex"); - ctx->StoreInst(taskIndex, taskIndexSym->storagePtr); - - taskCountSym->storagePtr = ctx->AllocaInst(LLVMTypes::Int32Type, "taskCount"); - ctx->StoreInst(taskCount, taskCountSym->storagePtr); - - /* nvptx map: - * programCount : llvm.nvvm.read.ptx.sreg.warpsize - * programIndex : llvm.ptx.read.laneid _or_ ed.ptx.sreg.tid.llvm.nvvm.read.ptx.sreg.tid.x & programCount - * taskIndex0 : llvm.nvvm.read.ptx.sreg.ctaid.x - * taskIndex1 : llvm.nvvm.read.ptx.sreg.ctaid.y - * taskIndex3 : llvm.nvvm.read.ptx.sreg.ctaid.z - * taskCount0 : llvm.nvvm.read.ptx.sreg.nctaid.x - * taskCount1 : llvm.nvvm.read.ptx.sreg.nctaid.y - * taskCount3 : llvm.nvvm.read.ptx.sreg.nctaid.z - */ - - // llvm.nvvm.read.ptx.sreg.ctaid.x - taskIndexSym0->storagePtr = ctx->AllocaInst(LLVMTypes::Int32Type, "taskIndex0"); - ctx->StoreInst(taskIndex0, taskIndexSym0->storagePtr); - // llvm.nvvm.read.ptx.sreg.ctaid.y - taskIndexSym1->storagePtr = ctx->AllocaInst(LLVMTypes::Int32Type, "taskIndex1"); - ctx->StoreInst(taskIndex1, taskIndexSym1->storagePtr); - // llvm.nvvm.read.ptx.sreg.ctaid.z - taskIndexSym2->storagePtr = ctx->AllocaInst(LLVMTypes::Int32Type, "taskIndex2"); - ctx->StoreInst(taskIndex2, taskIndexSym2->storagePtr); - - // llvm.nvvm.read.ptx.sreg.nctaid.x - taskCountSym0->storagePtr = ctx->AllocaInst(LLVMTypes::Int32Type, "taskCount0"); - ctx->StoreInst(taskCount0, taskCountSym0->storagePtr); - // llvm.nvvm.read.ptx.sreg.nctaid.y - taskCountSym1->storagePtr = ctx->AllocaInst(LLVMTypes::Int32Type, "taskCount1"); - ctx->StoreInst(taskCount1, taskCountSym1->storagePtr); - // llvm.nvvm.read.ptx.sreg.nctaid.z - taskCountSym2->storagePtr = ctx->AllocaInst(LLVMTypes::Int32Type, "taskCount2"); - ctx->StoreInst(taskCount2, taskCountSym2->storagePtr); - } - else - { - llvm::Function::arg_iterator argIter = function->arg_begin(); - for (unsigned int i = 0; i < args.size(); ++i, ++argIter) { - Symbol *sym = args[i]; - if (sym == NULL) - // anonymous function parameter - continue; - - argIter->setName(sym->name.c_str()); - - // Allocate stack storage for the parameter and emit code - // to store the its value there. - sym->storagePtr = ctx->AllocaInst(argIter->getType(), sym->name.c_str()); - ctx->StoreInst(argIter, sym->storagePtr); - ctx->EmitFunctionParameterDebugInfo(sym, i); - } - if (argIter == function->arg_end()) - { - Assert(type->isUnmasked || type->isExported); - ctx->SetFunctionMask(LLVMMaskAllOn); - } - else /* for NVPTX, function must be unmasked */ - { - assert(0); - Assert(type->isUnmasked == false); - - // Otherwise use the mask to set the entry mask value - argIter->setName("__mask"); - Assert(argIter->getType() == LLVMTypes::MaskType); - ctx->SetFunctionMask(argIter); - Assert(++argIter == function->arg_end()); - } - - if (g->target->getISA() == Target::NVPTX) - { - llvm::NamedMDNode* annotations = - m->module->getOrInsertNamedMetadata("nvvm.annotations"); - llvm::SmallVector av; - av.push_back(function); - av.push_back(llvm::MDString::get(*g->ctx, "kernel")); - av.push_back(llvm::ConstantInt::get(llvm::IntegerType::get(*g->ctx,32), 1)); - annotations->addOperand(llvm::MDNode::get(*g->ctx, av)); - } - } - } - else { - // Regular, non-task function - llvm::Function::arg_iterator argIter = function->arg_begin(); - for (unsigned int i = 0; i < args.size(); ++i, ++argIter) { - Symbol *sym = args[i]; - if (sym == NULL) - // anonymous function parameter - continue; - - argIter->setName(sym->name.c_str()); - - // Allocate stack storage for the parameter and emit code - // to store the its value there. - sym->storagePtr = ctx->AllocaInst(argIter->getType(), sym->name.c_str()); - ctx->StoreInst(argIter, sym->storagePtr); - ctx->EmitFunctionParameterDebugInfo(sym, i); - } - - // If the number of actual function arguments is equal to the - // number of declared arguments in decl->functionParams, then we - // don't have a mask parameter, so set it to be all on. This - // happens for exmaple with 'export'ed functions that the app - // calls. - if (argIter == function->arg_end()) { - Assert(type->isUnmasked || type->isExported); - ctx->SetFunctionMask(LLVMMaskAllOn); - } - else { - Assert(type->isUnmasked == false); - - // Otherwise use the mask to set the entry mask value - argIter->setName("__mask"); - Assert(argIter->getType() == LLVMTypes::MaskType); - ctx->SetFunctionMask(argIter); - Assert(++argIter == function->arg_end()); - } - } -#endif // Finally, we can generate code for the function if (code != NULL) { @@ -527,7 +359,7 @@ Function::emitCode(FunctionEmitContext *ctx, llvm::Function *function, // entire thing inside code that tests to see if the mask is all // on, all off, or mixed. If this is a simple function, then this // isn't worth the code bloat / overhead. - bool checkMask = (type->isTask == true) || + bool checkMask = (type->isTask == true && g->target->getISA() != Target::NVPTX) || ( #if defined(LLVM_3_1) (function->hasFnAttr(llvm::Attribute::AlwaysInline) == false) @@ -665,16 +497,6 @@ Function::GenerateIR() { Assert(type != NULL); if (type->isExported) { if (!type->isTask) { - if (g->target->getISA() == Target::NVPTX) - { - llvm::NamedMDNode* annotations = - m->module->getOrInsertNamedMetadata("nvvm.annotations"); - llvm::SmallVector av; - av.push_back(function); - av.push_back(llvm::MDString::get(*g->ctx, "kernel")); - av.push_back(llvm::ConstantInt::get(llvm::IntegerType::get(*g->ctx,32), 1)); - annotations->addOperand(llvm::MDNode::get(*g->ctx, av)); - } llvm::FunctionType *ftype = type->LLVMFunctionType(g->ctx, true); llvm::GlobalValue::LinkageTypes linkage = llvm::GlobalValue::ExternalLinkage; std::string functionName = sym->name; @@ -683,7 +505,16 @@ Function::GenerateIR() { functionName += std::string("_") + g->target->GetISAString(); if (g->target->getISA() == Target::NVPTX) - functionName += std::string("___export"); + { + functionName += std::string("___export"); /* add ___export to the end, for ptxcc to recognize it is exported */ + llvm::NamedMDNode* annotations = + m->module->getOrInsertNamedMetadata("nvvm.annotations"); + llvm::SmallVector av; + av.push_back(function); + av.push_back(llvm::MDString::get(*g->ctx, "kernel")); + av.push_back(llvm::ConstantInt::get(llvm::IntegerType::get(*g->ctx,32), 1)); + annotations->addOperand(llvm::MDNode::get(*g->ctx, av)); + } llvm::Function *appFunction = llvm::Function::Create(ftype, linkage, functionName.c_str(), m->module); #if defined(LLVM_3_1) diff --git a/ispc.cpp b/ispc.cpp index e0ddb061..103e9983 100644 --- a/ispc.cpp +++ b/ispc.cpp @@ -769,11 +769,6 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) : dl_string = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-" "f80:128:128-n8:16:32:64-S128-v16:16:16-v32:32:32-v4:128:128"; -#if 0 /* evghenii: this generate warrning about Module DataLayout is incompatible with .." */ - } else if (m_isa == Target::NVPTX) - { - dl_string = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-n16:32:64"; -#endif } // 3. Finally set member data diff --git a/module.cpp b/module.cpp index a745db29..38853419 100644 --- a/module.cpp +++ b/module.cpp @@ -733,8 +733,7 @@ Module::AddFunctionDeclaration(const std::string &name, if (storageClass == SC_EXTERN_C) { // Make sure the user hasn't supplied both an 'extern "C"' and a // 'task' qualifier with the function - if (functionType->isTask) - { + if (functionType->isTask) { Error(pos, "\"task\" qualifier is illegal with C-linkage extern " "function \"%s\". Ignoring this function.", name.c_str()); return; @@ -796,7 +795,6 @@ Module::AddFunctionDeclaration(const std::string &name, #else // LLVM 3.1 and 3.3+ function->addFnAttr(llvm::Attribute::AlwaysInline); #endif - /* evghenii: on PTX target the following must not be set ... why ?!? */ if (functionType->isTask && g->target->getISA() != Target::NVPTX) // This also applies transitively to members I think? #if defined(LLVM_3_1) diff --git a/type.cpp b/type.cpp index 6be852ad..95a7a4ef 100644 --- a/type.cpp +++ b/type.cpp @@ -2924,7 +2924,6 @@ FunctionType::GetReturnTypeString() const { llvm::FunctionType * FunctionType::LLVMFunctionType(llvm::LLVMContext *ctx, bool removeMask) const { - if (isTask == true) Assert(removeMask == false); @@ -2973,7 +2972,6 @@ FunctionType::LLVMFunctionType(llvm::LLVMContext *ctx, bool removeMask) const { // Otherwise we already have the types of the arguments callTypes = llvmArgTypes; - if (returnType == NULL) { Assert(m->errorCount > 0); return NULL;