From 92d905914b86e0f479e96e3b346a44f7cf02b271 Mon Sep 17 00:00:00 2001 From: Akash Kothari <akashk4@tyler.cs.illinois.edu> Date: Mon, 21 Dec 2020 11:58:13 -0600 Subject: [PATCH] LLVM-9-port ReplaceIntrinsics pass --- .../ReplaceIntrinsics/CMakeLists.txt | 3 +- .../ReplaceIntrinsics/LLVMBuild.txt | 3 +- .../ReplaceIntrinsics/ReplaceIntrinsics.cpp | 81 ++++++++++--------- .../ReplaceIntrinsics.exports | 2 + 4 files changed, 47 insertions(+), 42 deletions(-) diff --git a/hpvm/lib/Transforms/ReplaceIntrinsics/CMakeLists.txt b/hpvm/lib/Transforms/ReplaceIntrinsics/CMakeLists.txt index 0bfb2bf221..460aabcc27 100644 --- a/hpvm/lib/Transforms/ReplaceIntrinsics/CMakeLists.txt +++ b/hpvm/lib/Transforms/ReplaceIntrinsics/CMakeLists.txt @@ -2,7 +2,8 @@ if(WIN32 OR CYGWIN) set(LLVM_LINK_COMPONENTS Core Support) endif() -add_llvm_loadable_module( ReplaceIntrinsics +add_llvm_library( ReplaceIntrinsics + MODULE ReplaceIntrinsics.cpp DEPENDS diff --git a/hpvm/lib/Transforms/ReplaceIntrinsics/LLVMBuild.txt b/hpvm/lib/Transforms/ReplaceIntrinsics/LLVMBuild.txt index 6450fa1714..95739b3d4d 100644 --- a/hpvm/lib/Transforms/ReplaceIntrinsics/LLVMBuild.txt +++ b/hpvm/lib/Transforms/ReplaceIntrinsics/LLVMBuild.txt @@ -1,4 +1,4 @@ -;===- ./lib/Transforms/DFG2LLVM_NVPTX/LLVMBuild.txt ------------*- Conf -*--===; +;===- ./lib/Transforms/DFG2LLVM_WrapperAPI/LLVMBuild.txt -------*- Conf -*--===; ; ; The LLVM Compiler Infrastructure ; @@ -19,4 +19,3 @@ type = Library name = ReplaceIntrinsics parent = Transforms - diff --git a/hpvm/lib/Transforms/ReplaceIntrinsics/ReplaceIntrinsics.cpp b/hpvm/lib/Transforms/ReplaceIntrinsics/ReplaceIntrinsics.cpp index ef649d8e17..6944d0d0e2 100644 --- a/hpvm/lib/Transforms/ReplaceIntrinsics/ReplaceIntrinsics.cpp +++ b/hpvm/lib/Transforms/ReplaceIntrinsics/ReplaceIntrinsics.cpp @@ -9,6 +9,7 @@ #define ENABLE_ASSERTS #define DEBUG_TYPE "REPLACE_APPROXHPVM_INTRINSICS_WITH_FCALLS" + #include "llvm/IR/DataLayout.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Module.h" @@ -23,9 +24,10 @@ #include "llvm/Support/FileSystem.h" #include "llvm/IR/Attributes.h" #include "llvm-c/Core.h" -#include "llvm/SupportVISC/VISCTimer.h" -#include "llvm/SupportVISC/DFG2LLVM.h" -#include "llvm/InPlaceDFG/InPlaceDFGAnalysis.h" + +#include "SupportHPVM/DFG2LLVM.h" +#include "InPlaceDFG/InPlaceDFGAnalysis.h" + #include <sstream> using namespace llvm; @@ -70,8 +72,8 @@ private: /* TODO: I believe that TensorRt is not needed, since we will have llvm implementations linked in, so init and cleanup calls can be removed and relevant code also, but I leave in in for now until verified. */ - Constant* llvm_hpvm_initTensorRt; - Constant* llvm_hpvm_cleanupTensorRt; + FunctionCallee llvm_hpvm_initTensorRt; + FunctionCallee llvm_hpvm_cleanupTensorRt; // Constant* hpvm_request_tensor; DONE: request tensor will not be used // Functions @@ -169,18 +171,18 @@ void CGT_ReplaceApproxHPVMIntrinsicsWithFCalls::initRuntimeAPI() { DECLARE(llvm_hpvm_cleanupTensorRt); // DECLARE(hpvm_request_tensor); - // Find visc.init and visc.cleanup calls, and add placeholder methods + // Find hpvm.init and visc.cleanup calls, and add placeholder methods // for initialization and cleanup of the hpvm tensor runtime - Function* VI = M.getFunction("llvm.visc.init"); - assert(VI->getNumUses() == 1 && "__visc__init should only be used once\n"); + Function* VI = M.getFunction("llvm.hpvm.init"); + assert(VI->getNumUses() == 1 && "__hpvm__init should only be used once\n"); InitCall = cast<Instruction>(*VI->user_begin()); CallInst::Create(llvm_hpvm_initTensorRt, ArrayRef<Value*>(ConstantInt::get(Type::getInt32Ty(M.getContext()), 0)), "", InitCall); - Function* VC = M.getFunction("llvm.visc.cleanup"); - assert(VC->getNumUses() == 1 && "__visc__clear should only be used once\n"); + Function* VC = M.getFunction("llvm.hpvm.cleanup"); + assert(VC->getNumUses() == 1 && "__hpvm__clear should only be used once\n"); CleanupCall = cast<Instruction>(*VC->user_begin()); CallInst::Create(llvm_hpvm_cleanupTensorRt, ArrayRef<Value*>(), "", CleanupCall); @@ -207,7 +209,7 @@ void CGT_ReplaceApproxHPVMIntrinsicsWithFCalls::codeGen(DFLeafNode* N) { } // Search for intrinsic only if it has the right hint - if (!checkPreferredTarget(N, visc::CPU_TARGET)) { + if (!checkPreferredTarget(N, hpvm::CPU_TARGET)) { errs() << "Skipping node: "<< N->getFuncPointer()->getName() << "\n"; return; } @@ -220,15 +222,15 @@ void CGT_ReplaceApproxHPVMIntrinsicsWithFCalls::codeGen(DFLeafNode* N) { for (inst_iterator i = inst_begin(F), e = inst_end(F); i != e; ++i) { Instruction *I = &(*i); - if (BuildDFG::isViscIntrinsic(I)) { + if (BuildDFG::isHPVMIntrinsic(I)) { IntrinsicInst* II = dyn_cast<IntrinsicInst>(I); - assert((II->getCalledFunction()->getName()).startswith("llvm.visc.tensor") + assert((II->getCalledFunction()->getName()).startswith("llvm.hpvm.tensor") && "Only HPVM tensor intrinsics allowed in ApproxHPVM leaf nodes\n"); /********************* Handle VISC Tensor intrinsics ********************/ // We replace them with calls to functions with implementations at the LLVM level switch (II->getIntrinsicID()) { - case Intrinsic::visc_tensor_convolution: + case Intrinsic::hpvm_tensor_convolution: { /* llvm.hpvm.tensor.convolution */ DEBUG(errs() << F->getName() << "\t: Handling tensor convolution \n"); @@ -248,7 +250,7 @@ void CGT_ReplaceApproxHPVMIntrinsicsWithFCalls::codeGen(DFLeafNode* N) { Args.push_back(conv_precision); // Create function call - Constant* tensorConvolutionCPU; + FunctionCallee tensorConvolutionCPU; DECLARE(tensorConvolutionCPU); CallInst* CI = CallInst::Create(tensorConvolutionCPU, @@ -261,7 +263,7 @@ void CGT_ReplaceApproxHPVMIntrinsicsWithFCalls::codeGen(DFLeafNode* N) { } break; - case Intrinsic::visc_tensor_mul: + case Intrinsic::hpvm_tensor_mul: { /* llvm.hpvm.tensor.mul */ DEBUG(errs() << F->getName() << "\t: Handling tensor mul\n"); @@ -271,7 +273,7 @@ void CGT_ReplaceApproxHPVMIntrinsicsWithFCalls::codeGen(DFLeafNode* N) { Args.push_back(II->getOperand(1)); // Create function call - Constant* tensorGemmCPU; + FunctionCallee tensorGemmCPU; DECLARE(tensorGemmCPU); CallInst* CI = CallInst::Create(tensorGemmCPU, @@ -284,7 +286,7 @@ void CGT_ReplaceApproxHPVMIntrinsicsWithFCalls::codeGen(DFLeafNode* N) { } break; - case Intrinsic::visc_tensor_add: + case Intrinsic::hpvm_tensor_add: { /* llvm.hpvm.tensor.add */ DEBUG(errs() << F->getName() << "\t: Handling tensor add\n"); // Tensor add(a,b) is in place for argument a. @@ -305,7 +307,7 @@ void CGT_ReplaceApproxHPVMIntrinsicsWithFCalls::codeGen(DFLeafNode* N) { Args.push_back(II->getOperand(1)); // Create function call - Constant* tensorAddCPU; + FunctionCallee tensorAddCPU; DECLARE(tensorAddCPU); CallInst::Create(tensorAddCPU, Args, "", II); // We can replace the call to hpvm.tensor.add with the 1st argument @@ -317,9 +319,9 @@ void CGT_ReplaceApproxHPVMIntrinsicsWithFCalls::codeGen(DFLeafNode* N) { } break; - case Intrinsic::visc_tensor_pool_max: - case Intrinsic::visc_tensor_pool_mean: - { /* llvm.visc.tensor.relu */ + case Intrinsic::hpvm_tensor_pool_max: + case Intrinsic::hpvm_tensor_pool_mean: + { /* llvm.hpvm.tensor.relu */ DEBUG(errs() << F->getName() << "\t: Handling tensor_pool_max\n"); // Tensor relu(a) is in place for argument a. Value *Op = II->getOperand(0); @@ -337,10 +339,10 @@ void CGT_ReplaceApproxHPVMIntrinsicsWithFCalls::codeGen(DFLeafNode* N) { Args.push_back(II->getOperand(0)); int pool_type = 0; - if (II->getIntrinsicID() == Intrinsic::visc_tensor_pool_max){ + if (II->getIntrinsicID() == Intrinsic::hpvm_tensor_pool_max){ pool_type = 0; } - if (II->getIntrinsicID() == Intrinsic::visc_tensor_pool_mean){ + if (II->getIntrinsicID() == Intrinsic::hpvm_tensor_pool_mean){ pool_type = 1; } @@ -354,7 +356,7 @@ void CGT_ReplaceApproxHPVMIntrinsicsWithFCalls::codeGen(DFLeafNode* N) { Args.push_back(II->getOperand(6)); // Create function call - Constant* tensorPoolingCPU; + FunctionCallee tensorPoolingCPU; DECLARE(tensorPoolingCPU); CallInst* CI = CallInst::Create(tensorPoolingCPU, Args, "", II); @@ -365,10 +367,10 @@ void CGT_ReplaceApproxHPVMIntrinsicsWithFCalls::codeGen(DFLeafNode* N) { IItoRemove.push_back(II); }break; - case Intrinsic::visc_tensor_relu: - case Intrinsic::visc_tensor_clipped_relu: - case Intrinsic::visc_tensor_tanh: - { /* llvm.visc.tensor.relu */ + case Intrinsic::hpvm_tensor_relu: + case Intrinsic::hpvm_tensor_clipped_relu: + case Intrinsic::hpvm_tensor_tanh: + { /* llvm.hpvm.tensor.relu */ DEBUG(errs() << F->getName() << "\t: Handling tensor activation functions \n"); // Tensor relu(a) is in place for argument a. Value *Op = II->getOperand(0); @@ -384,22 +386,22 @@ void CGT_ReplaceApproxHPVMIntrinsicsWithFCalls::codeGen(DFLeafNode* N) { std::vector<Value*> Args; Args.push_back(II->getOperand(0)); - if (II->getIntrinsicID() == Intrinsic::visc_tensor_relu){ + if (II->getIntrinsicID() == Intrinsic::hpvm_tensor_relu){ // Create function call - Constant* tensorReluCPU; + FunctionCallee tensorReluCPU; DECLARE(tensorReluCPU); CallInst::Create(tensorReluCPU, Args, "", II); } - else if (II->getIntrinsicID() == Intrinsic::visc_tensor_clipped_relu){ + else if (II->getIntrinsicID() == Intrinsic::hpvm_tensor_clipped_relu){ // Create function call - //-- Constant* tensorClippedRelu; - Constant* tensorRelu2CPU; + //-- FunctionCallee tensorClippedRelu; + FunctionCallee tensorRelu2CPU; DECLARE(tensorRelu2CPU); CallInst::Create(tensorRelu2CPU, Args, "", II); } - else if (II->getIntrinsicID() == Intrinsic::visc_tensor_tanh){ + else if (II->getIntrinsicID() == Intrinsic::hpvm_tensor_tanh){ // Create function call - Constant* tensorTanhCPU; + FunctionCallee tensorTanhCPU; errs()<<"tensorTanh Call = \n\n"; DECLARE(tensorTanhCPU); //errs()<<"tensorTanh Call = "<<*tensorTanh<<"\l"; @@ -415,8 +417,8 @@ void CGT_ReplaceApproxHPVMIntrinsicsWithFCalls::codeGen(DFLeafNode* N) { } break; - case Intrinsic::visc_tensor_softmax: - { /* llvm.visc.tensor.softmax */ + case Intrinsic::hpvm_tensor_softmax: + { /* llvm.hpvm.tensor.softmax */ DEBUG(errs() << F->getName() << "\t: Handling tensor softmax\n"); // Tensor relu(a) is in place for argument a. Value *Op = II->getOperand(0); @@ -433,7 +435,7 @@ void CGT_ReplaceApproxHPVMIntrinsicsWithFCalls::codeGen(DFLeafNode* N) { Args.push_back(II->getOperand(0)); // Create function call - Constant* tensorSoftmaxCPU; + FunctionCallee tensorSoftmaxCPU; DECLARE(tensorSoftmaxCPU); CallInst::Create(tensorSoftmaxCPU, Args, "", II); // We can replace the call to hpvm.tensor.softmax with the 1st argument @@ -514,3 +516,4 @@ static RegisterPass<DFG2LLVM_ReplaceApproxHPVMIntrinsicsWithFCalls> X("replace-i true /* transformation, * * not just analysis */); + diff --git a/hpvm/lib/Transforms/ReplaceIntrinsics/ReplaceIntrinsics.exports b/hpvm/lib/Transforms/ReplaceIntrinsics/ReplaceIntrinsics.exports index e69de29bb2..139597f9cb 100644 --- a/hpvm/lib/Transforms/ReplaceIntrinsics/ReplaceIntrinsics.exports +++ b/hpvm/lib/Transforms/ReplaceIntrinsics/ReplaceIntrinsics.exports @@ -0,0 +1,2 @@ + + -- GitLab