From 1601e64f7a029546671ff2a7273cdc4b73ebb118 Mon Sep 17 00:00:00 2001
From: Maria Kotsifakou <kotsifa2@illinois.edu>
Date: Mon, 24 Nov 2014 03:35:42 +0000
Subject: [PATCH] Added kernel argument mapping information for dfg2llvm_nvptx.

---
 llvm/include/llvm/IR/DFGraph.h                | 12 +++++++++
 .../DFG2LLVM_NVPTX/DFG2LLVM_NVPTX.cpp         | 26 +++++++++++++------
 llvm/lib/Transforms/Makefile                  |  2 +-
 3 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/llvm/include/llvm/IR/DFGraph.h b/llvm/include/llvm/IR/DFGraph.h
index 2ab5f91c83..06e8e499b2 100644
--- a/llvm/include/llvm/IR/DFGraph.h
+++ b/llvm/include/llvm/IR/DFGraph.h
@@ -335,6 +335,7 @@ public:
   bool isEntryNode();
   bool isExitNode();
   DFEdge* getInDFEdgeAt(unsigned inPort);
+  std::vector<unsigned>* getInArgMap();
   int getAncestorHops(DFNode* N);
 
   virtual void applyDFNodeVisitor(DFNodeVisitor &V) = 0;
@@ -565,6 +566,17 @@ DFEdge* DFNode::getInDFEdgeAt(unsigned inPort) {
   }
   return NULL;
 }
+
+std::vector<unsigned>* DFNode::getInArgMap() {
+  std::vector<unsigned>* map = new std::vector<unsigned>(InDFEdges.size());
+  for (unsigned i = 0; i < InDFEdges.size(); i++) {
+    DFEdge* E = getInDFEdgeAt(i);
+    unsigned pos = E->getSourcePosition();
+    map[i] = pos;
+  }
+  return map;
+}
+
 int DFNode::getAncestorHops(DFNode* N) {
   DFNode* temp = this->getParent();
   int hops = 1;
diff --git a/llvm/lib/Transforms/DFG2LLVM_NVPTX/DFG2LLVM_NVPTX.cpp b/llvm/lib/Transforms/DFG2LLVM_NVPTX/DFG2LLVM_NVPTX.cpp
index c3e49e3904..6140b97c42 100644
--- a/llvm/lib/Transforms/DFG2LLVM_NVPTX/DFG2LLVM_NVPTX.cpp
+++ b/llvm/lib/Transforms/DFG2LLVM_NVPTX/DFG2LLVM_NVPTX.cpp
@@ -55,11 +55,12 @@ public:
 class Kernel {
 public:
   Kernel(Function* _KF, unsigned _gridDim = 0, std::vector<Value*>
-         _globalWGSize = std::vector<Value*>(), unsigned _blockDim = 0,
+         _globalWGSize = std::vector<Value*>(),
+         std::vector<unsigned>* _inArgMap = NULL, unsigned _blockDim = 0,
          std::vector<Value*> _localWGSize = std::vector<Value*>())
     : KernelFunction(_KF),
-      gridDim(_gridDim), globalWGSize(_globalWGSize), blockDim(_blockDim),
-      localWGSize(_localWGSize) {
+      gridDim(_gridDim), globalWGSize(_globalWGSize), inArgMap(_inArgMap),
+      blockDim(_blockDim), localWGSize(_localWGSize) {
 
     assert(gridDim == globalWGSize.size()
            && "gridDim should be same as the size of vector globalWGSize");
@@ -72,9 +73,9 @@ public:
   unsigned blockDim;
   std::vector<Value*> globalWGSize;
   std::vector<Value*> localWGSize;
+  std::vector<unsigned>* inArgMap;
 };
 
-
 // Helper function declarations
 static void getExecuteNodeParams(Value* &, Value* &, Value* &, Kernel*,
                                  ValueToValueMapTy&, Instruction*);
@@ -685,8 +686,16 @@ void CodeGenTraversal::codeGen(DFInternalNode* N) {
 
   } else {
     DEBUG(errs() << "Found intermediate node. Getting size parameters.\n");
-    //TODO : Check that the arguments order of root to intermediate matches
-    // the intermediate to leaf.
+    // Keep track of the arguments order.
+
+    std::vector<unsigned>* map1 = N->getInArgMap();
+    std::vector<unsigned>* map2 = kernel->getInArgMap();
+
+    // The limit is the size of map2, because this is the number of kernel arguments
+    for (unsigned i = 0; i < map2.size(); i++) {
+      map2[i] = map1[map2[i]];
+    }
+    free(map1);
 
   }
 
@@ -707,7 +716,7 @@ void CodeGenTraversal::codeGen(DFLeafNode* N) {
 
   if (!pLevel || !pReplFactor) {
     KernelLaunchNode = PNode;
-    kernel = new Kernel(NULL, N->getNumOfDim(), N->getDimLimits());
+    kernel = new Kernel(NULL, N->getNumOfDim(), N->getDimLimits(), N->getInArgMap());
     // TODO: Find a better way of choosing parameters
     //kernel->gridDim = N->getNumOfDim();
     //kernel->blockDim = N->getNumOfDim();
@@ -725,11 +734,12 @@ void CodeGenTraversal::codeGen(DFLeafNode* N) {
   }
   else {
     errs() << "*************** Entering else part **************\n";
+    KernelLaunchNode = PNode->getParent();
+    assert((PNode->getNumOfDim() == N->getNumOfDim()) && "Dimension number must match");
     /*
     KernelLaunchNode = PNode->getParent();
     kernel->gridDim = PNode->getNumOfDim();
     kernel->blockDim = N->getNumOfDim();
-    // TODO: Handle different number of dimensions
     assert((kernel->gridDim == kernel->blockDim) && "Dimension number must match");
     std::vector<Value*> numOfBlocks = PNode->getDimLimits();
     kernel->localWGSize = N->getDimLimits();
diff --git a/llvm/lib/Transforms/Makefile b/llvm/lib/Transforms/Makefile
index 575ed37a67..69748f6f0d 100644
--- a/llvm/lib/Transforms/Makefile
+++ b/llvm/lib/Transforms/Makefile
@@ -9,7 +9,7 @@
 
 LEVEL = ../..
 PARALLEL_DIRS = Utils Instrumentation Scalar InstCombine IPO Vectorize Hello \
-                ObjCARC BuildDFG DFG2LLVM_NVPTX DFG2LLVM_X86
+                ObjCARC BuildDFG DFG2LLVM_NVPTX DFG2LLVM_X86 ClearDFG
 
 include $(LEVEL)/Makefile.config
 
-- 
GitLab