9 #ifndef IR_SEG_SEGCALLSITE_H
10 #define IR_SEG_SEGCALLSITE_H
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>
21 #include "IR/LLVMWrapper/FunctionWrapper.h"
22 #include "IR/SEG/SEGCallSitePseudoInputNode.h"
23 #include "IR/SEG/SymbolicExprGraph.h"
31 class PersistedSEGCallSite;
39 : InputNode(N), InputIndex(I), IsCommonInput(C) {}
43 std::vector<SEGCallSiteInputStruct> PseudoInputs;
44 std::vector<SEGCallSitePseudoOutputNode *> PseudoOutputs;
45 bool IsBackEdge =
false;
46 bool IsExpanded =
false;
49 namespace FalconPlus {
60 virtual void assembleSEGObject(std::map<int, SEGObject *> &FuncSEGObjMap);
63 std::set<const SEGNodeBase *> CommonInputNodes;
65 std::vector<SEGCallSiteInputStruct> CommonInputs;
68 std::map<WrappedFunction *, SideEffectIO, CmpPointerOfFunction> SideEffectMap;
75 kvec<SEGCallSiteArgumentSummaryNode *> InputSummaryNodes;
76 kvec<SEGOperandNode *> OutputSummaryNodes;
80 friend class IntraFalcon;
81 friend class FalconPlus::IntraFalcon;
82 friend class MantaIntraFalcon;
90 void addPseudoOutput(WrappedFunction *WrappedCallee,
95 void addPseudoInput(WrappedFunction *WrappedCallee,
SEGOperandNode *Node);
101 void addCallee(Function *Callee) {
102 if (getCalledFunction()) {
103 assert(getCalledFunction() == Callee);
105 auto *WrappedCallee = WrappedValue::findWrappedFunction(Callee);
106 SideEffectMap[WrappedCallee];
110 void setInputSummaryNode(
int APDepth,
112 void setOutputSummaryNode(
int APDepth,
SEGOperandNode *SummaryNode);
115 void setBackEdge(WrappedFunction *Callee) {
116 SideEffectMap[Callee].IsBackEdge =
true;
119 bool isBackEdge(WrappedFunction *Callee)
const {
120 if (SideEffectMap.count(Callee)) {
121 return SideEffectMap.at(Callee).IsBackEdge;
126 void setExpanded(WrappedFunction *Callee) {
127 SideEffectMap[Callee].IsExpanded =
true;
130 bool isExpanded(WrappedFunction *Callee)
const {
131 if (Callee && SideEffectMap.count(Callee)) {
132 return SideEffectMap.at(Callee).IsExpanded;
137 virtual PersistedSEGObject *createPersistedObject()
const;
141 const SEGOperandNode *getPseudoInput(Function *,
size_t Index)
const;
143 const SEGOperandNode *getPseudoInput(WrappedFunction *,
size_t Index)
const;
153 bool hasCommonOutput()
const;
155 bool isCommonInput(
const SEGNodeBase *Node)
const {
156 return this->CommonInputNodes.count(Node);
159 size_t getNumOutputs(Function *)
const;
161 size_t getNumPseudoOutputs(Function *)
const;
163 size_t getNumInputs(Function *)
const;
165 size_t getNumCommonInputs()
const;
167 size_t getNumPseudoInputs(Function *)
const;
169 size_t getInputIndex(
const SEGNodeBase *Input)
const;
171 bool hasCallee(Function *Func)
const {
172 auto *WrappedFunc = WrappedValue::findWrappedFunction(Func);
173 return SideEffectMap.count(WrappedFunc);
176 Function *getCalledFunction()
const {
177 return this->getLLVMCallSite().getCalledFunction();
180 WrappedFunction *getWrappedCalledFunction()
const {
181 return this->getWrappedLLVMCallSite().getCalledFunction();
184 static bool classof(
const SEGObject *N) {
185 return N->getKind() == SEGOBJK_CallSite;
193 CmpPointerOfFunction>::const_iterator It;
197 CmpPointerOfFunction> &M) {
225 WrappedFunction *operator*() {
return It->first; }
227 bool operator==(
const CalleeIterator &CIt) {
return It == CIt.It; }
229 bool operator!=(
const CalleeIterator &CIt) {
return It != CIt.It; }
236 const std::vector<SEGCallSiteInputStruct> &CommonIns;
237 const std::vector<SEGCallSiteInputStruct> &PseudoIns;
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) {}
245 : I(It.I), CommonIns(It.CommonIns), PseudoIns(It.PseudoIns) {}
259 return I < CommonIns.size() ? CommonIns[I]
260 : PseudoIns[I - CommonIns.size()];
263 bool operator==(
const InputIterator &It) {
return I == It.I; }
265 bool operator!=(
const InputIterator &It) {
return I != It.I; }
273 const std::vector<SEGCallSitePseudoOutputNode *> &PseudoOuts;
277 const std::vector<SEGCallSitePseudoOutputNode *> &POs)
278 : I(End ? (POs.size() + (CO ? 1 : 0)) : 0), CommonOut(CO),
282 : I(It.I), CommonOut(It.CommonOut), PseudoOuts(It.PseudoOuts) {}
317 CalleeIterator callee_end()
const {
318 return CalleeIterator(
true, SideEffectMap);
321 size_t callee_size()
const {
return SideEffectMap.size(); }
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);
330 InputIterator input_begin(Function *Callee)
const {
331 auto *WrappedCallee = WrappedValue::findWrappedFunction(Callee);
332 return input_begin(WrappedCallee);
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);
342 InputIterator input_end(Function *Callee)
const {
343 auto *WrappedCallee = WrappedValue::findWrappedFunction(Callee);
344 return input_end(WrappedCallee);
347 std::vector<SEGCallSiteInputStruct>::const_iterator
348 common_input_begin()
const {
349 return CommonInputs.begin();
352 std::vector<SEGCallSiteInputStruct>::const_iterator common_input_end()
const {
353 return CommonInputs.end();
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);
363 OutputIterator output_begin(Function *Callee)
const {
364 auto *WrappedCallee = WrappedValue::findWrappedFunction(Callee);
365 return output_begin(WrappedCallee);
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);
375 OutputIterator output_end(Function *Callee)
const {
376 auto *WrappedCallee = WrappedValue::findWrappedFunction(Callee);
377 return output_end(WrappedCallee);