Skip to content
Snippets Groups Projects
Commit 49ae0d44 authored by Akash Kothari's avatar Akash Kothari
Browse files

Add LLVM-9-ported InPlaceDFG analysis pass

parent 92d90591
No related branches found
No related tags found
No related merge requests found
...@@ -53,6 +53,8 @@ bool BuildDFG::runOnModule(Module &M) { ...@@ -53,6 +53,8 @@ bool BuildDFG::runOnModule(Module &M) {
// Intrinsic Instruction has been initialized from this point on. // Intrinsic Instruction has been initialized from this point on.
Function *F = cast<Function>(II->getOperand(0)->stripPointerCasts()); Function *F = cast<Function>(II->getOperand(0)->stripPointerCasts());
Root = DFInternalNode::Create(II, F, hpvmUtils::getPreferredTarget(F)); Root = DFInternalNode::Create(II, F, hpvmUtils::getPreferredTarget(F));
errs() << "INTRINSIC: " << II << "\n";
errs() << "ROOT NODE" << Root << "\n";
Roots.push_back(Root); Roots.push_back(Root);
BuildGraph(Root, F); BuildGraph(Root, F);
...@@ -174,6 +176,9 @@ bool BuildDFG::isTypeCongruent(Type *L, Type *R) { ...@@ -174,6 +176,9 @@ bool BuildDFG::isTypeCongruent(Type *L, Type *R) {
// Handles all the createNodeXX hpvm intrinsics. // Handles all the createNodeXX hpvm intrinsics.
void BuildDFG::handleCreateNode(DFInternalNode *N, IntrinsicInst *II) { void BuildDFG::handleCreateNode(DFInternalNode *N, IntrinsicInst *II) {
errs() << "************ HANDLE CREATE NODE *********\n";
II->print(errs());
errs() << "\n";
bool isInternalNode = false; bool isInternalNode = false;
Function *F = cast<Function>((II->getOperand(0))->stripPointerCasts()); Function *F = cast<Function>((II->getOperand(0))->stripPointerCasts());
...@@ -206,6 +211,7 @@ void BuildDFG::handleCreateNode(DFInternalNode *N, IntrinsicInst *II) { ...@@ -206,6 +211,7 @@ void BuildDFG::handleCreateNode(DFInternalNode *N, IntrinsicInst *II) {
// dataflow graph // dataflow graph
DFInternalNode *childDFNode = DFInternalNode::Create( DFInternalNode *childDFNode = DFInternalNode::Create(
II, F, hpvmUtils::getPreferredTarget(F), N, numOfDim, dimLimits); II, F, hpvmUtils::getPreferredTarget(F), N, numOfDim, dimLimits);
errs() << "INTERNAL NODE: " << childDFNode << "\n";
N->addChildToDFGraph(childDFNode); N->addChildToDFGraph(childDFNode);
HandleToDFNodeMap[II] = childDFNode; HandleToDFNodeMap[II] = childDFNode;
BuildGraph(childDFNode, F); BuildGraph(childDFNode, F);
...@@ -213,18 +219,26 @@ void BuildDFG::handleCreateNode(DFInternalNode *N, IntrinsicInst *II) { ...@@ -213,18 +219,26 @@ void BuildDFG::handleCreateNode(DFInternalNode *N, IntrinsicInst *II) {
// Create Leaf DFnode and add it to the map. // Create Leaf DFnode and add it to the map.
DFLeafNode *childDFNode = DFLeafNode::Create( DFLeafNode *childDFNode = DFLeafNode::Create(
II, F, hpvmUtils::getPreferredTarget(F), N, numOfDim, dimLimits); II, F, hpvmUtils::getPreferredTarget(F), N, numOfDim, dimLimits);
errs() << "LEAF NODE: " << childDFNode << "\n";
N->addChildToDFGraph(childDFNode); N->addChildToDFGraph(childDFNode);
HandleToDFNodeMap[II] = childDFNode; HandleToDFNodeMap[II] = childDFNode;
} }
} }
void BuildDFG::handleCreateEdge(DFInternalNode *N, IntrinsicInst *II) { void BuildDFG::handleCreateEdge(DFInternalNode *N, IntrinsicInst *II) {
errs() << "************ HANDLE CREATE EDGE *********\n";
II->print(errs());
errs() << "\n";
// The DFNode structures must be in the map before the edge is processed // The DFNode structures must be in the map before the edge is processed
HandleToDFNode::iterator DFI = HandleToDFNodeMap.find(II->getOperand(0)); HandleToDFNode::iterator DFI = HandleToDFNodeMap.find(II->getOperand(0));
assert(DFI != HandleToDFNodeMap.end()); assert(DFI != HandleToDFNodeMap.end());
DFI = HandleToDFNodeMap.find(II->getOperand(1)); DFI = HandleToDFNodeMap.find(II->getOperand(1));
assert(DFI != HandleToDFNodeMap.end()); assert(DFI != HandleToDFNodeMap.end());
errs() << "NODE TO MAP OPERAND 0: " << II->getOperand(0) << "\n";
errs() << "NODE TO MAP OPERAND 1: " << II->getOperand(1) << "\n";
errs() << "SRC NODE: " << HandleToDFNodeMap[II->getOperand(0)] << "\n";
errs() << "DEST NODE: " << HandleToDFNodeMap[II->getOperand(1)] << "\n";
DFNode *SrcDF = HandleToDFNodeMap[II->getOperand(0)]; DFNode *SrcDF = HandleToDFNodeMap[II->getOperand(0)];
DFNode *DestDF = HandleToDFNodeMap[II->getOperand(1)]; DFNode *DestDF = HandleToDFNodeMap[II->getOperand(1)];
...@@ -258,16 +272,23 @@ void BuildDFG::handleCreateEdge(DFInternalNode *N, IntrinsicInst *II) { ...@@ -258,16 +272,23 @@ void BuildDFG::handleCreateEdge(DFInternalNode *N, IntrinsicInst *II) {
DestPosition, DestTy, isStreaming); DestPosition, DestTy, isStreaming);
HandleToDFEdgeMap[II] = newDFEdge; HandleToDFEdgeMap[II] = newDFEdge;
errs() << "NEW EDGE: " << newDFEdge << "\n";
// Add Edge to the dataflow graph associated with the parent node // Add Edge to the dataflow graph associated with the parent node
N->addEdgeToDFGraph(newDFEdge); N->addEdgeToDFGraph(newDFEdge);
} }
void BuildDFG::handleBindInput(DFInternalNode *N, IntrinsicInst *II) { void BuildDFG::handleBindInput(DFInternalNode *N, IntrinsicInst *II) {
errs() << "************ HANDLE BIND INPUT *********\n";
II->print(errs());
errs() << "\n";
// The DFNode structures must be in the map before the edge is processed // The DFNode structures must be in the map before the edge is processed
HandleToDFNode::iterator DFI = HandleToDFNodeMap.find(II->getOperand(0)); HandleToDFNode::iterator DFI = HandleToDFNodeMap.find(II->getOperand(0));
assert(DFI != HandleToDFNodeMap.end()); assert(DFI != HandleToDFNodeMap.end());
errs() << "NODE TP MAP: " << II->getOperand(0) << "\n";
errs() << "SRC NODE: " << N->getChildGraph()->getEntry() << "\n";
errs() << "DEST NODE: " << HandleToDFNodeMap[II->getOperand(0)] << "\n";
DFNode *SrcDF = N->getChildGraph()->getEntry(); DFNode *SrcDF = N->getChildGraph()->getEntry();
DFNode *DestDF = HandleToDFNodeMap[II->getOperand(0)]; DFNode *DestDF = HandleToDFNodeMap[II->getOperand(0)];
...@@ -298,16 +319,23 @@ void BuildDFG::handleBindInput(DFInternalNode *N, IntrinsicInst *II) { ...@@ -298,16 +319,23 @@ void BuildDFG::handleBindInput(DFInternalNode *N, IntrinsicInst *II) {
DestPosition, DestTy, isStreaming); DestPosition, DestTy, isStreaming);
HandleToDFEdgeMap[II] = newDFEdge; HandleToDFEdgeMap[II] = newDFEdge;
errs() << "NEW EDGE: " << newDFEdge << "\n";
// Add Edge to the dataflow graph associated with the parent node // Add Edge to the dataflow graph associated with the parent node
N->addEdgeToDFGraph(newDFEdge); N->addEdgeToDFGraph(newDFEdge);
} }
void BuildDFG::handleBindOutput(DFInternalNode *N, IntrinsicInst *II) { void BuildDFG::handleBindOutput(DFInternalNode *N, IntrinsicInst *II) {
errs() << "************ HANDLE BIND OUTPUT *********\n";
II->print(errs());
errs() << "\n";
// The DFNode structures must be in the map before the edge is processed // The DFNode structures must be in the map before the edge is processed
HandleToDFNode::iterator DFI = HandleToDFNodeMap.find(II->getOperand(0)); HandleToDFNode::iterator DFI = HandleToDFNodeMap.find(II->getOperand(0));
assert(DFI != HandleToDFNodeMap.end()); assert(DFI != HandleToDFNodeMap.end());
errs() << "NODE TP MAP: " << II->getOperand(0) << "\n";
errs() << "SRC NODE: " << HandleToDFNodeMap[II->getOperand(0)] << "\n";
errs() << "DEST NODE: " << N->getChildGraph()->getExit() << "\n";
DFNode *SrcDF = HandleToDFNodeMap[II->getOperand(0)]; DFNode *SrcDF = HandleToDFNodeMap[II->getOperand(0)];
DFNode *DestDF = N->getChildGraph()->getExit(); DFNode *DestDF = N->getChildGraph()->getExit();
...@@ -338,6 +366,7 @@ void BuildDFG::handleBindOutput(DFInternalNode *N, IntrinsicInst *II) { ...@@ -338,6 +366,7 @@ void BuildDFG::handleBindOutput(DFInternalNode *N, IntrinsicInst *II) {
DestPosition, DestTy, isStreaming); DestPosition, DestTy, isStreaming);
HandleToDFEdgeMap[II] = newDFEdge; HandleToDFEdgeMap[II] = newDFEdge;
errs() << "NEW EDGE: " << newDFEdge << "\n";
// Add Edge to the dataflow graph associated with the parent node // Add Edge to the dataflow graph associated with the parent node
N->addEdgeToDFGraph(newDFEdge); N->addEdgeToDFGraph(newDFEdge);
......
...@@ -4,6 +4,7 @@ add_subdirectory(DFG2LLVM_OpenCL) ...@@ -4,6 +4,7 @@ add_subdirectory(DFG2LLVM_OpenCL)
add_subdirectory(DFG2LLVM_CPU) add_subdirectory(DFG2LLVM_CPU)
add_subdirectory(GenHPVM) add_subdirectory(GenHPVM)
add_subdirectory(LocalMem) add_subdirectory(LocalMem)
add_subdirectory(HPVM2NGRAPH)
add_subdirectory(DFG2LLVM_WrapperAPI) add_subdirectory(DFG2LLVM_WrapperAPI)
add_subdirectory(ReplaceIntrinsics) add_subdirectory(ReplaceIntrinsics)
add_subdirectory(DFG2LLVM_CUDNN) add_subdirectory(DFG2LLVM_CUDNN)
......
...@@ -2,7 +2,8 @@ if(WIN32 OR CYGWIN) ...@@ -2,7 +2,8 @@ if(WIN32 OR CYGWIN)
set(LLVM_LINK_COMPONENTS Core Support) set(LLVM_LINK_COMPONENTS Core Support)
endif() endif()
add_llvm_loadable_module( LLVMDFG2LLVM_WrapperAPI add_llvm_library( LLVMDFG2LLVM_WrapperAPI
MODULE
DFG2LLVM_WrapperAPI.cpp DFG2LLVM_WrapperAPI.cpp
DEPENDS DEPENDS
...@@ -10,3 +11,4 @@ add_llvm_loadable_module( LLVMDFG2LLVM_WrapperAPI ...@@ -10,3 +11,4 @@ add_llvm_loadable_module( LLVMDFG2LLVM_WrapperAPI
PLUGIN_TOOL PLUGIN_TOOL
opt opt
) )
...@@ -169,6 +169,21 @@ IS_HPVM_CALL(requestMemory) ...@@ -169,6 +169,21 @@ IS_HPVM_CALL(requestMemory)
IS_HPVM_CALL(attributes) IS_HPVM_CALL(attributes)
IS_HPVM_CALL(hint) IS_HPVM_CALL(hint)
// Tensor Operators
IS_HPVM_CALL(tensor_mul)
IS_HPVM_CALL(tensor_convolution)
IS_HPVM_CALL(tensor_group_convolution)
IS_HPVM_CALL(tensor_batchnorm)
IS_HPVM_CALL(tensor_add)
IS_HPVM_CALL(tensor_pool_max)
IS_HPVM_CALL(tensor_pool_min)
IS_HPVM_CALL(tensor_pool_mean)
IS_HPVM_CALL(tensor_relu)
IS_HPVM_CALL(tensor_clipped_relu)
IS_HPVM_CALL(tensor_tanh)
IS_HPVM_CALL(tensor_sigmoid)
IS_HPVM_CALL(tensor_softmax)
// Return the constant integer represented by value V // Return the constant integer represented by value V
static unsigned getNumericValue(Value *V) { static unsigned getNumericValue(Value *V) {
assert(isa<ConstantInt>(V) && assert(isa<ConstantInt>(V) &&
...@@ -264,32 +279,32 @@ bool GenHPVM::runOnModule(Module &M) { ...@@ -264,32 +279,32 @@ bool GenHPVM::runOnModule(Module &M) {
// Load Runtime API Module // Load Runtime API Module
SMDiagnostic Err; SMDiagnostic Err;
std::string runtimeAPI = std::string(LLVM_BUILD_DIR_STR) + //std::string runtimeAPI = std::string(LLVM_BUILD_DIR_STR) +
"/tools/hpvm/projects/hpvm-rt/hpvm-rt.bc"; // "/tools/hpvm/projects/hpvm-rt/hpvm-rt.bc";
std::unique_ptr<Module> runtimeModule = //std::unique_ptr<Module> runtimeModule =
parseIRFile(runtimeAPI, Err, M.getContext()); // parseIRFile(runtimeAPI, Err, M.getContext());
if (runtimeModule == NULL) { //if (runtimeModule == NULL) {
DEBUG(errs() << Err.getMessage() << " " << runtimeAPI << "\n"); //DEBUG(errs() << Err.getMessage() << " " << runtimeAPI << "\n");
assert(false && "couldn't parse runtime"); // assert(false && "couldn't parse runtime");
} else //} else
DEBUG(errs() << "Successfully loaded hpvm-rt API module\n"); // DEBUG(errs() << "Successfully loaded hpvm-rt API module\n");
llvm_hpvm_initializeTimerSet = M.getOrInsertFunction( //llvm_hpvm_initializeTimerSet = M.getOrInsertFunction(
"llvm_hpvm_initializeTimerSet", // "llvm_hpvm_initializeTimerSet",
runtimeModule->getFunction("llvm_hpvm_initializeTimerSet") // runtimeModule->getFunction("llvm_hpvm_initializeTimerSet")
->getFunctionType()); // ->getFunctionType());
// DEBUG(errs() << *llvm_hpvm_initializeTimerSet); // DEBUG(errs() << *llvm_hpvm_initializeTimerSet);
llvm_hpvm_switchToTimer = M.getOrInsertFunction( //llvm_hpvm_switchToTimer = M.getOrInsertFunction(
"llvm_hpvm_switchToTimer", // "llvm_hpvm_switchToTimer",
runtimeModule->getFunction("llvm_hpvm_switchToTimer")->getFunctionType()); // runtimeModule->getFunction("llvm_hpvm_switchToTimer")->getFunctionType());
// DEBUG(errs() << *llvm_hpvm_switchToTimer); // DEBUG(errs() << *llvm_hpvm_switchToTimer);
llvm_hpvm_printTimerSet = M.getOrInsertFunction( //llvm_hpvm_printTimerSet = M.getOrInsertFunction(
"llvm_hpvm_printTimerSet", // "llvm_hpvm_printTimerSet",
runtimeModule->getFunction("llvm_hpvm_printTimerSet")->getFunctionType()); // runtimeModule->getFunction("llvm_hpvm_printTimerSet")->getFunctionType());
// DEBUG(errs() << *llvm_hpvm_printTimerSet); // DEBUG(errs() << *llvm_hpvm_printTimerSet);
// Insert init context in main // Insert init context in main
...@@ -298,16 +313,16 @@ bool GenHPVM::runOnModule(Module &M) { ...@@ -298,16 +313,16 @@ bool GenHPVM::runOnModule(Module &M) {
assert(VI->getNumUses() == 1 && "__hpvm__init should only be used once"); assert(VI->getNumUses() == 1 && "__hpvm__init should only be used once");
Instruction *I = cast<Instruction>(*VI->user_begin()); Instruction *I = cast<Instruction>(*VI->user_begin());
DEBUG(errs() << "Initialize Timer Set\n"); //DEBUG(errs() << "Initialize Timer Set\n");
initializeTimerSet(I); //initializeTimerSet(I);
switchToTimer(hpvm_TimerID_NONE, I); //switchToTimer(hpvm_TimerID_NONE, I);
// Insert print instruction at hpvm exit // Insert print instruction at hpvm exit
DEBUG(errs() << "Locate __hpvm__cleanup()\n"); DEBUG(errs() << "Locate __hpvm__cleanup()\n");
Function *VC = M.getFunction("__hpvm__cleanup"); Function *VC = M.getFunction("__hpvm__cleanup");
assert(VC->getNumUses() == 1 && "__hpvm__cleanup should only be used once"); assert(VC->getNumUses() == 1 && "__hpvm__cleanup should only be used once");
I = cast<Instruction>(*VC->user_begin()); I = cast<Instruction>(*VC->user_begin());
printTimerSet(I); //printTimerSet(I);
DEBUG(errs() << "-------- Searching for launch sites ----------\n"); DEBUG(errs() << "-------- Searching for launch sites ----------\n");
...@@ -711,6 +726,42 @@ bool GenHPVM::runOnModule(Module &M) { ...@@ -711,6 +726,42 @@ bool GenHPVM::runOnModule(Module &M) {
if (isHPVMCall_cos(I)) { if (isHPVMCall_cos(I)) {
ReplaceCallWithIntrinsic(I, Intrinsic::cos, &toBeErased); ReplaceCallWithIntrinsic(I, Intrinsic::cos, &toBeErased);
} }
if (isHPVMCall_tensor_convolution(I)) {
ReplaceCallWithIntrinsic(I, Intrinsic::hpvm_tensor_convolution, &toBeErased);
}
if (isHPVMCall_tensor_group_convolution(I)) {
ReplaceCallWithIntrinsic(I, Intrinsic::hpvm_tensor_group_convolution, &toBeErased);
}
if (isHPVMCall_tensor_add(I)) {
ReplaceCallWithIntrinsic(I, Intrinsic::hpvm_tensor_add, &toBeErased);
}
if (isHPVMCall_tensor_batchnorm(I)) {
ReplaceCallWithIntrinsic(I, Intrinsic::hpvm_tensor_batchnorm, &toBeErased);
}
if (isHPVMCall_tensor_mul(I)) {
ReplaceCallWithIntrinsic(I, Intrinsic::hpvm_tensor_mul, &toBeErased);
}
if (isHPVMCall_tensor_pool_max(I)) {
ReplaceCallWithIntrinsic(I, Intrinsic::hpvm_tensor_pool_max, &toBeErased);
}
if (isHPVMCall_tensor_pool_min(I)) {
ReplaceCallWithIntrinsic(I, Intrinsic::hpvm_tensor_pool_min, &toBeErased);
}
if (isHPVMCall_tensor_pool_mean(I)) {
ReplaceCallWithIntrinsic(I, Intrinsic::hpvm_tensor_pool_mean, &toBeErased);
}
if (isHPVMCall_tensor_relu(I)) {
ReplaceCallWithIntrinsic(I, Intrinsic::hpvm_tensor_relu, &toBeErased);
}
if (isHPVMCall_tensor_tanh(I)) {
ReplaceCallWithIntrinsic(I, Intrinsic::hpvm_tensor_tanh, &toBeErased);
}
if (isHPVMCall_tensor_clipped_relu(I)) {
ReplaceCallWithIntrinsic(I, Intrinsic::hpvm_tensor_clipped_relu, &toBeErased);
}
if (isHPVMCall_tensor_softmax(I)) {
ReplaceCallWithIntrinsic(I, Intrinsic::hpvm_tensor_softmax, &toBeErased);
}
} }
// Erase the __hpvm__node calls // Erase the __hpvm__node calls
......
...@@ -17,8 +17,8 @@ ...@@ -17,8 +17,8 @@
#define DEBUG_TYPE "InPlaceDFGAnalysis" #define DEBUG_TYPE "InPlaceDFGAnalysis"
#include "llvm/Support/SourceMgr.h" #include "llvm/Support/SourceMgr.h"
#include "llvm/InPlaceDFG/InPlaceDFGAnalysis.h" #include "InPlaceDFG/InPlaceDFGAnalysis.h"
#include "llvm/SupportVISC/DFG2LLVM.h" #include "SupportHPVM/DFG2LLVM.h"
using namespace llvm; using namespace llvm;
using namespace builddfg; using namespace builddfg;
...@@ -279,7 +279,7 @@ void AT_OCL::codeGen(DFLeafNode* N) { ...@@ -279,7 +279,7 @@ void AT_OCL::codeGen(DFLeafNode* N) {
CallInst *CI = dyn_cast<CallInst>(OutValues[i]); CallInst *CI = dyn_cast<CallInst>(OutValues[i]);
assert(CI && assert(CI &&
"Expected return value to be the result of a call instruction\n"); "Expected return value to be the result of a call instruction\n");
assert ((CI->getCalledFunction()->getName()).startswith("llvm.visc.tensor") && assert ((CI->getCalledFunction()->getName()).startswith("llvm.hpvm.tensor") &&
"Node output must be the result of an HPVM tensor intrinsic\n"); "Node output must be the result of an HPVM tensor intrinsic\n");
} }
} }
...@@ -316,3 +316,4 @@ static RegisterPass<InPlaceDFGAnalysisWrapper> X("inplace", ...@@ -316,3 +316,4 @@ static RegisterPass<InPlaceDFGAnalysisWrapper> X("inplace",
} // End of namespace } // End of namespace
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment