BinaryTreeNode* first_common_ancestor(BinaryTreeNode* root, BinaryTreeNode* p, BinaryTreeNode* q) { if (!covers(root, p) || !covers(root, q)) { return nullptr; } return search_ancestor(root, p, q); }
// Update active and inactive lists based on pos void Vxls::update(unsigned pos) { // check for active intervals in that are expired or inactive for (auto i = active.begin(); i != active.end();) { auto ivl = *i; if (pos >= ivl->end()) { erase(active, i); } else if (!ivl->covers(pos)) { erase(active, i); inactive.push_back(ivl); } else { i++; } } // check for intervals that are expired or active for (auto i = inactive.begin(); i != inactive.end();) { auto ivl = *i; if (pos >= ivl->end()) { erase(inactive, i); } else if (ivl->covers(pos)) { erase(inactive, i); active.push_back(ivl); } else { i++; } } }
boost::shared_ptr<tree> common_ancestor_helper(boost::shared_ptr<tree> root, boost::shared_ptr<tree> p, boost::shared_ptr<tree> q) { if (root == nullptr) return nullptr; if (root == p || root == q) return root; bool p_in_left = covers(root->left, p); bool q_in_left = covers(root->left, q); if (p_in_left != q_in_left) return root; else { boost::shared_ptr<tree> child = p_in_left ? root->left : root->right; return common_ancestor_helper(child, p, q); } }
/*! Checks if there is an entry at the given position. True when this node is a leaf and the entry is set or the child at p exists and returns true on getChild(p)->hasEntry(p). */ bool hasEntry(float p[6]) { if (leaf) { if (!covers(p)) { return false; } if (entry) { return true; } else { return false; } } int indx = getChildIndx(p); if (indx < 0 || !children[indx]) { return false; } return children[indx]->hasEntry(p); };
// 親ノードから見て,pとqが同じ側にあるところを追っていく // 同じ側にない→そこが共通の上位ノード BinaryTreeNode* search_ancestor(BinaryTreeNode* root, BinaryTreeNode* p, BinaryTreeNode* q) { if (root == nullptr || root == p || root == q) { return root; } bool p_is_on_left = covers(root->left, p); bool q_is_on_left = covers(root->left, q); if (p_is_on_left != q_is_on_left) { // 2つのノードが反対側にある return root; } // 同じ側にあるので,そちら側に進む BinaryTreeNode* child_side = p_is_on_left ? root->left : root->right; return search_ancestor(child_side, p, q); }
int getChildIndx(float p[6]) { if (!covers(p)) { VR_ERROR << "Node do not cover this pos" << endl; return -1; } if (leaf) { VR_ERROR << "Node is already a leaf node?!" << endl; return -1; } int res = 0; for (int i=0;i<6;i++) { if (p[i] > pos[i] + extends[i]*0.5f ) { // right side int powI = 1; for (int j = 0; j<i; j++) powI *= 2; res += powI;//pow(2,i) // no int version of pow } } // test, remove this if (res<0 || res>=64) { VR_ERROR << "INTERNAL ERROR?!" << endl; return -1; } return res; };
void CCoverManager::clear () { if (!get_covers()) return; covers().all (m_nearest); delete_data (m_nearest); m_covers->clear (); }
/*! Automatically checks if a new child element has to be created. A copy of e is stored. */ bool setEntry(float p[6], const T &e) { if (!covers(p)) return false; if (leaf || level>=(maxLevels-1)) { leaf = true; delete entry; entry = new T(e); return true; } VoxelTree6DElement* c = createChild(p); // returns child if it is already existing if (!c->setEntry(p,e)) return false; return true; };
const char* draw(Interval* parent, unsigned pos, Mode m, Pred covers) { // Light Heavy static const char* top[] = { "\u2575", "\u2579" }; static const char* bottom[] = { "\u2577", "\u257B" }; static const char* both[] = { "\u2502", "\u2503" }; static const char* empty[] = { " ", " " }; auto f = [&](unsigned pos) { for (auto ivl = parent; ivl; ivl = ivl->next) { if (covers(ivl, pos)) return true; } return false; }; auto s = f(pos); auto d = pos%2 == 1 ? s : f(pos+1); return ( s && !d) ? top[m] : ( s && d) ? both[m] : (!s && d) ? bottom[m] : empty[m]; }
void Vxls::resolveEdges() { for (auto b1 : blocks) { auto& block1 = unit.blocks[b1]; auto p1 = block_ranges[b1].end - 2; auto succlist = succs(block1); auto& inst1 = block1.code.back(); if (inst1.op == Vinstr::phijmp) { auto target = inst1.phijmp_.target; auto& uses = unit.tuples[inst1.phijmp_.uses]; auto& defs = unit.tuples[findDefs(unit, target)]; for (unsigned i = 0, n = uses.size(); i < n; ++i) { auto i1 = intervals[uses[i]]; if (i1) i1 = i1->childAt(p1); auto i2 = intervals[defs[i]]; if (i2->reg != i1->reg) { edge_copies[{b1,0}][i2->reg] = i1; } } inst1 = jmp{target}; } for (unsigned i = 0, n = succlist.size(); i < n; i++) { auto b2 = succlist[i]; auto p2 = block_ranges[b2].start; forEach(livein[b2], [&](Vreg vr) { Interval* i1 = nullptr; Interval* i2 = nullptr; for (auto ivl = intervals[vr]; ivl && !(i1 && i2); ivl = ivl->next) { if (ivl->covers(p1)) i1 = ivl; if (ivl->covers(p2)) i2 = ivl; } // i2 can be unallocated if the tmp is a constant or is spilled. if (i2->reg != InvalidReg && i2->reg != i1->reg) { edge_copies[{b1,i}][i2->reg] = i1; } }); } } }
int ArmorType::get_armor(int bodypart) const { if(covers(bodypart)) { switch(bodypart) { case BODYPART_HEAD: return armor_head_; case BODYPART_BODY: return armor_body_; case BODYPART_ARM_RIGHT: case BODYPART_ARM_LEFT: return armor_limbs_; case BODYPART_LEG_RIGHT: case BODYPART_LEG_LEFT: return armor_limbs_; } } return 0; }
bool covers(BinaryTreeNode* root, BinaryTreeNode* p) { if (root == nullptr) return false; if (root == p) return true; return covers(root->left, p) || covers(root->right, p); }
Value *DataflowAnalyzer::computeValue(const Term *term, const MemoryLocation &memoryLocation, const ReachingDefinitions &definitions) { assert(term); assert(term->isRead()); assert(memoryLocation || definitions.empty()); auto value = dataflow().getValue(term); if (definitions.empty()) { return value; } auto byteOrder = architecture()->getByteOrder(memoryLocation.domain()); /* * Merge abstract values. */ auto abstractValue = value->abstractValue(); foreach (const auto &chunk, definitions.chunks()) { assert(memoryLocation.covers(chunk.location())); /* * Mask of bits inside abstractValue which are covered by chunk's location. */ auto mask = bitMask<ConstantValue>(chunk.location().size()); if (byteOrder == ByteOrder::LittleEndian) { mask = bitShift(mask, chunk.location().addr() - memoryLocation.addr()); } else { mask = bitShift(mask, memoryLocation.endAddr() - chunk.location().endAddr()); } foreach (auto definition, chunk.definitions()) { auto definitionLocation = dataflow().getMemoryLocation(definition); assert(definitionLocation.covers(chunk.location())); auto definitionValue = dataflow().getValue(definition); auto definitionAbstractValue = definitionValue->abstractValue(); /* * Shift definition's abstract value to match term's location. */ if (byteOrder == ByteOrder::LittleEndian) { definitionAbstractValue.shift(definitionLocation.addr() - memoryLocation.addr()); } else { definitionAbstractValue.shift(memoryLocation.endAddr() - definitionLocation.endAddr()); } /* Project the value to the defined location. */ definitionAbstractValue.project(mask); /* Update term's value. */ abstractValue.merge(definitionAbstractValue); } } value->setAbstractValue(abstractValue.resize(term->size())); /* * Merge stack offset and product flags. * * Heuristic: merge information only from terms that define lower bits of the term's value. */ const std::vector<const Term *> *lowerBitsDefinitions = nullptr; if (byteOrder == ByteOrder::LittleEndian) { if (definitions.chunks().front().location().addr() == memoryLocation.addr()) { lowerBitsDefinitions = &definitions.chunks().front().definitions(); } } else { if (definitions.chunks().back().location().endAddr() == memoryLocation.endAddr()) { lowerBitsDefinitions = &definitions.chunks().back().definitions(); } } if (lowerBitsDefinitions) { foreach (auto definition, *lowerBitsDefinitions) { auto definitionValue = dataflow().getValue(definition); if (definitionValue->isNotStackOffset()) { value->makeNotStackOffset(); } else if (definitionValue->isStackOffset()) { value->makeStackOffset(definitionValue->stackOffset()); } if (definitionValue->isNotProduct()) { value->makeNotProduct(); } else if (definitionValue->isProduct()) { value->makeProduct(); } } } /* * Merge return address flag. */ if (definitions.chunks().front().location() == memoryLocation) { foreach (auto definition, definitions.chunks().front().definitions()) { auto definitionValue = dataflow().getValue(definition); if (definitionValue->isNotReturnAddress()) { value->makeNotReturnAddress(); } else if (definitionValue->isReturnAddress()) { value->makeReturnAddress(); } } }
//this function determines any interactions with the existing list //this function adds the building to the list and adjusts or removes the existing buildings //to maintain the list with only disjoint buildings //the list is maintained in order by the left coordianate of the building void addBuilding(std::list< Building >& _buildingList,const Building& _building,bool debug=false) { std::list<Building>::iterator p = _buildingList.begin(); Building bld = _building; if(debug) std::cout << "Add: " << bld.l << " " << bld.h << " " << bld.r << std::endl; //if(debug) std::cout << "debug is enabled" << std::endl; if( p == _buildingList.end() ) { if(debug) std::cout << "Insert first" << std::endl; insertBuilding(_buildingList,p,bld,debug); return; } bool inserted(false); while(p!=_buildingList.end()) { if(debug) std::cout << "Consider: " << p->l << " " << p->h << " " << p->r << std::endl; //Will not intersect any buildings //because they are all to its right if( bld.r <= p->l) { if(debug) std::cout << "will not intersect" << std::endl; insertBuilding(_buildingList,p,bld,debug); return; } //no overlap so examine the next building if( !overlap(bld,*p) ) { if(debug) std::cout << "no overlap" << std::endl; ++p; continue; } if( covers(*p,bld) ) { if(debug) std::cout << "this building is covered" << std::endl; //since this building is covered, we don't need it return; } //this one is covered so not visible if( covers(bld,*p) ) { if(debug) std::cout << "this building covers considered" << std::endl; if(debug) std::cout << "remove considered" << std::endl; _buildingList.erase(p++); continue; } //new building is shorter if( bld.h < p->h ) { if(debug) std::cout << "new is shorter" << std::endl; if( bld.l < p->l ) { if(debug) std::cout << "new overlaps on left" << std::endl; if(debug) std::cout << "insert new one before old" << std::endl; Building leftBuilding = bld; leftBuilding.r = p->l; insertBuilding(_buildingList,p,leftBuilding,debug); } if( bld.r > p->r ) { if(debug) std::cout << "New overlaps on right" << std::endl; if(debug) std::cout << "Adjust left side and check against next" << std::endl; //move left wall of new building to remove overlap bld.l = p->r; } else { return; } } //the new building is taller else { if(debug) std::cout << "new is taller" << std::endl; Building saveOld = *p; if( p->l < bld.l ) { if(debug) std::cout << "old overlaps on left" << std::endl; if(debug) std::cout << "Shorten right side of old" << std::endl; p->r = bld.l; if( p->r <= p->l ) { if(debug) { std::cout << "Adjustment created invalid building: " << p->l << " " << p->r << std::endl; } } if( saveOld.r > bld.r ) { if(debug) std::cout << "old overlaps on right" << std::endl; ++p; if(debug) std::cout << "insert new after old" << std::endl; p = insertBuilding(_buildingList,p,bld,debug); ++p; saveOld.l = bld.r; insertBuilding(_buildingList,p,saveOld,debug); //since overlap on right, we are done return; } } else { if(debug) std::cout << "old does not overlap on left" << std::endl; if( p->r > bld.r ) { if(debug) std::cout << "old overlaps on right" << std::endl; if(debug) std::cout << "insert new before old" << std::endl; insertBuilding(_buildingList,p,bld,debug); if(debug) std::cout << "adjust left side of old so it does not overlap new" << std::endl; p->l = bld.r; //since overlap on right, we are done return; } } } ++p; continue; } if(!inserted) { if(debug) std::cout << "insert at end" << std::endl; insertBuilding(_buildingList,_buildingList.end(),bld,debug); } return; }
boost::shared_ptr<tree> common_ancestor(boost::shared_ptr<tree> root, boost::shared_ptr<tree> p, boost::shared_ptr<tree> q) { if (!covers(root, p) || !covers(root, q)) return nullptr; return common_ancestor_helper(root, p, q); }
bool covers(boost::shared_ptr<tree> root, boost::shared_ptr<tree> p) { if (root == nullptr) return false; if (root == p) return true; return covers(root->left, p) || covers(root->right, p); }