Assign APValues by swapping from a temporary. Removes a bunch of unnecessary
copy-construction, which Daniel Dunbar reports as giving a 0.75% speedup on
403.gcc/combine.c. The performance differences on my constexpr torture tests
are below the noise floor.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152455 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/APValue.cpp b/lib/AST/APValue.cpp
index 976629c..0b5b3b0 100644
--- a/lib/AST/APValue.cpp
+++ b/lib/AST/APValue.cpp
@@ -122,71 +122,68 @@
   delete Value;
 }
 
-const APValue &APValue::operator=(const APValue &RHS) {
-  if (this == &RHS)
-    return *this;
-  if (Kind != RHS.Kind || Kind == Array || Kind == Struct ||
-      Kind == MemberPointer) {
-    MakeUninit();
-    if (RHS.isInt())
-      MakeInt();
-    else if (RHS.isFloat())
-      MakeFloat();
-    else if (RHS.isVector())
-      MakeVector();
-    else if (RHS.isComplexInt())
-      MakeComplexInt();
-    else if (RHS.isComplexFloat())
-      MakeComplexFloat();
-    else if (RHS.isLValue())
-      MakeLValue();
-    else if (RHS.isArray())
-      MakeArray(RHS.getArrayInitializedElts(), RHS.getArraySize());
-    else if (RHS.isStruct())
-      MakeStruct(RHS.getStructNumBases(), RHS.getStructNumFields());
-    else if (RHS.isUnion())
-      MakeUnion();
-    else if (RHS.isMemberPointer())
-      MakeMemberPointer(RHS.getMemberPointerDecl(),
-                        RHS.isMemberPointerToDerivedMember(),
-                        RHS.getMemberPointerPath());
-    else if (RHS.isAddrLabelDiff())
-      MakeAddrLabelDiff();
-  }
-  if (isInt())
+APValue::APValue(const APValue &RHS) : Kind(Uninitialized) {
+  switch (RHS.getKind()) {
+  case Uninitialized:
+    break;
+  case Int:
+    MakeInt();
     setInt(RHS.getInt());
-  else if (isFloat())
+    break;
+  case Float:
+    MakeFloat();
     setFloat(RHS.getFloat());
-  else if (isVector())
+    break;
+  case Vector:
+    MakeVector();
     setVector(((const Vec *)(const char *)RHS.Data)->Elts,
               RHS.getVectorLength());
-  else if (isComplexInt())
+    break;
+  case ComplexInt:
+    MakeComplexInt();
     setComplexInt(RHS.getComplexIntReal(), RHS.getComplexIntImag());
-  else if (isComplexFloat())
+    break;
+  case ComplexFloat:
+    MakeComplexFloat();
     setComplexFloat(RHS.getComplexFloatReal(), RHS.getComplexFloatImag());
-  else if (isLValue()) {
+    break;
+  case LValue:
+    MakeLValue();
     if (RHS.hasLValuePath())
       setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), RHS.getLValuePath(),
                 RHS.isLValueOnePastTheEnd(), RHS.getLValueCallIndex());
     else
       setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), NoLValuePath(),
                 RHS.getLValueCallIndex());
-  } else if (isArray()) {
+    break;
+  case Array:
+    MakeArray(RHS.getArrayInitializedElts(), RHS.getArraySize());
     for (unsigned I = 0, N = RHS.getArrayInitializedElts(); I != N; ++I)
       getArrayInitializedElt(I) = RHS.getArrayInitializedElt(I);
     if (RHS.hasArrayFiller())
       getArrayFiller() = RHS.getArrayFiller();
-  } else if (isStruct()) {
+    break;
+  case Struct:
+    MakeStruct(RHS.getStructNumBases(), RHS.getStructNumFields());
     for (unsigned I = 0, N = RHS.getStructNumBases(); I != N; ++I)
       getStructBase(I) = RHS.getStructBase(I);
     for (unsigned I = 0, N = RHS.getStructNumFields(); I != N; ++I)
       getStructField(I) = RHS.getStructField(I);
-  } else if (isUnion()) {
+    break;
+  case Union:
+    MakeUnion();
     setUnion(RHS.getUnionField(), RHS.getUnionValue());
-  } else if (isAddrLabelDiff()) {
+    break;
+  case MemberPointer:
+    MakeMemberPointer(RHS.getMemberPointerDecl(),
+                      RHS.isMemberPointerToDerivedMember(),
+                      RHS.getMemberPointerPath());
+    break;
+  case AddrLabelDiff:
+    MakeAddrLabelDiff();
     setAddrLabelDiff(RHS.getAddrLabelDiffLHS(), RHS.getAddrLabelDiffRHS());
+    break;
   }
-  return *this;
 }
 
 void APValue::DestroyDataAndMakeUninit() {
@@ -215,6 +212,14 @@
   Kind = Uninitialized;
 }
 
+void APValue::swap(APValue &RHS) {
+  std::swap(Kind, RHS.Kind);
+  char TmpData[MaxSize];
+  memcpy(TmpData, Data, MaxSize);
+  memcpy(Data, RHS.Data, MaxSize);
+  memcpy(RHS.Data, TmpData, MaxSize);
+}
+
 void APValue::dump() const {
   dump(llvm::errs());
   llvm::errs() << '\n';