ClearBlue
SEGCallSite.h
1 /*
2  * SEGCallSite.h
3  *
4  * Qingkai
5  *
6  * This node is to model a call site.
7  */
8 
9 #ifndef IR_SEG_SEGCALLSITE_H
10 #define IR_SEG_SEGCALLSITE_H
11 
12 #include <llvm/IR/BasicBlock.h>
13 #include <llvm/IR/CallSite.h>
14 #include <llvm/IR/Function.h>
15 #include <llvm/IR/Instructions.h>
16 #include <llvm/IR/Value.h>
17 
18 #include <map>
19 #include <vector>
20 
21 #include "IR/LLVMWrapper/FunctionWrapper.h"
22 #include "IR/SEG/SEGCallSitePseudoInputNode.h"
23 #include "IR/SEG/SymbolicExprGraph.h"
24 
25 using namespace llvm;
26 
31 class PersistedSEGCallSite;
32 
33 typedef struct SEGCallSiteInputStruct {
34  SEGOperandNode *InputNode;
35  size_t InputIndex;
36  bool IsCommonInput;
37 
38  SEGCallSiteInputStruct(SEGOperandNode *N, size_t I, bool C)
39  : InputNode(N), InputIndex(I), IsCommonInput(C) {}
41 
42 typedef struct SideEffectIO {
43  std::vector<SEGCallSiteInputStruct> PseudoInputs;
44  std::vector<SEGCallSitePseudoOutputNode *> PseudoOutputs;
45  bool IsBackEdge = false;
46  bool IsExpanded = false;
47 } SideEffectIO;
48 
49 namespace FalconPlus {
50 class IntraFalcon;
51 }
52 
53 class SEGCallSite : public SEGSiteBase {
54 public:
57  SEGCallSite(PersistedSEGCallSite *Site, SymbolicExprGraph *SEG)
58  : SEGSiteBase(Site, SEG) {}
59 
60  virtual void assembleSEGObject(std::map<int, SEGObject *> &FuncSEGObjMap);
61 
62 private:
63  std::set<const SEGNodeBase *> CommonInputNodes;
64 
65  std::vector<SEGCallSiteInputStruct> CommonInputs;
66  SEGCallSiteCommonOutputNode *CommonOutput = nullptr;
67 
68  std::map<WrappedFunction *, SideEffectIO, CmpPointerOfFunction> SideEffectMap;
69 
70  // Input and output summary nodes
71  // Index 0 means the ap-depth larger than considered
72  // Index from 1 to InputSummaryNode.size(), is the summary nodes for the
73  // corresponding ap-depth
74  // TODO: Summary outputs are not enabled now
75  kvec<SEGCallSiteArgumentSummaryNode *> InputSummaryNodes;
76  kvec<SEGOperandNode *> OutputSummaryNodes;
77 
78  SEGCallSite(Instruction *CS, SymbolicExprGraph *G);
79 
80  friend class IntraFalcon;
81  friend class FalconPlus::IntraFalcon;
82  friend class MantaIntraFalcon;
83  friend class SymbolicExprGraph;
84  friend class SymbolicExprGraphBuilder;
85  friend class OCValueFlowBuilder;
86 
87 private:
88  void addPseudoOutput(Function *, SEGCallSitePseudoOutputNode *Node);
89 
90  void addPseudoOutput(WrappedFunction *WrappedCallee,
92 
93  void addPseudoInput(Function *, SEGOperandNode *Node);
94 
95  void addPseudoInput(WrappedFunction *WrappedCallee, SEGOperandNode *Node);
96 
97  void setCommonOutput(SEGCallSiteCommonOutputNode *Node);
98 
99  void addCommonInput(SEGOperandNode *Node);
100 
101  void addCallee(Function *Callee) {
102  if (getCalledFunction()) {
103  assert(getCalledFunction() == Callee);
104  }
105  auto *WrappedCallee = WrappedValue::findWrappedFunction(Callee);
106  SideEffectMap[WrappedCallee];
107  }
108 
109  // set input/output summary node with ap-depth
110  void setInputSummaryNode(int APDepth,
111  SEGCallSiteArgumentSummaryNode *SummaryNode);
112  void setOutputSummaryNode(int APDepth, SEGOperandNode *SummaryNode);
113 
114 public:
115  void setBackEdge(WrappedFunction *Callee) {
116  SideEffectMap[Callee].IsBackEdge = true;
117  }
118 
119  bool isBackEdge(WrappedFunction *Callee) const {
120  if (SideEffectMap.count(Callee)) {
121  return SideEffectMap.at(Callee).IsBackEdge;
122  }
123  return false;
124  }
125 
126  void setExpanded(WrappedFunction *Callee) {
127  SideEffectMap[Callee].IsExpanded = true;
128  }
129 
130  bool isExpanded(WrappedFunction *Callee) const {
131  if (Callee && SideEffectMap.count(Callee)) {
132  return SideEffectMap.at(Callee).IsExpanded;
133  }
134  return false;
135  }
136 
137  virtual PersistedSEGObject *createPersistedObject() const;
138 
139  const SEGOperandNode *getCommonInput(size_t Index) const;
140 
141  const SEGOperandNode *getPseudoInput(Function *, size_t Index) const;
142 
143  const SEGOperandNode *getPseudoInput(WrappedFunction *, size_t Index) const;
144 
145  const SEGCallSiteCommonOutputNode *getCommonOutput() const;
146 
147  const SEGCallSitePseudoOutputNode *getPseudoOutput(Function *,
148  size_t Index) const;
149 
150  const SEGCallSitePseudoOutputNode *getPseudoOutput(WrappedFunction *,
151  size_t Index) const;
152 
153  bool hasCommonOutput() const;
154 
155  bool isCommonInput(const SEGNodeBase *Node) const {
156  return this->CommonInputNodes.count(Node);
157  }
158 
159  size_t getNumOutputs(Function *) const;
160 
161  size_t getNumPseudoOutputs(Function *) const;
162 
163  size_t getNumInputs(Function *) const;
164 
165  size_t getNumCommonInputs() const;
166 
167  size_t getNumPseudoInputs(Function *) const;
168 
169  size_t getInputIndex(const SEGNodeBase *Input) const;
170 
171  bool hasCallee(Function *Func) const {
172  auto *WrappedFunc = WrappedValue::findWrappedFunction(Func);
173  return SideEffectMap.count(WrappedFunc);
174  }
175 
176  Function *getCalledFunction() const {
177  return this->getLLVMCallSite().getCalledFunction();
178  }
179 
180  WrappedFunction *getWrappedCalledFunction() const {
181  return this->getWrappedLLVMCallSite().getCalledFunction();
182  }
183 
184  static bool classof(const SEGObject *N) {
185  return N->getKind() == SEGOBJK_CallSite;
186  }
187 
188  /*==------------------------Iterators--------------------==*/
189 
191  private:
192  std::map<WrappedFunction *, SideEffectIO,
193  CmpPointerOfFunction>::const_iterator It;
194 
195  public:
196  CalleeIterator(bool End, const std::map<WrappedFunction *, SideEffectIO,
197  CmpPointerOfFunction> &M) {
198  if (End) {
199  It = M.end();
200  } else {
201  It = M.begin();
202  }
203  }
204 
205  CalleeIterator(const CalleeIterator &CIt) : It(CIt.It) {}
206 
207  CalleeIterator &operator=(const CalleeIterator &CIt) {
208  if (this != &CIt) {
209  this->It = CIt.It;
210  }
211  return *this;
212  }
213 
214  CalleeIterator operator++(int) {
215  CalleeIterator Old(*this);
216  ++(*this);
217  return Old;
218  }
219 
220  CalleeIterator &operator++() {
221  It++;
222  return *this;
223  }
224 
225  WrappedFunction *operator*() { return It->first; }
226 
227  bool operator==(const CalleeIterator &CIt) { return It == CIt.It; }
228 
229  bool operator!=(const CalleeIterator &CIt) { return It != CIt.It; }
230  };
231 
233  private:
234  size_t I;
235 
236  const std::vector<SEGCallSiteInputStruct> &CommonIns;
237  const std::vector<SEGCallSiteInputStruct> &PseudoIns;
238 
239  public:
240  InputIterator(bool End, const std::vector<SEGCallSiteInputStruct> &CI,
241  const std::vector<SEGCallSiteInputStruct> &PI)
242  : I(End ? CI.size() + PI.size() : 0), CommonIns(CI), PseudoIns(PI) {}
243 
244  InputIterator(const InputIterator &It)
245  : I(It.I), CommonIns(It.CommonIns), PseudoIns(It.PseudoIns) {}
246 
247  InputIterator operator++(int) {
248  InputIterator Old(*this);
249  ++(*this);
250  return Old;
251  }
252 
253  InputIterator &operator++() {
254  I++;
255  return *this;
256  }
257 
258  const SEGCallSiteInputStruct &operator*() {
259  return I < CommonIns.size() ? CommonIns[I]
260  : PseudoIns[I - CommonIns.size()];
261  }
262 
263  bool operator==(const InputIterator &It) { return I == It.I; }
264 
265  bool operator!=(const InputIterator &It) { return I != It.I; }
266  };
267 
269  private:
270  size_t I;
271 
272  SEGCallSiteCommonOutputNode *CommonOut;
273  const std::vector<SEGCallSitePseudoOutputNode *> &PseudoOuts;
274 
275  public:
277  const std::vector<SEGCallSitePseudoOutputNode *> &POs)
278  : I(End ? (POs.size() + (CO ? 1 : 0)) : 0), CommonOut(CO),
279  PseudoOuts(POs) {}
280 
281  OutputIterator(const OutputIterator &It)
282  : I(It.I), CommonOut(It.CommonOut), PseudoOuts(It.PseudoOuts) {}
283 
284  OutputIterator operator++(int) {
285  OutputIterator Old(*this);
286  ++(*this);
287  return Old;
288  }
289 
290  OutputIterator &operator++() {
291  I++;
292  return *this;
293  }
294 
295  const SEGCallSiteOutputNode *operator*() {
296  if (CommonOut) {
297  if (I == 0) {
298  return (const SEGCallSiteOutputNode *)CommonOut;
299  } else {
300  assert(I >= 1);
301  return (const SEGCallSiteOutputNode *)PseudoOuts[I - 1];
302  }
303  } else {
304  return (const SEGCallSiteOutputNode *)PseudoOuts[I];
305  }
306  }
307 
308  bool operator==(const OutputIterator &It) { return I == It.I; }
309 
310  bool operator!=(const OutputIterator &It) { return I != It.I; }
311  };
312 
313  CalleeIterator callee_begin() const {
314  return CalleeIterator(false, SideEffectMap);
315  }
316 
317  CalleeIterator callee_end() const {
318  return CalleeIterator(true, SideEffectMap);
319  }
320 
321  size_t callee_size() const { return SideEffectMap.size(); }
322 
323  InputIterator input_begin(WrappedFunction *Callee) const {
324  auto It = SideEffectMap.find(Callee);
325  assert(It != SideEffectMap.end());
326  auto &PseudoInputsVec = It->second.PseudoInputs;
327  return InputIterator(false, CommonInputs, PseudoInputsVec);
328  }
329 
330  InputIterator input_begin(Function *Callee) const {
331  auto *WrappedCallee = WrappedValue::findWrappedFunction(Callee);
332  return input_begin(WrappedCallee);
333  }
334 
335  InputIterator input_end(WrappedFunction *Callee) const {
336  auto It = SideEffectMap.find(Callee);
337  assert(It != SideEffectMap.end());
338  auto &PseudoInputsVec = It->second.PseudoInputs;
339  return InputIterator(true, CommonInputs, PseudoInputsVec);
340  }
341 
342  InputIterator input_end(Function *Callee) const {
343  auto *WrappedCallee = WrappedValue::findWrappedFunction(Callee);
344  return input_end(WrappedCallee);
345  }
346 
347  std::vector<SEGCallSiteInputStruct>::const_iterator
348  common_input_begin() const {
349  return CommonInputs.begin();
350  }
351 
352  std::vector<SEGCallSiteInputStruct>::const_iterator common_input_end() const {
353  return CommonInputs.end();
354  }
355 
356  OutputIterator output_begin(WrappedFunction *Callee) const {
357  auto It = SideEffectMap.find(Callee);
358  assert(It != SideEffectMap.end());
359  auto &PseudoOutputsVec = It->second.PseudoOutputs;
360  return OutputIterator(false, CommonOutput, PseudoOutputsVec);
361  }
362 
363  OutputIterator output_begin(Function *Callee) const {
364  auto *WrappedCallee = WrappedValue::findWrappedFunction(Callee);
365  return output_begin(WrappedCallee);
366  }
367 
368  OutputIterator output_end(WrappedFunction *Callee) const {
369  auto It = SideEffectMap.find(Callee);
370  assert(It != SideEffectMap.end());
371  auto &PseudoOutputsVec = It->second.PseudoOutputs;
372  return OutputIterator(true, CommonOutput, PseudoOutputsVec);
373  }
374 
375  OutputIterator output_end(Function *Callee) const {
376  auto *WrappedCallee = WrappedValue::findWrappedFunction(Callee);
377  return output_end(WrappedCallee);
378  }
379 };
380 
381 #endif
SEGOperandNode
Definition: SymbolicExprGraph.h:539
SEGCallSiteOutputNode
Definition: SEGCallSiteOutputNode.h:20
SEGCallSite
Definition: SEGCallSite.h:53
SEGCallSite::CalleeIterator
Definition: SEGCallSite.h:190
SEGCallSiteArgumentSummaryNode
Definition: SEGCallSiteArgumentSummaryNode.h:18
SymbolicExprGraph
Definition: SymbolicExprGraph.h:855
SEGCallSiteCommonOutputNode
Definition: SEGCallSiteOutputNode.h:60
SEGCallSiteInputStruct
Definition: SEGCallSite.h:33
SEGCallSite::SEGCallSite
SEGCallSite(PersistedSEGCallSite *Site, SymbolicExprGraph *SEG)
Definition: SEGCallSite.h:57
SideEffectIO
Definition: SEGCallSite.h:42
SymbolicExprGraphBuilder
Definition: SymbolicExprGraphBuilder.h:38
SEGObject
Definition: SymbolicExprGraph.h:87
OCValueFlowBuilder
Definition: OCValueFlowBuilder.h:25
SEGCallSite::OutputIterator
Definition: SEGCallSite.h:268
SEGCallSitePseudoOutputNode
Definition: SEGCallSiteOutputNode.h:96
SEGCallSite::InputIterator
Definition: SEGCallSite.h:232
SEGSiteBase
Definition: SymbolicExprGraph.h:776
SEGNodeBase
The node base of symbolic expression graph.
Definition: SymbolicExprGraph.h:288