/* Code for computing and reporting statistics. Turned on by -stats command line flag. */ #include "AST.h" #include "stats.h" #include "code-util.h" #include #include bool stat_foreach = false; static int SRorOSR(TreeNode *t, bool local) { if (isDummyNode(t)) return 0; if (isOSRArrayAccessNode(t) ||isSRArrayAccessNode(t)) return (t->array()->type()->isLocal() == local) ? 1 : 0; int count = 0; for (int i = t->arity(); i-- > 0; ) count += SRorOSR(t->child(i), local); return count; } static int OSR(TreeNode *t, bool local) { if (isDummyNode(t)) return 0; if (isOSRArrayAccessNode(t)) return (t->array()->type()->isLocal() == local) ? 1 : 0; int count = 0; for (int i = t->arity(); i-- > 0; ) count += OSR(t->child(i), local); return count; } static int plaingrid(TreeNode *t, bool local) { if (isDummyNode(t)) return 0; if (isTitaniumArrayAccessNode(t)) return (t->array()->type()->isLocal() == local) ? 1 : 0; int count = 0; for (int i = t->arity(); i-- > 0; ) count += plaingrid(t->child(i), local); return count; } static int java(TreeNode *t) { if (isDummyNode(t)) return 0; if (isJavaArrayAccessNode(t)) return 1; int count = 0; for (int i = t->arity(); i-- > 0; ) count += java(t->child(i)); return count; } static TreeNode *child0(TreeNode *x) { return (x->arity() > 0) ? x->child(0) : x; } // t is the tree to search for uses of array. d is the type of the domain // we're iterating over (or NULL if not a foreach loop). void loopStats(TreeNode *t, TypeNode *d, bool partialDomain, bool needPoint, int usi, int lifted, ostream &os) { char q[1000], p[1000]; static bool inited = false; if (!inited) { os << "How to interpret loop stats:\n" "\n" " There are two lines per loop. The source code position\n" " of the loop is given in parenthesis before a colon.\n" "\n" " The first line of stats is for unit stride inference\n" " (USI) and lifting. The number of array dimensions that\n" " must have unit stride is shown. The number of\n" " itermediate form assignment statements lifted from the\n" " loop is shown. Next may be `Rk' or `Dk' to indicate over\n" " what the loop iterates. `R' and `D' indicate RectDomain\n" " and Domain, respectively. If neither 'R' or 'D' is shown\n" " then the stats are for a loop that wasn't a foreach in the\n" " source program (i.e., a for, do, or while loop). Finally,\n" " there will be the letter `n' if the iteration point is\n" " necessary and the letter `p' if it is a `partial\n" " domain' loop. A `partial domain' loop is one that may\n" " be cut short by a return, break, continue, exception, etc.\n" "\n" " The second line of stats are reported in three groups.\n" " The first three numbers are for local grids. The next\n" " three are for global grids. The last is for Java\n" " arrays. The three numbers for grids are as follows:\n" " `SR(OSR) Regular.' SR is the number of strength\n" " reduced array accesses. OSR is the number of those that\n" " are offset strength reduced. Regular is the number\n" " that are not optimized. Accesses to Java arrays are\n" " always local and are never strength reduced so there is\n" " just one number.\n\n"; inited = true; } // Guestimate a node to tell us the source code position of the loop. TreeNode *pos = (d == NULL) ? t : child0(child0(t->parent())); string s = "Loop stats (" + pos->position().asString() + "): "; sprintf(q, "%s", s.c_str()); while (strlen(q) < 46) sprintf(q + strlen(q), " "); strcpy(p, q); sprintf(p + strlen(p), "USI: %2d, lifted: %2d, ", usi, lifted); os << p; if (d != NULL) os << (d->isRectDomainType() ? 'R' : 'D') << int2string(d->tiArity()) << ' '; if (needPoint) os << 'n'; if (partialDomain) os << 'p'; os << endl; sprintf(q + strlen(q), "%2d(%2d) %2d | %2d(%2d) %2d | %2d", SRorOSR(t, true), OSR(t, true), plaingrid(t, true), SRorOSR(t, false), OSR(t, false), plaingrid(t, false), java(t)); os << q << endl; }