ClearBlue
BotUpParallelPass.h
1 //
2 // Created by yongchao on 12/20/22.
3 //
4 
5 #ifndef CLEARBLUE_BOTUPPARALLELPASS_H
6 #define CLEARBLUE_BOTUPPARALLELPASS_H
7 
8 #include <condition_variable>
9 #include <llvm/IR/Function.h>
10 #include <llvm/IR/Module.h>
11 #include <llvm/Pass.h>
12 #include <mutex>
13 #include <set>
14 
15 #include "Analysis/CallGraph/CBCallGraph.h"
16 #include "IR/SEG/SymbolicExprGraphBuilder.h"
17 #include "Utils/ProgressBar.h"
18 
19 using namespace llvm;
20 
22 private:
23  Function *F;
24  size_t Index;
25 
27  std::set<TaskDepVertex *> Parents;
28 
30  std::set<TaskDepVertex *> InternalChildren;
31  std::set<TaskDepVertex *> ExternalChildren;
32 
33 public:
34  TaskDepVertex(Function *F, size_t I) : F(F), Index(I) {}
35 
36  void internallyDependsOn(TaskDepVertex *T) {
37  assert(T);
38  InternalChildren.insert(T);
39  T->Parents.insert(this);
40  }
41 
42  void externallyDependsOn(TaskDepVertex *T) {
43  assert(T);
44  ExternalChildren.insert(T);
45  T->Parents.insert(this);
46  }
47 
48  std::set<TaskDepVertex *>::iterator
49  removeParent(std::set<TaskDepVertex *>::iterator It) {
50  if ((*It)->F != F) {
51  (*It)->ExternalChildren.erase(this);
52  } else {
53  (*It)->InternalChildren.erase(this);
54  }
55  return Parents.erase(It);
56  }
57 
58  void removeParent(TaskDepVertex *T) {
59  if (T->F != F) {
60  T->ExternalChildren.erase(this);
61  } else {
62  T->InternalChildren.erase(this);
63  }
64  Parents.erase(T);
65  }
66 
67  bool hasChild(TaskDepVertex *T) {
68  if (T->F != F) {
69  return ExternalChildren.count(T);
70  }
71  return InternalChildren.count(T);
72  }
73 
74  size_t getIndex() { return Index; }
75 
76  Function *getFunction() { return F; }
77 
79  private:
80  std::set<TaskDepVertex *> &InternalChildren;
81  std::set<TaskDepVertex *> &ExternalChildren;
82 
83  std::set<TaskDepVertex *>::iterator It;
84 
85  public:
86  ChildrenIterator(std::set<TaskDepVertex *> &InternalChildren,
87  std::set<TaskDepVertex *> &ExternalChildren, bool Begin)
88  : InternalChildren(InternalChildren),
89  ExternalChildren(ExternalChildren) {
90  if (Begin) {
91  It = InternalChildren.begin();
92  if (It == InternalChildren.end())
93  It = ExternalChildren.begin();
94  } else {
95  It = ExternalChildren.end();
96  }
97  }
98 
99  ChildrenIterator(const ChildrenIterator &ChildrenIt)
100  : InternalChildren(ChildrenIt.InternalChildren),
101  ExternalChildren(ChildrenIt.ExternalChildren), It(ChildrenIt.It) {}
102 
103  ChildrenIterator &operator++() {
104  It++;
105  if (It == InternalChildren.end()) {
106  It = ExternalChildren.begin();
107  }
108  return *this;
109  }
110 
111  ChildrenIterator operator++(int) {
112  ChildrenIterator Old(*this);
113  ++(*this);
114  return Old;
115  }
116 
117  TaskDepVertex *operator*() { return *It; }
118 
119  bool operator==(const ChildrenIterator &CIt) { return It == CIt.It; }
120 
121  bool operator!=(const ChildrenIterator &CIt) { return It != CIt.It; }
122  };
123 
124  std::set<TaskDepVertex *>::iterator internal_children_begin() {
125  return InternalChildren.begin();
126  }
127 
128  std::set<TaskDepVertex *>::iterator internal_children_end() {
129  return InternalChildren.end();
130  }
131 
132  bool internal_children_empty() { return InternalChildren.empty(); }
133 
134  std::set<TaskDepVertex *>::iterator external_children_begin() {
135  return ExternalChildren.begin();
136  }
137 
138  std::set<TaskDepVertex *>::iterator external_children_end() {
139  return ExternalChildren.end();
140  }
141 
142  bool external_children_empty() { return ExternalChildren.empty(); }
143 
144  ChildrenIterator children_begin() {
145  return ChildrenIterator(InternalChildren, ExternalChildren, true);
146  }
147 
148  ChildrenIterator children_end() {
149  return ChildrenIterator(InternalChildren, ExternalChildren, false);
150  }
151 
152  bool children_empty() {
153  return internal_children_empty() && external_children_empty();
154  }
155 
156  std::set<TaskDepVertex *>::iterator parents_begin() {
157  return Parents.begin();
158  }
159 
160  std::set<TaskDepVertex *>::iterator parents_end() { return Parents.end(); }
161 };
162 
164 private:
165  std::vector<TaskDepVertex *> Vertices;
166 
167 public:
168  TaskDepGraph() {}
169 
170  ~TaskDepGraph() {
171  for (auto *V : Vertices) {
172  delete V;
173  }
174  }
175 
176  void add(TaskDepVertex *V) { Vertices.push_back(V); }
177 
178  std::vector<TaskDepVertex *>::iterator begin() { return Vertices.begin(); }
179 
180  std::vector<TaskDepVertex *>::iterator end() { return Vertices.end(); }
181 
182  size_t size() { return Vertices.size(); }
183 
184  const std::vector<TaskDepVertex *> &getVertices() { return Vertices; }
185 };
186 
187 class BotUpParallelPass : public ModulePass {
188 private:
189  unsigned NumTasksEachFunc;
190 
191  ProgressBar Prog;
192  std::mutex Mutex;
193  std::condition_variable Cond;
194  std::vector<TaskDepVertex *> FinishedTasks;
195  std::map<Function *, unsigned> FunctionIndegreeMap;
196 
197 protected:
198  CBCallGraph *CG = nullptr;
199  SymbolicExprGraphBuilder *SEGBuilder = nullptr;
200 
201 public:
202  BotUpParallelPass(char &ID, unsigned NumTasks)
203  : ModulePass(ID), NumTasksEachFunc(NumTasks),
204  Prog("[Sailfish Checking]", ProgressBar::PBS_CharacterStyle) {}
205 
206  virtual ~BotUpParallelPass() {}
207 
208  virtual void getAnalysisUsage(AnalysisUsage &AU) const override;
209 
210  virtual bool runOnModule(Module &M) override;
211 
212  virtual bool runOnFunction(Function &F) = 0;
213 
222  virtual bool runOnFunction(Function &F, unsigned TaskID) = 0;
223 
227  virtual bool releaseMemory(Function &F) = 0;
228 
231  virtual bool internallyDepends(unsigned TaskAID, unsigned TaskBID) = 0;
232 
235  virtual bool externallyDepends(unsigned CallerTaskID,
236  unsigned CalleeTaskID) = 0;
238  inline bool toCheck(const Function *Func) {
239  if (Func && Func->hasName() &&
240  Func->getName().startswith("Pinpoint.CondExit.")) {
241  return false;
242  }
243  return Func && !Func->isIntrinsic() && !Func->isDeclaration();
244  }
245 
246 private:
247  void buildTaskDependenceGraph(TaskDepGraph &TDG, CBCallGraph &CG, Module &M);
248 
249  void buildDepsTemplate(std::vector<TaskDepVertex *> &Tasks);
250 
251  void buildTasks(TaskDepGraph &TDG, Function *F,
252  std::vector<TaskDepVertex *> &Tasks,
253  std::vector<TaskDepVertex *> &Templates);
254 
255  void buildExternalDeps(std::vector<TaskDepVertex *> &CallerTasks,
256  std::vector<TaskDepVertex *> &CalleeTasks,
257  std::vector<TaskDepVertex *> &Templates);
258 
259  void execute(TaskDepVertex *);
260 
261  void finish(TaskDepVertex *);
262 
263  void postProcess(TaskDepVertex *, CBCallGraph &CG);
264 
265  void wait(TaskDepGraph &, CBCallGraph &CG);
266 };
267 
268 #endif // CLEARBLUE_BOTUPPARALLELPASS_H
BotUpParallelPass
Definition: BotUpParallelPass.h:187
TaskDepVertex::ChildrenIterator
Definition: BotUpParallelPass.h:78
BotUpParallelPass::toCheck
bool toCheck(const Function *Func)
return true if the function should be in the dependence graph
Definition: BotUpParallelPass.h:238
SymbolicExprGraphBuilder
Definition: SymbolicExprGraphBuilder.h:38
TaskDepVertex
Definition: BotUpParallelPass.h:21
TaskDepGraph
Definition: BotUpParallelPass.h:163