cfa.cpp
No OneTemporary

File Metadata

Created
Wed, Jul 8, 8:53 AM
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*
* cfa.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/cfagraph.h"
#include "pass/cfatemporalseqpass.h"
#include "analysis/temporalseqgraph.h"
#include "pass/compilepass.h"
#include "compilation/decorators.h"
#include "gtest/gtest.h"
#include "aux/xreatemanager-decorators.h"
#include <boost/scoped_ptr.hpp>
#include <boost/smart_ptr/scoped_array.hpp>
#include <boost/format.hpp>
using namespace xreate;
using namespace xreate::cfa;
using namespace std;
TEST(CFA, testFunctionAnnotations) {
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();
StaticModel answer = man->transcend->query("annotationF1");
EXPECT_EQ(1, answer.size());
answer = man->transcend->query("annotationF2");
EXPECT_EQ(1, answer.size());
}
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"
"}"
"guard:: annotation1 {"
" f1 = function::int {\n"
" x = 0:: int. "
" x\n"
" }"
"}"
);
man->analyse();
StaticModel model = man->transcend->query("annotation1");
ScopePacked scopeIdActual = std::get<0>(TranscendLayer::parse<ScopePacked>(model.begin()->second));
CodeScope* scopeEntry = man->root->findFunction("main")->getEntryScope();
const Expression& exprSum = scopeEntry->getDefinition(scopeEntry->getSymbol("sum"));
CodeScope* scopeExpected = exprSum.blocks.front();
ScopePacked scopeIdExpected = man->transcend->pack(scopeExpected);
ASSERT_EQ(scopeIdExpected, scopeIdActual);
}
TEST(CFA, TemporalFnCall) {
details::tier2::XreateManager* man = details::tier2::XreateManager::prepare(
R"Code(
a = function::int{
seq
{x = b():: int. x}
{x = 0 :: 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();
CodeScope* scopeA = man->root->findFunction("a")->getEntryScope();
ScopePacked psSeq1 = man->transcend->pack(scopeSeq1);
ScopePacked psSeq2 = man->transcend->pack(scopeSeq2);
ScopePacked psB = man->transcend->pack(scopeB);
ScopePacked psA = man->transcend->pack(scopeA);
CFATemporalSeqPass* pass = new CFATemporalSeqPass(man);
man->registerPass(pass, PassId::CFATemporalSeqPass);
man->executePasses();
const TemporalSeqGraph* report = dynamic_cast<CFATemporalSeqPass*> (
man->getPassById(PassId::CFATemporalSeqPass))->getReport();
delete pass;
std::ostringstream output;
report->print(output);
cout << output.str() << endl;
ASSERT_TRUE(report->isOrdered(psSeq2, psSeq1));
//ASSERT_TRUE(report->isOrdered(psSeq2, psB));
ASSERT_FALSE(report->isOrdered(psSeq1, psA));
}
TEST(CFA, TemporalChildScope) {
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->transcend->pack(scopeSeq1);
ScopePacked psSeq2 = man->transcend->pack(scopeSeq2);
ScopePacked psIf1 = man->transcend->pack(scopeIf1);
ScopePacked psIf2 = man->transcend->pack(scopeIf2);
CFATemporalSeqPass* pass = new CFATemporalSeqPass(man);
man->registerPass(pass, PassId::CFATemporalSeqPass);
man->executePasses();
const TemporalSeqGraph* report = dynamic_cast<CFATemporalSeqPass*> (
man->getPassById(PassId::CFATemporalSeqPass))->getReport();
delete pass;
std::ostringstream output;
report->print(output);
cout << output.str() << endl;
ASSERT_TRUE(report->isOrdered(psSeq2, psSeq1));
ASSERT_TRUE(report->isOrdered(psIf1, psSeq1));
ASSERT_TRUE(report->isOrdered(psIf2, psSeq1));
ASSERT_FALSE(report->isOrdered(psIf2, psSeq2));
}
TEST(CFA, Temporal_Payload_PathCollapse_1){
details::tier2::XreateManager* man = details::tier2::XreateManager::prepare(
R"Code(
import raw("scripts/cfa/payload.lp").
b = function::int {d()}
c = function::int {d()}
d = function::int {0}
a = function:: int {
seq {context:: test. 0} {b() + c()}
}
)Code");
string script =
R"Code(
cfa_payload(P, scope(Scope), ()):-
bind_scope(Scope, P, strong).
)Code";
CFATemporalSeqPass* pass = new CFATemporalSeqPass(man);
man->registerPass(pass, PassId::CFATemporalSeqPass);
man->registerPass(new CFAPass(man), PassId::CFAPass);
man->executePasses();
const TemporalSeqGraph* report = dynamic_cast<CFATemporalSeqPass*> (
man->getPassById(PassId::CFATemporalSeqPass))->getReport();
man->transcend->addRawScript(move(script));
testing::internal::CaptureStdout();
man->analyse();
std::string outputActual = testing::internal::GetCapturedStdout();
cout << outputActual << endl;
string outputExpected = "cfa_payload(test,scope(2),())";
ASSERT_NE(std::string::npos, outputActual.find(outputExpected));
delete pass;
}

Event Timeline