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