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