cfa.cpp
No OneTemporary

File Metadata

Created
Sat, Mar 14, 2:54 AM
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*
* testsCFG.cpp
*
* Created on: Jul 17, 2015
* Author: pgess <v.melnychenko@xreate.org>
*/
#include "xreatemanager.h"
#include "pass/dfapass.h"
#include "pass/cfapass.h"
#include "analysis/DominatorsTreeAnalysisProvider.h"
#include "gtest/gtest.h"
#include "analysis/cfagraph.h"
#include <boost/scoped_ptr.hpp>
#include <boost/smart_ptr/scoped_array.hpp>
using namespace xreate;
using namespace xreate::cfa;
using namespace std;
TEST(CFA, testFunctionAnnotationsClasp){
string&& program =
"f2 = function::int; annotationF2 {\n"
" 0\n"
"}\n"
"\n"
"f1 = function:: int; entry; annotationF1 {\n"
" f2() + 10\n"
"}";
details::tier1::XreateManager* man = details::tier1::XreateManager::prepare(move(program));
man->analyse();
ClaspLayer::ModelFragment answer = man->clasp->query("annotationF1");
int countNoneValue = 0;
if (answer) countNoneValue = std::distance(answer->first, answer->second);
EXPECT_EQ(1, countNoneValue);
answer = man->clasp->query("annotationF2");
countNoneValue = 0;
if (answer) countNoneValue = std::distance(answer->first, answer->second);
EXPECT_EQ(1, countNoneValue);
}
TEST(CFA, testLoopContextExists){
details::tier1::XreateManager* man = details::tier1::XreateManager::prepare (
"interface(cfa){\n"
" operator fold:: annotation1.\n"
"}\n"
"\n"
"main = function:: int; entry {\n"
" x = [1..10]:: [int].\n"
" sum = loop fold (x->el:: int, 0->sum):: int {\n"
" el + sum + f1()\n"
" }. \n"
" sum\n"
"}"
"case context:: annotation1 {"
" f1 = function::int {\n"
" x = 0:: int. "
" x\n"
" }"
"}"
);
man->analyse();
ClaspLayer::ModelFragment model = man->clasp->query("annotation1");
ScopePacked scopeIdActual = std::get<0>(ClaspLayer::parse<ScopePacked>(model->first->second));
CodeScope* scopeEntry = man->root->findFunction("main")->getEntryScope();
const Expression& exprSum = scopeEntry->getDefinition(scopeEntry->getSymbol("sum"));
CodeScope* scopeExpected = exprSum.blocks.front();
ScopePacked scopeIdExpected = man->clasp->pack(scopeExpected);
ASSERT_EQ(scopeIdExpected, scopeIdActual);
}
TEST(CFA, DependenciesFnCall){
details::tier2::XreateManager* man = details::tier2::XreateManager::prepare(
R"Code(
a = function::int{
seq
{x = 0:: int. x}
{x = b():: int. x}::int
}
b = function::int {y = 0. y}
)Code");
CodeScope* scopeSeq1 = man->root->findFunction("a")->getEntryScope()->getBody().blocks.front();
CodeScope* scopeSeq2 = *(++man->root->findFunction("a")->getEntryScope()->getBody().blocks.begin());
CodeScope* scopeB = man->root->findFunction("b")->getEntryScope();
ScopePacked psSeq1 = man->clasp->pack(scopeSeq1);
ScopePacked psSeq2 = man->clasp->pack(scopeSeq2);
ScopePacked psB = man->clasp->pack(scopeB);
CFAPass* pass = new CFAPass(man);
man->registerPass(pass, PassId::CFGPass);
man->executePasses();
const CFAGraph* report = dynamic_cast<CFAPassBasic*>(man->getPassById(PassId::CFGPass))->getReport();
auto dependencies = report->__dependencyRelations;
delete pass;
ASSERT_EQ(1, dependencies.count(psSeq2));
ASSERT_EQ(1, dependencies.count(psB));
}
TEST(CFA, DependenciesChildScope){
details::tier2::XreateManager* man = details::tier2::XreateManager::prepare(
R"Code(
a = function::int{
seq
{x = 0:: int. x}
{x=0::int. if(x>0)::int{1} else {0}}::int
}
)Code");
CodeScope* scopeSeq1 = man->root->findFunction("a")->getEntryScope()->getBody().blocks.front();
CodeScope* scopeSeq2 = *(++man->root->findFunction("a")->getEntryScope()->getBody().blocks.begin());
CodeScope* scopeIf1 = scopeSeq2->getBody().blocks.front();
CodeScope* scopeIf2 = *(++scopeSeq2->getBody().blocks.begin());
ScopePacked psSeq1 = man->clasp->pack(scopeSeq1);
ScopePacked psSeq2 = man->clasp->pack(scopeSeq2);
ScopePacked psIf1 = man->clasp->pack(scopeIf1);
ScopePacked psIf2 = man->clasp->pack(scopeIf2);
CFAPass* pass = new CFAPass(man);
man->registerPass(pass, PassId::CFGPass);
man->executePasses();
const CFAGraph* report = dynamic_cast<CFAPassBasic*>(man->getPassById(PassId::CFGPass))->getReport();
auto dependencies = report->__dependencyRelations;
delete pass;
ASSERT_EQ(0, dependencies.count(psSeq1));
ASSERT_EQ(1, dependencies.count(psSeq2));
ASSERT_EQ(1, dependencies.count(psIf1));
ASSERT_EQ(1, dependencies.count(psIf2));
for(auto rec: dependencies)
{
std::cout << rec.first << " " << rec.second << std::endl;
}
}
TEST(CFA, DomReportOneRoot){
std::string program =
R"CODE(
a = function:: int; entry{
seq
{x = 0:: int. x}
{x = 1:: int. x}::int
}
)CODE";
std::unique_ptr<details::tier2::XreateManager> man(details::tier2::XreateManager::prepare(move(program)));
CFAPass* pass = new CFAPass(man.get());
man->registerPass(pass, PassId::CFGPass);
pass->run();
ScopePacked scope1 = man->clasp->pack(man->root->findFunction("a")->getEntryScope()->getBody().blocks.front());
ScopePacked scope2 = man->clasp->pack(*++man->root->findFunction("a")->getEntryScope()->getBody().blocks.begin());
dominators::DominatorsTreeAnalysisProvider* providerDomAnalysis = new dominators::DominatorsTreeAnalysisProvider();
providerDomAnalysis->run(pass->getReport());
dominators::DominatorsTreeAnalysisProvider::Dominators expectedFDom= {
{1, {0, 3}}
,{2, {1, 2}}
};
dominators::DominatorsTreeAnalysisProvider::Dominators expectedPostDom= {
{2, {0, 3}}
,{1, {1, 2}}
};
auto actualFDom = providerDomAnalysis->getForwardDominators();
auto actualPostDom = providerDomAnalysis->getPostDominators();
ASSERT_EQ(expectedFDom, actualFDom);
ASSERT_EQ(expectedPostDom, actualPostDom);
delete providerDomAnalysis;
delete pass;
}

Event Timeline