/* UNUSED */ #include #include #include "utils.h" #include "AST.h" #include "cfg.h" #include "code-util.h" #include "code-defs.h" #include "code-poly.h" // Copy the passed-in poly, if it exists. void TreeNode::setPoly(Poly *poly) { if (poly) { setPoly(poly->astNode(), poly->invariant(), poly->primary_iv(), poly->derived_iv()); } else { _poly = NULL; } } void TreeNode::setPoly(TreeNode *expr, bool inv, bool p_iv, bool d_iv) { if (!_poly) { _poly = new Poly(expr,inv,p_iv,d_iv); } else { _poly->astNode() = expr; _poly->invariant() = inv; _poly->primary_iv() = p_iv; _poly->derived_iv() = d_iv; } } void UnaryPlusNode::calcPoly(void) { setPoly(opnd0()->getPoly()); } void UnaryMinusNode::calcPoly(void) { Poly *childPoly; if (childPoly = opnd0()->getPoly()) { TreeNode *expr = new UnaryMinusNode(childPoly->astNode(), where); setPoly(expr, childPoly->invariant(), childPoly->primary_iv(), childPoly->derived_iv()); } } void MultNode::calcPoly(void) { if (opnd0()->getPoly() && opnd1()->getPoly()) { Poly *poly0 = opnd0()->getPoly(); Poly *poly1 = opnd1()->getPoly(); TreeNode *expr = new MultNode(poly0->astNode(), poly1->astNode(), where); setPoly(expr, poly0->invariant() && poly1->invariant(), false, poly0->derived_iv() | poly1->derived_iv() | poly0->primary_iv() | poly1->primary_iv()); } } void DivNode::calcPoly(void) { if (opnd0()->getPoly() && opnd1()->getPoly()) { Poly *poly0 = opnd0()->getPoly(); Poly *poly1 = opnd1()->getPoly(); TreeNode *expr = new DivNode(poly0->astNode(), poly1->astNode(), where); setPoly(expr, poly0->invariant() && poly1->invariant(), false, poly0->derived_iv() | poly1->derived_iv() | poly0->primary_iv() | poly1->primary_iv()); } } void RemNode::calcPoly(void) { if (opnd0()->getPoly() && opnd1()->getPoly()) { Poly *poly0 = opnd0()->getPoly(); Poly *poly1 = opnd1()->getPoly(); TreeNode *expr = new RemNode(poly0->astNode(), poly1->astNode(), where); setPoly(expr, poly0->invariant() && poly1->invariant(), false, poly0->derived_iv() | poly1->derived_iv() | poly0->primary_iv() | poly1->primary_iv()); } } void PlusNode::calcPoly(void) { if (opnd0()->getPoly() && opnd1()->getPoly()) { Poly *poly0 = opnd0()->getPoly(); Poly *poly1 = opnd1()->getPoly(); TreeNode *expr = new PlusNode(poly0->astNode(), poly1->astNode(), where); setPoly(expr, poly0->invariant() && poly1->invariant(), false, poly0->derived_iv() | poly1->derived_iv() | poly0->primary_iv() | poly1->primary_iv()); } } void MinusNode::calcPoly(void) { if (opnd0()->getPoly() && opnd1()->getPoly()) { Poly *poly0 = opnd0()->getPoly(); Poly *poly1 = opnd1()->getPoly(); TreeNode *expr = new MinusNode(poly0->astNode(), poly1->astNode(), where); setPoly(expr, poly0->invariant() && poly1->invariant(), false, poly0->derived_iv() | poly1->derived_iv() | poly0->primary_iv() | poly1->primary_iv()); } } void LitNode::calcPoly(void) { if (isIntConstant(-MAXINT,MAXINT)) { setPoly(this, true, false, false); } } void ObjectNode::calcPoly(void) { Poly *childPoly = name()->getPoly(); if (childPoly && isNameNode(childPoly->astNode())) { setPoly(new ObjectNode(childPoly->astNode()), childPoly->invariant(), childPoly->primary_iv(), childPoly->derived_iv()); } else { setPoly(childPoly); } } // Is the given name "t" invariant w.r.t. the given loop? static bool isNameInvariant(TreeNode *t, TreeNode *loop) { if (!t->getDefs()) { return false; } ListIterator iter = t->getDefs(); for (; !iter.isDone(); iter.next()) { TreeNode *def = *iter; while (def && def != loop) { def = def->parent(); } if (def == loop) { return false; } } return true; } static TreeNode *currentLoop = NULL; // If a NameNode is defined by a single assignment, propagate its rhs as the // poly for this NameNode. void NameNode::calcPoly(void) { if (isObjectNode(parent())) { if (!((ObjectNode *)parent())->__type()->isIntegralType()) { return; } } // Invariance doesn't change, so only calculate this once. // If the object is invariant, we don't propagate its def to its poly. if (!getPoly()) { if (isNameInvariant(this, currentLoop)) { setPoly(this, true, false, false); return; } } else if (getPoly()->invariant()) { return; } // If the NameNode has a single def, propagate it to its poly. if (getDefs()) { if (!getDefs()->tail()) { TreeNode *defExpr = getDefs()->front(); if (isAssignNode(defExpr)) { Poly *defPoly = defExpr->child(1)->getPoly(); if (defPoly) { setPoly(defPoly->astNode(), false, false, defPoly->derived_iv() | defPoly->primary_iv()); return; } } else if (isForEachPairNode(defExpr)) { // We have an instance of the primary iv for the loop. setPoly(this, false, true, false); return; } } } ListIterator iter = getDefs(); bool d_iv = false; for (; iter.isDone(); iter.next()) { TreeNode *defExpr = *iter; Poly *defPoly = defExpr->getPoly(); if (defPoly->derived_iv() | defPoly->primary_iv()) { d_iv = true; break; } } setPoly(this, false, false, d_iv); } void printPoly(Poly *poly) { if (!poly) { cout << "poly: NULL\n"; return; } cout << "poly:"; if (poly->invariant()) { cout << "I"; } if (poly->primary_iv()) { cout << "P"; } if (poly->derived_iv()) { cout << "D"; } cout << ":"; poly->astNode()->print(cout,0); cout << endl; } void polyCfg(CfgNode *cfg, void*) { cfg->astNode()->calcPoly(); cout << "astnode: "; cfg->astNode()->print(cout,0); cout << endl; printPoly(cfg->astNode()->getPoly()); } void polyAnalyze(TreeNode *foreach) { assert(isForEachStmtNode(foreach)); currentLoop = foreach; UnmarkCfgExts(foreach->getCfgExtent().entry, foreach->getCfgExtent().exit); TraverseCfgExtents(foreach->getCfgExtent().entry, foreach->getCfgExtent().exit, polyCfg, NULL); currentLoop = NULL; } /* To do: 1. Since we go in depth-first CF order, is it necessary that the algorithm be iterative? The ud analysis should have propagated all the info we want to know around the loops. 2. What about non-local variables? 3. What about variables with multiple defs? Are we going to do some kind of quasi-SSA where uses with different defs should be named the same? Should we just implement a full SSA instead? 4. Is this work at all useful to anyone? */