// - Setting the appropriate candidates for a store of a multi-reg call return value.
// - Handling of contained immediates.
//
-void Lowering::TreeNodeInfoInitStoreLoc(GenTreeLclVarCommon* storeLoc)
+void LinearScan::TreeNodeInfoInitStoreLoc(GenTreeLclVarCommon* storeLoc)
{
TreeNodeInfo* info = &(storeLoc->gtLsraInfo);
GenTree* op1 = storeLoc->gtGetOp1();
info->srcCount = retTypeDesc->GetReturnRegCount();
// Call node srcCandidates = Bitwise-OR(allregs(GetReturnRegType(i))) for all i=0..RetRegCount-1
- regMaskTP srcCandidates = m_lsra->allMultiRegCallNodeRegs(call);
- op1->gtLsraInfo.setSrcCandidates(m_lsra, srcCandidates);
+ regMaskTP srcCandidates = allMultiRegCallNodeRegs(call);
+ op1->gtLsraInfo.setSrcCandidates(this, srcCandidates);
}
else
{
// Return Value:
// None.
//
-void Lowering::TreeNodeInfoInitCmp(GenTreePtr tree)
+void LinearScan::TreeNodeInfoInitCmp(GenTreePtr tree)
{
TreeNodeInfo* info = &(tree->gtLsraInfo);
}
}
-void Lowering::TreeNodeInfoInitGCWriteBarrier(GenTree* tree)
+void LinearScan::TreeNodeInfoInitGCWriteBarrier(GenTree* tree)
{
GenTreePtr dst = tree;
GenTreePtr addr = tree->gtOp.gtOp1;
// the 'addr' goes into x14 (REG_WRITE_BARRIER_DST_BYREF)
// the 'src' goes into x15 (REG_WRITE_BARRIER)
//
- addr->gtLsraInfo.setSrcCandidates(m_lsra, RBM_WRITE_BARRIER_DST_BYREF);
- src->gtLsraInfo.setSrcCandidates(m_lsra, RBM_WRITE_BARRIER);
+ addr->gtLsraInfo.setSrcCandidates(this, RBM_WRITE_BARRIER_DST_BYREF);
+ src->gtLsraInfo.setSrcCandidates(this, RBM_WRITE_BARRIER);
#else
// For the standard JIT Helper calls
// op1 goes into REG_ARG_0 and
// op2 goes into REG_ARG_1
//
- addr->gtLsraInfo.setSrcCandidates(m_lsra, RBM_ARG_0);
- src->gtLsraInfo.setSrcCandidates(m_lsra, RBM_ARG_1);
+ addr->gtLsraInfo.setSrcCandidates(this, RBM_ARG_0);
+ src->gtLsraInfo.setSrcCandidates(this, RBM_ARG_1);
#endif // NOGC_WRITE_BARRIERS
// Both src and dst must reside in a register, which they should since we haven't set
// Arguments:
// indirTree - GT_IND, GT_STOREIND, block node or GT_NULLCHECK gentree node
//
-void Lowering::TreeNodeInfoInitIndir(GenTreeIndir* indirTree)
+void LinearScan::TreeNodeInfoInitIndir(GenTreeIndir* indirTree)
{
// If this is the rhs of a block copy (i.e. non-enregisterable struct),
// it has no register requirements.
// Return Value:
// None.
//
-void Lowering::TreeNodeInfoInitShiftRotate(GenTree* tree)
+void LinearScan::TreeNodeInfoInitShiftRotate(GenTree* tree)
{
TreeNodeInfo* info = &(tree->gtLsraInfo);
- LinearScan* l = m_lsra;
GenTreePtr shiftBy = tree->gtOp.gtOp2;
info->srcCount = shiftBy->isContained() ? 1 : 2;
// Return Value:
// None.
//
-void Lowering::TreeNodeInfoInitPutArgReg(GenTreeUnOp* node)
+void LinearScan::TreeNodeInfoInitPutArgReg(GenTreeUnOp* node)
{
assert(node != nullptr);
assert(node->OperIsPutArgReg());
argMask |= genRegMask(REG_NEXT(argReg));
}
#endif // ARM_SOFTFP
- node->gtLsraInfo.setDstCandidates(m_lsra, argMask);
- node->gtLsraInfo.setSrcCandidates(m_lsra, argMask);
+ node->gtLsraInfo.setDstCandidates(this, argMask);
+ node->gtLsraInfo.setSrcCandidates(this, argMask);
// To avoid redundant moves, have the argument operand computed in the
// register in which the argument is passed to the call.
- node->gtOp.gtOp1->gtLsraInfo.setSrcCandidates(m_lsra, m_lsra->getUseCandidates(node));
+ node->gtOp.gtOp1->gtLsraInfo.setSrcCandidates(this, getUseCandidates(node));
}
//------------------------------------------------------------------------
// Since the integer register is not associated with the arg node, we will reserve it as
// an internal register on the call so that it is not used during the evaluation of the call node
// (e.g. for the target).
-void Lowering::HandleFloatVarArgs(GenTreeCall* call, GenTree* argNode, bool* callHasFloatRegArgs)
+void LinearScan::HandleFloatVarArgs(GenTreeCall* call, GenTree* argNode, bool* callHasFloatRegArgs)
{
#if FEATURE_VARARG
if (call->IsVarargs() && varTypeIsFloating(argNode))
*callHasFloatRegArgs = true;
regNumber argReg = argNode->gtRegNum;
- regNumber targetReg = comp->getCallArgIntRegister(argReg);
+ regNumber targetReg = compiler->getCallArgIntRegister(argReg);
call->gtLsraInfo.setInternalIntCount(call->gtLsraInfo.internalIntCount + 1);
- call->gtLsraInfo.addInternalCandidates(m_lsra, genRegMask(targetReg));
+ call->gtLsraInfo.addInternalCandidates(this, genRegMask(targetReg));
}
#endif // FEATURE_VARARG
}
// Return Value:
// None.
//
-void Lowering::TreeNodeInfoInitCall(GenTreeCall* call)
+void LinearScan::TreeNodeInfoInitCall(GenTreeCall* call)
{
TreeNodeInfo* info = &(call->gtLsraInfo);
- LinearScan* l = m_lsra;
- Compiler* compiler = comp;
bool hasMultiRegRetVal = false;
ReturnTypeDesc* retTypeDesc = nullptr;
#ifdef _TARGET_ARM64_
// Fast tail call - make sure that call target is always computed in IP0
// so that epilog sequence can generate "br xip0" to achieve fast tail call.
- ctrlExpr->gtLsraInfo.setSrcCandidates(l, genRegMask(REG_IP0));
+ ctrlExpr->gtLsraInfo.setSrcCandidates(this, genRegMask(REG_IP0));
#endif // _TARGET_ARM64_
}
}
{
// The ARM CORINFO_HELP_INIT_PINVOKE_FRAME helper uses a custom calling convention that returns with
// TCB in REG_PINVOKE_TCB. fgMorphCall() sets the correct argument registers.
- info->setDstCandidates(l, RBM_PINVOKE_TCB);
+ info->setDstCandidates(this, RBM_PINVOKE_TCB);
}
else
#endif // _TARGET_ARM_
if (hasMultiRegRetVal)
{
assert(retTypeDesc != nullptr);
- info->setDstCandidates(l, retTypeDesc->GetABIReturnRegs());
+ info->setDstCandidates(this, retTypeDesc->GetABIReturnRegs());
}
else if (varTypeIsFloating(registerType))
{
- info->setDstCandidates(l, RBM_FLOATRET);
+ info->setDstCandidates(this, RBM_FLOATRET);
}
else if (registerType == TYP_LONG)
{
- info->setDstCandidates(l, RBM_LNGRET);
+ info->setDstCandidates(this, RBM_LNGRET);
}
else
{
- info->setDstCandidates(l, RBM_INTRET);
+ info->setDstCandidates(this, RBM_INTRET);
}
// First, count reg args
// Don't assign the call target to any of the argument registers because
// we will use them to also pass floating point arguments as required
// by Arm64 ABI.
- ctrlExpr->gtLsraInfo.setSrcCandidates(l, l->allRegs(TYP_INT) & ~(RBM_ARG_REGS));
+ ctrlExpr->gtLsraInfo.setSrcCandidates(this, allRegs(TYP_INT) & ~(RBM_ARG_REGS));
}
#ifdef _TARGET_ARM_
// Notes:
// Set the child node(s) to be contained when we have a multireg arg
//
-void Lowering::TreeNodeInfoInitPutArgStk(GenTreePutArgStk* argNode)
+void LinearScan::TreeNodeInfoInitPutArgStk(GenTreePutArgStk* argNode)
{
assert(argNode->gtOper == GT_PUTARG_STK);
// Notes:
// Set the child node(s) to be contained
//
-void Lowering::TreeNodeInfoInitPutArgSplit(GenTreePutArgSplit* argNode)
+void LinearScan::TreeNodeInfoInitPutArgSplit(GenTreePutArgSplit* argNode)
{
assert(argNode->gtOper == GT_PUTARG_SPLIT);
{
argMask |= genRegMask((regNumber)((unsigned)argReg + i));
}
- argNode->gtLsraInfo.setDstCandidates(m_lsra, argMask);
- argNode->gtLsraInfo.setSrcCandidates(m_lsra, argMask);
+ argNode->gtLsraInfo.setDstCandidates(this, argMask);
+ argNode->gtLsraInfo.setSrcCandidates(this, argMask);
if (putArgChild->OperGet() == GT_FIELD_LIST)
{
if (idx < argNode->gtNumRegs)
{
GenTreePtr node = fieldListPtr->gtGetOp1();
- node->gtLsraInfo.setSrcCandidates(m_lsra, genRegMask((regNumber)((unsigned)argReg + idx)));
+ node->gtLsraInfo.setSrcCandidates(this, genRegMask((regNumber)((unsigned)argReg + idx)));
}
else
{
// We can use a ldr/str sequence so we need an internal register
argNode->gtLsraInfo.internalIntCount = 1;
regMaskTP internalMask = RBM_ALLINT & ~argMask;
- argNode->gtLsraInfo.setInternalCandidates(m_lsra, internalMask);
+ argNode->gtLsraInfo.setInternalCandidates(this, internalMask);
GenTreePtr objChild = putArgChild->gtOp.gtOp1;
if (objChild->OperGet() == GT_LCL_VAR_ADDR)
// Return Value:
// None.
//
-void Lowering::TreeNodeInfoInitBlockStore(GenTreeBlk* blkNode)
+void LinearScan::TreeNodeInfoInitBlockStore(GenTreeBlk* blkNode)
{
- GenTree* dstAddr = blkNode->Addr();
- unsigned size = blkNode->gtBlkSize;
- GenTree* source = blkNode->Data();
- LinearScan* l = m_lsra;
- Compiler* compiler = comp;
+ GenTree* dstAddr = blkNode->Addr();
+ unsigned size = blkNode->gtBlkSize;
+ GenTree* source = blkNode->Data();
// Sources are dest address and initVal or source.
// We may require an additional source or temp register for the size.
{
assert(blkNode->gtBlkOpKind == GenTreeBlk::BlkOpKindHelper);
// The helper follows the regular ABI.
- dstAddr->gtLsraInfo.setSrcCandidates(l, RBM_ARG_0);
+ dstAddr->gtLsraInfo.setSrcCandidates(this, RBM_ARG_0);
assert(!initVal->isContained());
blkNode->gtLsraInfo.srcCount++;
- initVal->gtLsraInfo.setSrcCandidates(l, RBM_ARG_1);
+ initVal->gtLsraInfo.setSrcCandidates(this, RBM_ARG_1);
if (size != 0)
{
// Reserve a temp register for the block size argument.
- blkNode->gtLsraInfo.setInternalCandidates(l, RBM_ARG_2);
+ blkNode->gtLsraInfo.setInternalCandidates(this, RBM_ARG_2);
blkNode->gtLsraInfo.internalIntCount = 1;
}
else
noway_assert(blkNode->gtOper == GT_STORE_DYN_BLK);
blkNode->gtLsraInfo.setSrcCount(3);
GenTree* sizeNode = blkNode->AsDynBlk()->gtDynamicSize;
- sizeNode->gtLsraInfo.setSrcCandidates(l, RBM_ARG_2);
+ sizeNode->gtLsraInfo.setSrcCandidates(this, RBM_ARG_2);
}
}
}
// We can't use the special Write Barrier registers, so exclude them from the mask
regMaskTP internalIntCandidates = RBM_ALLINT & ~(RBM_WRITE_BARRIER_DST_BYREF | RBM_WRITE_BARRIER_SRC_BYREF);
- blkNode->gtLsraInfo.setInternalCandidates(l, internalIntCandidates);
+ blkNode->gtLsraInfo.setInternalCandidates(this, internalIntCandidates);
// If we have a dest address we want it in RBM_WRITE_BARRIER_DST_BYREF.
- dstAddr->gtLsraInfo.setSrcCandidates(l, RBM_WRITE_BARRIER_DST_BYREF);
+ dstAddr->gtLsraInfo.setSrcCandidates(this, RBM_WRITE_BARRIER_DST_BYREF);
// If we have a source address we want it in REG_WRITE_BARRIER_SRC_BYREF.
// Otherwise, if it is a local, codegen will put its address in REG_WRITE_BARRIER_SRC_BYREF,
// which is killed by a StoreObj (and thus needn't be reserved).
if (srcAddrOrFill != nullptr)
{
- srcAddrOrFill->gtLsraInfo.setSrcCandidates(l, RBM_WRITE_BARRIER_SRC_BYREF);
+ srcAddrOrFill->gtLsraInfo.setSrcCandidates(this, RBM_WRITE_BARRIER_SRC_BYREF);
}
}
else
else
{
assert(blkNode->gtBlkOpKind == GenTreeBlk::BlkOpKindHelper);
- dstAddr->gtLsraInfo.setSrcCandidates(l, RBM_ARG_0);
+ dstAddr->gtLsraInfo.setSrcCandidates(this, RBM_ARG_0);
// The srcAddr goes in arg1.
if (srcAddrOrFill != nullptr)
{
- srcAddrOrFill->gtLsraInfo.setSrcCandidates(l, RBM_ARG_1);
+ srcAddrOrFill->gtLsraInfo.setSrcCandidates(this, RBM_ARG_1);
}
if (size != 0)
{
assert(blkNode->gtOper == GT_STORE_DYN_BLK);
blkNode->gtLsraInfo.srcCount++;
GenTree* blockSize = blkNode->AsDynBlk()->gtDynamicSize;
- blockSize->gtLsraInfo.setSrcCandidates(l, RBM_ARG_2);
+ blockSize->gtLsraInfo.setSrcCandidates(this, RBM_ARG_2);
}
}
if (internalIntCount != 0)
{
blkNode->gtLsraInfo.internalIntCount = internalIntCount;
- blkNode->gtLsraInfo.setInternalCandidates(l, internalIntCandidates);
+ blkNode->gtLsraInfo.setInternalCandidates(this, internalIntCandidates);
}
}
blkNode->gtLsraInfo.srcCount += GetOperandSourceCount(source);
// Return Value:
// The number of source registers used by the *parent* of this node.
//
-int Lowering::GetOperandSourceCount(GenTree* node)
+int LinearScan::GetOperandSourceCount(GenTree* node)
{
if (!node->isContained())
{