Improve TableGen performance of -gen-dag-isel (motivated by X86 backend)

The introduction of parameterized register classes in r313271 caused the
matcher generation code in TableGen to run much slower, particularly so
in the unoptimized (debug) build. This patch recovers some of the lost
performance.

Summary of changes:
- Cache the set of legal types in TypeInfer::getLegalTypes. The contents
  of this set do not change.
- Add LLVM_ATTRIBUTE_ALWAYS_INLINE to several small functions. Normally
  this would not be necessary, but in the debug build TableGen is not
  optimized, so this helps a little bit.
- Add an early exit from TypeSetByHwMode::operator== for the case when
  one or both arguments are "simple", i.e. only have one mode. This
  saves some time in GenerateVariants.
- Finally, replace the underlying storage type in TypeSetByHwMode::SetType
  with MachineValueTypeSet based on std::array instead of std::set.
  This significantly reduces the number of memory allocation calls.

I've done a number of experiments with the underlying type of InfoByHwMode.
The type is a map, and for targets that do not use the parameterization,
this map has only one entry. The best (unoptimized) performance, somewhat
surprisingly came from std::map, followed closely by std::unordered_map.
DenseMap was the slowest by a large margin.
Various hand-crafted solutions (emulating enough of the map interface
not to make sweeping changes to the users) did not yield any observable
improvements.

llvm-svn: 313647
diff --git a/llvm/utils/TableGen/InfoByHwMode.h b/llvm/utils/TableGen/InfoByHwMode.h
index d20bdab..71149e8 100644
--- a/llvm/utils/TableGen/InfoByHwMode.h
+++ b/llvm/utils/TableGen/InfoByHwMode.h
@@ -63,23 +63,30 @@
   typedef typename MapType::const_iterator const_iterator;
 
   InfoByHwMode() = default;
-  InfoByHwMode(const MapType &&M) : Map(M) {}
+  InfoByHwMode(const MapType &M) : Map(M) {}
 
+  LLVM_ATTRIBUTE_ALWAYS_INLINE
   iterator begin() { return Map.begin(); }
+  LLVM_ATTRIBUTE_ALWAYS_INLINE
   iterator end()   { return Map.end(); }
+  LLVM_ATTRIBUTE_ALWAYS_INLINE
   const_iterator begin() const { return Map.begin(); }
+  LLVM_ATTRIBUTE_ALWAYS_INLINE
   const_iterator end() const   { return Map.end(); }
+  LLVM_ATTRIBUTE_ALWAYS_INLINE
   bool empty() const { return Map.empty(); }
 
+  LLVM_ATTRIBUTE_ALWAYS_INLINE
   bool hasMode(unsigned M) const { return Map.find(M) != Map.end(); }
+  LLVM_ATTRIBUTE_ALWAYS_INLINE
   bool hasDefault() const { return hasMode(DefaultMode); }
 
   InfoT &get(unsigned Mode) {
     if (!hasMode(Mode)) {
       assert(hasMode(DefaultMode));
-      Map[Mode] = Map[DefaultMode];
+      Map.insert({Mode, Map.at(DefaultMode)});
     }
-    return Map[Mode];
+    return Map.at(Mode);
   }
   const InfoT &get(unsigned Mode) const {
     auto F = Map.find(Mode);
@@ -89,9 +96,11 @@
     return F->second;
   }
 
+  LLVM_ATTRIBUTE_ALWAYS_INLINE
   bool isSimple() const {
     return Map.size() == 1 && Map.begin()->first == DefaultMode;
   }
+  LLVM_ATTRIBUTE_ALWAYS_INLINE
   InfoT getSimple() const {
     assert(isSimple());
     return Map.begin()->second;