dfgpass.cpp
No OneTemporary

File Metadata

Created
Tue, Aug 25, 7:50 AM

dfgpass.cpp

#include <kimproxy.h>
#include "dfgpass.h"
#include "../passmanager.h"
using namespace xreate;
using namespace std;
DFGPass::DFGPass(PassManager* manager)
: AbstractPass(manager)
{}
SymbolPacked
DFGPass::processExpression(const Expression& expression, PassContext context, const std::string& decl)
{
switch(expression.op) {
case Operator::CALL: {
const string &name = expression.getValueString();
ManagedFnPtr function = man->root->findFunction(name);
CodeScope *scopeRemote = function->getEntryScope();
std::vector<SymbolPacked> operands;
operands.reserve(expression.getOperands().size());
for (const Expression &op: expression.getOperands()) {
operands.push_back(processExpression(op, context));
}
std::vector<SymbolPacked>::iterator op = operands.begin();
for (const std::string &arg: scopeRemote->__args) {
if (op->isValid()) {
const Symbol &nodeRemote = scopeRemote->findSymbol(arg, *man->llvm, false);
__context.graph.addLink(__context.graph.pack(nodeRemote), *op, DFGConnection::OPT);
}
++op;
}
SymbolPacked ret = __context.graph.pack(Symbol{0, scopeRemote});
if (!decl.empty()) {
__context.graph.addLink(
__context.graph.pack(
context.scope->findSymbol(decl, *man->llvm, false)),
ret, DFGConnection::OPT);
}
return ret;
}
default: {
std::vector<SymbolPacked> operands;
if (__schemes.count(expression.op)) {
const Expression &scheme = __schemes.at(expression.op);
operands.reserve(expression.getOperands().size());
for (const Expression &op: expression.getOperands()) {
operands.push_back(processExpression(op, context));
}
std::vector<SymbolPacked>::const_iterator arg = operands.begin();
std::vector<Expression>::const_iterator tag = ++scheme.getOperands().begin();
while (tag != scheme.getOperands().end()) {
if (arg->isValid() && 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 = __context.graph.pack(context.scope->findSymbol(decl, *man->llvm, false));
__context.graph.addTag(pdecl, move(retTag));
}
}
// adhoc for MAP case, TODO reorganize code in more clear manner
if (expression.op == Operator::MAP) {
SymbolPacked nodeFrom;
if (operands.size()) {
nodeFrom = operands.at(0);
} else {
nodeFrom = processExpression(expression.getOperands().at(0), context);
}
assert(!decl.empty());
SymbolPacked nodeTo = __context.graph.pack(context.scope->findSymbol(decl, *man->llvm, false));
__context.graph.addLink(move(nodeTo), move(nodeFrom), DFGConnection::PROTO);
}
}
}
switch(expression.__state) {
case Expression::IDENT:
AbstractPass::process(expression, context, decl);
string ident = expression.getValueString();
const Symbol& identSymbol = context.scope->findSymbol(ident, *man->llvm);
SymbolPacked nodeFrom = __context.graph.pack(identSymbol);
if (!decl.empty()) {
SymbolPacked nodeTo = __context.graph.pack(context.scope->findSymbol(decl, *man->llvm));
__context.graph.addLink(move(nodeTo), move(nodeFrom), DFGConnection::STRONG);
}
return nodeFrom;
}
AbstractPass::process(expression, context, decl);
return SYMBOL_INVALID;
}
void
DFGPass::run()
{
init();
return AbstractPass::run();
}
void
DFGPass::process(const Expression& expression, PassContext context, const std::string& decl)
{
processExpression(expression, context, decl);
}
void
DFGPass::init()
{
for (const Expression& scheme: man->root->__dfadata)
{
__schemes.emplace(scheme.op, scheme);
}
}
void DFGPass::finish()
{
man->clasp->addDFAData(move(__context.graph));
}

Event Timeline