ClearDFG.cpp 5.21 KB
Newer Older
1
2
3
4
5
6
7
8
//===-------------------------- ClearDFG.cpp --------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
9
//
10
// This pass HPVM intrinsics from HPVM IR. This pass is the final pass that
11
12
13
14
// runs as a part of clean up after construction of dataflowgraph and LLVM
// code generation for different targets from the dataflow graph.
//
//===----------------------------------------------------------------------===//
15
16

#define DEBUG_TYPE "ClearDFG"
Yifan Zhao's avatar
Yifan Zhao committed
17
18
#include "BuildDFG/BuildDFG.h"
#include "llvm/IR/InstIterator.h"
19
20
#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
kotsifa2's avatar
kotsifa2 committed
21
#include "llvm/Support/Debug.h"
Yifan Zhao's avatar
Yifan Zhao committed
22
#include "llvm/Transforms/Utils/ValueMapper.h"
23
24
25
26

using namespace llvm;
using namespace builddfg;

Yifan Zhao's avatar
Yifan Zhao committed
27
// STATISTIC(IntrinsicCounter, "Counts number of hpvm intrinsics greeted");
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

namespace {

// ClearDFG - The first implementation.
struct ClearDFG : public ModulePass {
  static char ID; // Pass identification, replacement for typeid
  ClearDFG() : ModulePass(ID) {}

private:
  // Member variables

  // Functions

public:
  bool runOnModule(Module &M);

Yifan Zhao's avatar
Yifan Zhao committed
44
  void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired<BuildDFG>(); }
45
46
47
48
49
50
};

// Visitor for Code generation traversal (tree traversal for now)
class TreeTraversal : public DFNodeVisitor {

private:
Yifan Zhao's avatar
Yifan Zhao committed
51
  // Member variables
52
53
54
55
56
57
58
  Module &M;
  BuildDFG &DFG;

  // Map from Old function associated with DFNode to new cloned function with
  // extra index and dimension arguments. This map also serves to find out if
  // we already have an index and dim extended function copy or not (i.e.,
  // "Have we visited this function before?")
Yifan Zhao's avatar
Yifan Zhao committed
59
60
61
62
63
  ValueMap<Function *, Function *> FMap;
  DenseMap<DFNode *, CallInst *> CallMap;

  // Functions
  void deleteNode(DFNode *N);
64
65
66

public:
  // Constructor
Yifan Zhao's avatar
Yifan Zhao committed
67
  TreeTraversal(Module &_M, BuildDFG &_DFG) : M(_M), DFG(_DFG) {}
68

Yifan Zhao's avatar
Yifan Zhao committed
69
  virtual void visit(DFInternalNode *N) {
70
71
    // Follows a bottom-up approach for code generation.
    // First generate code for all the child nodes
Yifan Zhao's avatar
Yifan Zhao committed
72
73
74
75
    for (DFGraph::children_iterator i = N->getChildGraph()->begin(),
                                    e = N->getChildGraph()->end();
         i != e; ++i) {
      DFNode *child = *i;
76
77
      child->applyDFNodeVisitor(*this);
    }
Yifan Zhao's avatar
Yifan Zhao committed
78
79
    DEBUG(errs() << "Erasing Node (I) - " << N->getFuncPointer()->getName()
                 << "\n");
80
81
82
    // Generate code for this internal node now. This way all the cloned
    // functions for children exist.
    deleteNode(N);
Yifan Zhao's avatar
Yifan Zhao committed
83
84
85
86
    DEBUG(errs() << "\tDone - "
                 << "\n");
    // errs() << "DONE: Generating Code for Node (I) - " <<
    // N->getFuncPointer()->getName() << "\n";
87
88
  }

Yifan Zhao's avatar
Yifan Zhao committed
89
90
91
  virtual void visit(DFLeafNode *N) {
    DEBUG(errs() << "Erasing Node (L) - " << N->getFuncPointer()->getName()
                 << "\n");
92
    deleteNode(N);
Yifan Zhao's avatar
Yifan Zhao committed
93
94
    DEBUG(errs() << "DONE"
                 << "\n");
95
96
97
98
  }
};

