void
TR_ExpressionsSimplification::removeUncertainBlocks(TR_RegionStructure* region, List<TR::Block> *candidateBlocksList)
   {
   // Examine the top region block first
   //
   TR::Block *entryBlock = _currentRegion->getEntryBlock();
   ListIterator<TR::Block> blocks;
   blocks.set(candidateBlocksList);

   if (trace())
      traceMsg(comp(), "Number of blocks %d, entry block number %d\n", candidateBlocksList->getSize(), entryBlock->getNumber());

   for (TR::Block *block = blocks.getFirst(); block; block = blocks.getNext())
      {
      TR::CFGNode *cfgNode = block;
      if (!(cfgNode->getExceptionSuccessors().empty()) || blockHasCalls(block, comp()))
         {
         if (trace())
            traceMsg(comp(), "An exception can be thrown from block_%d. Removing all the blocks, since we cannot know the number of iterations.\n", block->getNumber());
         candidateBlocksList->deleteAll();
         break;
         }
      }

   TR_PostDominators postDominators(comp());
   if (postDominators.isValid())
      {
	  postDominators.findControlDependents();
      for (TR::Block *block = blocks.getFirst(); block; block = blocks.getNext())
         {
         if (postDominators.dominates(block, entryBlock) == 0)
            {
            candidateBlocksList->remove(block);
            if (trace())
               traceMsg(comp(), "Block_%d is not guaranteed to be executed at least once. Removing it from the list.\n", block->getNumber());
            }
         }
      }
   else
      {
	  if (trace())
	     traceMsg(comp(), "There is no post dominators information. Removing all the blocks.\n");
	  for (TR::Block *block = blocks.getFirst(); block; block = blocks.getNext())
	     {
	     candidateBlocksList->remove(block);
	     if (trace())
	        traceMsg(comp(), "Block_%d is removed from the list\n", block->getNumber());
	     }
      }
   }
