4#include <unordered_map>
7#include "llvm/ADT/SmallVector.h"
8#include "llvm/ADT/SmallPtrSet.h"
101 llvm::SmallVectorImpl<const clang::CFGElement *>;
109 std::unique_ptr<clang::CFG>
cfg_;
118 std::unordered_map<unsigned int, SplitCFGBlock *>
sccfg_;
124 std::pair<const SplitCFGBlock *, unsigned int>>
130 std::unordered_map<const SplitCFGBlock *, SplitCFGPathInfo>
path_info_;
132 llvm::SmallVector<std::unordered_map<const SplitCFGBlock *, SplitCFGPathInfo>>
144 std::map<SplitCFGBlock*,SplitCFGBlock*>
cop_;
172 clang::CFGBlock *block,
173 const llvm::SmallVectorImpl<std::pair<VectorCFGElementPtr, bool>>
178 const llvm::SmallVector<std::pair<VectorCFGElementPtr, bool>>
185 SplitCFG(clang::ASTContext &context);
187 SplitCFG(clang::ASTContext &context,
const clang::CXXMethodDecl *cxx_decl);
201 const llvm::SmallVectorImpl<llvm::SmallVector<SplitCFGPathPair>>
210 const std::unordered_map<const SplitCFGBlock *, SplitCFGPathInfo>
213 const llvm::SmallVector<std::unordered_map<const SplitCFGBlock *, SplitCFGPathInfo>>
250 template <
typename T>
252 for (
const auto v : vlist) {
253 llvm::dbgs() << v.first->getBlockID() <<
" ";
268 llvm::SmallPtrSet<const SplitCFGBlock *, 32> &visited_blocks,
269 llvm::SmallVectorImpl<const SplitCFGBlock *> &waits_to_visit,
270 llvm::SmallPtrSetImpl<const SplitCFGBlock *> &visited_waits,
271 llvm::SmallVector<SplitCFGPathPair> &curr_path);
288 llvm::SmallPtrSetImpl<const SplitCFGBlock *> &visited,
295 std::pair<const SplitCFGBlock *, SplitCFGBlock::const_succ_iterator>,
304 const llvm::SmallPtrSetImpl<const SplitCFGBlock *> &larger,
305 const llvm::SmallPtrSetImpl<const SplitCFGBlock *> &smaller,
306 llvm::SmallPtrSetImpl<const SplitCFGBlock *> &to);
320 llvm::SmallPtrSetImpl<const SplitCFGBlock *> &to,
321 const llvm::SmallPtrSetImpl<const SplitCFGBlock *> &from);
SuccessorIterator::const_iterator const_succ_iterator
virtual ~SplitCFGPathInfo()
SplitCFGBlockPtrVector true_path_
SplitCFGBlockPtrVector false_path_
llvm::SmallVector< const SplitCFGBlock * > SplitCFGBlockPtrVector
bool isFalsePathValid() const
Return if there is a valid FALSE path.
SplitCFGPathInfo(const SplitCFGBlock *block)
class SplitCFGPathInfo
const SplitCFGBlockPtrVector & getFalsePath() const
Return the list of blocks visited on the FALSE path.
const SplitCFGBlockPtrVector & getTruePath() const
Return the list of blocks visited on the TRUE path.
const clang::CFGBlock * cfg_block_
void dump() const
Dump the paths.
std::string toStringFalsePath() const
Converts the TRUE path into a string for testing.
bool isTruePathValid() const
Return if there is a valid TRUE path.
SplitCFGPathInfo & operator=(const SplitCFGPathInfo &from)
std::string toStringTruePath() const
Converts the FALSE path into a string for testing.
const SplitCFGBlock * split_block_
unsigned int next_state_count_
SplitCFGPath sub_path_to_special_node_
llvm::SmallVector< const SplitCFGBlock * > VectorSplitCFGBlockImpl
std::unordered_map< const SplitCFGBlock *, std::pair< const SplitCFGBlock *, unsigned int > > wait_next_state_
Predecessor SplitCFGBlock* => (Wait SplitCFGBlock*)
bool has_ternary_op_
Set to true if the CFG has a ternary operator (ConditionalOperator).
void addSuccessorToVisitOrPop(bool parent_has_wait, const SplitCFGBlock *BB, llvm::SmallVector< std::pair< const SplitCFGBlock *, SplitCFGBlock::const_succ_iterator >, 8 > &to_visit, bool found)
void setTruePathInfo(const SplitCFGBlock *sblock, const SplitCFGPath &newly_visited, int ix=-1)
void splitBlock(clang::CFGBlock *block)
Split a CFGBlock into respective SplitCFGBlock if the CFGBlock has wait statements in it.
bool isConditional(const SplitCFGBlock *block) const
Checks if the block is a conditional. Note that this is different than ternary since the terminator i...
void dumpWaitNextStates() const
void dump() const
Dump member functions.
SplitCFG(const SplitCFG &from)=delete
Disallow a copy constructor for SCCFG.
llvm::SmallVector< const SplitCFGBlock * > VectorSplitCFGBlock
void dumpSmallVector(llvm::SmallVectorImpl< T > &vlist)
bool isElementWait(const clang::CFGElement &element) const
Checks if a CFGBlock has a wait() call in it.
void updateVisitedBlocks(llvm::SmallPtrSetImpl< const SplitCFGBlock * > &to, const llvm::SmallPtrSetImpl< const SplitCFGBlock * > &from)
void dumpPathInfo() const
void generate_paths()
Generates the paths between wait statements.
clang::ASTContext & context_
The context necessary to access translation unit.
void identifyConfluenceBlocks()
Identify confluence blocks in the CFG.
bool getUnvisitedSuccessor(const SplitCFGBlock *curr_block, SplitCFGBlock::const_succ_iterator &I, llvm::SmallPtrSetImpl< const SplitCFGBlock * > &visited, const SplitCFGBlock *&block)
std::set< SplitCFGBlock * > identifySkipBlocks()
std::pair< const SplitCFGBlock *, SupplementaryInfo > SplitCFGPathPair
bool isTruePath(const SplitCFGBlock *parent_block, const SplitCFGBlock *block) const
void setFalsePathInfo(const SplitCFGBlock *sblock, const SplitCFGPath &newly_visited)
SplitCFG(clang::ASTContext &context)
Constructor.
bool isLoop(const SplitCFGBlock *block) const
Checks if the block is a loop block.
const llvm::SmallVectorImpl< llvm::SmallVector< SplitCFGPathPair > > & getPathsFound()
Returns the paths that were found in the SCCFG.
void dumpCurrPath(SplitCFGPath &curr_path) const
llvm::SmallVector< SplitCFGPathPair > SplitCFGPath
void addSuccessors(SplitCFGBlock *to, const clang::CFGBlock *from)
Add successors to the SplitCFGBlock.
std::unordered_map< const clang::CFGBlock *, SplitCFGBlock > split_blocks_
The split blocks in the CFG.
llvm::APInt getWaitArgument(const clang::CFGElement &element) const
Returns the argument to a wait statement. Note that the only one supported are no arguments or intege...
SplitCFGBlock * outter_top_
This is the pointer to the outtermost ternary operator.
llvm::SmallVector< SplitCFGPath > paths_
Paths of BBs generated.
bool isLoopWithTwoSuccessors(const SplitCFGBlock *block) const
void setDifference(const llvm::SmallPtrSetImpl< const SplitCFGBlock * > &larger, const llvm::SmallPtrSetImpl< const SplitCFGBlock * > &smaller, llvm::SmallPtrSetImpl< const SplitCFGBlock * > &to)
Compute the set difference between two SmallPtrSets.
llvm::SmallVector< std::pair< VectorCFGElementPtrImpl, bool > > split_elements
const llvm::SmallVector< std::unordered_map< const SplitCFGBlock *, SplitCFGPathInfo > > & getAllPathInfo() const
void addPathToSpecialNode(const SplitCFGPath &from)
llvm::SmallVector< std::unordered_map< const SplitCFGBlock *, SplitCFGPathInfo > > all_path_info_
std::unordered_map< const SplitCFGBlock *, SplitCFGPathInfo > path_info_
Map a SplitCFGBlock* to its path information. Stores the path information for the blocks that are imp...
std::unordered_map< unsigned int, SplitCFGBlock * > sccfg_
The block id to block for SCCFG.
llvm::SmallVectorImpl< const clang::CFGElement * > VectorCFGElementPtrImpl
const std::unordered_map< const SplitCFGBlock *, SplitCFGPathInfo > & getPathInfo() const
void createWaitSplitCFGBlocks(clang::CFGBlock *block, const llvm::SmallVectorImpl< std::pair< VectorCFGElementPtr, bool > > &split_elements)
Creates the SplitCFGBlocks for CFGBlock with a wait.
bool isTernaryOperator(const SplitCFGBlock *block) const
Checks if the block is contains a terminator that is a ternary operator.
std::map< SplitCFGBlock *, SplitCFGBlock * > getConfluenceBlocks() const
Rework.
llvm::SmallVector< const clang::CFGElement * > VectorCFGElementPtr
void createUnsplitBlocks()
Creates SplitCFGBlocks for all CFGBlocks that do not have a wiat. splitBlock() creates the SplitCFGBl...
std::map< SplitCFGBlock *, SplitCFGBlock * > cop_
virtual ~SplitCFG()
Destructor that erases all SplitCFGBlocks created.
SplitCFG & operator=(const SplitCFG &)=delete
Disallow assignment operator.
void dumpVisitedBlocks(llvm::SmallPtrSetImpl< const SplitCFGBlock * > &visited)
void addNextStatesToBlocks()
void construct_sccfg(const clang::CXXMethodDecl *method)
Construct the SCCFG.
void dumpSplitElements(const llvm::SmallVector< std::pair< VectorCFGElementPtr, bool > > &split_elements) const
Dump all the CFGElements that were split.
void addPredecessors(SplitCFGBlock *to, const clang::CFGBlock *from)
Add predecessors to the SplitCFGBlock.
void dumpAllPathInfo() const
const SplitCFGPath dfs_visit_wait(const SplitCFGBlock *BB, llvm::SmallPtrSet< const SplitCFGBlock *, 32 > &visited_blocks, llvm::SmallVectorImpl< const SplitCFGBlock * > &waits_to_visit, llvm::SmallPtrSetImpl< const SplitCFGBlock * > &visited_waits, llvm::SmallVector< SplitCFGPathPair > &curr_path)
Modified DFS to create all paths within wait statements and from the root node.
std::unique_ptr< clang::CFG > cfg_
The saved CFG for a given method.
SupplementaryInfo(const SplitCFGBlock *block)
Construct object using SplitCFGBlock.
int getPathId() const
Returns the path identifier.
int getFalseId() const
Returns the path identifier for the false path.
SupplementaryInfo & operator=(const SupplementaryInfo &from)
virtual ~SupplementaryInfo()
const SplitCFGBlock * getSplitCFGBlock() const
Returns pointer to the SplitCFGBlock.
const SplitCFGBlock * split_block_
Member variables.