예제 #1
0
static void handle_static_children_suif_object(WalkingMaps *walk,
					SuifObject *obj) {
  // use the object iterator to find all suiffobjects.
  // check to see that the parent is ME
  for (Iter<SuifObject> iter =
	 collect_instance_objects<SuifObject>(obj);
       iter.is_valid(); iter.next()) {
    //  list<SuifObject *>::iterator iter = the_list->begin();
    //  for (; iter != the_list->end(); iter++) {
    SuifObject *child = &iter.current();

    if (child == 0 ) continue;
    suif_assert(child->get_parent() == obj);
    walk->get_process_map()->apply(child);
    if (walk->is_done()) return;
  }
}
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) ;
  }  

}