llvm.org GIT mirror llvm / 70dbc39
[tablegen] Improve performance of -gen-register-info by replacing barely-necessary std::map with a sorted vector Summary: This particular map is hardly ever queried and has a phased usage pattern (insert, iterate, query, insert, iterate) so it's a good candidate for a sorted vector and std::lower_bound. This significantly reduces the run time of runTargetDesc() in some circumstances. One llvm-tblgen invocation in my build improves the time spent in runTargetDesc() from 9.86s down to 0.80s (~92%) without changing the output. The same invocation also has 2GB less allocation churn. Reviewers: bogner, rtereshin, aditya_nandakumar, volkan Reviewed By: rtereshin Subscribers: mgrang, dexonsmith, llvm-commits Differential Revision: https://reviews.llvm.org/D50272 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339208 91177308-0d34-0410-b5e6-96231b3b80d8 Daniel Sanders 2 years ago
2 changed file(s) with 65 addition(s) and 12 deletion(s). Raw diff Collapse all Expand all
823823 }
824824 };
825825
826 /// \brief Function object to apply a binary function to the first component of
827 /// a std::pair.
828 template
829 struct on_first {
830 FuncTy func;
831
832 template
833 auto operator()(const T &lhs, const T &rhs) const
834 -> decltype(func(lhs.first, rhs.first)) {
835 return func(lhs.first, rhs.first);
836 }
837 };
838
826839 // A subset of N3658. More stuff can be added as-needed.
827840
828841 /// Represents a compile-time sequence of integers.
339339 << "}\n\n";
340340 }
341341
342 using DwarfRegNumsMapPair = std::pair>;
343 using DwarfRegNumsVecTy = std::vector;
344
345 void finalizeDwarfRegNumsKeys(DwarfRegNumsVecTy &DwarfRegNums) {
346 // Sort and unique to get a map-like vector. We want the last assignment to
347 // match previous behaviour.
348 std::stable_sort(DwarfRegNums.begin(), DwarfRegNums.end(),
349 on_first());
350 // Warn about duplicate assignments.
351 const Record *LastSeenReg = nullptr;
352 for (const auto &X : DwarfRegNums) {
353 const auto &Reg = X.first;
354 // The only way LessRecordRegister can return equal is if they're the same
355 // string. Use simple equality instead.
356 if (LastSeenReg && Reg->getName() == LastSeenReg->getName())
357 PrintWarning(Reg->getLoc(), Twine("DWARF numbers for register ") +
358 getQualifiedName(Reg) +
359 "specified multiple times");
360 LastSeenReg = Reg;
361 }
362 auto Last = std::unique(
363 DwarfRegNums.begin(), DwarfRegNums.end(),
364 [](const DwarfRegNumsMapPair &A, const DwarfRegNumsMapPair &B) {
365 return A.first->getName() == B.first->getName();
366 });
367 DwarfRegNums.erase(Last, DwarfRegNums.end());
368 }
369
342370 void RegisterInfoEmitter::EmitRegMappingTables(
343371 raw_ostream &OS, const std::deque &Regs, bool isCtor) {
344372 // Collect all information about dwarf register numbers
345 typedef std::map, LessRecordRegister> DwarfRegNumsMapTy;
346 DwarfRegNumsMapTy DwarfRegNums;
373 DwarfRegNumsVecTy DwarfRegNums;
347374
348375 // First, just pull all provided information to the map
349376 unsigned maxLength = 0;
351378 Record *Reg = RE.TheDef;
352379 std::vector RegNums = Reg->getValueAsListOfInts("DwarfNumbers");
353380 maxLength = std::max((size_t)maxLength, RegNums.size());
354 if (DwarfRegNums.count(Reg))
355 PrintWarning(Reg->getLoc(), Twine("DWARF numbers for register ") +
356 getQualifiedName(Reg) + "specified multiple times");
357 DwarfRegNums[Reg] = RegNums;
358 }
381 DwarfRegNums.emplace_back(Reg, std::move(RegNums));
382 }
383 finalizeDwarfRegNumsKeys(DwarfRegNums);
359384
360385 if (!maxLength)
361386 return;
362387
363388 // Now we know maximal length of number list. Append -1's, where needed
364 for (DwarfRegNumsMapTy::iterator
365 I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I)
389 for (DwarfRegNumsVecTy::iterator I = DwarfRegNums.begin(),
390 E = DwarfRegNums.end();
391 I != E; ++I)
366392 for (unsigned i = I->second.size(), e = maxLength; i != e; ++i)
367393 I->second.push_back(-1);
368394
383409 // Store the mapping sorted by the LLVM reg num so lookup can be done
384410 // with a binary search.
385411 std::map Dwarf2LMap;
386 for (DwarfRegNumsMapTy::iterator
412 for (DwarfRegNumsVecTy::iterator
387413 I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) {
388414 int DwarfRegNo = I->second[i];
389415 if (DwarfRegNo < 0)
422448
423449 DefInit *DI = cast(V->getValue());
424450 Record *Alias = DI->getDef();
425 DwarfRegNums[Reg] = DwarfRegNums[Alias];
451 const auto &AliasIter =
452 std::lower_bound(DwarfRegNums.begin(), DwarfRegNums.end(), Alias,
453 [](const DwarfRegNumsMapPair &A, const Record *B) {
454 return LessRecordRegister()(A.first, B);
455 });
456 assert(AliasIter != DwarfRegNums.end() && AliasIter->first == Alias &&
457 "Expected Alias to be present in map");
458 const auto &RegIter =
459 std::lower_bound(DwarfRegNums.begin(), DwarfRegNums.end(), Reg,
460 [](const DwarfRegNumsMapPair &A, const Record *B) {
461 return LessRecordRegister()(A.first, B);
462 });
463 assert(RegIter != DwarfRegNums.end() && RegIter->first == Reg &&
464 "Expected Reg to be present in map");
465 RegIter->second = AliasIter->second;
426466 }
427467
428468 // Emit information about the dwarf register numbers.
435475 OS << " = {\n";
436476 // Store the mapping sorted by the Dwarf reg num so lookup can be done
437477 // with a binary search.
438 for (DwarfRegNumsMapTy::iterator
478 for (DwarfRegNumsVecTy::iterator
439479 I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) {
440480 int RegNo = I->second[i];
441481 if (RegNo == -1) // -1 is the default value, don't emit a mapping.