From f19eacfe0bc7a5746f8bb92f6ef27b9437bb716e Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 21 Mar 2018 02:48:34 +0000 Subject: [PATCH] [TableGen] Use SmallMapVector to simplify some code that was trying to keep a vector unique Summary: This code previously had a SmallVector of std::pairs containing an unsigned and another SmallVector. The outer vector was using the unsigned effectively as a key to decide which SmallVector to add into. So each time something new needed to be added the out vector needed to be scanned. If it wasn't found a new entry needed to be added to be added. This sounds very much like a map, but the next loop iterates over the outer vector to get a deterministic order. We can simplify this code greatly if use SmallMapVector instead. This uses more stack space since we now have a vector and a map, but the searching and creating new entries all happens behind the scenes. It should also make the search more efficient though usually there are only a few entries so that doesn't matter much. We could probably get determinism by just using std::map which would iterate over the unsigned key, but that would generate different output from what we get with the current implementation. Reviewers: RKSimon, dblaikie Reviewed By: dblaikie Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D44711 llvm-svn: 328070 --- llvm/utils/TableGen/CodeGenSchedule.cpp | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/llvm/utils/TableGen/CodeGenSchedule.cpp b/llvm/utils/TableGen/CodeGenSchedule.cpp index f7420cf..90d7c8e 100644 --- a/llvm/utils/TableGen/CodeGenSchedule.cpp +++ b/llvm/utils/TableGen/CodeGenSchedule.cpp @@ -15,6 +15,7 @@ #include "CodeGenSchedule.h" #include "CodeGenInstruction.h" #include "CodeGenTarget.h" +#include "llvm/ADT/MapVector.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallSet.h" @@ -743,7 +744,7 @@ void CodeGenSchedModels::createInstRWClass(Record *InstRWDef) { // intersects with an existing class via a previous InstRWDef. Instrs that do // not intersect with an existing class refer back to their former class as // determined from ItinDef or SchedRW. - SmallVector>, 4> ClassInstrs; + SmallMapVector, 4> ClassInstrs; // Sort Instrs into sets. const RecVec *InstDefs = Sets.expand(InstRWDef); if (InstDefs->empty()) @@ -754,22 +755,13 @@ void CodeGenSchedModels::createInstRWClass(Record *InstRWDef) { if (Pos == InstrClassMap.end()) PrintFatalError(InstDef->getLoc(), "No sched class for instruction."); unsigned SCIdx = Pos->second; - unsigned CIdx = 0, CEnd = ClassInstrs.size(); - for (; CIdx != CEnd; ++CIdx) { - if (ClassInstrs[CIdx].first == SCIdx) - break; - } - if (CIdx == CEnd) { - ClassInstrs.resize(CEnd + 1); - ClassInstrs[CIdx].first = SCIdx; - } - ClassInstrs[CIdx].second.push_back(InstDef); + ClassInstrs[SCIdx].push_back(InstDef); } // For each set of Instrs, create a new class if necessary, and map or remap // the Instrs to it. - for (unsigned CIdx = 0, CEnd = ClassInstrs.size(); CIdx != CEnd; ++CIdx) { - unsigned OldSCIdx = ClassInstrs[CIdx].first; - ArrayRef InstDefs = ClassInstrs[CIdx].second; + for (auto &Entry : ClassInstrs) { + unsigned OldSCIdx = Entry.first; + ArrayRef InstDefs = Entry.second; // If the all instrs in the current class are accounted for, then leave // them mapped to their old class. if (OldSCIdx) { -- 2.7.4