Move temp info from Compiler to RegSet
authorMike Danes <onemihaid@hotmail.com>
Sat, 16 Jun 2018 13:45:02 +0000 (16:45 +0300)
committerMike Danes <onemihaid@hotmail.com>
Sat, 30 Jun 2018 19:31:19 +0000 (22:31 +0300)
Temporaries are only used during register allocation and code generation. They waste space (136 bytes) in the compiler object during inlining.

Commit migrated from https://github.com/dotnet/coreclr/commit/9ca3690ab2f7828cc46c84a8a55de04d3d9667aa

15 files changed:
src/coreclr/src/jit/codegencommon.cpp
src/coreclr/src/jit/codegenlinear.cpp
src/coreclr/src/jit/codegenxarch.cpp
src/coreclr/src/jit/compiler.h
src/coreclr/src/jit/compiler.hpp
src/coreclr/src/jit/emitarm.cpp
src/coreclr/src/jit/emitarm64.cpp
src/coreclr/src/jit/emitxarch.cpp
src/coreclr/src/jit/gcencode.cpp
src/coreclr/src/jit/gcinfo.cpp
src/coreclr/src/jit/hwintrinsiccodegenxarch.cpp
src/coreclr/src/jit/lclvars.cpp
src/coreclr/src/jit/lsra.cpp
src/coreclr/src/jit/regset.cpp
src/coreclr/src/jit/regset.h

index 56cebe0..5ed6a63 100644 (file)
@@ -121,7 +121,7 @@ CodeGen::CodeGen(Compiler* theCompiler) : CodeGenInterface(theCompiler)
     setVerbose(compiler->verbose);
 #endif // DEBUG
 
-    compiler->tmpInit();
+    regSet.tmpInit();
 
     instInit();
 
@@ -2314,7 +2314,7 @@ void CodeGen::genGenerateCode(void** codePtr, ULONG* nativeSizeOfCode)
 
     genFinalizeFrame();
 