//
// Print the group information into the cfg file.
//
bool PanelGroupManager::cfgPrintComment(FILE *f)
{
    int	  i, inst;
    List  plist;
    ListIterator li;
    char  *name;

    for(i=1; (name = (char*)this->getPanelGroup(i, &plist)); i++)
    {
        if (fprintf(f, "// panel group: \"%s\"", name) < 0)
            return false;

        li.setList(plist);

        while( (inst = (int)(long)li.getNext()) )
            if (fprintf(f, " %d", inst-1) < 0)
                return false;

        if (fputc('\n', f) < 0)
            return false;

        plist.clear();
    }

    return true;
}
PageSelector::~PageSelector()
{
    if (this->page_buttons) {
	// The superclass destructor calls clear() but I'm confused
	// about what the virtual call from the destructor is going
	// to do.  So I'll add the needed statements.
	ListIterator it (*this->page_buttons);
	PageTab* page_button;
	while ( (page_button = (PageTab*)it.getNext()) ) {
	    page_button->unmanage();
	    delete page_button;
	}
	delete this->page_buttons;
	this->page_buttons = NUL(List*);
    }
boolean
MacroParameterNode::canCoerceValue (const char* option, List* types)
{
	ListIterator iter;
	boolean coerced = FALSE;
	DXType* dxtype;
	for (iter.setList(*types) ; (dxtype = (DXType*)iter.getNext()) ; ) {
		char* s = DXValue::CoerceValue (option, dxtype->getType());
		if (s) {
			coerced = TRUE;
			delete s;
			break;
		}
	}
	return coerced;
}
boolean MacroParameterNode::removeIOArk(List *io, int index, Ark *a)
{
    int destIndex;
    int srcIndex;
    Node* destinationNode = a->getDestinationNode(destIndex);
    Node* sourceNode = a->getSourceNode(srcIndex);
    NodeDefinition* destinationDefinition = destinationNode->getDefinition();
    if (!this->UniqueNameNode::removeIOArk(io, index, a))
	return FALSE;

    ParameterDefinition *macroPd = this->getParameterDefinition();

    //
    // During deletion of a MacroDefinition, there is no MacroDefinition
    // for this node and therefore no ParameterDefinition.  So just return.
    //
    if (!macroPd)
	return TRUE;

    Parameter *pout;
    if (this->isInput())
	pout = this->getOutputParameter(1);
    else
	pout = this->getInputParameter(1);

    ParameterDefinition *nodePd = pout->getDefinition();

    List *outTypes = macroPd->getTypes();
    DXType *t;
    while( (t = (DXType*)(outTypes->getElement(1))) )
    {
	macroPd->removeType(t);
    }

    outTypes = nodePd->getTypes();
    while( (t = (DXType*)(outTypes->getElement(1))) )
    {
	nodePd->removeType(t);
    }

    // for each arc connected to this, intersect this type
    // list with "typesList" and set this to be the current types list.
    const List *arcs;
    if (this->isInput())
	arcs = this->getOutputArks(srcIndex);
    else
	arcs = this->getInputArks(destIndex);
    

    ListIterator li;
    li.setList(*(List *)arcs);

    List *typesList = new List;
    typesList->appendElement(new DXType(DXType::ObjectType));

    while( (a = (Ark*)li.getNext()) )
    {
	ParameterDefinition *pind;
	if (this->isInput())
	{
	    int dummy;
	    Node *dest = a->getDestinationNode(dummy);
	    pind = ((MacroParameterNode*)dest)->getInputParameter(dummy)->
				    getDefinition();
	}
	else
	{
	    int dummy;
	    Node *dest = a->getSourceNode(dummy);
	    pind = ((MacroParameterNode*)dest)->getOutputParameter(dummy)->
				    getDefinition();
	}
	List *newTypesList = DXType::IntersectTypeLists(
	    *typesList,
	    *pind->getTypes());
	// FIXME:  don't you have to delete the items in the list first?
	delete typesList;
	typesList = newTypesList;
    }


    li.setList(*typesList);
    while( (t = (DXType*)li.getNext()) )
    {
	DXType *newt = t->duplicate(); 
	nodePd->addType(newt);
	macroPd->addType(t);
    }
    delete typesList;

    if (this->isInput()) {
	const char *const *dest_option_vals;
	const char *const *src_option_vals;
	// If our current option values are equal to the options
	// values at the other end of the ark that we're disconnecting,
	// then assume that our option values came over this ark, and
	// toss ours out.  This prevents us from discarding a user's input.
	boolean we_disconnected_the_one = FALSE;

	ParameterDefinition *dpd = destinationDefinition->getInputDefinition(destIndex);
	dest_option_vals = dpd->getValueOptions();
	ParameterDefinition *macroPd = this->getParameterDefinition();
	src_option_vals = macroPd->getValueOptions();

	if (src_option_vals && src_option_vals[0] && 
	    dest_option_vals && dest_option_vals[0]) {
	    int i=0;
	    while (dest_option_vals[i] && src_option_vals[i]) {
		if (!EqualString (dest_option_vals[i], src_option_vals[i])) break;
		i++;
	    }
	    if ((dest_option_vals[i] == NULL) && (src_option_vals[i] == NULL))
		we_disconnected_the_one = TRUE;
	}

	if (we_disconnected_the_one) {
	    macroPd->removeValueOptions();
	    this->setTypeSafeOptions();
	}
    }
    if (this->isInput())
    {
	if (this->getConfigurationDialog())
	    this->getConfigurationDialog()->changeInput(1);
    }
    else
    {
	if (this->getConfigurationDialog())
	    this->getConfigurationDialog()->changeOutput(1);
    }
    return TRUE;
}
Example #6
0
//
// When a Receiver gets a new label, it has to disconnect from its existing
// transmitter, and connect to the new one.  This will work even if it's
// the transmitter that's changing our label.
boolean ReceiverNode::setLabelString(const char *label)
{
    if (EqualString(label, this->getLabelString()))
        return TRUE;

    if (initializing && this->getNetwork()->isReadingNetwork())
        return this->UniqueNameNode::setLabelString(label);

    if (!this->verifyRestrictedLabel(label))
        return FALSE;

    //
    // Skip the conflict check when reading in a newer style net since
    // there can't be any conflict in these nets.
    //
    const char* conflict = NUL(char*);
    if (this->getNetwork()->isReadingNetwork()) {
        int net_major = this->getNetwork()->getNetMajorVersion();
        int net_minor = this->getNetwork()->getNetMinorVersion();
        int net_micro = this->getNetwork()->getNetMicroVersion();
        int net_version =   VERSION_NUMBER( net_major, net_minor, net_micro);
        if (net_version < VERSION_NUMBER(3,1,1))
            conflict = this->getNetwork()->nameConflictExists(this, label);
    }

    //
    // If there is a name conflict while reading a network, it's important to try
    // to continue in spite of the conflict and fix things up later.  Reason: older
    // versions of dx allowed the name conflict and we would like to try and fix
    // things and report what happened rather than read the net incorrectly.
    //
    if ((conflict) && (this->getNetwork()->isReadingNetwork() == FALSE)) {
        ErrorMessage("A %s with name \"%s\" already exists.", conflict, label);
        return FALSE;
    }

    boolean found = FALSE;
    List *ia = (List*)this->getInputArks(1);
    if ((ia) && (ia->getSize() > 0)) {
        Ark *a = (Ark*)ia->getElement(1);
        int dummy;
        if (EqualString(a->getSourceNode(dummy)->getLabelString(), label))
            found = TRUE;
        else
            delete a;
    }
    ia = NUL(List*);


    if (!found) {
        List* l = this->getNetwork()->makeClassifiedNodeList(ClassTransmitterNode, FALSE);
        ListIterator iterator;
        Node *n;

        if ((l) && (this->getNetwork()->isReadingNetwork() == FALSE)) {
            //
            // Before creating any Arks, check for cycles.
            //
            iterator.setList(*l);
            while ( (n = (Node*)iterator.getNext()) ) {
                if (EqualString(label, n->getLabelString())) {
                    Network* net = this->getNetwork();
                    if (net->checkForCycle(n, this)) {
                        ErrorMessage (
                            "Unable to rename Receiver \"%s\" to \"%s\"\n"
                            "because that would cause a cyclic connection.",
                            this->getLabelString(), label
                        );
                        delete l;
                        return FALSE;
                    }
                }
            }
        }

        if (l) {
            iterator.setList(*l);
            while ( (n = (Node*)iterator.getNext()) ) {
                if (EqualString(label, n->getLabelString()))
                {
                    found = TRUE;
                    // link me to transmitter
                    new Ark(n, 1, this, 1);
                }
            }
            delete l;
        }
    }

    //
    // There was a name conflict because earlier versions of dx were less restrictive.
    // Record the transmitter for later fixup.  When the transmitter is fixed up,
    // then we'll automatically get fixed up also.  Caveat:  if there is no transmitter
    // connected, then it's cool to refuse the name because then we're not breaking
    // anything.
    //
    if (conflict) {
        ASSERT (this->getNetwork()->isReadingNetwork());
        if (this->isTransmitterConnected() == FALSE) {
            ErrorMessage("A %s with name \"%s\" already exists.", conflict, label);
            return FALSE;
        }
        List *l = (List*)this->getInputArks(1);
        ASSERT (l->getSize() > 0);
        Ark *a = (Ark*)l->getElement(1);
        int dummy;
        TransmitterNode* tn = (TransmitterNode*)a->getSourceNode(dummy);
        this->getNetwork()->fixupTransmitter(tn);
    }

    return this->UniqueNameNode::setLabelString(label);

}
void TR_ExpressionsSimplification::simplifyInvariantLoopExpressions(ListIterator<TR::Block> &blocks)
   {
   // Need to locate the induction variable of the loop
   //
   LoopInfo *loopInfo = findLoopInfo(_currentRegion);

   if (trace())
      {
      if (!loopInfo)
         {
         traceMsg(comp(), "Accurate loop info is not found, cannot carry out summation reduction\n");
         }
      else
         {
         traceMsg(comp(), "Accurate loop info has been found, will try to carry out summation reduction\n");
         if (loopInfo->getBoundaryNode())
            {
            traceMsg(comp(), "Variable iterations from node %p has not been handled\n",loopInfo->getBoundaryNode());
            }
         else
            {
            traceMsg(comp(), "Natural Loop %p will run %d times\n", _currentRegion, loopInfo->getNumIterations());
            }
         }
      }

   // Initialize the list of candidates
   //
   _candidateTTs = new (trStackMemory()) TR_ScratchList<TR::TreeTop>(trMemory());

   for (TR::Block *currentBlock = blocks.getFirst(); currentBlock; currentBlock  = blocks.getNext())
      {
      if (trace())
         traceMsg(comp(), "Analyzing block #%d, which must be executed once per iteration\n", currentBlock->getNumber());


      // Scan through each node in the block
      //
      TR::TreeTop *tt = currentBlock->getEntry();
      TR::TreeTop *exitTreeTop = currentBlock->getExit();
      while (tt != exitTreeTop)
         {
         TR::Node *currentNode = tt->getNode();
         if (trace())
            traceMsg(comp(), "Analyzing tree top node %p\n", currentNode);

         if (loopInfo)
            {
            // requires loop info for the number of iterations
            setSummationReductionCandidates(currentNode, tt);
            }
         setStoreMotionCandidates(currentNode, tt);

         tt = tt->getNextTreeTop();
         }
      }

   // New code: without using any UDI
   // walk through the trees in the loop
   // to invalidate the candidates
   //
   if (!_supportedExpressions)
      {
      _supportedExpressions = new (trStackMemory()) TR_BitVector(comp()->getNodeCount(), trMemory(), stackAlloc, growable);
      }

   invalidateCandidates();

   ListIterator<TR::TreeTop> treeTops(_candidateTTs);
   for (TR::TreeTop *treeTop = treeTops.getFirst(); treeTop; treeTop = treeTops.getNext())
      {
      if (trace())
         traceMsg(comp(), "Candidate TreeTop: %p, Node:%p\n", treeTop, treeTop->getNode());

      bool usedCandidate = false;
      bool isPreheaderBlockInvalid = false;

      if (loopInfo)
         {
         usedCandidate = tranformSummationReductionCandidate(treeTop, loopInfo, &isPreheaderBlockInvalid);
         }

      if (isPreheaderBlockInvalid)
         {
         break;
         }

      if (!usedCandidate)
         {
         tranformStoreMotionCandidate(treeTop, &isPreheaderBlockInvalid);
         }
      if (isPreheaderBlockInvalid)
         {
         break;
         }
      }
   }