Add siVarLoc::Equals (dotnet/coreclr#23275)
authorBrian Bohe <brianbohe@gmail.com>
Sat, 16 Mar 2019 03:54:22 +0000 (20:54 -0700)
committerJan Kotas <jkotas@microsoft.com>
Sat, 16 Mar 2019 03:54:22 +0000 (20:54 -0700)
Commit migrated from https://github.com/dotnet/coreclr/commit/c247e12e00d2ee671f105819afebd65950134199

src/coreclr/src/jit/codegeninterface.h
src/coreclr/src/jit/scopeinfo.cpp

index 25027c1..01febd4 100644 (file)
@@ -518,6 +518,9 @@ public:
         siVarLoc(const LclVarDsc* varDsc, regNumber baseReg, int offset, bool isFramePointerUsed);
         siVarLoc(){};
 
+        // An overload for the equality comparator
+        static bool Equals(const siVarLoc* lhs, const siVarLoc* rhs);
+
     private:
         // Fill "siVarLoc" properties indicating the register position of the variable
         // using "LclVarDsc" and "baseReg"/"offset" if it has a part in the stack (x64 bit float or long).
index 19aa542..24c6701 100644 (file)
@@ -155,6 +155,79 @@ CodeGenInterface::siVarLoc::siVarLoc(const LclVarDsc* varDsc, regNumber baseReg,
 }
 
 //------------------------------------------------------------------------
+// Equals: Compares first reference and then values of the structures.
+//
+// Arguments:
+//    lhs   - a "siVarLoc *" to compare.
+//    rhs   - a "siVarLoc *" to compare.
+//
+// Notes:
+//    Return true if both are nullptr.
+//
+// static
+bool CodeGenInterface::siVarLoc::Equals(const siVarLoc* lhs, const siVarLoc* rhs)
+{
+    if (lhs == rhs)
+    {
+        // Are both nullptr or the same reference
+        return true;
+    }
+    if ((lhs == nullptr) || (rhs == nullptr))
+    {
+        // Just one of them is a nullptr
+        return false;
+    }
+    if (lhs->vlType != rhs->vlType)
+    {
+        return false;
+    }
+    assert(lhs->vlType == rhs->vlType);
+    // If neither is nullptr, and are not the same reference, compare values
+    switch (lhs->vlType)
+    {
+        case VLT_STK:
+        case VLT_STK_BYREF:
+            return (lhs->vlStk.vlsBaseReg == rhs->vlStk.vlsBaseReg) && (lhs->vlStk.vlsOffset == rhs->vlStk.vlsOffset);
+
+        case VLT_STK2:
+            return (lhs->vlStk2.vls2BaseReg == rhs->vlStk2.vls2BaseReg) &&
+                   (lhs->vlStk2.vls2Offset == rhs->vlStk2.vls2Offset);
+
+        case VLT_REG:
+        case VLT_REG_FP:
+        case VLT_REG_BYREF:
+            return (lhs->vlReg.vlrReg == rhs->vlReg.vlrReg);
+
+        case VLT_REG_REG:
+            return (lhs->vlRegReg.vlrrReg1 == rhs->vlRegReg.vlrrReg1) &&
+                   (lhs->vlRegReg.vlrrReg2 == rhs->vlRegReg.vlrrReg2);
+
+        case VLT_REG_STK:
+            return (lhs->vlRegStk.vlrsReg == rhs->vlRegStk.vlrsReg) &&
+                   (lhs->vlRegStk.vlrsStk.vlrssBaseReg == rhs->vlRegStk.vlrsStk.vlrssBaseReg) &&
+                   (lhs->vlRegStk.vlrsStk.vlrssOffset == rhs->vlRegStk.vlrsStk.vlrssOffset);
+
+        case VLT_STK_REG:
+            return (lhs->vlStkReg.vlsrReg == rhs->vlStkReg.vlsrReg) &&
+                   (lhs->vlStkReg.vlsrStk.vlsrsBaseReg == rhs->vlStkReg.vlsrStk.vlsrsBaseReg) &&
+                   (lhs->vlStkReg.vlsrStk.vlsrsOffset == rhs->vlStkReg.vlsrStk.vlsrsOffset);
+
+        case VLT_FPSTK:
+            return (lhs->vlFPstk.vlfReg == rhs->vlFPstk.vlfReg);
+
+        case VLT_FIXED_VA:
+            return (lhs->vlFixedVarArg.vlfvOffset == rhs->vlFixedVarArg.vlfvOffset);
+
+        case VLT_COUNT:
+        case VLT_INVALID:
+            return true;
+
+        default:
+            unreached();
+    }
+}
+
+//------------------------------------------------------------------------
 // getSiVarLoc: Creates a "CodegenInterface::siVarLoc" instance from using the properties
 // of the "psiScope" instance.
 //