Skip to content
Snippets Groups Projects
Commit ab576ce4 authored by daniilp2's avatar daniilp2
Browse files

Added a hack to delete all unreachable DFNodes

parent 9015a730
Branches dhpvm
No related tags found
No related merge requests found
...@@ -500,6 +500,113 @@ namespace { ...@@ -500,6 +500,113 @@ namespace {
}; };
/**
* Objects from this class traverse the DFG and partitions nodes into three
* categories:
* 1) Offload nodes: Nodes that have the Remote target
* 2) Worker nodes: Nodes that are descended from a node with the Remote target
* 3) Client nodes: All other nodes
*/
class RemoteNodeDetector : public DFNodeVisitor {
private:
public:
std::set<StringRef> offloadNodes;
std::set<StringRef> workerNodes;
std::set<StringRef> clientNodes;
virtual ~RemoteNodeDetector() {}
void visitWorkerNode(DFInternalNode *N) {
if (N->isDummyNode())
return;
Function *F = N->getFuncPointer();
workerNodes.insert(F->getName());
DEBUG(errs() << "Found worker node" << F->getName() << "\n");
for (DFGraph::children_iterator i = N->getChildGraph()->begin(),
e = N->getChildGraph()->end();
i != e; ++i) {
DFNode *child = *i;
if (auto *internal = dyn_cast<DFInternalNode>(child)) {
visitWorkerNode(internal);
}
else if (auto *leaf = dyn_cast<DFLeafNode>(child)) {
visitWorkerNode(leaf);
}
else {
assert(false && "Unexpected DFNode: Neither a leaf, nor an internal node");
}
}
}
void visitWorkerNode(DFLeafNode *N) {
if (N->isDummyNode())
return;
Function *F = N->getFuncPointer();
workerNodes.insert(F->getName());
DEBUG(errs() << "Found worker node" << F->getName() << "\n");
}
virtual void visit(DFInternalNode *N) {
if (N->isDummyNode())
return;
Function *F = N->getFuncPointer();
if (hpvmUtils::getPreferredTarget(F) == hpvm::REMOTE_TARGET) {
offloadNodes.insert(F->getName());
DEBUG(errs() << "Found offload node" << F->getName() << "\n");
for (DFGraph::children_iterator i = N->getChildGraph()->begin(),
e = N->getChildGraph()->end();
i != e; ++i) {
DFNode *child = *i;
if (auto *internal = dyn_cast<DFInternalNode>(child)) {
visitWorkerNode(internal);
}
else if (auto *leaf = dyn_cast<DFLeafNode>(child)) {
visitWorkerNode(leaf);
}
else {
assert(false && "Unexpected DFNode: Neither a leaf, nor an internal node");
}
}
}
else {
clientNodes.insert(F->getName());
DEBUG(errs() << "Found client node" << F->getName() << "\n");
for (DFGraph::children_iterator i = N->getChildGraph()->begin(),
e = N->getChildGraph()->end();
i != e; ++i) {
DFNode *child = *i;
if (auto *internal = dyn_cast<DFInternalNode>(child)) {
visit(internal);
}
else if (auto *leaf = dyn_cast<DFLeafNode>(child)) {
visit(leaf);
}
else {
assert(false && "Unexpected DFNode: Neither a leaf, nor an internal node");
}
}
}
}
virtual void visit(DFLeafNode *N) {
if (N->isDummyNode())
return;
Function *F = N->getFuncPointer();
if (hpvmUtils::getPreferredTarget(F) == hpvm::REMOTE_TARGET) {
offloadNodes.insert(F->getName());
DEBUG(errs() << "Found offload node" << F->getName() << "\n");
}
else {
clientNodes.insert(F->getName());
DEBUG(errs() << "Found client node" << F->getName() << "\n");
}
}
};
// Returns true if instruction I is a hpvm launch intrinsic, false otherwise // Returns true if instruction I is a hpvm launch intrinsic, false otherwise
bool isHPVMLaunchIntrinsic(Instruction *I) { bool isHPVMLaunchIntrinsic(Instruction *I) {
if (!isa<IntrinsicInst>(I)) if (!isa<IntrinsicInst>(I))
...@@ -588,6 +695,7 @@ namespace { ...@@ -588,6 +695,7 @@ namespace {
initWorkerModule(); initWorkerModule();
} }
void deleteUnreachableNodes(std::set<StringRef> &clientNodes, std::set<StringRef> &workerNodes);
void writeWorkerModule(); void writeWorkerModule();
}; };
...@@ -995,15 +1103,21 @@ namespace { ...@@ -995,15 +1103,21 @@ namespace {
// DFInternalNode *Root = DFG.getRoot(); // DFInternalNode *Root = DFG.getRoot();
std::vector<DFInternalNode *> Roots = DFG.getRoots(); std::vector<DFInternalNode *> Roots = DFG.getRoots();
// Top-down visitor for partitioning nodes between the client and the worker
RemoteNodeDetector *Partitioner = new RemoteNodeDetector();
// Visitor for Code Generation Graph Traversal // Visitor for Code Generation Graph Traversal
CGT_Remote *CGTVisitor = new CGT_Remote(M, DFG); CGT_Remote *CGTVisitor = new CGT_Remote(M, DFG);
// Iterate over all the DFGs and produce code for each one of them // Iterate over all the DFGs and produce code for each one of them
for (auto &rootNode : Roots) { for (auto &rootNode : Roots) {
// Detect the partition before any hints are updated
Partitioner->visit(rootNode);
// Initiate code generation for root DFNode // Initiate code generation for root DFNode
CGTVisitor->visit(rootNode); CGTVisitor->visit(rootNode);
} }
CGTVisitor->deleteUnreachableNodes(Partitioner->clientNodes, Partitioner->workerNodes);
CGTVisitor->writeWorkerModule(); CGTVisitor->writeWorkerModule();
delete CGTVisitor; delete CGTVisitor;
...@@ -1016,6 +1130,23 @@ namespace { ...@@ -1016,6 +1130,23 @@ namespace {
return mid.append(".worker.ll"); return mid.append(".worker.ll");
} }
void CGT_Remote::deleteUnreachableNodes(std::set<StringRef> &clientNodes, std::set<StringRef> &workerNodes) {
for (auto FName : workerNodes) {
Function *F = M.getFunction(FName);
DEBUG(errs() << "Deleting worker node " << FName << " from the client module\n");
F->replaceAllUsesWith(UndefValue::get(F->getType()));
F->eraseFromParent();
F->dropAllReferences();
}
for (auto FName : clientNodes) {
Function *F = WorkerModule.get()->getFunction(FName);
DEBUG(errs() << "Deleting client node " << FName << " from the worker module\n");
F->replaceAllUsesWith(UndefValue::get(F->getType()));
F->eraseFromParent();
F->dropAllReferences();
}
}
void CGT_Remote::writeWorkerModule() { void CGT_Remote::writeWorkerModule() {
DEBUG(errs() << "Writing to File --- "); DEBUG(errs() << "Writing to File --- ");
DEBUG(errs() << getWorkerModuleName(M).c_str() << "\n"); DEBUG(errs() << getWorkerModuleName(M).c_str() << "\n");
......
...@@ -32,42 +32,42 @@ echo ...@@ -32,42 +32,42 @@ echo
$BUILD/bin/opt -load $BUILD/lib/LLVMBuildDFG.so -load $BUILD/lib/LLVMDFG2LLVM_Remote.so -dfg2llvm-remote -S main.hpvm.ll -o main.hpvm.ll.client.ll -debug $BUILD/bin/opt -load $BUILD/lib/LLVMBuildDFG.so -load $BUILD/lib/LLVMDFG2LLVM_Remote.so -dfg2llvm-remote -S main.hpvm.ll -o main.hpvm.ll.client.ll -debug
# $BUILD/bin/opt -load $BUILD/lib/LLVMBuildDFG.so -load $BUILD/lib/LLVMDFG2LLVM_Remote.so -load $BUILD/lib/LLVMDFG2LLVM_CPU.so -load $BUILD/lib/LLVMClearDFG.so -dfg2llvm-remote -dfg2llvm-cpu -clearDFG -S main.hpvm.ll -o main.client.ll -debug # $BUILD/bin/opt -load $BUILD/lib/LLVMBuildDFG.so -load $BUILD/lib/LLVMDFG2LLVM_Remote.so -load $BUILD/lib/LLVMDFG2LLVM_CPU.so -load $BUILD/lib/LLVMClearDFG.so -dfg2llvm-remote -dfg2llvm-cpu -clearDFG -S main.hpvm.ll -o main.client.ll -debug
### echo echo
### echo echo
### echo echo
### echo echo
### echo "Compiling worker HPVM into LLVM..." echo "Compiling worker HPVM into LLVM..."
### echo echo
### echo echo
### echo echo
### echo echo
### $BUILD/bin/opt -load $BUILD/lib/LLVMBuildDFG.so -load $BUILD/lib/LLVMDFG2LLVM_CPU.so -load $BUILD/lib/LLVMClearDFG.so -dfg2llvm-cpu -clearDFG -S main.hpvm.ll.client.ll -o main.client.ll -debug $BUILD/bin/opt -load $BUILD/lib/LLVMBuildDFG.so -load $BUILD/lib/LLVMDFG2LLVM_CPU.so -load $BUILD/lib/LLVMClearDFG.so -dfg2llvm-cpu -clearDFG -S main.hpvm.ll.client.ll -o main.client.ll -debug
### $BUILD/bin/opt -load $BUILD/lib/LLVMBuildDFG.so -load $BUILD/lib/LLVMDFG2LLVM_CPU.so -load $BUILD/lib/LLVMClearDFG.so -dfg2llvm-cpu -clearDFG -S main.hpvm.ll.worker.ll -o main.worker.ll -debug $BUILD/bin/opt -load $BUILD/lib/LLVMBuildDFG.so -load $BUILD/lib/LLVMDFG2LLVM_CPU.so -load $BUILD/lib/LLVMClearDFG.so -dfg2llvm-cpu -clearDFG -S main.hpvm.ll.worker.ll -o main.worker.ll -debug
### # $BUILD/bin/opt -load $BUILD/lib/LLVMBuildDFG.so -load $BUILD/lib/LLVMDFG2LLVM_CPU.so -load $BUILD/lib/LLVMClearDFG.so -dfg2llvm-cpu -clearDFG -S main.hpvm.ll.worker.ll -o main.worker.ll -debug # $BUILD/bin/opt -load $BUILD/lib/LLVMBuildDFG.so -load $BUILD/lib/LLVMDFG2LLVM_CPU.so -load $BUILD/lib/LLVMClearDFG.so -dfg2llvm-cpu -clearDFG -S main.hpvm.ll.worker.ll -o main.worker.ll -debug
###
###
### echo echo
### echo echo
### echo echo
### echo echo
### echo "Linking to the runtime..." echo "Linking to the runtime..."
### echo echo
### echo echo
### echo echo
### echo echo
###
### $BUILD/bin/llvm-link -S main.client.ll $BUILD/tools/hpvm/projects/hpvm-rt/hpvm-rt.bc -o main.client.linked.ll $BUILD/bin/llvm-link -S main.client.ll $BUILD/tools/hpvm/projects/hpvm-rt/hpvm-rt.bc -o main.client.linked.ll
### $BUILD/bin/llvm-link -S main.worker.ll $BUILD/tools/hpvm/projects/hpvm-rt/hpvm-rt.bc -o main.worker.linked.ll $BUILD/bin/llvm-link -S main.worker.ll $BUILD/tools/hpvm/projects/hpvm-rt/hpvm-rt.bc -o main.worker.linked.ll
###
### echo echo
### echo echo
### echo echo
### echo echo
### echo "Generating binaries..." echo "Generating binaries..."
### echo echo
### echo echo
### echo echo
### echo echo
###
### $BUILD/bin/clang++ -O1 -lzmq -lOpenCL -L/usr/lib/x86_64-linux-gnu -lrt -lpthread main.client.linked.ll -o client $BUILD/bin/clang++ -O1 -lzmq -lOpenCL -L/usr/lib/x86_64-linux-gnu -lrt -lpthread main.client.linked.ll -o client
### $BUILD/bin/clang++ -O1 -lzmq -lOpenCL -L/usr/lib/x86_64-linux-gnu -lrt -lpthread main.worker.linked.ll -o worker $BUILD/bin/clang++ -O1 -lzmq -lOpenCL -L/usr/lib/x86_64-linux-gnu -lrt -lpthread main.worker.linked.ll -o worker
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