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