systemc-clang 2.0.0
Parsing SystemC constructs
Loading...
Searching...
No Matches
SplitCFGBlock.h
Go to the documentation of this file.
1//===- SplitCFGBlock.h - Split the CFGBlock separated by waits -*- C++
2//-*-=====//
3//
4// Part of the systemc-clang project.
5// See License.rst
6//
7//===----------------------------------------------------------------------===//
8//
11//
13//===----------------------------------------------------------------------===//
14
15#ifndef _SPLIT_CFG_BLOCK_H_
16#define _SPLIT_CFG_BLOCK_H_
17
18#include "clang/Analysis/CFG.h"
19
20#include "clang/ASTMatchers/ASTMatchers.h"
21#include "clang/ASTMatchers/ASTMatchFinder.h"
22
24#undef DEBUG_TYPE
25#define DEBUG_TYPE "SplitCFGMatcher"
26
27using namespace clang::ast_matchers;
28
29namespace systemc_clang {
30
31class BreakMatcher : public MatchFinder::MatchCallback {
32 private:
35
36 public:
37 bool hasBreak() const { return break_found_; }
38 bool hasWait() const { return wait_found_; }
39
40 void registerMatchers(MatchFinder &finder) {
41 // clang-format off
42 //auto bstmt = stmt(hasDescendant(breakStmt().bind("break_stmt")));
43 auto bstmt = findAll(breakStmt().bind("break_stmt"));
44 auto wait_stmt = findAll(cxxMemberCallExpr(callee(cxxMethodDecl(hasName("wait")))).bind("wait_stmt"));
45 // clang-format on
46
47 finder.addMatcher(bstmt, this);
48 finder.addMatcher(wait_stmt, this);
49 }
50
51 virtual void run(const MatchFinder::MatchResult &result) {
52 auto bk_stmt = const_cast<clang::Stmt *>(
53 result.Nodes.getNodeAs<clang::Stmt>("break_stmt"));
54 auto wait_stmt = const_cast<clang::CXXMemberCallExpr *>(
55 result.Nodes.getNodeAs<clang::CXXMemberCallExpr>("wait_stmt"));
56
57 if (bk_stmt) {
58 LLVM_DEBUG(llvm::dbgs() << "## BreakStmt \n");
59 break_found_ = true;
60 }
61 if (wait_stmt) {
62 LLVM_DEBUG(llvm::dbgs() << "## Wait\n");
63 wait_found_ = true;
64 }
65 }
66
67 void dump() {
68 if (break_found_) {
69 LLVM_DEBUG(llvm::dbgs() << "## BREAK FOUND\n");
70 }
71 }
72};
73
80 public:
81 using VectorCFGElementPtr = llvm::SmallVector<const clang::CFGElement *>;
83 llvm::SmallVectorImpl<const clang::CFGElement *>;
84 using VectorSplitCFGBlockPtr = llvm::SmallVector<const SplitCFGBlock *>;
85 using VectorSplitCFGBlockPtrImpl = llvm::SmallVector<const SplitCFGBlock *>;
86
87 private:
88 friend class SplitCFG;
89
91 const clang::CFGBlock *block_;
95
97
99
102
105
107 unsigned int id_;
109 unsigned int next_state_;
111 llvm::APInt wait_arg_;
112
113
116 llvm::SmallVector<unsigned int> wait_element_ids_;
117
121 llvm::SmallVector<const SplitCFGBlock *> predecessors_;
122 llvm::SmallVector<const SplitCFGBlock *> successors_;
123
124 public:
126 using iterator_category = std::forward_iterator_tag;
127 using difference_type = std::ptrdiff_t;
129 using pointer = SplitCFGBlock *; // or also value_type*
130 using reference = SplitCFGBlock &; // or also value_type&
131 using VectorSuccessors = llvm::SmallVector<const SplitCFGBlock *>;
132 using const_iterator = VectorSuccessors::const_iterator;
133
134 public:
135 VectorSuccessors::const_iterator begin() { return succs_.begin(); }
136 VectorSuccessors::const_iterator end() { return succs_.end(); }
137
138 SuccessorIterator(const llvm::SmallVector<const SplitCFGBlock *> &succ)
139 : succs_{succ} {}
140
141 private:
143 };
144
145 public:
148 using succ_iterator_range = llvm::iterator_range<succ_iterator>;
149 using const_succ_iterator_range = llvm::iterator_range<const_succ_iterator>;
150
151 bool succ_empty() const { return (successors_.size() == 0); }
158 // succ_iterator_range succs() { return succ_iterator_range{succ_begin(),
159 // succ_end()}; }
163
164 private:
165 // bool isFunctionCall(const clang::CFGElement &element) const;
166 void setNextState(unsigned int state);
167
168 public:
169 friend class SplitCFG;
172
174 SplitCFGBlock(const SplitCFGBlock &from);
175
178 const clang::CFGBlock *getCFGBlock() const;
179
181 std::size_t getNumOfElements() const;
182
185
188
191
193 bool hasWait() const;
194
196 bool isConditional() const;
197
200 bool isLoopWithTwoSuccessors() const;
201
203 bool hasTerminatorBreak() const;
204
206 bool hasTerminatorWait() const;
207
209 unsigned int getBlockID() const;
210
213 unsigned int getNextState() const;
214
216 llvm::APInt getWaitArg() const;
217
219 void insertElements(VectorCFGElementPtr &elements);
220
222 void identifyBreaks(clang::ASTContext &context);
223
224 void dump() const;
225 void dumpColored() const;
226};
227
228}; // namespace systemc_clang
229
230#endif
virtual void run(const MatchFinder::MatchResult &result)
void registerMatchers(MatchFinder &finder)
const_succ_iterator_range const_succs()
SuccessorIterator::const_iterator const_succ_iterator
void identifyBreaks(clang::ASTContext &context)
Identify if the terminator of a CFGBlock has a break in it.
SuccessorIterator::const_iterator succ_begin() const
unsigned int getNextState() const
Returns the next state. Only pertinent for blocks that have waits in them.
llvm::APInt getWaitArg() const
Returns the integer value of the argument supplied to the wait().
llvm::SmallVector< unsigned int > wait_element_ids_
llvm::SmallVector< const SplitCFGBlock * > predecessors_
Predecessors and successors.
const VectorCFGElementPtrImpl & getElements() const
Returns the elements in this block.
void insertElements(VectorCFGElementPtr &elements)
The elements are added to this SplitCFGBlock.
bool hasTerminatorWait() const
Return whether the terminator for this block has a wait statement in it.
void setNextState(unsigned int state)
const clang::CFGBlock * getCFGBlock() const
Returns the pointer to the original CFGBlock from which the SplitCFGBlock was created.
const clang::CFGBlock * block_
A pointer to the original CFGBlock.
llvm::iterator_range< succ_iterator > succ_iterator_range
bool isLoopWithTwoSuccessors() const
Return whether the SplitCFGBlock is a loop CFGBlock with two succesors.
llvm::iterator_range< const_succ_iterator > const_succ_iterator_range
bool terminator_has_break_
The terminator has break.
unsigned int id_
The block id.
const VectorSplitCFGBlockPtrImpl & getPredecessors() const
Returns the predecessors for the block.
llvm::SmallVector< const clang::CFGElement * > VectorCFGElementPtr
bool isConditional() const
Return whether the SplitCFGBlock is an IF CFGBlock.
llvm::SmallVector< const SplitCFGBlock * > VectorSplitCFGBlockPtrImpl
llvm::SmallVectorImpl< const clang::CFGElement * > VectorCFGElementPtrImpl
unsigned int getBlockID() const
Returns the block ID for the SplitCFGBlock.
bool hasWait() const
Returns whether the SplitCFGBlock is a wait block or not.
SuccessorIterator::const_iterator succ_end() const
const VectorSplitCFGBlockPtrImpl & getSuccessors() const
Returns the successors for the block.
bool terminator_has_wait_
The terminator has break.
unsigned int next_state_
The next state that the wait would transform to.
llvm::SmallVector< const SplitCFGBlock * > successors_
llvm::SmallVector< const SplitCFGBlock * > VectorSplitCFGBlockPtr
VectorCFGElementPtr elements_
CFG Elements.
llvm::APInt wait_arg_
The wait argument.
bool hasTerminatorBreak() const
Return whether the terminator for this block has a break statement in it.
std::size_t getNumOfElements() const
Returns the number of CFGElements in this block.
VectorSuccessors::const_iterator begin()
llvm::SmallVector< const SplitCFGBlock * > VectorSuccessors
SuccessorIterator(const llvm::SmallVector< const SplitCFGBlock * > &succ)
VectorSuccessors::const_iterator end()
VectorSuccessors::const_iterator const_iterator