dfagraph.cpp
No OneTemporary

File Metadata

Created
Tue, Jul 7, 5:29 PM

dfagraph.cpp

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* File: DFAGraph.h
* Author: pgess <v.melnychenko@xreate.org>
*
*/
/**
* \file dfagraph.h
* \brief Data Flow Analysis(DFA) graph representation
*
*/
#include "analysis/dfagraph.h"
#include "analysis/utils.h"
using namespace std;
using namespace xreate::analysis;
namespace xreate { namespace dfa {
void
DFACallInstance::print(std::ostringstream& output) const{
boost::format formatArgs;
boost::format formatInstance("dfa_callfn(%1%, %2%).");
switch (type) {
case WEAK:
formatArgs = boost::format("weak(dfa_callargs(%1%, %2%, %3%)).");
break;
case STRONG:
formatArgs = boost::format("weak(dfa_callargs(%1%, %2%, %3%)).\ndfa_callargs(%1%, %2%, %3%).");
break;
}
output << formatInstance
% analysis::writeSymbolNode(retActual)
% fnName
<< endl;
for(std::pair<SymbolPacked, SymbolNode> rec: args) {
SymbolNode argFormal(rec.first);
output << formatArgs
% analysis::writeSymbolNode(retActual)
% analysis::writeSymbolNode(argFormal)
% analysis::writeSymbolNode(rec.second)
<< endl;
}
}
void
DFAGraph::addDependency(const SymbolNode& node, const SymbolNode& subnode){
__dependencies.emplace(node, subnode);
if (boost::get<SymbolPacked>(&node)){
__usedSymbols.insert(node);
}
if (boost::get<SymbolPacked>(&subnode)){
__usedSymbols.insert(node);
}
}
void
DFAGraph::printDependencies(std::ostringstream& output) const{
for(const SymbolNode& root: __roots){
printDependency(output, root, root);
}
}
void
DFAGraph::printDependency(std::ostringstream& output, const SymbolNode& nodeCurrent, const SymbolNode& nodeDependent) const {
auto range = __dependencies.equal_range(nodeCurrent);
for (auto it = range.first; it != range.second; ++it){
if (boost::get<SymbolAnonymous>(&it->second)){
if (!__usedSymbols.count(it->second)){
printDependency(output, it->second, nodeDependent);
continue;
}
}
boost::format formatDependency("dfa_depends(%1%, %2%).");
output << formatDependency
% analysis::writeSymbolNode(nodeDependent)
% analysis::writeSymbolNode(it->second)
<< endl;
printDependency(output, it->second, it->second);
}
}
void
DFAGraph::printInplaceAnnotation(const SymbolNode& node, const Expression& expression) {
// write down in-place expression tags:
boost::format formatBind("bind(%1%, %2%).");
__usedSymbols.insert(node);
for (const string& tag: xreate::analysis::compile(expression)) {
__output << formatBind
% analysis::writeSymbolNode(node)
% tag
<< endl;
}
}
void
DFAGraph::printLateAnnotation(const SymbolNode& node,
const Expression& expression,
const std::list<latereasoning::LateParameter>& symbols,
const std::list<std::string>& domains){
boost::format formatLateAnnotation("late(%1%, (%2%), (%3%), %4%):- %5%.");
boost::format formatDom("%1%(%2%)");
std::list<std::string> exprSerialized = xreate::analysis::compile(expression);
assert(exprSerialized.size() == 1);
list<string> identSymbols, identNames, domainsSerialised;
auto domainI = domains.begin();
for(auto symbol: symbols){
identSymbols.push_back(analysis::writeSymbolNode(symbol.second).str());
identNames.push_back(symbol.first);
domainsSerialised.push_back((formatDom % *domainI % symbol.first).str());
++domainI;
}
__output << formatLateAnnotation
% analysis::writeSymbolNode(node)
% boost::algorithm::join(identSymbols, ", ")
% boost::algorithm::join(identNames, ", ")
% exprSerialized.front()
% boost::algorithm::join(domainsSerialised, "; ")
<< endl;
}
void
DFAGraph::printAlias(const SymbolNode& symbFormal, const SymbolNode& symbActual){
__usedSymbols.insert(symbFormal); __usedSymbols.insert(symbActual);
boost::format formatAlias("dfa_alias(%1%, %2%).");
__output << formatAlias
% analysis::writeSymbolNode(symbFormal)
% analysis::writeSymbolNode(symbActual)
<< endl;
}
void
DFAGraph::printWeakAlias(const SymbolNode& symbFormal, const SymbolNode& symbActual){
__usedSymbols.insert(symbFormal); __usedSymbols.insert(symbActual);
boost::format formatAlias("weak(dfa_alias(%1%, %2%)).");
__output << formatAlias
% analysis::writeSymbolNode(symbFormal)
% analysis::writeSymbolNode(symbActual)
<< endl;
}
void
DFAGraph::printFunctionRet(ManagedFnPtr function, const SymbolNode& symbolRet){
boost::format formatRet("dfa_fnret(%1%, %2%).");
__usedSymbols.insert(symbolRet);
__output << formatRet
% function->getName()
% analysis::writeSymbolNode(symbolRet)
<< endl;
__roots.insert(symbolRet);
}
void
DFAGraph::addCallInstance(DFACallInstance&& instance){
__usedSymbols.insert(instance.retActual);
for(const auto arg: instance.args){
__usedSymbols.insert(SymbolNode(arg.first));
__usedSymbols.insert(arg.second);
}
__callInstances.push_back(std::move(instance));
}
void
DFAGraph::print(std::ostringstream& output) const{
output << endl << "%\t\tStatic analysis: DFA" << endl;
//Dependencies
printDependencies(output);
//Add generated report
output << __output.str() << endl;
//Call instances
for(const DFACallInstance& instance: __callInstances){
instance.print(output);
}
output << endl;
}
void
DFAGraph::printSymbols(TranscendLayer* transcend){
boost::format formatHint("shint(%1%, \"%2%\").");
for (const SymbolNode& node : __usedSymbols) {
__output << "v(" << analysis::writeSymbolNode(node) << "). ";
if (const SymbolPacked* symbol = boost::get<SymbolPacked>(&node)){
__output << formatHint % analysis::writeSymbolNode(node) % transcend->getHintForPackedSymbol(*symbol);
}
__output << endl;
}
}
void
DFAGraph::printOperator(Operator op, std::list<SymbolNode>&& operands, int dataOpListSize){
std::string opStr;
switch(op){
case Operator::MAP: opStr = "map"; break;
case Operator::FOLD: opStr = "fold"; break;
case Operator::LIST: opStr = "list"; break;
case Operator::LIST_RANGE: opStr = "list_range"; break;
case Operator::INDEX: opStr = "index"; break;
default: assert(false);
}
std::ostringstream bufOperands;
for(const SymbolNode& operand: operands){
__usedSymbols.insert(operand);
bufOperands << analysis::writeSymbolNode(operand) << ", ";
}
if(op == Operator::LIST){
bufOperands << dataOpListSize << ", ";
}
boost::format formatOperator("ast_op_%1%(%2%).");
__output << (formatOperator % opStr % bufOperands.str().substr(0, bufOperands.str().size() - 2)) << endl;
}
}} //end of namespace xreate::dfa

Event Timeline