inline void backward_statements(P& problem, O& OUT, I& IN, OS& OUT_S, IS& IN_S, Statements& statements, mtac::basic_block_p& B, bool& changes){ if(statements.size() > 0){ log::emit<Dev>("Data-Flow") << "OUT_S[" << (statements.size() - 1) << "] before transfer " << OUT_S[statements[statements.size() - 1]] << log::endl; assign(OUT_S[statements.back()], OUT[B], changes); log::emit<Dev>("Data-Flow") << "OUT_S[" << (statements.size() - 1) << "] after transfer " << OUT_S[statements[statements.size() - 1]] << log::endl; for(unsigned i = statements.size() - 1; i > 0; --i){ auto& statement = statements[i]; log::emit<Dev>("Data-Flow") << "IN_S[" << i << "] before transfer " << IN_S[statement] << log::endl; assign(IN_S[statement], problem.transfer(B, statement, OUT_S[statement]), changes); log::emit<Dev>("Data-Flow") << "IN_S[" << i << "] after transfer " << IN_S[statement] << log::endl; log::emit<Dev>("Data-Flow") << "OUT_S[" << (i - 1) << "] before transfer " << OUT_S[statements[i - 1]] << log::endl; OUT_S[statements[i-1]] = IN_S[statement]; log::emit<Dev>("Data-Flow") << "OUT_S[" << (i - 1) << "] after transfer " << OUT_S[statements[i - 1]] << log::endl; } log::emit<Dev>("Data-Flow") << "IN_S[" << 0 << "] before transfer " << IN_S[statements[0]] << log::endl; assign(IN_S[statements[0]], problem.transfer(B, statements[0], OUT_S[statements[0]]), changes); log::emit<Dev>("Data-Flow") << "IN_S[" << 0 << "] after transfer " << IN_S[statements[0]] << log::endl; assign(IN[B], IN_S[statements.front()], changes); } else { //If the basic block is empty, the IN values are the OUT values assign(IN[B], OUT[B], changes); } }
CompoundStmt* wrapInCompoundStmt(clang::ASTContext& C) const { assert(!isSingleStmt() && "Must be more than 1"); llvm::ArrayRef<Stmt*> stmts = llvm::makeArrayRef(m_Stmts.data(), m_Stmts.size()); clang::SourceLocation noLoc; return new (C) clang::CompoundStmt(C, stmts, noLoc, noLoc); }
inline void forward_statements(P& problem, O& OUT, I& IN, OS& OUT_S, IS& IN_S, Statements& statements, mtac::basic_block_p& B, bool& changes){ if(statements.size() > 0){ IN_S[statements.front()] = IN[B]; for(unsigned i = 0; i < statements.size(); ++i){ auto& statement = statements[i]; assign(OUT_S[statement], problem.transfer(B, statement, IN_S[statement]), changes); //The entry value of the next statement are the exit values of the current statement if(i != statements.size() - 1){ IN_S[statements[i+1]] = OUT_S[statement]; } } assign(OUT[B], OUT_S[statements.back()], changes); } else { //If the basic block is empty, the OUT values are the IN values assign(OUT[B], IN[B], changes); } }
void Fix(CompoundStmt* CS) { if (!CS->size()) return; typedef llvm::SmallVector<Stmt*, 32> Statements; Statements Stmts; Stmts.append(CS->body_begin(), CS->body_end()); for (Statements::iterator I = Stmts.begin(); I != Stmts.end(); ++I) { if (!TraverseStmt(*I) && !m_HandledDecls.count(m_FoundDRE->getDecl())) { Sema::DeclGroupPtrTy VDPtrTy = m_Sema->ConvertDeclToDeclGroup(m_FoundDRE->getDecl()); StmtResult DS = m_Sema->ActOnDeclStmt(VDPtrTy, m_FoundDRE->getLocStart(), m_FoundDRE->getLocEnd()); assert(!DS.isInvalid() && "Invalid DeclStmt."); I = Stmts.insert(I, DS.take()); m_HandledDecls.insert(m_FoundDRE->getDecl()); } } CS->setStmts(m_Sema->getASTContext(), Stmts.data(), Stmts.size()); }
bool isSingleStmt() const { return m_Stmts.size() == 1; }