Implement value type abstraction for types.

This is done by changing Type to be a POD interface around an underlying pointer storage and adding in-class support for isa/dyn_cast/cast.

PiperOrigin-RevId: 219372163
diff --git a/lib/Analysis/LoopAnalysis.cpp b/lib/Analysis/LoopAnalysis.cpp
index 1b3c24f..1904a63 100644
--- a/lib/Analysis/LoopAnalysis.cpp
+++ b/lib/Analysis/LoopAnalysis.cpp
@@ -118,15 +118,15 @@
   return tripCountExpr.getLargestKnownDivisor();
 }
 
-bool mlir::isAccessInvariant(const MLValue &input, MemRefType *memRefType,
+bool mlir::isAccessInvariant(const MLValue &input, MemRefType memRefType,
                              ArrayRef<MLValue *> indices, unsigned dim) {
-  assert(indices.size() == memRefType->getRank());
+  assert(indices.size() == memRefType.getRank());
   assert(dim < indices.size());
-  auto layoutMap = memRefType->getAffineMaps();
-  assert(memRefType->getAffineMaps().size() <= 1);
+  auto layoutMap = memRefType.getAffineMaps();
+  assert(memRefType.getAffineMaps().size() <= 1);
   // TODO(ntv): remove dependency on Builder once we support non-identity
   // layout map.
-  Builder b(memRefType->getContext());
+  Builder b(memRefType.getContext());
   assert(layoutMap.empty() ||
          layoutMap[0] == b.getMultiDimIdentityMap(indices.size()));
   (void)layoutMap;
@@ -170,7 +170,7 @@
   using namespace functional;
   auto indices = map([](SSAValue *val) { return dyn_cast<MLValue>(val); },
                      memoryOp->getIndices());
-  auto *memRefType = memoryOp->getMemRefType();
+  auto memRefType = memoryOp->getMemRefType();
   for (unsigned d = 0, numIndices = indices.size(); d < numIndices; ++d) {
     if (fastestVaryingDim == (numIndices - 1) - d) {
       continue;
@@ -184,8 +184,8 @@
 
 template <typename LoadOrStoreOpPointer>
 static bool isVectorElement(LoadOrStoreOpPointer memoryOp) {
-  auto *memRefType = memoryOp->getMemRefType();
-  return isa<VectorType>(memRefType->getElementType());
+  auto memRefType = memoryOp->getMemRefType();
+  return memRefType.getElementType().template isa<VectorType>();
 }
 
 bool mlir::isVectorizableLoop(const ForStmt &loop, unsigned fastestVaryingDim) {
diff --git a/lib/Analysis/Verifier.cpp b/lib/Analysis/Verifier.cpp
index bfbcb16..0dd030d 100644
--- a/lib/Analysis/Verifier.cpp
+++ b/lib/Analysis/Verifier.cpp
@@ -195,7 +195,7 @@
 
   // Verify that the argument list of the function and the arg list of the first
   // block line up.
-  auto fnInputTypes = fn.getType()->getInputs();
+  auto fnInputTypes = fn.getType().getInputs();
   if (fnInputTypes.size() != firstBB->getNumArguments())
     return failure("first block of cfgfunc must have " +
                        Twine(fnInputTypes.size()) +
@@ -306,7 +306,7 @@
 
 bool CFGFuncVerifier::verifyReturn(const ReturnInst &inst) {
   // Verify that the return operands match the results of the function.
-  auto results = fn.getType()->getResults();
+  auto results = fn.getType().getResults();
   if (inst.getNumOperands() != results.size())
     return failure("return has " + Twine(inst.getNumOperands()) +
                        " operands, but enclosing function returns " +