#include "codegen.h"
//------------------------------------------------------------------------
+// genInitializeRegisterState: Initialize the register state contained in 'regSet'.
+//
+// Assumptions:
+// On exit the "rsModifiedRegsMask" (in "regSet") holds all the registers' masks hosting an argument on the function
+// and elements of "rsSpillDesc" (in "regSet") are setted to nullptr.
+//
+// Notes:
+// This method is intended to be called only from initializeStructuresBeforeBlockCodeGeneration.
+void CodeGen::genInitializeRegisterState()
+{
+ // Initialize the spill tracking logic
+
+ regSet.rsSpillBeg();
+
+ // If any arguments live in registers, mark those regs as such
+
+ unsigned varNum;
+ LclVarDsc* varDsc;
+
+ for (varNum = 0, varDsc = compiler->lvaTable; varNum < compiler->lvaCount; varNum++, varDsc++)
+ {
+ // Is this variable a parameter assigned to a register?
+ if (!varDsc->lvIsParam || !varDsc->lvRegister)
+ {
+ continue;
+ }
+
+ // Is the argument live on entry to the method?
+ if (!VarSetOps::IsMember(compiler, compiler->fgFirstBB->bbLiveIn, varDsc->lvVarIndex))
+ {
+ continue;
+ }
+
+ // Is this a floating-point argument?
+ if (varDsc->IsFloatRegType())
+ {
+ continue;
+ }
+
+ noway_assert(!varTypeIsFloating(varDsc->TypeGet()));
+
+ // Mark the register as holding the variable
+ assert(varDsc->lvRegNum != REG_STK);
+ if (!varDsc->lvAddrExposed)
+ {
+ regSet.verifyRegUsed(varDsc->lvRegNum);
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+// genInitialize: Initialize Scopes, registers, gcInfo and current liveness variables structures
+// used in the generation of blocks' code before.
+//
+// Assumptions:
+// -The pointer logic in "gcInfo" for pointers on registers and variable is cleaned.
+// -"compiler->compCurLife" becomes an empty set
+// -"compiler->compCurLife" are set to be a clean set
+// -If there is local var info siScopes scope logic in codegen is initialized in "siInit()"
+//
+// Notes:
+// This method is intended to be called when code generation for blocks happens, and before the list of blocks is
+// iterated.
+void CodeGen::genInitialize()
+{
+ // Initialize the line# tracking logic
+
+ if (compiler->opts.compScopeInfo)
+ {
+ siInit();
+ }
+
+ // The current implementation of switch tables requires the first block to have a label so it
+ // can generate offsets to the switch label targets.
+ // TODO-CQ: remove this when switches have been re-implemented to not use this.
+ if (compiler->fgHasSwitch)
+ {
+ compiler->fgFirstBB->bbFlags |= BBF_JMP_TARGET;
+ }
+
+ genPendingCallLabel = nullptr;
+
+ // Initialize the pointer tracking code
+
+ gcInfo.gcRegPtrSetInit();
+ gcInfo.gcVarPtrSetInit();
+
+ // Initialize the register set logic
+
+ genInitializeRegisterState();
+
+ // Make sure a set is allocated for compiler->compCurLife (in the long case), so we can set it to empty without
+ // allocation at the start of each basic block.
+ VarSetOps::AssignNoCopy(compiler, compiler->compCurLife, VarSetOps::MakeEmpty(compiler));
+}
+
+//------------------------------------------------------------------------
// genCodeForBBlist: Generate code for all the blocks in a method
//
// Arguments:
//
void CodeGen::genCodeForBBlist()
{
- unsigned varNum;
- LclVarDsc* varDsc;
-
unsigned savedStkLvl;
#ifdef DEBUG
assert(!compiler->fgFirstBBScratch ||
compiler->fgFirstBB == compiler->fgFirstBBScratch); // compiler->fgFirstBBScratch has to be first.
- /* Initialize the spill tracking logic */
-
- regSet.rsSpillBeg();
-
- /* Initialize the line# tracking logic */
-
- if (compiler->opts.compScopeInfo)
- {
- siInit();
- }
-
- // The current implementation of switch tables requires the first block to have a label so it
- // can generate offsets to the switch label targets.
- // TODO-CQ: remove this when switches have been re-implemented to not use this.
- if (compiler->fgHasSwitch)
- {
- compiler->fgFirstBB->bbFlags |= BBF_JMP_TARGET;
- }
-
- genPendingCallLabel = nullptr;
-
- /* Initialize the pointer tracking code */
-
- gcInfo.gcRegPtrSetInit();
- gcInfo.gcVarPtrSetInit();
-
- /* If any arguments live in registers, mark those regs as such */
-
- for (varNum = 0, varDsc = compiler->lvaTable; varNum < compiler->lvaCount; varNum++, varDsc++)
- {
- /* Is this variable a parameter assigned to a register? */
-
- if (!varDsc->lvIsParam || !varDsc->lvRegister)
- {
- continue;
- }
-
- /* Is the argument live on entry to the method? */
-
- if (!VarSetOps::IsMember(compiler, compiler->fgFirstBB->bbLiveIn, varDsc->lvVarIndex))
- {
- continue;
- }
-
- /* Is this a floating-point argument? */
-
- if (varDsc->IsFloatRegType())
- {
- continue;
- }
-
- noway_assert(!varTypeIsFloating(varDsc->TypeGet()));
-
- /* Mark the register as holding the variable */
-
- assert(varDsc->lvRegNum != REG_STK);
- if (!varDsc->lvAddrExposed)
- {
- regSet.verifyRegUsed(varDsc->lvRegNum);
- }
- }
-
- unsigned finallyNesting = 0;
-
- // Make sure a set is allocated for compiler->compCurLife (in the long case), so we can set it to empty without
- // allocation at the start of each basic block.
- VarSetOps::AssignNoCopy(compiler, compiler->compCurLife, VarSetOps::MakeEmpty(compiler));
+ /* Initialize structures used in the block list iteration */
+ genInitialize();
/*-------------------------------------------------------------------------
*