/* Useful for printing annotations as comments. Expects that * the annotation is a BrickAnnote. */ void Printer::print_annote(Annote *annote) { start_comment(); IdString name = annote->get_name(); if (name != k_comment) fprintf(out, "[%s", name.chars()); if (is_kind_of<BrickAnnote>(annote)) { BrickAnnote *an = (BrickAnnote *)(annote); char *separator = ": "; for (Iter<SuifBrick*> iter = an->get_brick_iterator(); iter.is_valid(); iter.next()) { fputs(separator, out); separator = ", "; SuifBrick *brick = iter.current(); if (is_a<IntegerBrick>(brick)) { Integer i = ((IntegerBrick*)iter.current())->get_value(); if (i.is_c_string_int()) fputs(i.chars(), out); else fprintf(out, "%ld", i.c_long()); } else if (is_a<StringBrick>(brick)) { putc('"', out); for (const char *p = ((StringBrick*)iter.current())->get_value().c_str(); *p != '\0'; ++p) { if (*p == '"' || *p == '\\') putc('\\', out); putc(*p, out); } putc('"', out); } else { claim(is_a<SuifObjectBrick>(brick)); SuifObject *so = ((SuifObjectBrick*)brick)->get_object(); if (is_kind_of<Type>(so)) fprint(out, (TypeId)so); else { const char *kind = so ? get_class_name(so) : "NULL"; fprintf(out, "<<<%s object>>>", kind); } } } } else { claim(is_kind_of<GeneralAnnote>(annote), "Unexpected kind of Annote"); } if (name != k_comment) fputs("]", out); fputs("\n", out); }
void CopyPropagationPass2::ProcessSpecialIfs() { list<IfStatement*>* allIfs = collect_objects<IfStatement>(procDef->get_body()) ; assert(allIfs != NULL) ; list<IfStatement*>::iterator ifIter = allIfs->begin() ; while (ifIter != allIfs->end()) { Statement* elsePart = (*ifIter)->get_else_part() ; assert(elsePart != NULL) ; StatementList* elseList = dynamic_cast<StatementList*>(elsePart) ; if (elseList == NULL) { ++ifIter ; continue ; } assert(elseList != NULL) ; if (elseList->get_statement_count() == 2) { // Process this if statement Statement* thenPart = (*ifIter)->get_then_part() ; assert(thenPart != NULL) ; /* StatementList* thenList = dynamic_cast<StatementList*>(thenPart) ; assert(thenList != NULL) ; assert(thenList->get_statement_count() == 1) ; Statement* thenStatement = thenList->get_statement(0) ; assert(thenStatement != NULL) ; */ StoreVariableStatement* thenStoreVar = dynamic_cast<StoreVariableStatement*>(thenPart) ; assert(thenStoreVar != NULL) ; Statement* firstElseStatement = elseList->get_statement(0) ; Statement* secondElseStatement = elseList->get_statement(1) ; assert(firstElseStatement != NULL && secondElseStatement != NULL) ; // We are definitely going to break the rules here // We know that the destination has to be replaced with // the source StoreVariableStatement* secondElseStore = dynamic_cast<StoreVariableStatement*>(secondElseStatement) ; assert(secondElseStore != NULL) ; Expression* source = secondElseStore->get_value() ; assert(source != NULL) ; LoadVariableExpression* sourceLoadExp = dynamic_cast<LoadVariableExpression*>(source) ; assert(sourceLoadExp != NULL) ; VariableSymbol* sourceVariable = sourceLoadExp->get_source() ; assert(sourceVariable != NULL) ; // First, find the use of the then portion and replace that use // with the source variable BrickAnnote* ba = to<BrickAnnote>(thenStoreVar->lookup_annote_by_name("reached_uses")) ; assert(ba != NULL) ; assert(ba->get_brick_count() == 1) ; Iter<SuifBrick*> tmpIter = ba->get_brick_iterator() ; SuifObjectBrick* sob = to<SuifObjectBrick>(tmpIter.current()) ; assert(sob != NULL) ; SuifObject* finalDest = sob->get_object() ; LoadVariableExpression* finalLoad = dynamic_cast<LoadVariableExpression*>(finalDest) ; assert(finalLoad != NULL) ; // Before we make the change, mark the variable we are replacing as // removed. finalLoad->get_source()->append_annote(create_brick_annote(theEnv, "RemovedVariable")) ; finalLoad->set_source(sourceVariable) ; // Now, change the then portion thenStoreVar->set_destination(sourceVariable) ; // Now, remove the second else statement elseList->remove_statement(1) ; // We should be done. } ++ifIter ; } delete allIfs ; }
void CopyPropagationPass2::ProcessPossibleCopy(StoreVariableStatement* c) { assert(c != NULL) ; // If this isn't a straight copy, just return LoadVariableExpression* replacement = dynamic_cast<LoadVariableExpression*>(c->get_value()) ; if (replacement == NULL) { return ; } // If the variables are different types, don't propagate this away // (it is a cast) DataType* destType = c->get_destination()->get_type()->get_base_type() ; DataType* sourceType = replacement->get_source()->get_type()->get_base_type(); if (!EquivalentTypes(destType, sourceType)) { return ; } // Find all the reached uses BrickAnnote* reachedUses = to<BrickAnnote>(c->lookup_annote_by_name("reached_uses")) ; assert(reachedUses != NULL) ; // Just in case we have no reached uses, we don't want to do // dead code elimination in this pass as well... bool removable = false ; Iter<SuifBrick*> useIter = reachedUses->get_brick_iterator() ; // First verify that we are the only definition for all of our uses. // If we aren't then we can't make the replacement while(useIter.is_valid()) { SuifObjectBrick* sob = to<SuifObjectBrick>(useIter.current()) ; assert (sob != NULL) ; LoadVariableExpression* nextLoad = dynamic_cast<LoadVariableExpression*>(sob->get_object()) ; assert(nextLoad != NULL) ; if (IsOnlyDefinition(c, nextLoad) == false) { return ; } useIter.next() ; } // We also need to make sure that for each reached use, the copy is // not redefined. We do this by checking to make sure all of the // definitions associated with it in the kill map are identical. // This is a little conservative, but will make sure that no incorrect // code is created. // Get the bit vector associated with all the reaching definitions // coming into this statement BrickAnnote* inStatements = dynamic_cast<BrickAnnote*>(c->lookup_annote_by_name("in_stmts")) ; assert(inStatements != NULL) ; SuifBrick* inBrick = inStatements->get_brick(0) ; assert(inBrick != NULL) ; SuifObjectBrick* inSOB = dynamic_cast<SuifObjectBrick*>(inBrick) ; assert(inSOB != NULL) ; SuifObject* inObj = inSOB->get_object() ; assert(inObj != NULL) ; BitVector2* inBits = dynamic_cast<BitVector2*>(inObj) ; assert(inBits != NULL) ; VariableSymbol* replacementVariable = replacement->get_source() ; assert(replacementVariable != NULL) ; list<std::pair<Statement*, int> >* definitions =killMap[replacementVariable]; assert(definitions != NULL) ; list<bool> activeDefinitions ; list<std::pair<Statement*, int> >::iterator defIter = definitions->begin() ; while (defIter != definitions->end()) { activeDefinitions.push_back(inBits->isMarked((*defIter).second)) ; ++defIter ; } useIter = reachedUses->get_brick_iterator() ; while (useIter.is_valid()) { SuifObjectBrick* sob = to<SuifObjectBrick>(useIter.current()) ; assert(sob != NULL) ; LoadVariableExpression* nextLoad = dynamic_cast<LoadVariableExpression*>(sob->get_object()) ; assert(nextLoad != NULL) ; SuifObject* loadParent = nextLoad->get_parent() ; while (dynamic_cast<Statement*>(loadParent) == NULL && loadParent != NULL) { loadParent = loadParent->get_parent() ; } assert(loadParent != NULL) ; Statement* parentStatement = dynamic_cast<Statement*>(loadParent) ; assert(parentStatement != NULL) ; BrickAnnote* parentInAnnote = dynamic_cast<BrickAnnote*> (parentStatement->lookup_annote_by_name("in_stmts")) ; assert(parentInAnnote != NULL) ; SuifBrick* parentInBrick = parentInAnnote->get_brick(0) ; assert(parentInBrick != NULL) ; SuifObjectBrick* parentInSOB = dynamic_cast<SuifObjectBrick*>(parentInBrick) ; assert(parentInSOB != NULL) ; SuifObject* parentInObj = parentInSOB->get_object() ; assert(parentInObj != NULL) ; BitVector2* parentInBits = dynamic_cast<BitVector2*>(parentInObj) ; assert(parentInBits != NULL) ; defIter = definitions->begin() ; list<bool>::iterator activeIter = activeDefinitions.begin() ; while (defIter != definitions->end()) { if ((*activeIter) != parentInBits->isMarked((*defIter).second)) { // They are different, so don't do the replacement. return ; } ++activeIter ; ++defIter ; } useIter.next() ; } // Now go through each reached use and replace it with the copy. // Each reached use should be a load variable expression. // We also have to deal with any feedback variables useIter = reachedUses->get_brick_iterator() ; while (useIter.is_valid()) { SuifObjectBrick* sob = to<SuifObjectBrick>(useIter.current()) ; assert(sob != NULL) ; LoadVariableExpression* nextLoad = dynamic_cast<LoadVariableExpression*>(sob->get_object()) ; assert(nextLoad != NULL) ; // Keep track of if we need to handle feedback variables HandleFeedbackVariables(nextLoad, replacement->get_source()) ; nextLoad->set_source(replacement->get_source()) ; removable = true ; useIter.next() ; } if (removable) { toBeRemoved.push_back(c) ; } }