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