dfgpass.cpp
No OneTemporary

File Metadata

Created
Thu, Jul 9, 6:11 AM

dfgpass.cpp

#include "dfgpass.h"
#include "../passmanager.h"
using namespace xreate;
using namespace std;
DFGPass::DFGPass(PassManager* manager)
: AbstractPass(manager), clasp(man->clasp)
{}
SymbolPackedOptional
DFGPass::process(const Expression& expression, PassContext context, const std::string& decl)
{
// write down adhoc expression tags:
if (expression.tags.size() && decl.length()) {
for (pair<std::string, Expression> tag: expression.tags) {
SymbolPacked nodeThis = clasp->pack(context.scope->findSymbol(decl), decl);
__context.graph.addTag(nodeThis, Expression(tag.second));
}
}
switch(expression.__state) {
case Expression::IDENT:
AbstractPass::process(expression, context, decl);
string ident = expression.getValueString();
const Symbol& identSymbol = context.scope->findSymbol(ident);
SymbolPacked nodeFrom = clasp->pack(identSymbol);
if (!decl.empty()) {
SymbolPacked nodeTo = clasp->pack(context.scope->findSymbol(decl));
__context.graph.addLink(move(nodeTo), move(nodeFrom), DFGConnection::ALIAS);
}
return nodeFrom;
}
switch(expression.op) {
case Operator::CALL: {
const string &name = expression.getValueString();
std::vector<SymbolPackedOptional> operands;
operands.reserve(expression.getOperands().size());
for (const Expression &op: expression.getOperands()) {
operands.push_back(process(op, context));
}
ManagedFnPtr function = man->root->findFunction(name);
if (!function) return boost::none;
// set calling relations:
CodeScope *scopeRemote = function->getEntryScope();
std::vector<SymbolPackedOptional>::iterator op = operands.begin();
for (const std::string &arg: scopeRemote->__args) {
if (*op) {
const Symbol &nodeRemote = scopeRemote->findSymbol(arg);
__context.graph.addLink(clasp->pack(nodeRemote), **op, DFGConnection::OPT);
}
++op;
}
SymbolPacked ret = clasp->pack(Symbol{0, scopeRemote});
if (!decl.empty()) {
__context.graph.addLink(
clasp->pack(
context.scope->findSymbol(decl)),
ret, DFGConnection::OPT);
}
return ret;
}
}
std::vector<SymbolPackedOptional> operands;
if (__signatures.count(expression.op)) {
const Expression &scheme = __signatures.at(expression.op);
operands.reserve(expression.getOperands().size());
for (const Expression &op: expression.getOperands()) {
operands.push_back(process(op, context));
}
std::vector<SymbolPackedOptional>::const_iterator arg = operands.begin();
std::vector<Expression>::const_iterator tag = ++scheme.getOperands().begin();
while (tag != scheme.getOperands().end()) {
if (*arg && tag->__state != Expression::INVALID) {
__context.graph.addTag(**arg, Expression(*tag));
}
++arg; ++tag;
}
Expression retTag = *scheme.getOperands().begin();
if (retTag.__state != Expression::INVALID) {
assert(!decl.empty());
SymbolPacked pdecl = clasp->pack(context.scope->findSymbol(decl));
__context.graph.addTag(pdecl, move(retTag));
}
}
// adhoc for MAP case, TODO reorganize code in more clear manner
if (expression.op == Operator::MAP) {
SymbolPackedOptional nodeFrom;
if (operands.size()) {
nodeFrom = operands.at(0);
} else {
nodeFrom = process(expression.getOperands().at(0), context);
}
assert(!decl.empty());
SymbolPacked nodeTo = clasp->pack(context.scope->findSymbol(decl));
__context.graph.addLink(move(nodeTo), move(*nodeFrom), DFGConnection::PROTO);
}
if (__signatures.count(expression.op) || expression.op == Operator::MAP) {
for (CodeScope* scope: expression.blocks) {
AbstractPass::process(scope, context);
}
return boost::none;
}
AbstractPass::process(expression, context, decl);
return boost::none;
}
void
DFGPass::run()
{
init();
return AbstractPass::run();
}
void
DFGPass::init()
{
for (const Expression& scheme: man->root->__dfadata)
{
__signatures.emplace(scheme.op, scheme);
}
}
void DFGPass::finish()
{
man->clasp->addDFAData(move(__context.graph));
}

Event Timeline