Skip to content

Commit 5927be1

Browse files
committed
Added generalization of control dependence graph construction
1 parent 7d0253d commit 5927be1

File tree

6 files changed

+520
-395
lines changed

6 files changed

+520
-395
lines changed

include/tsar/Analysis/Clang/SourceCFG.h

Lines changed: 45 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,12 @@ class WrapperNodeOp : public NodeOp {
7979
Op(clang::DynTypedNode::create(*_Op)) {}
8080
void print(StmtStringType &ResStr) const;
8181
static bool classof(const NodeOp *Node) {
82-
return Node->getKind()==NodeOpKind::Wrapper;
83-
}
82+
return Node->getKind()==NodeOpKind::Wrapper;
83+
}
8484

8585
std::string getOpAddr() const {
8686
return "0x"+(std::stringstream()<<std::hex<<
87-
(long unsigned)&Op.getUnchecked<clang::Stmt>()).str();
87+
(long unsigned)&Op.getUnchecked<clang::Stmt>()).str();
8888
}
8989

9090
~WrapperNodeOp() {
@@ -104,8 +104,8 @@ class NativeNodeOp : public NodeOp {
104104
NativeNodeOp(clang::VarDecl *_Op) : NodeOp(NodeOpKind::Native),
105105
Op(clang::DynTypedNode::create(*_Op)) {}
106106
NativeNodeOp(const WrapperNodeOp &WNO) : NodeOp(WNO), Op(WNO.Op) {
107-
mKind=NodeOpKind::Native;
108-
}
107+
mKind=NodeOpKind::Native;
108+
}
109109
static bool classof(const NodeOp *Node) {
110110
return Node->getKind()==NodeOpKind::Native;
111111
}
@@ -115,15 +115,15 @@ class NativeNodeOp : public NodeOp {
115115
printRefDecl(ResStr);
116116
if (Op.get<clang::Stmt>()) {
117117
Op.getUnchecked<clang::Stmt>().printPretty(StrStream, nullptr,
118-
clang::PrintingPolicy(clang::LangOptions()));
118+
clang::PrintingPolicy(clang::LangOptions()));
119119
}
120120
else
121121
Op.getUnchecked<clang::VarDecl>().print(StrStream);
122122
}
123123