bool ClearDFG::runOnModule(Module &M) {
99
  DEBUG(errs() << "\nCLEARDFG PASS\n");
100
101
102
103
104
  // Get the BuildDFG Analysis Results:
  // - Dataflow graph
  // - Maps from i8* hansles to DFNode and DFEdge
  BuildDFG &DFG = getAnalysis<BuildDFG>();

105
  // DFInternalNode *Root = DFG.getRoot();
Yifan Zhao's avatar
Yifan Zhao committed
106
  std::vector<DFInternalNode *> Roots = DFG.getRoots();
107
108
109
  // BuildDFG::HandleToDFNode &HandleToDFNodeMap = DFG.getHandleToDFNodeMap();
  // BuildDFG::HandleToDFEdge &HandleToDFEdgeMap = DFG.getHandleToDFEdgeMap();

Yifan Zhao's avatar
Yifan Zhao committed
110
111
  Function *VI = M.getFunction("llvm.hpvm.init");
  assert(VI->hasOneUse() && "More than one use of llvm.hpvm.init\n");
Yifan Zhao's avatar
Yifan Zhao committed
112
113
114
  for (Value::user_iterator ui = VI->user_begin(), ue = VI->user_end();
       ui != ue; ui++) {
    Instruction *I = dyn_cast<Instruction>(*ui);
115
116
    I->eraseFromParent();
  }
117
118
  VI->replaceAllUsesWith(UndefValue::get(VI->getType()));
  VI->eraseFromParent();
119

Yifan Zhao's avatar
Yifan Zhao committed
120
121
  Function *VC = M.getFunction("llvm.hpvm.cleanup");
  assert(VC->hasOneUse() && "More than one use of llvm.hpvm.cleanup\n");
Yifan Zhao's avatar
Yifan Zhao committed
122
123
124
  for (Value::user_iterator ui = VC->user_begin(), ue = VC->user_end();
       ui != ue; ui++) {
    Instruction *I = dyn_cast<Instruction>(*ui);
125
126
    I->eraseFromParent();
  }
Yifan Zhao's avatar
Yifan Zhao committed
127

128
129
  VC->replaceAllUsesWith(UndefValue::get(VC->getType()));
  VC->eraseFromParent();
130

131
132
133
134
  // Visitor for Code Generation Graph Traversal
  TreeTraversal *Visitor = new TreeTraversal(M, DFG);

  // Initiate code generation for root DFNode
Yifan Zhao's avatar
Yifan Zhao committed
135
  for (auto rootNode : Roots) {
136
137
    Visitor->visit(rootNode);
  }
138
139
140
141
  delete Visitor;
  return true;
}

Yifan Zhao's avatar
Yifan Zhao committed
142
143
void TreeTraversal::deleteNode(DFNode *N) {
  if (N->isDummyNode())
144
145
    return;
  // Erase Function associated with this node
Yifan Zhao's avatar
Yifan Zhao committed
146
  Function *F = N->getFuncPointer();
147
148
149
  F->replaceAllUsesWith(UndefValue::get(F->getType()));
  F->eraseFromParent();
  // If N is not a root node, we are done. Return.
Yifan Zhao's avatar
Yifan Zhao committed
150
  if (!N->isRoot())
151
152
    return;
  // N is a root node. Delete the Launch Intrinsic associated it with as well.
Yifan Zhao's avatar
Yifan Zhao committed
153
  IntrinsicInst *LI = N->getInstruction();
154
155
156
157
158
159
160
  LI->replaceAllUsesWith(UndefValue::get(LI->getType()));
  LI->eraseFromParent();
}

} // End of namespace

char ClearDFG::ID = 0;
Yifan Zhao's avatar
Yifan Zhao committed
161
162
163
164
static RegisterPass<ClearDFG>
    X("clearDFG", "Delete all DFG functions for which code has been generated",
      false /* does not modify the CFG */,
      true /* transformation, not just analysis */);