Page Menu
Home
Xreate
Search
Configure Global Search
Log In
Docs
Questions
Repository
Issues
Patches
Internal API
Files
F2730028
dfagraph.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Fri, Mar 13, 7:37 PM
Size
6 KB
Mime Type
text/x-c++
Expires
Sun, Mar 15, 7:37 PM (1 d, 21 h)
Engine
blob
Format
Raw Data
Handle
243300
Attached To
rXR Xreate
dfagraph.cpp
View Options
/* 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 data
*
*/
#include "analysis/dfagraph.h"
#include "analysis/utils.h"
#include <list>
using namespace std;
namespace xreate {namespace dfa {
struct VisitorNodeHash : public boost::static_visitor<size_t>
{
std::size_t operator()(const xreate::SymbolPacked& node) const noexcept
{
return 2* (node.identifier + 2 * node.scope + 3 * std::abs(node.version)) + 1;
}
std::size_t operator()(const xreate::dfa::SymbolAnonymous& node) const noexcept
{
return 2 * node.id;
}
};
}}
std::size_t
hash<xreate::dfa::SymbolNode>::operator()(xreate::dfa::SymbolNode const& s) const noexcept
{
return boost::apply_visitor(xreate::dfa::VisitorNodeHash(), s);
}
namespace xreate { namespace dfa {
bool operator==(const SymbolAnonymous& s1, const SymbolAnonymous& s2){
return s1.id == s2.id && s1.flagIsUsed == s2.flagIsUsed;
}
//NOTE: Any changes should be reflected in ParseImplAtom<SymbolPacked>
class VisitorFormatSymbol: public boost::static_visitor<boost::format> {
public:
boost::format operator()(const SymbolPacked& node) const {
boost::format formatSymbNamed("s(%1%,%2%,%3%)");
return formatSymbNamed % node.identifier % node.version % node.scope ;
}
boost::format operator()(const SymbolAnonymous& node) const {
//boost::format formatSymbAnonymous("anon(%1%)");
boost::format formatSymbAnonymous("a%1%");
return formatSymbAnonymous % node.id;
}
};
void
DFACallInstance::print(std::ostringstream& output) const{
boost::format formatArgs;
boost::format formatInstance("dfa_callinstance(%1%, %2%).");
boost::format formatRet("dfa_callret(%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
% id % fnName
<< endl;
for(std::pair<SymbolPacked, SymbolNode> rec: args) {
SymbolNode argFormal(rec.first);
output << formatArgs
% id
% boost::apply_visitor(VisitorFormatSymbol(), argFormal)
% boost::apply_visitor(VisitorFormatSymbol(), rec.second)
<< endl;
}
output << formatRet
% id
% boost::apply_visitor(VisitorFormatSymbol(), retActual)
<< 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
% boost::apply_visitor(VisitorFormatSymbol(), nodeDependent)
% boost::apply_visitor(VisitorFormatSymbol(), it->second)
<< endl;
printDependency(output, it->second, it->second);
}
}
void
DFAGraph::printInplaceAnnotations(SymbolNode node, const Expression& expression) {
// write down in-place expression tags:
boost::format formatBind("bind(%1%, %2%).");
if (expression.tags.size()) __usedSymbols.insert(node);
for (const pair<std::string, Expression>& tag : expression.tags){
for (const string& tagPart: xreate::analysis::compile(tag.second)) {
__output << formatBind
% boost::apply_visitor(VisitorFormatSymbol(), node)
% tagPart
<< 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
% boost::apply_visitor(VisitorFormatSymbol(), symbFormal)
% boost::apply_visitor(VisitorFormatSymbol(), 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
% boost::apply_visitor(VisitorFormatSymbol(), symbFormal)
% boost::apply_visitor(VisitorFormatSymbol(), symbActual)
<< endl;
}
void
DFAGraph::printFunctionRet(ManagedFnPtr function, const SymbolNode& symbolRet){
boost::format formatRet("dfa_fnret(%1%, %2%).");
__usedSymbols.insert(symbolRet);
__output << formatRet
% function->getName()
% boost::apply_visitor(VisitorFormatSymbol(), 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(ClaspLayer* clasp){
boost::format formatHint("shint(%1%, \"%2%\").");
for (const SymbolNode& node : __usedSymbols) {
__output << "v(" << boost::apply_visitor(VisitorFormatSymbol(), node) << "). ";
if (const SymbolPacked* symbol = boost::get<SymbolPacked>(&node)){
__output << formatHint % boost::apply_visitor(VisitorFormatSymbol(), node) % clasp->getHintForPackedSymbol(*symbol);
}
__output << endl;
}
}
}} //end of namespace xreate::dfa
Event Timeline
Log In to Comment