From 9035cd08290cfd63a57d0860abea9a857d8ddab9 Mon Sep 17 00:00:00 2001 From: Maria Kotsifakou <kotsifa2@illinois.edu> Date: Mon, 14 Oct 2019 13:20:21 -0500 Subject: [PATCH] Minor edits to Wrapper API pass --- .../DFG2LLVM_WrapperAPI.cpp | 103 ++++++++++++++---- 1 file changed, 79 insertions(+), 24 deletions(-) diff --git a/llvm/lib/Transforms/DFG2LLVM_WrapperAPI/DFG2LLVM_WrapperAPI.cpp b/llvm/lib/Transforms/DFG2LLVM_WrapperAPI/DFG2LLVM_WrapperAPI.cpp index 3366141512..7ea0c1dce2 100644 --- a/llvm/lib/Transforms/DFG2LLVM_WrapperAPI/DFG2LLVM_WrapperAPI.cpp +++ b/llvm/lib/Transforms/DFG2LLVM_WrapperAPI/DFG2LLVM_WrapperAPI.cpp @@ -869,7 +869,7 @@ errs() << "TensorII: " << *TensorII << "\n"; case Intrinsic::visc_tensor_batchnorm: { /* llvm.hpvm.tensor.batchnorm */ - // Tensor batchnorm is in place. + // Tensor batchnorm is not in place. // FIXME: Add Check for InPlace Analysis DEBUG(errs() << F->getName() << "\t: Handling tensor batch normalization \n"); @@ -1122,7 +1122,62 @@ errs() << "TensorII: " << *TensorII << "\n"; TensorII->replaceAllUsesWith(TensorII->getOperand(0)); } break; +/* + case Intrinsic::visc_image_fft_transform: + { // llvm.hpvm.image.fft.transform - Or another image intrinsic + // All will be treated as not in place + DEBUG(errs() << F->getName() << "\t: Handling fft transform \n"); + // Create argument list for the runtime call - stored in Args + + // All interfaces will have a string as first argument, which will be + // used to identify the dataflow node at runtime + // Create string for node name, as first argument for wrapper API call + Constant *ConstArray = ConstantDataArray::getString(M->getContext(), + strRef, true); + GlobalVariable *GV = new GlobalVariable(*M,ConstArray->getType(), + true, GlobalValue::ExternalLinkage, ConstArray, ""); + // Create GEP expression to access it + Constant* Int_0 = ConstantInt::get(Type::getInt32Ty(M->getContext()), 0); + Constant* GEPIndices[] = { Int_0, Int_0 }; + Constant* GEPConst = + ConstantExpr::getGetElementPtr(GV->getType()->getPointerElementType(), + GV, GEPIndices); + + Args.push_back(GEPConst); + + // Here, use you will access the appropriate arruments of the intrinsic + // and push_back, in order to create the argument list of runtime call + Args.push_back(TensorII->getOperand(0)); + Args.push_back(TensorII->getOperand(1)); + Args.push_back(TensorII->getOperand(2)); + Args.push_back(TensorII->getOperand(3)); + Args.push_back(TensorII->getOperand(4)); + Args.push_back(TensorII->getOperand(5)); + + Constant *conv_mode = ConstantInt::get(Type::getInt32Ty(M->getContext()), 1); + Args.push_back(conv_mode); + + Args.push_back(TensorII->getOperand(7)); + + // Done with argument list. + + // Create wrapper API runtime function call + // Appropriately set the name of the function of the runtime that you + // want to call + // Note: the Constant * is what we need to pass to the callInst. + // This name does not have to match, but does so for similarity. + Constant* wrapper_tensorGroupConvolution; + M->getOrInsertFunction(StringRef("wrapper_tensorGroupConvolution"), + RtM->getFunction(StringRef("wrapper_tensorGroupConvolution"))->getFunctionType()); + CallInst* CI = CallInst::Create(wrapper_tensorGroupConvolution, + Args, "", TensorII); + // We can replace the call to hpvm.tensor.xxx with the runtime call + TensorII->replaceAllUsesWith(CI); + } + break; + +*/ default: llvm_unreachable("Unknown VISC Intrinsic!"); break; @@ -1162,7 +1217,7 @@ public: }; // Visitor for Code generation traversal (tree traversal for now) -class CGT_PROMISE : public CodeGenTraversal { +class CGT_WrapperAPI : public CodeGenTraversal { private: //Member variables @@ -1192,7 +1247,7 @@ private: public: // Constructor - CGT_PROMISE(Module &_M, BuildDFG &_DFG, + CGT_WrapperAPI(Module &_M, BuildDFG &_DFG, InPlaceDFGAnalysis::InPlaceDFGParameter &_IPP, std::string &_QuantizationInputsFilenameStr, std::string &_ConfigurationInputsFilenameStr) @@ -1206,12 +1261,12 @@ public: }; -void CGT_PROMISE::init() { +void CGT_WrapperAPI::init() { // FIXME: what to do here? If anything? } // Initialize the VISC runtime API. This makes it easier to insert these calls -void CGT_PROMISE::initRuntimeAPI() { +void CGT_WrapperAPI::initRuntimeAPI() { // Load Runtime API Module SMDiagnostic Err; @@ -1282,12 +1337,12 @@ void CGT_PROMISE::initRuntimeAPI() { } -void CGT_PROMISE::codeGen(DFInternalNode* N) { +void CGT_WrapperAPI::codeGen(DFInternalNode* N) { errs () << "Inside node: " << N->getFuncPointer()->getName() << "\n"; errs () << "Skipping internal node\n"; } -void CGT_PROMISE::codeGen(DFLeafNode* N) { +void CGT_WrapperAPI::codeGen(DFLeafNode* N) { // Skip code generation if it is a dummy node if(N->isDummyNode()) { @@ -1318,23 +1373,23 @@ errs() << "Node Function: " << *F << "\n"; // Look up if we have visited this function before. If we have, then just // get the cloned function pointer from DFNode. Otherwise, create the cloned // function and add it to the DFNode GenFunc. - Function *F_promise = N->getGenFuncForTarget(visc::PROMISE_TARGET); + Function *F_wrapper_api = N->getGenFuncForTarget(visc::PROMISE_TARGET); - assert((F_promise == NULL) && + assert((F_wrapper_api == NULL) && "Error: Visiting a node for which code already generated"); // Clone the function ValueToValueMapTy VMap; std::string FName(F->getName().data());//Twine FName = F->getName(); - F_promise = CloneFunction(F, VMap); - F_promise->setName(FName+"_promise"); - F_promise->removeFromParent(); - M.getFunctionList().push_back(F_promise); + F_wrapper_api = CloneFunction(F, VMap); + F_wrapper_api->setName(FName+"_wrapper_api"); + F_wrapper_api->removeFromParent(); + M.getFunctionList().push_back(F_wrapper_api); - N->addGenFunc(F_promise, visc::PROMISE_TARGET, true); + N->addGenFunc(F_wrapper_api, visc::PROMISE_TARGET, true); /* Removing HPVM in/out/inout function attributes */ - for(Function::arg_iterator ai = F_promise->arg_begin(), ae = F_promise->arg_end(); + for(Function::arg_iterator ai = F_wrapper_api->arg_begin(), ae = F_wrapper_api->arg_end(); ai != ae; ai++){ Argument *Arg = &*ai; if(Arg->hasAttribute(Attribute::In)) @@ -1347,20 +1402,20 @@ errs() << "Node Function: " << *F << "\n"; // Adding nounwind to generated function : FIXME: needed? DEBUG(errs() << "Adding nounwind to generated function\n"); - F_promise->addAttribute(AttributeSet::FunctionIndex, Attribute::NoUnwind); + F_wrapper_api->addAttribute(AttributeSet::FunctionIndex, Attribute::NoUnwind); // Add llvm_visc_requestTensor calls for every pointer argument of the function // (they are all expected to be tensors), at the beginning of the function. // This is the first instruction of the function, insert them before this - Instruction* FI = &*(F_promise->getEntryBlock().begin()); + Instruction* FI = &*(F_wrapper_api->getEntryBlock().begin()); // FIXME: verify that we want 1 as a target device // In this backend, the target device is GPU, represented by i32 1. ConstantInt *TargetDeviceID = ConstantInt::get(Type::getInt32Ty(M.getContext()), 1); - for (Function::arg_iterator ai = F_promise->arg_begin(), - ae = F_promise->arg_end(); ai != ae; ++ai) { + for (Function::arg_iterator ai = F_wrapper_api->arg_begin(), + ae = F_wrapper_api->arg_end(); ai != ae; ++ai) { Argument* Arg = &*ai; if (Arg->getType()->isPointerTy()) { Value *Args[] = {Arg, TargetDeviceID}; @@ -1372,18 +1427,18 @@ errs() << "Node Function: " << *F << "\n"; CodeGenStateMachine CGM(&M, runtimeModule.get()); - for (inst_iterator i = inst_begin(F_promise), e = inst_end(F_promise); + for (inst_iterator i = inst_begin(F_wrapper_api), e = inst_end(F_wrapper_api); i != e; ++i) { Instruction *I = &(*i); CGM.transition(dyn_cast<IntrinsicInst>(I)); } errs() << "Node ID string: "<< StringRef(std::to_string(nodeID)) << "\n"; - //CGM.codeGen(N, F_promise, N->getFuncPointer()->getName(), *IPP); - CGM.codeGen(N, F_promise, StringRef(std::to_string(nodeID)), *IPP); + //CGM.codeGen(N, F_wrapper_api, N->getFuncPointer()->getName(), *IPP); + CGM.codeGen(N, F_wrapper_api, StringRef(std::to_string(nodeID)), *IPP); //errs() << "-----------------------------------\n"; -//errs() << *F_promise << "\n"; +//errs() << *F_wrapper_api << "\n"; return; } @@ -1404,7 +1459,7 @@ bool DFG2LLVM_WrapperAPI::runOnModule(Module &M) { std::vector<DFInternalNode*> Roots = DFG.getRoots(); // Visitor for Code Generation Graph Traversal - CGT_PROMISE *CGTVisitor = new CGT_PROMISE(M, DFG, IPP, + CGT_WrapperAPI *CGTVisitor = new CGT_WrapperAPI(M, DFG, IPP, QuantizationInputsFilename, ConfigurationInputsFilename); -- GitLab