From 000c2facbf58328e63418551489ce707c851a1a7 Mon Sep 17 00:00:00 2001 From: Prakalp Srivastava <psrivas2@illinois.edu> Date: Wed, 14 Jun 2017 17:42:09 -0500 Subject: [PATCH] All passes working for now for sgemm visc version --- llvm/include/llvm/SupportVISC/VISCTimer.h | 8 - .../DFG2LLVM_NVPTX/DFG2LLVM_NVPTX.cpp | 133 ++++++------ .../Transforms/DFG2LLVM_X86/DFG2LLVM_X86.cpp | 10 +- llvm/lib/Transforms/GenVISC/GenVISC.cpp | 201 ++---------------- llvm/projects/visc-rt/makefile | 2 +- llvm/projects/visc-rt/visc-rt.h | 1 - llvm/test/VISC/parboil/common/mk/visc.mk | 4 +- 7 files changed, 102 insertions(+), 257 deletions(-) diff --git a/llvm/include/llvm/SupportVISC/VISCTimer.h b/llvm/include/llvm/SupportVISC/VISCTimer.h index 826de6723e..4dbadbd34f 100644 --- a/llvm/include/llvm/SupportVISC/VISCTimer.h +++ b/llvm/include/llvm/SupportVISC/VISCTimer.h @@ -10,14 +10,6 @@ #ifndef VISC_TIMER_HEADER #define VISC_TIMER_HEADER -#include "llvm/Support/CommandLine.h" - -using namespace llvm; - -// VISC Command line option to use timer or not -// static cl::opt<bool> -// VISCTimer("visc-timers", cl::desc("Enable visc timers")); - /************************** Timer Routines ***************************/ extern "C" { diff --git a/llvm/lib/Transforms/DFG2LLVM_NVPTX/DFG2LLVM_NVPTX.cpp b/llvm/lib/Transforms/DFG2LLVM_NVPTX/DFG2LLVM_NVPTX.cpp index 7aeebaef5f..b9645c14af 100644 --- a/llvm/lib/Transforms/DFG2LLVM_NVPTX/DFG2LLVM_NVPTX.cpp +++ b/llvm/lib/Transforms/DFG2LLVM_NVPTX/DFG2LLVM_NVPTX.cpp @@ -31,12 +31,20 @@ #include "llvm-c/Core.h" #include "llvm/SupportVISC/VISCTimer.h" #include "llvm/SupportVISC/DFG2LLVM.h" +#include "llvm/SupportVISC/VISCUtils.h" + +#include "llvm/IR/IRPrintingPasses.h" +#include "llvm/IR/LegacyPassManager.h" +#include "llvm/Support/ToolOutputFile.h" +#include "llvm/IR/UseListOrder.h" + #include <sstream> using namespace llvm; using namespace builddfg; using namespace dfg2llvm; +using namespace viscUtils; // VISC Command line option to use timer or not static cl::opt<bool> @@ -177,10 +185,9 @@ private: std::string getKernelsModuleName(Module &M); void fixValueAddrspace(Value* V, unsigned addrspace); std::vector<unsigned> globalToConstantMemoryOpt(std::vector<unsigned>*, Function*); - void changeArgAddrspace(Function* F, unsigned i); - void changeArgAddrspace(Function* F, std::vector<unsigned> &Ags, unsigned i); + Function* changeArgAddrspace(Function* F, std::vector<unsigned> &Ags, unsigned i); void addCLMetadata(Function* F); - void transformFunctionToVoid(Function* F); + Function* transformFunctionToVoid(Function* F); void insertRuntimeCalls(DFInternalNode* N, Kernel* K, const Twine& FileName); // Virtual Functions @@ -920,7 +927,10 @@ void CGT_NVPTX::codeGen(DFLeafNode* N) { // (1) Parent is the top level node i.e., Root of DFG // OR // (2) Parent does not have multiple instances + errs() << "pLevel = " << pLevel << "\n"; + errs() << "pReplFactor = " << pReplFactor << "\n"; if (!pLevel || !pReplFactor) { + errs() << "*************** Kernel Gen: 1-Level Hierarchy **************\n"; KernelLaunchNode = PNode; kernel = new Kernel(NULL, N, @@ -932,7 +942,7 @@ void CGT_NVPTX::codeGen(DFLeafNode* N) { } else { // Converting a 2-level DFG to opencl kernel - DEBUG(errs() << "*************** Kernel Gen: 2-Level Hierarchy **************\n"); + errs() << "*************** Kernel Gen: 2-Level Hierarchy **************\n"; KernelLaunchNode = PNode->getParent(); assert((PNode->getNumOfDim() == N->getNumOfDim()) && "Dimension number must match"); // Contains the instructions generating the kernel configuration parameters @@ -958,33 +968,37 @@ void CGT_NVPTX::codeGen(DFLeafNode* N) { // get the cloned function pointer from DFNode. Otherwise, create the cloned // function and add it to the DFNode GenFunc. Function *F_nvptx = N->getGenFunc(); - if(F_nvptx == NULL) { - // Clone the function - ValueToValueMapTy VMap; - F_nvptx = CloneFunction(F, VMap); - F_nvptx->removeFromParent(); + assert(F_nvptx == NULL && "Error: Visiting a node for which code already generated"); + // Clone the function + ValueToValueMapTy VMap; + Twine FName = F->getName(); + F_nvptx = CloneFunction(F, VMap); + F_nvptx->setName(FName+"_nvptx"); + errs() << "Old Function Name: " << F->getName() << "\n"; + errs() << "New Function Name: " << F_nvptx->getName() << "\n"; + F_nvptx->removeFromParent(); - // Insert the cloned function into the kernels module - KernelM.getFunctionList().push_back(F_nvptx); - //TODO: Iterate over all the instructions of F_nvptx and identify the - //callees and clone them into this module. - DEBUG(errs() << *F_nvptx->getType()); - DEBUG(errs() << *F_nvptx); + // Insert the cloned function into the kernels module + KernelM.getFunctionList().push_back(F_nvptx); - //Add generated function info to DFNode - N->setGenFunc(F_nvptx, visc::GPU_TARGET); - } else { - errs() << "WARNING: Visiting a node for which code already generated!\n"; - } + + //TODO: Iterate over all the instructions of F_nvptx and identify the + //callees and clone them into this module. + DEBUG(errs() << *F_nvptx->getType()); + DEBUG(errs() << *F_nvptx); // Transform the function to void and remove all target dependent attributes // from the function - transformFunctionToVoid(F_nvptx); + F_nvptx = transformFunctionToVoid(F_nvptx); + + //Add generated function info to DFNode + N->setGenFunc(F_nvptx, visc::GPU_TARGET); + DEBUG(errs() << "Removing all attributes from Kernel Function and adding nounwind\n"); F_nvptx->removeAttributes(AttributeSet::FunctionIndex, F_nvptx->getAttributes().getFnAttributes()); F_nvptx->addAttribute(AttributeSet::FunctionIndex, Attribute::NoUnwind); @@ -1077,9 +1091,9 @@ void CGT_NVPTX::codeGen(DFLeafNode* N) { // constant memory, subject to size of course std::vector<unsigned> ConstantMemArgs = globalToConstantMemoryOpt(&GlobalMemArgs, F_nvptx); - changeArgAddrspace(F_nvptx, ConstantMemArgs, CONSTANT_ADDRSPACE); - changeArgAddrspace(F_nvptx, SharedMemArgs, SHARED_ADDRSPACE); - changeArgAddrspace(F_nvptx, GlobalMemArgs, GLOBAL_ADDRSPACE); + F_nvptx = changeArgAddrspace(F_nvptx, ConstantMemArgs, CONSTANT_ADDRSPACE); + F_nvptx = changeArgAddrspace(F_nvptx, SharedMemArgs, SHARED_ADDRSPACE); + F_nvptx = changeArgAddrspace(F_nvptx, GlobalMemArgs, GLOBAL_ADDRSPACE); // Go through all the instructions @@ -1130,7 +1144,6 @@ void CGT_NVPTX::codeGen(DFLeafNode* N) { ArgDFNode = Leaf_HandleToDFNodeMap[ArgII]; int numOfDim = ArgDFNode->getNumOfDim(); DEBUG(errs() << "\t Got node dimension : " << numOfDim << "\n"); -// IntegerType* IntTy = Type::getInt32Ty(KernelM.getContext()); IntegerType* IntTy = Type::getInt32Ty(KernelM.getContext()); ConstantInt* numOfDimConstant = ConstantInt::getSigned(IntTy, (int64_t) numOfDim); @@ -1534,25 +1547,7 @@ std::vector<unsigned> CGT_NVPTX::globalToConstantMemoryOpt(std::vector<unsigned> return ConstantMemArgs; } -void CGT_NVPTX::changeArgAddrspace(Function* F, unsigned addrspace) { - std::vector<Type*> ArgTypes; - for(auto& arg: F->getArgumentList()) { - DEBUG(errs() << arg << "\n"); - if(PointerType* argTy = dyn_cast<PointerType>(arg.getType())) { - if(argTy->getAddressSpace() == 0) { - fixValueAddrspace(&arg, addrspace); - } - } - ArgTypes.push_back(arg.getType()); - } - FunctionType* FTy = FunctionType::get(F->getReturnType(), ArgTypes, false); - PointerType* PTy = FTy->getPointerTo(cast<PointerType>(F->getType())->getAddressSpace()); - - F->mutateType(PTy); - DEBUG(errs() << *F->getFunctionType() << "\n" <<*F << "\n"); -} - -void CGT_NVPTX::changeArgAddrspace(Function* F, std::vector<unsigned> &Args, unsigned addrspace) { +Function* CGT_NVPTX::changeArgAddrspace(Function* F, std::vector<unsigned> &Args, unsigned addrspace) { unsigned idx = 0; std::vector<Type*> ArgTypes; for(auto& arg: F->getArgumentList()) { @@ -1564,11 +1559,14 @@ void CGT_NVPTX::changeArgAddrspace(Function* F, std::vector<unsigned> &Args, uns } ArgTypes.push_back(arg.getType()); } - FunctionType* FTy = FunctionType::get(F->getReturnType(), ArgTypes, false); - PointerType* PTy = FTy->getPointerTo(cast<PointerType>(F->getType())->getAddressSpace()); + FunctionType* newFT = FunctionType::get(F->getReturnType(), ArgTypes, false); + + //F->mutateType(PTy); + Function* newF = cloneFunction(F, newFT, false); + replaceNodeFunctionInIR(*F->getParent(), F, newF); - F->mutateType(PTy); - DEBUG(errs() << *F->getFunctionType() << "\n" <<*F << "\n"); + DEBUG(errs() << *newF->getFunctionType() << "\n" <<*newF << "\n"); + return newF; } /* Add metadata to module KernelM, for OpenCL kernels */ @@ -1599,20 +1597,28 @@ void CGT_NVPTX::addCLMetadata(Function *F) { void CGT_NVPTX::writeKernelsModule() { - char* ErrorMessage = NULL; - LLVMModuleRef KernelMRef = wrap(&KernelM); + // In addition to deleting all other functions, we also want to spiff it + // up a little bit. Do this now. + legacy::PassManager Passes; + errs() << "Writing to File --- "; errs() << getKernelsModuleName(M).c_str() << "\n"; - LLVMPrintModuleToFile(KernelMRef, - getKernelsModuleName(M).c_str(), - &ErrorMessage); - if (ErrorMessage) { - LLVMDisposeMessage(ErrorMessage); + std::error_code EC; + tool_output_file Out(getKernelsModuleName(M).c_str(), EC, sys::fs::F_None); + if (EC) { + errs() << EC.message() << '\n'; } - LLVMDisposeModule(KernelMRef); + + Passes.add( + createPrintModulePass(Out.os())); + + Passes.run(KernelM); + + // Declare success. + Out.keep(); } -void CGT_NVPTX::transformFunctionToVoid(Function* F) { +Function* CGT_NVPTX::transformFunctionToVoid(Function* F) { DEBUG(errs() << "Transforming function to void: " << F->getName() << "\n"); // FIXME: Maybe do that using the Node? @@ -1685,11 +1691,14 @@ void CGT_NVPTX::transformFunctionToVoid(Function* F) { // function type. We need to change the type of this function to reflect the // added arguments Type* VoidRetType = Type::getVoidTy(F->getContext()); - FunctionType* FTy = FunctionType::get(VoidRetType, ArgTypes, F->isVarArg()); - PointerType* PTy = PointerType::get(FTy, cast<PointerType>(F->getType())->getAddressSpace()); + FunctionType* newFT = FunctionType::get(VoidRetType, ArgTypes, F->isVarArg()); // Change the function type - F->mutateType(PTy); + //F->mutateType(PTy); + Function* newF = cloneFunction(F, newFT, false); + replaceNodeFunctionInIR(*F->getParent(), F, newF); + //F->eraseFromParent(); + return newF; } /****************************************************************************** @@ -1917,8 +1926,8 @@ static std::string getFilenameFromModule(const Module& M) { // Changes the data layout of the Module to be compiled with NVPTX backend // TODO: Figure out when to call it, probably after duplicating the modules static void changeDataLayout(Module &M) { - std::string nvptx32_layoutStr = "e-p:32:32:32-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"; - std::string nvptx64_layoutStr = "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"; + std::string nvptx32_layoutStr = "e-p:32:32-i64:64-v16:16-v32:32-n16:32:64"; + std::string nvptx64_layoutStr = "e-i64:64-v16:16-v32:32-n16:32:64"; if (TARGET_PTX == 32) M.setDataLayout(StringRef(nvptx32_layoutStr)); diff --git a/llvm/lib/Transforms/DFG2LLVM_X86/DFG2LLVM_X86.cpp b/llvm/lib/Transforms/DFG2LLVM_X86/DFG2LLVM_X86.cpp index 88b464342c..6da326f701 100644 --- a/llvm/lib/Transforms/DFG2LLVM_X86/DFG2LLVM_X86.cpp +++ b/llvm/lib/Transforms/DFG2LLVM_X86/DFG2LLVM_X86.cpp @@ -163,7 +163,7 @@ void CGT_X86::initRuntimeAPI() { assert(LLVM_SRC_ROOT != NULL && "Define LLVM_SRC_ROOT environment variable!"); Twine llvmSrcRoot = LLVM_SRC_ROOT; - Twine runtimeAPI = llvmSrcRoot+"/projects/visc-rt/visc-rt.ll"; + Twine runtimeAPI = llvmSrcRoot+"/../build/projects/visc-rt/visc-rt.ll"; runtimeModule = parseIRFile(runtimeAPI.str(), Err, M.getContext()); @@ -201,7 +201,7 @@ void CGT_X86::initRuntimeAPI() { Function* VI = M.getFunction("llvm.visc.init"); assert(VI->getNumUses() == 1 && "__visc__init should only be used once"); DEBUG(errs() << "Inserting x86 timer initialization\n"); - Instruction* I = cast<Instruction>(*VI->use_begin()); + Instruction* I = cast<Instruction>(*VI->user_begin()); initializeTimerSet(I); switchToTimer(visc_TimerID_NONE, I); @@ -210,7 +210,7 @@ void CGT_X86::initRuntimeAPI() { assert(VC->getNumUses() == 1 && "__visc__cleanup should only be used once"); DEBUG(errs() << "Inserting x86 timer print\n"); - I = cast<Instruction>(*VC->use_begin()); + I = cast<Instruction>(*VC->user_begin()); printTimerSet(I); } @@ -220,8 +220,8 @@ void CGT_X86::initRuntimeAPI() { std::vector<IntrinsicInst*>* CGT_X86::getUseList(Value* GraphID) { std::vector<IntrinsicInst*>* UseList = new std::vector<IntrinsicInst*>(); // It must have been loaded from memory somewhere - for(Value::use_iterator ui = GraphID->use_begin(), - ue = GraphID->use_end(); ui!=ue; ++ui) { + for(Value::user_iterator ui = GraphID->user_begin(), + ue = GraphID->user_end(); ui!=ue; ++ui) { if(IntrinsicInst* waitI = dyn_cast<IntrinsicInst>(*ui)) { UseList->push_back(waitI); } diff --git a/llvm/lib/Transforms/GenVISC/GenVISC.cpp b/llvm/lib/Transforms/GenVISC/GenVISC.cpp index 7a5d8646e5..3858684e10 100644 --- a/llvm/lib/Transforms/GenVISC/GenVISC.cpp +++ b/llvm/lib/Transforms/GenVISC/GenVISC.cpp @@ -23,10 +23,13 @@ #include "llvm/Transforms/Utils/ValueMapper.h" #include "llvm/IR/Instructions.h" #include "llvm/Transforms/Utils/Cloning.h" +#include "llvm/SupportVISC/VISCUtils.h" + #define TIMER(X) do { if (VISCTimer) { X; } } while (0) using namespace llvm; +using namespace viscUtils; // VISC Command line option to use timer or not @@ -39,7 +42,6 @@ namespace genvisc { static inline ConstantInt* getTimerID(Module&, enum visc_TimerID); static Function* transformReturnTypeToStruct(Function* F); -static void replaceNodeFunctionInIR(Module &M, Function* F, Function* G); // Check if the dummy function call is a __visc__node call #define IS_VISC_CALL(callName) \ @@ -165,73 +167,7 @@ static unsigned getNumericValue(Value* V) { return cast<ConstantInt>(V)->getZExtValue(); } -// Create new function F' as a copy of old function F with a new signature. -// The following two most used cases are handled by this function. -// 1. When some extra arguments need to be added to this function -// - Here we can map the old function arguments to -// new ones -// 2. When each pointer argument needs an additional size argument -// - Here, in the absence of VMap, we map the arguments in order, skipping -// over extra pointer arguments. -// The function returns the list of return instructions to the caller to fix in -// case the return type is also changed. -static Function* cloneFunction(Function* F, FunctionType* newFT, bool - isAddingPtrSizeArg, SmallVectorImpl<ReturnInst*>* Returns = NULL) { - - errs() << "Cloning Function: " << F->getName() << "\n"; - errs() << "Old Function Type: " << *F->getFunctionType() << "\n"; - errs() << "Old Function Type: " << *F->getFunctionType() << "\n"; - errs() << "New Function Type: " << *newFT << "\n"; - - assert(F->getFunctionType()->getNumParams() <= newFT->getNumParams() - && "This function assumes that the new function has more arguments than the old function!"); - - // Create Function of specified type - Function* newF = Function::Create(newFT, F->getLinkage(), F->getName()+"_cloned", F->getParent()); - ValueToValueMapTy VMap; - errs() << "No value map provided. Creating default value map\n"; - errs() << "Old Function Type: " << *F->getType() << "\n"; - errs() << "New Function Type: " << *newF->getType() << "\n"; - if(isAddingPtrSizeArg) { - errs() << "Case 1: Pointer arg followed by a i64 size argument in new function\n"; - Function::arg_iterator new_ai = newF->arg_begin(); - for(Function::arg_iterator ai = F->arg_begin(), ae = F->arg_end(); - ai != ae; ++ai) { - errs() << ai->getArgNo() << ". " << *ai << " : " << *new_ai << "\n"; - assert(ai->getType() == new_ai->getType() && "Arguments type do not match!"); - VMap[&*ai] = &*new_ai; - new_ai->takeName(&*ai); - if(ai->getType()->isPointerTy()) { - std::string oldName = new_ai->getName(); - // If the current argument is pointer type, the next argument in new - // function would be an i64 type containing the data size of this - // argument. Hence, skip the next arguement in new function. - ++new_ai; - new_ai->setName("bytes_"+oldName); - } - ++new_ai; - } - } - else { - errs() << "Case 2: Extra arguments are added at the end of old function\n"; - Function::arg_iterator new_ai = newF->arg_begin(); - for(Function::arg_iterator ai = F->arg_begin(), ae = F->arg_end(); - ai != ae; ++ai, ++new_ai) { - errs() << ai->getArgNo() << ". " << *ai << " : " << *new_ai << "\n"; - assert(ai->getType() == new_ai->getType() && "Arguments type do not match!"); - VMap[&*ai] = &*new_ai; - new_ai->takeName(&*ai); - } - } - // Clone function - if (Returns == NULL) - Returns = new SmallVector<ReturnInst*, 8>(); - CloneFunctionInto(newF, F, VMap, false, *Returns); - errs() << *newF << "\n"; - - return newF; -} // Add <numArgs> to the argument list of Function <F>. The names for these arguments // should be put in the string array <names>. Ideally the length of <names> @@ -309,7 +245,7 @@ static Value* genCodeForReturn(CallInst* CI) { static void addHint(Function* F, visc::Target T) { // Get Module Module* M = F->getParent(); - DEBUG(errs() << "Set preferred target for " << F->getName() << ": " << T << "\n"); + DEBUG(errs() << "Set preferred target for " << F->getName() << ": "); //assert(isa<ConstantInt>(CI->getArgOperand(0)) //&& "Argument to hint must be constant integer!"); @@ -319,12 +255,15 @@ static void addHint(Function* F, visc::Target T) { NamedMDNode* HintNode; switch (T) { case visc::GPU_TARGET: + DEBUG(errs() << "GPU Target\n"); HintNode = M->getOrInsertNamedMetadata("visc_hint_gpu"); break; case visc::SPIR_TARGET: + DEBUG(errs() << "SPIR Target\n"); HintNode = M->getOrInsertNamedMetadata("visc_hint_spir"); break; case visc::CPU_TARGET: + DEBUG(errs() << "CPU Target\n"); HintNode = M->getOrInsertNamedMetadata("visc_hint_cpu"); break; default: @@ -1174,16 +1113,19 @@ bool GenVISC::runOnModule(Module &M) { TyList.insert(TyList.begin()+destpos, ChildReturnTy->getElementType(srcpos)); StructType* NewReturnTy = StructType::create(Ctx, TyList, ReturnStructTy->getName(), true); - // Create the argument type list with added argument types - std::vector<Type*> ArgTypes; - for(Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end(); - ai != ae; ++ai) { - ArgTypes.push_back(ai->getType()); - } - - FunctionType* FTy = FunctionType::get(NewReturnTy, ArgTypes, F->isVarArg()); - PointerType* PTy = FTy->getPointerTo(); - F->mutateType(PTy); + // Create the argument type list with added argument types + std::vector<Type*> ArgTypes; + for(Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end(); + ai != ae; ++ai) { + ArgTypes.push_back(ai->getType()); + } + + FunctionType* FTy = FunctionType::get(NewReturnTy, ArgTypes, F->isVarArg()); + PointerType* PTy = FTy->getPointerTo(); + F->mutateType(PTy); + + errs() << "Function Type: " << *F->getType() << "\n"; + errs() << "Function Type: " << *F->getFunctionType() << "\n"; // This is certainly an internal node, and hence just one BB with one // return terminator instruction. Change return statement ReturnInst* RI = cast<ReturnInst>(F->getEntryBlock().getTerminator()); @@ -1232,7 +1174,9 @@ bool GenVISC::runOnModule(Module &M) { FunctionType* FTy = FunctionType::get(ReturnVal->getType(), ArgTypes, F->isVarArg()); PointerType* PTy = FTy->getPointerTo(); F->mutateType(PTy); - DEBUG(errs() << "\tNew Function Type: " << *F->getType() << "\n"); + errs() << "\tNew Function Type: " << *F->getType() << "\n"; + errs() << "\tNew Function Type: " << *F->getFunctionType() << "\n"; + errs() << "\tNew Function Type: " << *F->getReturnType() << "\n"; } @@ -1615,106 +1559,7 @@ static Function* transformReturnTypeToStruct(Function* F) { return newF; } -static bool isViscCreateNodeIntrinsic(Instruction* I) { - if(!isa<IntrinsicInst>(I)) - return false; - IntrinsicInst* II = cast<IntrinsicInst>(I); - return (II->getCalledFunction()->getName()).startswith("llvm.visc.createNode"); -} - -// Creates a new createNode intrinsic, similar to II but with different -// associated function F instead -IntrinsicInst* createIdenticalCreateNodeWithDifferentFunction(Function* F, - IntrinsicInst* II) { - Module* M = F->getParent(); - - // Find which createNode intrinsic we need to create - Function* CreateNodeF = Intrinsic::getDeclaration(M, II->getIntrinsicID()); - Constant* Fp = ConstantExpr::getPointerCast(F, - Type::getInt8PtrTy(II->getContext())); - - ArrayRef<Value*> CreateNodeArgs; - switch (II->getIntrinsicID()) { - case Intrinsic::visc_createNode: - { - CreateNodeArgs = ArrayRef<Value*>(Fp); - break; - } - case Intrinsic::visc_createNode1D: - { - Value* CreateNode1DArgs[] = {Fp, II->getArgOperand(1)}; - CreateNodeArgs = ArrayRef<Value*>(CreateNode1DArgs, 2); - break; - } - case Intrinsic::visc_createNode2D: - { - Value* CreateNode2DArgs[] = {Fp, II->getArgOperand(1), - II->getArgOperand(2)}; - CreateNodeArgs = ArrayRef<Value*>(CreateNode2DArgs, 3); - break; - } - case Intrinsic::visc_createNode3D: - { - Value* CreateNode3DArgs[] = {Fp, II->getArgOperand(1), - II->getArgOperand(2), - II->getArgOperand(3)}; - CreateNodeArgs = ArrayRef<Value*>(CreateNode3DArgs, 4); - break; - } - default : - assert(false && "Unknown createNode intrinsic"); - break; - } - - CallInst* CI = CallInst::Create(CreateNodeF, - CreateNodeArgs, - F->getName()+".node"); - IntrinsicInst* CreateNodeII = cast<IntrinsicInst>(CI); - return CreateNodeII; -} - -// Assuming that the changed function is a node function, it is only used as a -// first operand of createNode*. It is enough to iterate through all createNode* -// calls in the program. -static void replaceNodeFunctionInIR(Module &M, Function* F, Function* G) { - - for (Module::iterator mi = M.begin(), me = M.end(); mi != me; ++mi) { - Function* f = &*mi; - DEBUG(errs() << "Function: " << f->getName() << "\n"); - - std::vector<Instruction*> toBeErased; - for (inst_iterator i = inst_begin(f), e = inst_end(f); i != e ; ++i) { - Instruction* I = &*i; // Grab pointer to Instruction - - if (isViscCreateNodeIntrinsic(I)) { - IntrinsicInst* II = cast<IntrinsicInst>(I); - // The found createNode is not associated with the changed function - if (II->getArgOperand(0) != F) - continue; // skip it - - // Otherwise, create a new createNode similar to the other one, - // but with the changed function as first operand. - IntrinsicInst* CreateNodeII = - createIdenticalCreateNodeWithDifferentFunction(G, II); - II->replaceAllUsesWith(CreateNodeII); - toBeErased.push_back(II); - } - } - - for(auto I: toBeErased) { - DEBUG(errs() << "\tErasing " << *I << "\n"); - I->eraseFromParent(); - } - } - - DEBUG(errs() << "DONE: Replacing function " << F->getName() << " with " << G->getName() << "\n"); - - // Remove replaced function from the module - F->replaceAllUsesWith(UndefValue::get(F->getType())); - F->eraseFromParent(); - -} char genvisc::GenVISC::ID = 0; static RegisterPass<genvisc::GenVISC> X("genvisc", "Pass to generate VISC IR from LLVM IR (with dummy function calls)", false, false); diff --git a/llvm/projects/visc-rt/makefile b/llvm/projects/visc-rt/makefile index 1e4a2f285c..b621292c3b 100644 --- a/llvm/projects/visc-rt/makefile +++ b/llvm/projects/visc-rt/makefile @@ -1,4 +1,4 @@ -LLVM_SRC_ROOT = ../../.. +LLVM_SRC_ROOT = ../../../llvm LLVM_BUILD_ROOT = ../.. OPENCL_INC_PATH = /opt/intel/opencl-sdk/include diff --git a/llvm/projects/visc-rt/visc-rt.h b/llvm/projects/visc-rt/visc-rt.h index a5fd214194..00e270d002 100644 --- a/llvm/projects/visc-rt/visc-rt.h +++ b/llvm/projects/visc-rt/visc-rt.h @@ -13,7 +13,6 @@ #include <string> //#include <condition_variable> -#include "llvm/Support/CommandLine.h" #include "llvm/SupportVISC/VISCHint.h" #include "llvm/SupportVISC/VISCTimer.h" diff --git a/llvm/test/VISC/parboil/common/mk/visc.mk b/llvm/test/VISC/parboil/common/mk/visc.mk index f2e6dfb33b..e3b541378d 100755 --- a/llvm/test/VISC/parboil/common/mk/visc.mk +++ b/llvm/test/VISC/parboil/common/mk/visc.mk @@ -10,8 +10,8 @@ CXXFLAGS=$(LANG_CXXFLAGS) $(PLATFORM_CXXFLAGS) $(APP_CXXFLAGS) LDFLAGS=$(LANG_LDFLAGS) $(PLATFORM_LDFLAGS) $(APP_LDFLAGS) # VISC -LIBCLC_LIB_PATH = $(LLVM_SRC_ROOT)/../libclc/built_libs -VISC_RT_PATH = $(LLVM_SRC_ROOT)/projects/visc-rt +LIBCLC_LIB_PATH = $(LLVM_SRC_ROOT)/../../libclc-install/lib/clc +VISC_RT_PATH = $(LLVM_SRC_ROOT)/../build/projects/visc-rt VISC_RT_LIB = $(VISC_RT_PATH)/visc-rt.ll LIBCLC_NVPTX_LIB = $(LIBCLC_LIB_PATH)/nvptx--nvidiacl.bc -- GitLab