// Flowgraph::Rewrite // // The sources of the values in this expression (may have) changed. Traverse // the graph and rewrite any nodes that depend on changed source values. Idea // for future improvement: define some placeholder node whose meaning can be // defined upstream by some kind of definition node, then have the PostOrderDFS // perform the substitution during traversal. This would free us from the need // to traverse the graph twice and to reallocate the intermediary nodes - this // could be a big memory win given that we will likely need to recreate the // majority of the loop body. Note that we fill out the map as we go, so we // don't re-traverse any shared subexpressions. // Node *Flowgraph::Rewrite( Node *exp, Pool &pool, NodeMap &reMap ) { NodeMap::const_iterator iter = reMap.find(exp); if (iter != reMap.end()) { exp = iter->second; } else if (exp->IsAnOperation()) { Operation *op = exp->AsOperation(); Node *left = Rewrite( op->Left(), pool, reMap ); Node *right = Rewrite( op->Right(), pool, reMap ); Node *newExp = pool.Operation( op->Type(), left, right ); if (exp->IsInductionVar() && !op->IsInductionVar()) { newExp = pool.Inductor( newExp ); } reMap[exp] = newExp; exp = newExp; } return exp; }
JITFunction* GenerateBaseFunction(Pipeline *pipeline, Thread *thread) { JITFunction *jf = CreateJITFunction(thread, pipeline); Operation *operation = pipeline->operation; jf->size = 0; jf->function = NULL; jf->jit = NULL; switch(operation->Type()) { case OPTYPE_nullop: jf->base = (base_function) ((NullaryOperation*)operation)->operation->gencode.base; break; case OPTYPE_unop: jf->base = (base_function) ((UnaryOperation*)operation)->operation->gencode.base; break; case OPTYPE_binop: jf->base = (base_function) ((BinaryOperation*)operation)->operation->gencode.base; break; default: return NULL; } return jf; }