// // Created by ztuowen on 9/26/16. // #include "chillAST.h" #include "printer/dump.h" #include "printer/cfamily.h" #include using namespace std; void chillAST_Node::fixChildInfo() {} void chillAST_Node::addChild(chillAST_Node *c) { c->parent = this; // check to see if it's already there for (int i = 0; i < children.size(); i++) { if (c == children[i]) { CHILL_ERROR("addchild ALREADY THERE\n"); return; // already there } } children.push_back(c); }; // not usually useful void chillAST_Node::addChildren(const chillAST_NodeList &c) { for (int i = 0; i < c.size(); ++i) { addChild(c[i]); } } void chillAST_Node::insertChild(int i, chillAST_Node *node) { //fprintf(stderr, "%s inserting child of type %s at location %d\n", getTypeString(), node->getTypeString(), i); node->parent = this; children.insert(children.begin() + i, node); }; void chillAST_Node::removeChild(int i) { children.erase(children.begin() + i); }; int chillAST_Node::findChild(chillAST_Node *c) { for (int i = 0; i < children.size(); i++) { if (children[i] == c) return i; } return -1; } void chillAST_Node::replaceChild(chillAST_Node *old, chillAST_Node *newchild) { CHILL_DEBUG_PRINT("(%s) forgot to implement replaceChild() ... using generic\n", getTypeString()); CHILL_DEBUG_PRINT("%d children\n", children.size()); for (int i = 0; i < children.size(); i++) { if (children[i] == old) { children[i] = newchild; newchild->setParent(this); return; } } CHILL_ERROR("%s %p generic replaceChild called with oldchild that was not a child\n", getTypeString(), this); CHILL_DEBUG_BEGIN fprintf(stderr, "printing\n"); print(); fprintf(stderr, "\nchild: "); if (!old) fprintf(stderr, "oldchild NULL!\n"); old->print(); fprintf(stderr, "\nnew: "); newchild->print(); fprintf(stderr, "\n"); CHILL_DEBUG_END exit(-1); }; void chillAST_Node::loseLoopWithLoopVar(char *var) { std::vector dupe = children; // simple enough? for (int i = 0; i < dupe.size(); i++) { // recurse on all children dupe[i]->loseLoopWithLoopVar(var); } } //! recursive walk parent links, looking for loops, and grabbing the declRefExpr in the loop init and cond. void chillAST_Node::gatherLoopIndeces( std::vector &indeces) { // you can quit when you get to certain nodes CHILL_DEBUG_PRINT("%s::gatherLoopIndeces()\n", getTypeString()); if (isSourceFile() || isFunctionDecl()) return; // end of the line if (!parent) return; // should not happen, but be careful // for most nodes, this just recurses upwards parent->gatherLoopIndeces(indeces); } //! recursive walk parent links, looking for loops chillAST_ForStmt *chillAST_Node::findContainingLoop() { CHILL_DEBUG_PRINT("%s::findContainingLoop() ", getTypeString()); if (!parent) return NULL; if (parent->isForStmt()) return (chillAST_ForStmt *) parent; return parent->findContainingLoop(); // recurse upwards } chillAST_Node *chillAST_Node::findContainingNonLoop() { fprintf(stderr, "%s::findContainingNonLoop() ", getTypeString()); if (!parent) return NULL; if (parent->isCompoundStmt() && parent->getParent()->isForStmt()) return parent->getParent()->findContainingNonLoop(); // keep recursing if (parent->isForStmt()) return parent->findContainingNonLoop(); // keep recursing return (chillAST_Node *) parent; // return non-loop } void chillAST_Node::getTopLevelLoops(std::vector &loops) { int n = children.size(); for (int i = 0; i < n; i++) { if (children[i]->isForStmt()) { loops.push_back(((chillAST_ForStmt *) (children[i]))); } } } void chillAST_Node::repairParentChild() { // for nodes where all subnodes are children int n = children.size(); for (int i = 0; i < n; i++) { if (children[i]->parent != this) { fprintf(stderr, "fixing child %s that didn't know its parent\n", children[i]->getTypeString()); children[i]->parent = this; } } } void chillAST_Node::get_deep_loops( std::vector &loops) { // this is probably broken - returns ALL loops under it int n = children.size(); //fprintf(stderr, "get_deep_loops of a %s with %d children\n", getTypeString(), n); for (int i = 0; i < n; i++) { //fprintf(stderr, "child %d is a %s\n", i, children[i]->getTypeString()); children[i]->get_deep_loops(loops); } //fprintf(stderr, "found %d deep loops\n", loops.size()); } // generic for chillAST_Node with children void chillAST_Node::find_deepest_loops(std::vector &loops) { // returns DEEPEST nesting of loops std::vector deepest; // deepest below here int n = children.size(); //fprintf(stderr, "find_deepest_loops of a %s with %d children\n", getTypeString(), n); for (int i = 0; i < n; i++) { std::vector subloops; // loops below here among a child of mine //fprintf(stderr, "child %d is a %s\n", i, children[i]->getTypeString()); children[i]->find_deepest_loops(subloops); if (subloops.size() > deepest.size()) { deepest = subloops; } } // append deepest we see at this level to loops for (int i = 0; i < deepest.size(); i++) { loops.push_back(deepest[i]); } //fprintf(stderr, "found %d deep loops\n", loops.size()); } chillAST_SourceFile *chillAST_Node::getSourceFile() { if (isSourceFile()) return ((chillAST_SourceFile *) this); if (parent != NULL) return parent->getSourceFile(); CHILL_ERROR("UHOH, getSourceFile() called on node %p %s that does not have a parent and is not a source file\n", this, this->getTypeString()); this->print(); exit(-1); } void chillAST_Node::addVariableToScope(chillAST_VarDecl *vd) { CHILL_DEBUG_PRINT("addVariableToScope( %s )\n", vd->varname); if (!symbolTable) return; symbolTable = addSymbolToTable(symbolTable, vd); vd->parent = this; } void chillAST_Node::addTypedefToScope(chillAST_TypedefDecl *tdd) { if (!typedefTable) return; typedefTable = addTypedefToTable(typedefTable, tdd); tdd->parent = this; } chillAST_TypedefDecl *chillAST_Node::findTypeDecleration(const char *t) { fprintf(stderr, " %s \n", t); chillAST_TypedefDecl *td = getTypeDeclaration(t); if (!td && parent) return parent->findTypeDecleration(t); return td; // should not happen } chillAST_VarDecl *chillAST_Node::findVariableDecleration(const char *t) { fprintf(stderr, " %s \n", t); chillAST_VarDecl *td = getVariableDeclaration(t); if (!td && parent) return parent->findVariableDecleration(t); return td; // should not happen } chillAST_VarDecl *chillAST_Node::getVariableDeclaration(const char *t) { chillAST_VarDecl *vd = symbolTableFindName(getSymbolTable(), t); if (!vd) vd = getParameter(t); return vd; } chillAST_TypedefDecl *chillAST_Node::getTypeDeclaration(const char *t) { return typedefTableFindName(getTypedefTable(), t); } void chillAST_Node::addParameter(chillAST_VarDecl *vd) { if (!parameters) { CHILL_ERROR("Calling addParameter on construct without parameters"); exit(-1); } if (symbolTableFindName(getParameters(), vd->varname)) { // NOT recursive. just in FunctionDecl CHILL_ERROR("parameter %s already exists?\n", vd->varname); return; } CHILL_DEBUG_PRINT("setting %s isAParameter\n", vd->varname); getParameters()->push_back(vd); vd->isAParameter = true; vd->setParent(this); // this is a combined list! } chillAST_VarDecl *chillAST_Node::getParameter(const char *t) { return symbolTableFindName(getParameters(), t); } void chillAST_Node::dump(int indent, FILE *fp) { if (fp == stderr) { chill::printer::Dump d; d.printErr("", this); fprintf(stderr, "\n"); } else { chill::printer::Dump d; d.printOut("", this); fprintf(stdout, "\n"); } } void chillAST_Node::print(int indent, FILE *fp) { if (fp == stderr) { chill::printer::CFamily d; d.printErr("", this); fprintf(stderr, "\n"); } else { chill::printer::CFamily d; d.printOut("", this); fprintf(stdout, "\n"); } } chillAST_Node* chillAST_Node::constantFold(){ CHILL_DEBUG_PRINT("Using generic\n"); for (int i = 0;iconstantFold()); } return this; }; void chillAST_Node::gatherVarDecls(vector &decls) { CHILL_DEBUG_PRINT("Using generic\n"); for (int i = 0;igatherVarDecls(decls); } } void chillAST_Node::gatherArrayVarDecls(vector &decls) { CHILL_DEBUG_PRINT("Using generic\n"); for (int i = 0;igatherArrayVarDecls(decls); } } void chillAST_Node::gatherArrayRefs(vector &refs, bool writtento) { CHILL_DEBUG_PRINT("Using generic\n"); for (int i = 0;igatherArrayRefs(refs,writtento); } } void chillAST_Node::gatherScalarRefs(vector &refs, bool writtento) { CHILL_DEBUG_PRINT("Using generic\n"); for (int i = 0;igatherScalarRefs(refs,writtento); } } void chillAST_Node::gatherDeclRefExprs(vector &refs) { CHILL_DEBUG_PRINT("Using generic\n"); for (int i = 0;igatherDeclRefExprs(refs); } } void chillAST_Node::gatherVarUsage(vector &decls) { CHILL_DEBUG_PRINT("Using generic\n"); for (int i = 0;igatherVarUsage(decls); } } void chillAST_Node::gatherStatements(vector &statements) { CHILL_DEBUG_PRINT("using generic\n"); for (int i = 0;igatherStatements(statements); } } void chillAST_Node::replaceVarDecls(chillAST_VarDecl* olddecl, chillAST_VarDecl *newdecl) { CHILL_DEBUG_PRINT("using generic\n"); for (int i = 0;ireplaceVarDecls(olddecl,newdecl); } } void chillAST_Node::gatherScalarVarDecls(vector &decls) { CHILL_DEBUG_PRINT("using generic\n"); for (int i = 0;igatherScalarVarDecls(decls); } }