-    unsigned maxTmpSize = compiler->tmpSize; // This is precise after LSRA has pre-allocated the temps.
+    unsigned maxTmpSize = regSet.tmpGetTotalSize(); // This is precise after LSRA has pre-allocated the temps.
 
     getEmitter()->emitBegFN(isFramePointerUsed()
 #if defined(DEBUG)
@@ -2581,7 +2581,7 @@ void CodeGen::genGenerateCode(void** codePtr, ULONG* nativeSizeOfCode)
 
     /* Shut down the temp logic */
 
-    compiler->tmpDone();
+    regSet.tmpDone();
 
 #if DISPLAY_SIZES
 
@@ -4781,8 +4781,8 @@ void CodeGen::genCheckUseBlockInit()
 
     if (!TRACK_GC_TEMP_LIFETIMES)
     {
-        assert(compiler->tmpAllFree());
-        for (TempDsc* tempThis = compiler->tmpListBeg(); tempThis != nullptr; tempThis = compiler->tmpListNxt(tempThis))
+        assert(regSet.tmpAllFree());
+        for (TempDsc* tempThis = regSet.tmpListBeg(); tempThis != nullptr; tempThis = regSet.tmpListNxt(tempThis))
         {
             if (varTypeIsGC(tempThis->tdTempType()))
             {
@@ -6542,9 +6542,8 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg,
 
         if (!TRACK_GC_TEMP_LIFETIMES)
         {
-            assert(compiler->tmpAllFree());
-            for (TempDsc* tempThis = compiler->tmpListBeg(); tempThis != nullptr;
-                 tempThis          = compiler->tmpListNxt(tempThis))
+            assert(regSet.tmpAllFree());
+            for (TempDsc* tempThis = regSet.tmpListBeg(); tempThis != nullptr; tempThis = regSet.tmpListNxt(tempThis))
             {
                 if (!varTypeIsGC(tempThis->tdTempType()))
                 {
@@ -7695,7 +7694,7 @@ void CodeGen::genFinalizeFrame()
        here (where we have committed to the final numbers for the frame offsets)
        This will ensure that the prolog size is always correct
     */
-    getEmitter()->emitMaxTmpSize = compiler->tmpSize;
+    getEmitter()->emitMaxTmpSize = regSet.tmpGetTotalSize();
 
 #ifdef DEBUG
     if (compiler->opts.dspCode || compiler->opts.disAsm || compiler->opts.disAsm2 || verbose)
@@ -7970,8 +7969,8 @@ void CodeGen::genFnProlog()
 
     if (!TRACK_GC_TEMP_LIFETIMES)
     {
-        assert(compiler->tmpAllFree());
-        for (TempDsc* tempThis = compiler->tmpListBeg(); tempThis != nullptr; tempThis = compiler->tmpListNxt(tempThis))
+        assert(regSet.tmpAllFree());
+        for (TempDsc* tempThis = regSet.tmpListBeg(); tempThis != nullptr; tempThis = regSet.tmpListNxt(tempThis))
         {
             if (!varTypeIsGC(tempThis->tdTempType()))
             {
@@ -8552,7 +8551,7 @@ void CodeGen::genFnProlog()
     getEmitter()->emitEndProlog();
     compiler->unwindEndProlog();
 
-    noway_assert(getEmitter()->emitMaxTmpSize == compiler->tmpSize);
+    noway_assert(getEmitter()->emitMaxTmpSize == regSet.tmpGetTotalSize());
 }
 #ifdef _PREFAST_
 #pragma warning(pop)
index 36a6fc8..428b107 100644 (file)
@@ -676,7 +676,7 @@ void CodeGen::genCodeForBBlist()
 
     /* Finalize the temp   tracking logic */
 
-    compiler->tmpEnd();
+    regSet.tmpEnd();
 
 #ifdef DEBUG
     if (compiler->verbose)
@@ -991,7 +991,7 @@ void CodeGen::genUnspillRegIfNeeded(GenTree* tree)
                     TempDsc* t = regSet.rsUnspillInPlace(call, unspillTreeReg, i);
                     getEmitter()->emitIns_R_S(ins_Load(dstType), emitActualTypeSize(dstType), dstReg, t->tdTempNum(),
                                               0);
-                    compiler->tmpRlsTemp(t);
+                    regSet.tmpRlsTemp(t);
                     gcInfo.gcMarkRegPtrVal(dstReg, dstType);
                 }
             }
@@ -1019,7 +1019,7 @@ void CodeGen::genUnspillRegIfNeeded(GenTree* tree)
                     TempDsc* t = regSet.rsUnspillInPlace(splitArg, dstReg, i);
                     getEmitter()->emitIns_R_S(ins_Load(dstType), emitActualTypeSize(dstType), dstReg, t->tdTempNum(),
                                               0);
-                    compiler->tmpRlsTemp(t);
+                    regSet.tmpRlsTemp(t);
                     gcInfo.gcMarkRegPtrVal(dstReg, dstType);
                 }
             }
@@ -1046,7 +1046,7 @@ void CodeGen::genUnspillRegIfNeeded(GenTree* tree)
                     TempDsc* t = regSet.rsUnspillInPlace(multiReg, dstReg, i);
                     getEmitter()->emitIns_R_S(ins_Load(dstType), emitActualTypeSize(dstType), dstReg, t->tdTempNum(),
                                               0);
-                    compiler->tmpRlsTemp(t);
+                    regSet.tmpRlsTemp(t);
                     gcInfo.gcMarkRegPtrVal(dstReg, dstType);
                 }
             }
@@ -1060,7 +1060,7 @@ void CodeGen::genUnspillRegIfNeeded(GenTree* tree)
             TempDsc* t = regSet.rsUnspillInPlace(unspillTree, unspillTree->gtRegNum);
             getEmitter()->emitIns_R_S(ins_Load(unspillTree->gtType), emitActualTypeSize(unspillTree->TypeGet()), dstReg,
                                       t->tdTempNum(), 0);
-            compiler->tmpRlsTemp(t);
+            regSet.tmpRlsTemp(t);
 
             unspillTree->gtFlags &= ~GTF_SPILLED;
             gcInfo.gcMarkRegPtrVal(dstReg, unspillTree->TypeGet());
index e74abeb..1ceb928 100644 (file)
@@ -1294,7 +1294,7 @@ void CodeGen::genFloatReturn(GenTree* treeNode)
         TempDsc* t = regSet.rsUnspillInPlace(op1, op1->gtRegNum);
         inst_FS_ST(INS_fld, emitActualTypeSize(op1->gtType), t, 0);
         op1->gtFlags &= ~GTF_SPILLED;
-        compiler->tmpRlsTemp(t);
+        regSet.tmpRlsTemp(t);
     }
 }
 #endif // _TARGET_X86_
@@ -7277,7 +7277,7 @@ void CodeGen::genSSE41RoundOp(GenTreeOp* treeNode)
             varNum = tmpDsc->tdTempNum();
             offset = 0;
 
-            compiler->tmpRlsTemp(tmpDsc);
+            regSet.tmpRlsTemp(tmpDsc);
         }
         else if (srcNode->isIndir())
         {
@@ -7766,7 +7766,7 @@ void CodeGen::genPutArgStkFieldList(GenTreePutArgStk* putArgStk)
                     assert(fieldNode->IsRegOptional());
                     TempDsc* tmp = getSpillTempDsc(fieldNode);
                     getEmitter()->emitIns_S(INS_push, emitActualTypeSize(fieldNode->TypeGet()), tmp->tdTempNum(), 0);
-                    compiler->tmpRlsTemp(tmp);
+                    regSet.tmpRlsTemp(tmp);
                 }
                 else
                 {
index 9bd55a8..4636d9a 100644 (file)
@@ -128,17 +128,6 @@ unsigned ReinterpretHexAsDecimal(unsigned);
 
 /*****************************************************************************/
 
-#if defined(FEATURE_SIMD)
-#if defined(_TARGET_XARCH_)
-const unsigned TEMP_MAX_SIZE = YMM_REGSIZE_BYTES;
-#elif defined(_TARGET_ARM64_)
-const unsigned       TEMP_MAX_SIZE = FP_REGSIZE_BYTES;
-#endif // defined(_TARGET_XARCH_) || defined(_TARGET_ARM64_)
-#else  // !FEATURE_SIMD
-const unsigned TEMP_MAX_SIZE = sizeof(double);
-#endif // !FEATURE_SIMD
-const unsigned TEMP_SLOT_COUNT = (TEMP_MAX_SIZE / sizeof(int));
-
 const unsigned FLG_CCTOR = (CORINFO_FLG_CONSTRUCTOR | CORINFO_FLG_STATIC);
 
 #ifdef DEBUG
@@ -1331,7 +1320,7 @@ public:
 #ifdef _TARGET_ARM_
         unsigned int regSize = (hfaType == TYP_DOUBLE) ? 2 : 1;
 #else
-        unsigned int regSize       = 1;
+        unsigned int regSize = 1;
 #endif
         for (unsigned int regIndex = 1; regIndex < numRegs; regIndex++)
         {
@@ -6871,45 +6860,6 @@ public:
 
     /*****************************************************************************/
 
-public:
-    void tmpInit();
-
-    enum TEMP_USAGE_TYPE
-    {
-        TEMP_USAGE_FREE,
-        TEMP_USAGE_USED
-    };
-
-    static var_types tmpNormalizeType(var_types type);
-    TempDsc* tmpGetTemp(var_types type); // get temp for the given type
-    void tmpRlsTemp(TempDsc* temp);
-    TempDsc* tmpFindNum(int temp, TEMP_USAGE_TYPE usageType = TEMP_USAGE_FREE) const;
-
-    void     tmpEnd();
-    TempDsc* tmpListBeg(TEMP_USAGE_TYPE usageType = TEMP_USAGE_FREE) const;
-    TempDsc* tmpListNxt(TempDsc* curTemp, TEMP_USAGE_TYPE usageType = TEMP_USAGE_FREE) const;
-    void tmpDone();
-
-#ifdef DEBUG
-    bool tmpAllFree() const;
-#endif // DEBUG
-
-    void tmpPreAllocateTemps(var_types type, unsigned count);
-
-protected:
-    unsigned tmpCount; // Number of temps
-    unsigned tmpSize;  // Size of all the temps
-#ifdef DEBUG
-public:
-    // Used by RegSet::rsSpillChk()
-    unsigned tmpGetCount; // Temps which haven't been released yet
-#endif
-private:
-    static unsigned tmpSlot(unsigned size); // which slot in tmpFree[] or tmpUsed[] to use
-
-    TempDsc* tmpFree[TEMP_MAX_SIZE / sizeof(int)];
-    TempDsc* tmpUsed[TEMP_MAX_SIZE / sizeof(int)];
-
     /*
     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
index d873ead..7ae6460 100644 (file)
@@ -2354,11 +2354,11 @@ inline
         FPbased = isFramePointerUsed();
         if (lvaDoneFrameLayout == Compiler::FINAL_FRAME_LAYOUT)
         {
-            TempDsc* tmpDsc = tmpFindNum(varNum);
+            TempDsc* tmpDsc = codeGen->regSet.tmpFindNum(varNum);
             // The temp might be in use, since this might be during code generation.
             if (tmpDsc == nullptr)
             {
-                tmpDsc = tmpFindNum(varNum, Compiler::TEMP_USAGE_USED);
+                tmpDsc = codeGen->regSet.tmpFindNum(varNum, RegSet::TEMP_USAGE_USED);
             }
             assert(tmpDsc != nullptr);
             offset = tmpDsc->tdTempOffs();
@@ -3063,7 +3063,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 
 /*****************************************************************************/
 
-/* static */ inline unsigned Compiler::tmpSlot(unsigned size)
+/* static */ inline unsigned RegSet::tmpSlot(unsigned size)
 {
     noway_assert(size >= sizeof(int));
     noway_assert(size <= TEMP_MAX_SIZE);
@@ -3079,10 +3079,10 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  *  over a function body.
  */
 
-inline void Compiler::tmpEnd()
+inline void RegSet::tmpEnd()
 {
 #ifdef DEBUG
-    if (verbose && (tmpCount > 0))
+    if (m_rsCompiler->verbose && (tmpCount > 0))
     {
         printf("%d tmps used\n", tmpCount);
     }
@@ -3095,7 +3095,7 @@ inline void Compiler::tmpEnd()
  *  compiled.
  */
 
-inline void Compiler::tmpDone()
+inline void RegSet::tmpDone()
 {
 #ifdef DEBUG
     unsigned count;
index 0ed5bce..b425caa 100644 (file)
@@ -6351,7 +6351,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
             }
             else
             {
-                TempDsc* tmpDsc = emitComp->tmpFindNum(varNum);
+                TempDsc* tmpDsc = codeGen->regSet.tmpFindNum(varNum);
                 vt              = tmpDsc->tdTempType();
             }
             if (vt == TYP_REF || vt == TYP_BYREF)
index 992cffb..fed3b5d 100644 (file)
@@ -10164,7 +10164,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
             }
             else
             {
-                TempDsc* tmpDsc = emitComp->tmpFindNum(varNum);
+                TempDsc* tmpDsc = codeGen->regSet.tmpFindNum(varNum);
                 vt              = tmpDsc->tdTempType();
             }
             if (vt == TYP_REF || vt == TYP_BYREF)
@@ -10188,7 +10188,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
                 }
                 else
                 {
-                    TempDsc* tmpDsc = emitComp->tmpFindNum(varNum);
+                    TempDsc* tmpDsc = codeGen->regSet.tmpFindNum(varNum);
                     vt              = tmpDsc->tdTempType();
                 }
                 if (vt == TYP_REF || vt == TYP_BYREF)
index bbc086d..0be0dae 100644 (file)
@@ -1865,11 +1865,11 @@ inline UNATIVE_OFFSET emitter::emitInsSizeSV(code_t code, int var, int dsp)
         }
 
         // The offset is already assigned. Find the temp.
-        TempDsc* tmp = emitComp->tmpFindNum(var, Compiler::TEMP_USAGE_USED);
+        TempDsc* tmp = codeGen->regSet.tmpFindNum(var, RegSet::TEMP_USAGE_USED);
         if (tmp == nullptr)
         {
             // It might be in the free lists, if we're working on zero initializing the temps.
-            tmp = emitComp->tmpFindNum(var, Compiler::TEMP_USAGE_FREE);
+            tmp = codeGen->regSet.tmpFindNum(var, RegSet::TEMP_USAGE_FREE);
         }
         assert(tmp != nullptr);
         offs = tmp->tdTempOffs();
@@ -3131,7 +3131,7 @@ regNumber emitter::emitInsBinary(instruction ins, emitAttr attr, GenTree* dst, G
             varNum = tmpDsc->tdTempNum();
             offset = 0;
 
-            emitComp->tmpRlsTemp(tmpDsc);
+            codeGen->regSet.tmpRlsTemp(tmpDsc);
         }
         else if (memOp->isIndir())
         {
index 9cd478b..bc38f64 100644 (file)
@@ -2365,8 +2365,9 @@ size_t GCInfo::gcMakeRegPtrTable(BYTE* dest, int mask, const InfoHdr& header, un
 
         /* Count&Write spill temps that hold pointers */
 
-        assert(compiler->tmpAllFree());
-        for (TempDsc* tempItem = compiler->tmpListBeg(); tempItem != nullptr; tempItem = compiler->tmpListNxt(tempItem))
+        assert(compiler->codeGen->regSet.tmpAllFree());
+        for (TempDsc* tempItem = compiler->codeGen->regSet.tmpListBeg(); tempItem != nullptr;
+             tempItem          = compiler->codeGen->regSet.tmpListNxt(tempItem))
         {
             if (varTypeIsGC(tempItem->tdTempType()))
             {
@@ -4330,8 +4331,9 @@ void GCInfo::gcMakeRegPtrTable(
     {
         // Count&Write spill temps that hold pointers.
 
-        assert(compiler->tmpAllFree());
-        for (TempDsc* tempItem = compiler->tmpListBeg(); tempItem != nullptr; tempItem = compiler->tmpListNxt(tempItem))
+        assert(compiler->codeGen->regSet.tmpAllFree());
+        for (TempDsc* tempItem = compiler->codeGen->regSet.tmpListBeg(); tempItem != nullptr;
+             tempItem          = compiler->codeGen->regSet.tmpListNxt(tempItem))
         {
             if (varTypeIsGC(tempItem->tdTempType()))
             {
index 36c7de0..ee9f91d 100644 (file)
@@ -499,8 +499,8 @@ void GCInfo::gcCountForHeader(UNALIGNED unsigned int* untrackedCount, UNALIGNED
 
     /* Also count spill temps that hold pointers */
 
-    assert(compiler->tmpAllFree());
-    for (TempDsc* tempThis = compiler->tmpListBeg(); tempThis != nullptr; tempThis = compiler->tmpListNxt(tempThis))
+    assert(regSet->tmpAllFree());
+    for (TempDsc* tempThis = regSet->tmpListBeg(); tempThis != nullptr; tempThis = regSet->tmpListNxt(tempThis))
     {
         if (varTypeIsGC(tempThis->tdTempType()) == false)
         {
index 0107273..97becaa 100644 (file)
@@ -410,7 +410,7 @@ void CodeGen::genHWIntrinsic_R_RM(GenTreeHWIntrinsic* node, instruction ins, emi
             varNum = tmpDsc->tdTempNum();
             offset = 0;
 
-            compiler->tmpRlsTemp(tmpDsc);
+            regSet.tmpRlsTemp(tmpDsc);
         }
         else if (op1->OperIsHWIntrinsic())
         {
@@ -534,7 +534,7 @@ void CodeGen::genHWIntrinsic_R_RM_I(GenTreeHWIntrinsic* node, instruction ins, i
             varNum = tmpDsc->tdTempNum();
             offset = 0;
 
-            compiler->tmpRlsTemp(tmpDsc);
+            regSet.tmpRlsTemp(tmpDsc);
         }
         else if (op1->OperIsHWIntrinsic())
         {
@@ -658,7 +658,7 @@ void CodeGen::genHWIntrinsic_R_R_RM(GenTreeHWIntrinsic* node, instruction ins)
             varNum = tmpDsc->tdTempNum();
             offset = 0;
 
-            compiler->tmpRlsTemp(tmpDsc);
+            regSet.tmpRlsTemp(tmpDsc);
         }
         else if (op2->OperIsHWIntrinsic())
         {
@@ -814,7 +814,7 @@ void CodeGen::genHWIntrinsic_R_R_RM_I(GenTreeHWIntrinsic* node, instruction ins,
             varNum = tmpDsc->tdTempNum();
             offset = 0;
 
-            compiler->tmpRlsTemp(tmpDsc);
+            regSet.tmpRlsTemp(tmpDsc);
         }
         else if (op2->OperIsHWIntrinsic())
         {
@@ -970,7 +970,7 @@ void CodeGen::genHWIntrinsic_R_R_RM_R(GenTreeHWIntrinsic* node, instruction ins)
             varNum = tmpDsc->tdTempNum();
             offset = 0;
 
-            compiler->tmpRlsTemp(tmpDsc);
+            regSet.tmpRlsTemp(tmpDsc);
         }
         else if (op2->OperIsHWIntrinsic())
         {
@@ -1089,7 +1089,7 @@ void CodeGen::genHWIntrinsic_R_R_R_RM(
             varNum = tmpDsc->tdTempNum();
             offset = 0;
 
-            compiler->tmpRlsTemp(tmpDsc);
+            regSet.tmpRlsTemp(tmpDsc);
         }
         else if (op3->OperIsHWIntrinsic())
         {
index 430dd7d..313aa1f 100644 (file)
@@ -4233,7 +4233,7 @@ unsigned Compiler::lvaGetMaxSpillTempSize()
 
     if (lvaDoneFrameLayout >= REGALLOC_FRAME_LAYOUT)
     {
-        result = tmpSize;
+        result = codeGen->regSet.tmpGetTotalSize();
     }
     else
     {
@@ -4802,8 +4802,8 @@ void Compiler::lvaFixVirtualFrameOffsets()
         }
     }
 
-    assert(tmpAllFree());
-    for (TempDsc* temp = tmpListBeg(); temp != nullptr; temp = tmpListNxt(temp))
+    assert(codeGen->regSet.tmpAllFree());
+    for (TempDsc* temp = codeGen->regSet.tmpListBeg(); temp != nullptr; temp = codeGen->regSet.tmpListNxt(temp))
     {
         temp->tdAdjustTempOffs(delta);
     }
@@ -6518,11 +6518,11 @@ int Compiler::lvaAllocateTemps(int stkOffs, bool mustDoubleAlign)
             assignDone = true;
         }
 
-        assert(tmpAllFree());
+        assert(codeGen->regSet.tmpAllFree());
 
     AGAIN2:
 
-        for (TempDsc* temp = tmpListBeg(); temp != nullptr; temp = tmpListNxt(temp))
+        for (TempDsc* temp = codeGen->regSet.tmpListBeg(); temp != nullptr; temp = codeGen->regSet.tmpListNxt(temp))
         {
             var_types tempType = temp->tdTempType();
             unsigned  size;
@@ -7004,8 +7004,8 @@ void Compiler::lvaTableDump(FrameLayoutState curState)
     //-------------------------------------------------------------------------
     // Display the code-gen temps
 
-    assert(tmpAllFree());
-    for (TempDsc* temp = tmpListBeg(); temp != nullptr; temp = tmpListNxt(temp))
+    assert(codeGen->regSet.tmpAllFree());
+    for (TempDsc* temp = codeGen->regSet.tmpListBeg(); temp != nullptr; temp = codeGen->regSet.tmpListNxt(temp))
     {
         printf(";  TEMP_%02u %26s%*s%7s  -> ", -temp->tdTempNum(), " ", refCntWtdWidth, " ",
                varTypeName(temp->tdTempType()));
index 01192b2..a2dcddf 100644 (file)
@@ -6352,7 +6352,7 @@ void LinearScan::recordMaxSpill()
     // only a few types should actually be seen here.
     JITDUMP("Recording the maximum number of concurrent spills:\n");
 #ifdef _TARGET_X86_
-    var_types returnType = compiler->tmpNormalizeType(compiler->info.compRetType);
+    var_types returnType = RegSet::tmpNormalizeType(compiler->info.compRetType);
     if (needDoubleTmpForFPCall || (returnType == TYP_DOUBLE))
     {
         JITDUMP("Adding a spill temp for moving a double call/return value between xmm reg and x87 stack.\n");
@@ -6366,7 +6366,7 @@ void LinearScan::recordMaxSpill()
 #endif // _TARGET_X86_
     for (int i = 0; i < TYP_COUNT; i++)
     {
-        if (var_types(i) != compiler->tmpNormalizeType(var_types(i)))
+        if (var_types(i) != RegSet::tmpNormalizeType(var_types(i)))
         {
             // Only normalized types should have anything in the maxSpill array.
             // We assume here that if type 'i' does not normalize to itself, then
@@ -6376,7 +6376,7 @@ void LinearScan::recordMaxSpill()
         if (maxSpill[i] != 0)
         {
             JITDUMP("  %s: %d\n", varTypeName(var_types(i)), maxSpill[i]);
-            compiler->tmpPreAllocateTemps(var_types(i), maxSpill[i]);
+            compiler->codeGen->regSet.tmpPreAllocateTemps(var_types(i), maxSpill[i]);
         }
     }
     JITDUMP("\n");
@@ -6458,7 +6458,7 @@ void LinearScan::updateMaxSpill(RefPosition* refPosition)
                 {
                     typ = treeNode->TypeGet();
                 }
-                typ = compiler->tmpNormalizeType(typ);
+                typ = RegSet::tmpNormalizeType(typ);
             }
 
             if (refPosition->spillAfter && !refPosition->reload)
index 7896fa2..81887cc 100644 (file)
@@ -325,7 +325,7 @@ void RegSet::rsSpillTree(regNumber reg, GenTree* tree, unsigned regIdx /* =0 */)
         treeType = tree->TypeGet();
     }
 
-    var_types tempType = Compiler::tmpNormalizeType(treeType);
+    var_types tempType = RegSet::tmpNormalizeType(treeType);
     regMaskTP mask;
     bool      floatSpill = false;
 
@@ -390,7 +390,7 @@ void RegSet::rsSpillTree(regNumber reg, GenTree* tree, unsigned regIdx /* =0 */)
     SpillDsc* spill = SpillDsc::alloc(m_rsCompiler, this, tempType);
 
     // Grab a temp to store the spilled value
-    TempDsc* temp    = m_rsCompiler->tmpGetTemp(tempType);
+    TempDsc* temp    = tmpGetTemp(tempType);
     spill->spillTemp = temp;
     tempType         = temp->tdTempType();
 
@@ -464,7 +464,7 @@ void RegSet::rsSpillFPStack(GenTreeCall* call)
 
     /* Grab a temp to store the spilled value */
 
-    spill->spillTemp = temp = m_rsCompiler->tmpGetTemp(treeType);
+    spill->spillTemp = temp = tmpGetTemp(treeType);
 
     /* Remember what it is we have spilled */
 
@@ -602,7 +602,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 */
 
-void Compiler::tmpInit()
+void RegSet::tmpInit()
 {
     tmpCount = 0;
     tmpSize  = 0;
@@ -615,7 +615,7 @@ void Compiler::tmpInit()
 }
 
 /* static */
-var_types Compiler::tmpNormalizeType(var_types type)
+var_types RegSet::tmpNormalizeType(var_types type)
 {
     type = genActualType(type);
 
@@ -638,7 +638,7 @@ var_types Compiler::tmpNormalizeType(var_types type)
  *  the garbage collector).
  */
 
-TempDsc* Compiler::tmpGetTemp(var_types type)
+TempDsc* RegSet::tmpGetTemp(var_types type)
 {
     type          = tmpNormalizeType(type);
     unsigned size = genTypeSize(type);
@@ -676,7 +676,7 @@ TempDsc* Compiler::tmpGetTemp(var_types type)
     noway_assert(temp != nullptr);
 
 #ifdef DEBUG
-    if (verbose)
+    if (m_rsCompiler->verbose)
     {
         printf("%s temp #%u, slot %u, size = %u\n", isNewTemp ? "created" : "reused", -temp->tdTempNum(), slot,
                temp->tdTempSize());
@@ -700,7 +700,7 @@ TempDsc* Compiler::tmpGetTemp(var_types type)
  * has been preallocated, it is a fatal error.
  */
 
-void Compiler::tmpPreAllocateTemps(var_types type, unsigned count)
+void RegSet::tmpPreAllocateTemps(var_types type, unsigned count)
 {
     assert(type == tmpNormalizeType(type));
     unsigned size = genTypeSize(type);
@@ -728,10 +728,10 @@ void Compiler::tmpPreAllocateTemps(var_types type, unsigned count)
         }
 #endif // _TARGET_ARM_
 
-        TempDsc* temp = new (this, CMK_Unknown) TempDsc(-((int)tmpCount), size, type);
+        TempDsc* temp = new (m_rsCompiler, CMK_Unknown) TempDsc(-((int)tmpCount), size, type);
 
 #ifdef DEBUG
-        if (verbose)
+        if (m_rsCompiler->verbose)
         {
             printf("pre-allocated temp #%u, slot %u, size = %u\n", -temp->tdTempNum(), slot, temp->tdTempSize());
         }
@@ -748,7 +748,7 @@ void Compiler::tmpPreAllocateTemps(var_types type, unsigned count)
  *  Release the given temp.
  */
 
-void Compiler::tmpRlsTemp(TempDsc* temp)
+void RegSet::tmpRlsTemp(TempDsc* temp)
 {
     assert(temp != nullptr);
 
@@ -759,7 +759,7 @@ void Compiler::tmpRlsTemp(TempDsc* temp)
     slot = tmpSlot(temp->tdTempSize());
 
 #ifdef DEBUG
-    if (verbose)
+    if (m_rsCompiler->verbose)
     {
         printf("release temp #%u, slot %u, size = %u\n", -temp->tdTempNum(), slot, temp->tdTempSize());
     }
@@ -798,7 +798,7 @@ void Compiler::tmpRlsTemp(TempDsc* temp)
  *
  *  When looking for temps on the "used" list, this can be used any time.
  */
-TempDsc* Compiler::tmpFindNum(int tnum, TEMP_USAGE_TYPE usageType /* = TEMP_USAGE_FREE */) const
+TempDsc* RegSet::tmpFindNum(int tnum, TEMP_USAGE_TYPE usageType /* = TEMP_USAGE_FREE */) const
 {
     assert(tnum < 0); // temp numbers are negative
 
@@ -818,7 +818,7 @@ TempDsc* Compiler::tmpFindNum(int tnum, TEMP_USAGE_TYPE usageType /* = TEMP_USAG
  *  A helper function is used to iterate over all the temps.
  */
 
-TempDsc* Compiler::tmpListBeg(TEMP_USAGE_TYPE usageType /* = TEMP_USAGE_FREE */) const
+TempDsc* RegSet::tmpListBeg(TEMP_USAGE_TYPE usageType /* = TEMP_USAGE_FREE */) const
 {
     TempDsc* const* tmpLists;
     if (usageType == TEMP_USAGE_FREE)
@@ -845,7 +845,7 @@ TempDsc* Compiler::tmpListBeg(TEMP_USAGE_TYPE usageType /* = TEMP_USAGE_FREE */)
  * Used with tmpListBeg() to iterate over the list of temps.
  */
 
-TempDsc* Compiler::tmpListNxt(TempDsc* curTemp, TEMP_USAGE_TYPE usageType /* = TEMP_USAGE_FREE */) const
+TempDsc* RegSet::tmpListNxt(TempDsc* curTemp, TEMP_USAGE_TYPE usageType /* = TEMP_USAGE_FREE */) const
 {
     assert(curTemp != nullptr);
 
@@ -884,7 +884,7 @@ TempDsc* Compiler::tmpListNxt(TempDsc* curTemp, TEMP_USAGE_TYPE usageType /* = T
 /*****************************************************************************
  * Return 'true' if all allocated temps are free (not in use).
  */
-bool Compiler::tmpAllFree() const
+bool RegSet::tmpAllFree() const
 {
     // The 'tmpGetCount' should equal the number of things in the 'tmpUsed' lists. This is a convenient place
     // to assert that.
@@ -1093,7 +1093,7 @@ void RegSet::SpillDsc::freeDsc(RegSet* regSet, RegSet::SpillDsc* spillDsc)
 void RegSet::rsSpillChk()
 {
     // All grabbed temps should have been released
-    assert(m_rsCompiler->tmpGetCount == 0);
+    assert(tmpGetCount == 0);
 
     for (regNumber reg = REG_FIRST; reg < REG_COUNT; reg = REG_NEXT(reg))
     {
index 88889d9..469178d 100644 (file)
@@ -172,6 +172,62 @@ private:
     TempDsc* rsUnspillInPlace(GenTree* tree, regNumber oldReg, unsigned regIdx = 0);
 
     void rsMarkSpill(GenTree* tree, regNumber reg);
+
+public:
+    void tmpInit();
+
+    enum TEMP_USAGE_TYPE
+    {
+        TEMP_USAGE_FREE,
+        TEMP_USAGE_USED
+    };
+
+    static var_types tmpNormalizeType(var_types type);
+    TempDsc* tmpGetTemp(var_types type); // get temp for the given type
+    void tmpRlsTemp(TempDsc* temp);
+    TempDsc* tmpFindNum(int temp, TEMP_USAGE_TYPE usageType = TEMP_USAGE_FREE) const;
+
+    void     tmpEnd();
+    TempDsc* tmpListBeg(TEMP_USAGE_TYPE usageType = TEMP_USAGE_FREE) const;
+    TempDsc* tmpListNxt(TempDsc* curTemp, TEMP_USAGE_TYPE usageType = TEMP_USAGE_FREE) const;
+    void tmpDone();
+
+#ifdef DEBUG
+    bool tmpAllFree() const;
+#endif // DEBUG
+
+    void tmpPreAllocateTemps(var_types type, unsigned count);
+
+    unsigned tmpGetTotalSize()
+    {
+        return tmpSize;
+    }
+
+private:
+    unsigned tmpCount; // Number of temps
+    unsigned tmpSize;  // Size of all the temps
+#ifdef DEBUG
+    // Used by RegSet::rsSpillChk()
+    unsigned tmpGetCount; // Temps which haven't been released yet
+#endif
+    static unsigned tmpSlot(unsigned size); // which slot in tmpFree[] or tmpUsed[] to use
+
+    enum TEMP_CONSTANTS : unsigned
+    {
+#if defined(FEATURE_SIMD)
+#if defined(_TARGET_XARCH_)
+        TEMP_MAX_SIZE = YMM_REGSIZE_BYTES,
+#elif defined(_TARGET_ARM64_)
+        TEMP_MAX_SIZE = FP_REGSIZE_BYTES,
+#endif // defined(_TARGET_XARCH_) || defined(_TARGET_ARM64_)
+#else  // !FEATURE_SIMD
+        TEMP_MAX_SIZE = sizeof(double),
+#endif // !FEATURE_SIMD
+        TEMP_SLOT_COUNT = (TEMP_MAX_SIZE / sizeof(int))
+    };
+
+    TempDsc* tmpFree[TEMP_MAX_SIZE / sizeof(int)];
+    TempDsc* tmpUsed[TEMP_MAX_SIZE / sizeof(int)];
 };
 
 #endif // _REGSET_H