void Forest::Color() { int nn, m; int c; int j, k = 17; int *p; CSet used; Tree *t; if (pass == 1) { for (c = 0; c < treecount; c++) { trees[c]->spill = false; trees[c]->color = k; if (trees[c]->var < 3) trees[c]->color = trees[c]->var; if (trees[c]->var >= regFirstArg && trees[c]->var <= regLastArg) { trees[c]->color = trees[c]->var - regFirstArg + 18; } if (trees[c]->var == regFP || trees[c]->var == regLR || trees[c]->var == regXLR || trees[c]->var == regSP) { trees[c]->color = trees[c]->var - regXLR + 28; } } } used.clear(); used.add(0); // reg0 is a constant 0 used.add(1); // these two are return value used.add(2); while (!stk->IsEmpty()) { t = trees[m=pop()]; if (pass == 1 && !t->infinite && t->cost < 0.0f) { // was <= 0.0f t->spill = true; } else { p = iGraph.GetNeighbours(m, &nn); for (j = 0; j < nn; j++) used.add(trees[p[j]]->color); for (c = 0; used.isMember(c) && c < k; c++); if (c < k && t->color == k) { // The tree may have been colored already t->color = c; used.add(c); } else if (t->color <= k) // Don't need to spill args t->spill = true; } } }
int Forest::GetSpillCount() { int c; int spillCount; CSet ts; char buf[2000]; ts.clear(); for (spillCount = c = 0; c < treecount; c++) { if (trees[c]->spill) { spillCount++; ts.add(c); } } dfs.printf("<SpillCount>%d</SpillCount>\n", spillCount); ts.sprint(buf, sizeof(buf)); dfs.printf("<TreesSpilled>%s</TreesSpilled>\n", buf); return (spillCount); }
void CRABMedium::Update() { /* Update positional index of RAB entities */ m_pcRABEquippedEntityIndex->Update(); /* Delete routing table */ for(TRoutingTable::iterator it = m_tRoutingTable.begin(); it != m_tRoutingTable.end(); ++it) { it->second.clear(); } /* This map contains the pairs that have already been checked */ unordered_map<ssize_t, std::pair<CRABEquippedEntity*, CRABEquippedEntity*> > mapPairsAlreadyChecked; /* Iterator for the above structure */ unordered_map<ssize_t, std::pair<CRABEquippedEntity*, CRABEquippedEntity*> >::iterator itPair; /* Used as test key */ std::pair<CRABEquippedEntity*, CRABEquippedEntity*> cTestKey; /* Used as hash for the test key */ UInt64 unTestHash; /* The ray to use for occlusion checking */ CRay3 cOcclusionCheckRay; /* Buffer for the communicating entities */ CSet<CRABEquippedEntity*,SEntityComparator> cOtherRABs; /* Buffer to store the intersection data */ SEmbodiedEntityIntersectionItem sIntersectionItem; /* The distance between two RABs in line of sight */ Real fDistance; /* Go through the RAB entities */ for(TRoutingTable::iterator it = m_tRoutingTable.begin(); it != m_tRoutingTable.end(); ++it) { /* Get a reference to the current RAB entity */ CRABEquippedEntity& cRAB = *reinterpret_cast<CRABEquippedEntity*>(GetSpace().GetEntityVector()[it->first]); /* Initialize the occlusion check ray start to the position of the robot */ cOcclusionCheckRay.SetStart(cRAB.GetPosition()); /* For each RAB entity, get the list of RAB entities in range */ cOtherRABs.clear(); m_pcRABEquippedEntityIndex->GetEntitiesAt(cOtherRABs, cRAB.GetPosition()); /* Go through the RAB entities in range */ for(CSet<CRABEquippedEntity*>::iterator it2 = cOtherRABs.begin(); it2 != cOtherRABs.end(); ++it2) { /* Get a reference to the RAB entity */ CRABEquippedEntity& cOtherRAB = **it2; /* First, make sure the entities are not the same */ if(&cRAB != &cOtherRAB) { /* Proceed if the pair has not been checked already */ if(&cRAB < &cOtherRAB) { cTestKey.first = &cRAB; cTestKey.second = &cOtherRAB; } else { cTestKey.first = &cOtherRAB; cTestKey.second = &cRAB; } unTestHash = HashRABPair(cTestKey); itPair = mapPairsAlreadyChecked.find(unTestHash); if(itPair == mapPairsAlreadyChecked.end() || /* Pair does not exist */ itPair->second.first != cTestKey.first || /* Pair exists, but first RAB involved is different */ itPair->second.second != cTestKey.second) { /* Pair exists, but second RAB involved is different */ /* Mark this pair as already checked */ mapPairsAlreadyChecked[unTestHash] = cTestKey; /* Proceed if the message size is compatible */ if(cRAB.GetMsgSize() == cOtherRAB.GetMsgSize()) { /* Proceed if the two entities are not obstructed by another object */ cOcclusionCheckRay.SetEnd(cOtherRAB.GetPosition()); if((!m_bCheckOcclusions) || (!GetClosestEmbodiedEntityIntersectedByRay(sIntersectionItem, cOcclusionCheckRay, cRAB.GetEntityBody())) || (&cOtherRAB.GetEntityBody() == sIntersectionItem.IntersectedEntity)) { /* If we get here, the two RAB entities are in direct line of sight */ /* cRAB can receive cOtherRAB's message if it is in range, and viceversa */ /* Calculate square distance */ fDistance = cOcclusionCheckRay.GetLength(); if(fDistance < cOtherRAB.GetRange()) { /* cRAB receives cOtherRAB's message */ m_tRoutingTable[cRAB.GetIndex()].insert(&cOtherRAB); } if(fDistance < cRAB.GetRange()) { /* cOtherRAB receives cRAB's message */ m_tRoutingTable[cOtherRAB.GetIndex()].insert(&cRAB); } } // occlusion found? } // is msg size the same? } // is check necessary? } // are entities the same? } // for entities in range } // for routing table }
bool Forest::SpillCode() { int c, m, n; Var *v; Tree *t; BasicBlock *bb; int64_t spillOffset; OCODE *cd; CSet spilled; bool ret; ret = false; cd = currentFn->spAdjust; if (cd == nullptr) return (ret); spillOffset = cd->oper3->offset->i; spilled.clear(); for (c = 0; c < treecount; c++) { t = trees[c]; // convenience // Tree couldn't be colored that means there are no available registers. // So, spill one of the registers. The register to spill should be one // that isn't live at the same time as this tree. if (t->spill) { ret = true; v = Var::Find(t->var); v = v->GetVarToSpill(&spilled); if (v == nullptr) continue; // The var is spilled at the head of the tree, and restored later t->blocks->resetPtr(); m = t->blocks->nextMember(); if (m >= 0) { // should always be true, otherwise no code bb = basicBlocks[m]; if (!spilled.isMember(v->num)) { v->spillOffset = spillOffset; spillOffset += sizeOfWord; spilled.add(v->num); } bb->InsertSpillCode(v->num, -v->spillOffset); while(1) { n = m; m = t->blocks->nextMember(); if (m < 0) break; // Detect when a different branch is present. The node // number will jump by more than 1 between branches. // *** suspect this won't work, should just pick last block in tree if (m - n > 1) { bb = basicBlocks[n]; bb->InsertFillCode(v->num, -v->spillOffset); } } bb = basicBlocks[n]; bb->InsertFillCode(v->num, -v->spillOffset); } t->spill = false; } } cd->oper3->offset->i = spillOffset; return (ret); }