int main() { /*TMemoryPool<int, 20> pool; for (int i = 0; i < 20; ++i) { int* num = pool.create(); *num = i; std::cout << num << " -> " << *num << std::endl; }*/ Boundary2D quadBoundary(Point2D(100.0f, 100.0f), Point2D(100.0f, 100.0f)); size_t quadCapacity = 5; Point2D minQuadSize(10.0f, 10.0f); QuadTree<size_t> qtree(quadBoundary, quadCapacity, minQuadSize); srand(static_cast <unsigned> (time(0))); for (int i = 0; i < 50; ++i) { size_t id = i; float x = static_cast <float> (rand()) / static_cast <float> (RAND_MAX) * 200.0f; float y = static_cast <float> (rand()) / static_cast <float> (RAND_MAX) * 200.0f; Point2D pos(x, y); qtree.insert(id, pos); } for (int i = 0; i < 20; ++i) { size_t id = 1337 + i; Point2D pos(0.0f, 0.0f); qtree.insert(id, pos); } qtree.print(); for (int i = 0; i < 20; ++i) { size_t id = 1337 + i; Point2D pos(0.0f, 0.0f); qtree.remove(id, pos); } std::cout << "DIVIDER" << std::endl; qtree.print(); Boundary2D targetRange(Point2D(100.0f, 100.0f), Point2D(20.0f, 20.0f)); std::vector<QuadTree<size_t>::Entry> entries = qtree.queryRange(targetRange); std::cout << std::endl << "RangeQuery " << targetRange << ": "; for (const QuadTree<size_t>::Entry& entry : entries) { std::cout << "[" << entry.obj << ":" << entry.pos << "]"; } std::cout << std::endl; }
bool AllocaMerging::runOnFunction(Function& F) { cheerp::PointerAnalyzer & PA = getAnalysis<cheerp::PointerAnalyzer>(); cheerp::Registerize & registerize = getAnalysis<cheerp::Registerize>(); cheerp::TypeSupport types(*F.getParent()); AllocaInfos allocaInfos; // Gather all the allocas for(BasicBlock& BB: F) analyzeBlock(registerize, BB, allocaInfos); if (allocaInfos.size() < 2) return false; bool Changed = false; BasicBlock& entryBlock=F.getEntryBlock(); // Look if we can merge allocas of the same type for(auto targetCandidate=allocaInfos.begin();targetCandidate!=allocaInfos.end();++targetCandidate) { AllocaInst* targetAlloca = targetCandidate->first; Type* targetType = targetAlloca->getAllocatedType(); // The range storing the sum of all ranges merged into target cheerp::Registerize::LiveRange targetRange(targetCandidate->second); // If the range is empty, we have an alloca that we can't analyze if (targetRange.empty()) continue; std::vector<AllocaInfos::iterator> mergeSet; auto sourceCandidate=targetCandidate; ++sourceCandidate; for(;sourceCandidate!=allocaInfos.end();++sourceCandidate) { AllocaInst* sourceAlloca = sourceCandidate->first; Type* sourceType = sourceAlloca->getAllocatedType(); // Bail out for non compatible types if(!areTypesEquivalent(types, PA, targetType, sourceType)) continue; const cheerp::Registerize::LiveRange& sourceRange = sourceCandidate->second; // Bail out if this source candidate is not analyzable if(sourceRange.empty()) continue; // Bail out if the allocas interfere if(targetRange.doesInterfere(sourceRange)) continue; // Add the range to the target range and the source alloca to the mergeSet mergeSet.push_back(sourceCandidate); PA.invalidate(sourceAlloca); targetRange.merge(sourceRange); } // If the merge set is empty try another target if(mergeSet.empty()) continue; PA.invalidate(targetAlloca); if(!Changed) registerize.invalidateLiveRangeForAllocas(F); // Make sure that this alloca is in the entry block if(targetAlloca->getParent()!=&entryBlock) targetAlloca->moveBefore(entryBlock.begin()); // We can merge the allocas for(const AllocaInfos::iterator& it: mergeSet) { AllocaInst* allocaToMerge = it->first; Instruction* targetVal=targetAlloca; if(targetVal->getType()!=allocaToMerge->getType()) { targetVal=new BitCastInst(targetVal, allocaToMerge->getType()); targetVal->insertAfter(targetAlloca); } allocaToMerge->replaceAllUsesWith(targetVal); allocaToMerge->eraseFromParent(); if(targetVal != targetAlloca) PA.getPointerKind(targetVal); allocaInfos.erase(it); NumAllocaMerged++; } PA.getPointerKind(targetAlloca); Changed = true; } if(Changed) registerize.computeLiveRangeForAllocas(F); return Changed; }