124124
std::string getOpAddr() const {
125125
return "0x"+(std::stringstream()<<std::hex<<
126-
(long unsigned)&Op.getUnchecked<clang::Stmt>()).str();
126+
(long unsigned)&Op.getUnchecked<clang::Stmt>()).str();
127127
}
128128
~NativeNodeOp() = default;
129129
private:
@@ -135,12 +135,12 @@ class ReferenceNodeOp : public NodeOp {
135135
public:
136136
ReferenceNodeOp(NodeOp *_mReferredNode, std::string _mReferenceName)
137137
: NodeOp(NodeOpKind::Reference), mReferredNode(_mReferredNode),
138-
mReferenceName(_mReferenceName) {
138+
mReferenceName(_mReferenceName) {
139139
mReferredNode->mIsReferred=true;
140140
}
141141
static bool classof(const NodeOp *Node) {
142-
return Node->getKind()==NodeOpKind::Reference;
143-
}
142+
return Node->getKind()==NodeOpKind::Reference;
143+
}
144144
void print(StmtStringType &ResStr) const {
145145
ResStr+="<"+mReferenceName+mReferredNode->getOpAddr()+"_REFERRENCE_>";
146146
}
@@ -215,10 +215,21 @@ class LabeledSCFGEdge : public SourceCFGEdge {
215215

216216
class SourceCFGNode : public SourceCFGNodeBase {
217217
friend class SourceCFG;
218+
friend class SourceCFGBuilder;
218219
public:
219-
enum class NodeKind {Default, Service};
220-
SourceCFGNode(NodeKind _mKind) : mKind(_mKind) {}
221-
NodeKind getKind() const { return mKind; }
220+
using OpStorageType=std::vector<NodeOp*>;
221+
SourceCFGNode() = default;
222+
std::size_t size() const { return mBlock.size(); }
223+
NodeOp &operator[](int Index) { return *mBlock[Index]; }
224+
void clearBlock() {
225+
for (auto Op : mBlock)
226+
Op->destroy();
227+
mBlock.clear();
228+
}
229+
230+
~SourceCFGNode() {
231+
clearBlock();
232+
}
222233

223234
inline SourceCFGEdge *addNewEdge(SourceCFGNode &TargetNode,
224235
SourceCFGEdge::EdgeKind Ekind) {
@@ -235,111 +246,43 @@ class SourceCFGNode : public SourceCFGNodeBase {
235246
SourceCFG *getParent() { return OwningGraph; }
236247
explicit operator std::string() const;
237248
void printAsOperand(llvm::raw_ostream &OS, bool B) {
238-
OS<<operator std::string();
239-
}
240-
~SourceCFGNode() = default;
241-
void destroy();
249+
OS<<operator std::string();
250+
}
242251
private:
243-
NodeKind mKind;
244252
SourceCFG *OwningGraph;
245-
};
246-
247-
class ServiceSCFGNode : public SourceCFGNode {
248-
public:
249-
enum class NodeType {GraphStart, GraphStop, GraphEntry};
250-
ServiceSCFGNode(NodeType _mType) : SourceCFGNode(NodeKind::Service),
251-
mType(_mType) {}
252-
NodeType getType() const { return mType; }
253-
static bool classof(const SourceCFGNode *Node) {
254-
return Node->getKind()==NodeKind::Service;
255-
}
256-
explicit operator std::string() const {
257-
switch (mType) {
258-
case NodeType::GraphStart:
259-
return "START";
260-
case NodeType::GraphStop:
261-
return "STOP";
262-
case NodeType::GraphEntry:
263-
return "ENTRY";
264-
}
265-
}
266-
private:
267-
NodeType mType;
268-
};
269-
270-
class DefaultSCFGNode : public SourceCFGNode {
271-
friend class SourceCFG;
272-
friend class SourceCFGBuilder;
273-
public:
274-
using OpStorageType=std::vector<NodeOp*>;
275-
DefaultSCFGNode() : SourceCFGNode(NodeKind::Default) {}
276-
std::size_t size() const { return mBlock.size(); }
277-
static bool classof(const SourceCFGNode *Node) {
278-
return Node->getKind()==NodeKind::Default;
279-
}
280-
NodeOp &operator[](int Index) { return *mBlock[Index]; }
281-
explicit operator std::string() const;
282-
283-
void clearBlock() {
284-
for (auto Op : mBlock)
285-
Op->destroy();
286-
mBlock.clear();
287-
}
288-
289-
~DefaultSCFGNode() {
290-
clearBlock();
291-
}
292-
293-
private:
294253
inline OpStorageType::iterator addOp(NodeOp *_Op) {
295254
mBlock.push_back(_Op);
296-
return mBlock.end()-1;
297-
}
255+
return mBlock.end()-1;
256+
}
298257

299258
template<typename It>
300259
OpStorageType::iterator addOp(It begin, It end) {
301260
for (auto I=begin; I!=end; ++I)
302-
mBlock.push_back(*I);
303-
return mBlock.end()-1;
261+
mBlock.push_back(*I);
262+
return mBlock.end()-1;
304263
}
305-
306264
OpStorageType mBlock;
307265
};
308266

309267
class SourceCFG : public SourceCFGBase {
268+
friend class SourceCFGBuilder;
310269
public:
311270
SourceCFG(const std::string &_mFunctionName) : mFunctionName(_mFunctionName),
312-
mStartNode(&emplaceNode(ServiceSCFGNode::NodeType::GraphStart)),
313-
mStopNode(&emplaceNode(ServiceSCFGNode::NodeType::GraphStop)),
314-
mEntryNode(nullptr) {}
271+
mStartNode(nullptr) {}
315272

316273

317274
inline bool addNode(SourceCFGNode &N) {
318275
return SourceCFGBase::addNode(N)?N.OwningGraph=this, true:false;
319276
}
320277

321-
DefaultSCFGNode &emplaceNode() {
322-
DefaultSCFGNode *CurrNode=new DefaultSCFGNode();
278+
SourceCFGNode &emplaceNode() {
279+
SourceCFGNode *CurrNode=new SourceCFGNode();
323280
addNode(*CurrNode);
324281
return *CurrNode;
325282
}
326283

327-
ServiceSCFGNode &emplaceNode(ServiceSCFGNode::NodeType Type) {
328-
ServiceSCFGNode *CurrNode=new ServiceSCFGNode(Type);
329-
addNode(*CurrNode);
330-
return *CurrNode;
331-
}
332-
333-
ServiceSCFGNode &emplaceEntryNode() {
334-
mEntryNode=new ServiceSCFGNode(ServiceSCFGNode::NodeType::GraphEntry);
335-
addNode(*mEntryNode);
336-
bindNodes(*mEntryNode, *mStartNode, DefaultSCFGEdge::EdgeType::True);
337-
bindNodes(*mEntryNode, *mStopNode, DefaultSCFGEdge::EdgeType::False);
338-
return *mEntryNode;
339-
}
340-
341284
inline void bindNodes(SourceCFGNode &SourceNode,
342-
SourceCFGNode &TargetNode ) {
285+
SourceCFGNode &TargetNode ) {
343286
connect(SourceNode, TargetNode, *(new DefaultSCFGEdge(TargetNode,
344287
DefaultSCFGEdge::EdgeType::Default)));
345288
}
@@ -354,17 +297,13 @@ class SourceCFG : public SourceCFGBase {
354297
clang::SwitchCase *Label) {
355298
connect(SourceNode, TargetNode, *(new LabeledSCFGEdge(TargetNode, Label)));
356299
}
357-
358-
inline ServiceSCFGNode *getStartNode() const { return mStartNode; }
359-
inline ServiceSCFGNode *getStopNode() const { return mStopNode; }
360-
inline ServiceSCFGNode *getEntryNode() const {
361-
return mEntryNode?mEntryNode:mStartNode;
362-
}
300+
// Needed for GraphTraits<AugmentedCFG>
301+
inline SourceCFGNode *getEntryNode() const { return mStartNode; }
363302
inline llvm::StringRef getName() const { return mFunctionName; }
364303
void mergeNodes(SourceCFGNode &AbsorbNode, SourceCFGNode &OutgoingNode);
365304
void deleteNode(SourceCFGNode &_Node);
366305
void deleteEdge(SourceCFGEdge &_Edge);
367-
DefaultSCFGNode *splitNode(DefaultSCFGNode &Node, int It);
306+
SourceCFGNode *splitNode(SourceCFGNode &Node, int It);
368307
void recalculatePredMap();
369308

370309
std::set<SourceCFGNode*> &getPredMap(SourceCFGNode *Node) {
@@ -398,12 +337,12 @@ class SourceCFG : public SourceCFGBase {
398337
for (auto N : Nodes) {
399338
for (auto E : N->getEdges())
400339
E->destroy();
401-
N->destroy();
340+
delete N;
402341
}
403342
}
404343
private:
405344
std::string mFunctionName;
406-
ServiceSCFGNode *mStartNode, *mStopNode, *mEntryNode;
345+
SourceCFGNode *mStartNode;
407346
std::map<SourceCFGNode*, std::set<SourceCFGNode*>> mPredecessorsMap;
408347
};
409348

@@ -419,7 +358,7 @@ class SourceCFGBuilder {
419358
using OutsType=llvm::SmallPtrSet<SourceCFGNode*, 5>;
420359

421360
struct LabelInfo {
422-
DefaultSCFGNode *Node;
361+
SourceCFGNode *Node;
423362
size_t LabelIt;
424363
};
425364

@@ -445,15 +384,15 @@ class SourceCFGBuilder {
445384
bool hasConditionalOperator(clang::Stmt *Root);
446385
SourceCFG *mSCFG;
447386
llvm::SmallDenseMap<clang::Stmt*, LabelInfo> mLabels;
448-
llvm::SmallVector<std::pair<clang::Stmt*, DefaultSCFGNode*>> mGotos;
387+
llvm::SmallVector<std::pair<clang::Stmt*, SourceCFGNode*>> mGotos;
449388
llvm::SmallVector<std::pair<clang::SwitchCase*,
450-
DefaultSCFGNode*>> mSwitchGotos;
389+
SourceCFGNode*>> mSwitchGotos;
451390
LabelInfo mPrevFirstLabel;
452391
size_t mLastLabelIt;
453-
DefaultSCFGNode *mEntryNode, *mNodeToAdd;
392+
SourceCFGNode *mEntryNode, *mNodeToAdd;
454393
std::vector<MarkedOutsType> mDirectOut;
455394
std::stack<OutsType> mContinueOut, mBreakOut;
456-
std::stack<DefaultSCFGNode*> mSwitchNodes;
395+
std::stack<SourceCFGNode*> mSwitchNodes;
457396
NodeOp *mTreeTopParentPtr;
458397
};
459398
} //namespace tsar

0 commit comments

Comments
 (0)