Skip to content

Commit efa0292

Browse files
committed
fix all platforms
1 parent 7f24e1b commit efa0292

File tree

5 files changed

+100
-61
lines changed

5 files changed

+100
-61
lines changed

src/coreclr/jit/lower.cpp

Lines changed: 81 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -8212,89 +8212,109 @@ void Lowering::ContainCheckBitCast(GenTree* node)
82128212
}
82138213
}
82148214

8215+
//------------------------------------------------------------------------
8216+
// TryLowerBlockStoreAsGcBulkCopyCall: Lower a block store node as a CORINFO_HELP_ASSIGN_STRUCT call
8217+
//
8218+
// Arguments:
8219+
// blkNode - The block store node to lower
8220+
//
82158221
bool Lowering::TryLowerBlockStoreAsGcBulkCopyCall(GenTreeBlk* blk)
82168222
{
8217-
if (comp->opts.OptimizationDisabled() || !ISMETHOD("Test"))
8223+
if (comp->opts.OptimizationDisabled())
82188224
{
82198225
return false;
82208226
}
82218227

82228228
// Replace STORE_BLK (struct copy) with CORINFO_HELP_ASSIGN_STRUCT which performs
82238229
// bulk copy for byrefs.
82248230
const unsigned bulkCopyThreshold = 4;
8225-
if (blk->OperIs(GT_STORE_BLK) && !blk->OperIsInitBlkOp() &&
8226-
(blk->GetLayout()->GetGCPtrCount() >= bulkCopyThreshold))
8231+
if (!blk->OperIs(GT_STORE_BLK) || blk->OperIsInitBlkOp() || (blk->GetLayout()->GetGCPtrCount() < bulkCopyThreshold))
82278232
{
8228-
GenTree* addr = blk->Addr();
8229-
GenTree* data = blk->Data();
8233+
return false;
8234+
}
82308235

8231-
const unsigned gcPtrs = blk->GetLayout()->GetGCPtrCount();
8232-
if (!CheckedOps::MulOverflows((int)gcPtrs, TARGET_POINTER_SIZE, true))
8233-
{
8234-
if (data->OperIs(GT_IND))
8235-
{
8236-
// Drop GT_IND nodes
8237-
BlockRange().Remove(data);
8238-
data = data->AsIndir()->Addr();
8239-
}
8240-
else
8241-
{
8242-
assert(data->OperIs(GT_LCL_VAR, GT_LCL_FLD));
8243-
8244-
// Convert local to LCL_ADDR
8245-
unsigned lclOffset = data->AsLclVarCommon()->GetLclOffs();
8246-
data->ChangeOper(GT_LCL_ADDR);
8247-
data->ChangeType(TYP_I_IMPL);
8248-
data->AsLclFld()->SetLclOffs(lclOffset);
8249-
data->ClearContained();
8250-
}
8236+
GenTree* dest = blk->Addr();
8237+
GenTree* data = blk->Data();
8238+
8239+
if (data->OperIs(GT_IND))
8240+
{
8241+
// Drop GT_IND nodes
8242+
BlockRange().Remove(data);
8243+
data = data->AsIndir()->Addr();
8244+
}
8245+
else
8246+
{
8247+
assert(data->OperIs(GT_LCL_VAR, GT_LCL_FLD));
8248+
8249+
// Convert local to LCL_ADDR
8250+
unsigned lclOffset = data->AsLclVarCommon()->GetLclOffs();
8251+
data->ChangeOper(GT_LCL_ADDR);
8252+
data->ChangeType(TYP_I_IMPL);
8253+
data->AsLclFld()->SetLclOffs(lclOffset);
8254+
data->ClearContained();
8255+
}
82518256

8252-
// Size is a constant
8253-
GenTreeIntCon* size = comp->gtNewIconNode((ssize_t)gcPtrs * TARGET_POINTER_SIZE, TYP_I_IMPL);
8254-
BlockRange().InsertBefore(data, size);
8257+
// Size is a constant
8258+
GenTreeIntCon* size = comp->gtNewIconNode((ssize_t)blk->GetLayout()->GetSize(), TYP_I_IMPL);
8259+
BlockRange().InsertBefore(data, size);
8260+
8261+
// A hacky way to safely call fgMorphTree in Lower
8262+
GenTree* destPlaceholder = comp->gtNewZeroConNode(dest->TypeGet());
8263+
GenTree* dataPlaceholder = comp->gtNewZeroConNode(genActualType(data));
8264+
GenTree* sizePlaceholder = comp->gtNewZeroConNode(genActualType(size));
82558265

8256-
// A hacky way to safely call fgMorphTree in Lower
8257-
GenTree* destPlaceholder = comp->gtNewZeroConNode(addr->TypeGet());
8258-
GenTree* dataPlaceholder = comp->gtNewZeroConNode(genActualType(data));
8259-
GenTree* sizePlaceholder = comp->gtNewZeroConNode(genActualType(size));
8266+
GenTreeCall* call = comp->gtNewHelperCallNode(CORINFO_HELP_ASSIGN_STRUCT, TYP_VOID, destPlaceholder,
8267+
dataPlaceholder, sizePlaceholder);
8268+
comp->fgMorphArgs(call);
82608269

8261-
GenTreeCall* call = comp->gtNewHelperCallNode(CORINFO_HELP_ASSIGN_STRUCT, TYP_VOID, destPlaceholder, dataPlaceholder, sizePlaceholder);
8262-
comp->fgMorphArgs(call);
8270+
LIR::Range range = LIR::SeqTree(comp, call);
8271+
GenTree* rangeStart = range.FirstNode();
8272+
GenTree* rangeEnd = range.LastNode();
82638273

8264-
LIR::Range range = LIR::SeqTree(comp, call);
8265-
GenTree* rangeStart = range.FirstNode();
8266-
GenTree* rangeEnd = range.LastNode();
8274+
BlockRange().InsertBefore(blk, std::move(range));
8275+
blk->gtBashToNOP();
82678276

8268-
BlockRange().InsertBefore(blk, std::move(range));
8269-
blk->gtBashToNOP();
8277+
LIR::Use destUse;
8278+
LIR::Use sizeUse;
8279+
BlockRange().TryGetUse(destPlaceholder, &destUse);
8280+
BlockRange().TryGetUse(sizePlaceholder, &sizeUse);
8281+
destUse.ReplaceWith(dest);
8282+
sizeUse.ReplaceWith(size);
8283+
destPlaceholder->SetUnusedValue();
8284+
sizePlaceholder->SetUnusedValue();
82708285

8271-
LIR::Use destUse;
8272-
LIR::Use sizeUse;
8273-
BlockRange().TryGetUse(destPlaceholder, &destUse);
8274-
BlockRange().TryGetUse(sizePlaceholder, &sizeUse);
8275-
destUse.ReplaceWith(addr);
8276-
sizeUse.ReplaceWith(size);
8277-
destPlaceholder->SetUnusedValue();
8278-
sizePlaceholder->SetUnusedValue();
8286+
LIR::Use dataUse;
8287+
BlockRange().TryGetUse(dataPlaceholder, &dataUse);
8288+
dataUse.ReplaceWith(data);
8289+
dataPlaceholder->SetUnusedValue();
82798290

8280-
LIR::Use dataUse;
8281-
BlockRange().TryGetUse(dataPlaceholder, &dataUse);
8282-
dataUse.ReplaceWith(data);
8283-
dataPlaceholder->SetUnusedValue();
8291+
LowerRange(rangeStart, rangeEnd);
82848292

8285-
LowerRange(rangeStart, rangeEnd);
8293+
// Finally move all GT_PUTARG_* nodes
8294+
// Re-use the existing logic for CFG call args here
8295+
MoveCFGCallArgs(call);
82868296

8287-
// Finally move all GT_PUTARG_* nodes
8288-
// Re-use the existing logic for CFG call args here
8289-
MoveCFGCallArgs(call);
8297+
BlockRange().Remove(destPlaceholder);
8298+
BlockRange().Remove(sizePlaceholder);
8299+
BlockRange().Remove(dataPlaceholder);
82908300

8291-
BlockRange().Remove(destPlaceholder);
8292-
BlockRange().Remove(sizePlaceholder);
8293-
BlockRange().Remove(dataPlaceholder);
8294-
return true;
8301+
// Add implicit nullchecks for dest and data if needed:
8302+
//
8303+
auto wrapWithNullcheck = [&](GenTree* node) {
8304+
if (comp->fgAddrCouldBeNull(node))
8305+
{
8306+
LIR::Use nodeUse;
8307+
BlockRange().TryGetUse(node, &nodeUse);
8308+
GenTree* nodeClone = comp->gtNewLclvNode(nodeUse.ReplaceWithLclVar(comp), genActualType(node));
8309+
GenTree* nullcheck = comp->gtNewNullCheck(nodeClone, comp->compCurBB);
8310+
BlockRange().InsertAfter(nodeUse.Def(), nodeClone, nullcheck);
8311+
LowerNode(nullcheck);
82958312
}
8296-
}
8297-
return false;
8313+
};
8314+
wrapWithNullcheck(dest);
8315+
wrapWithNullcheck(data);
8316+
8317+
return true;
82988318
}
82998319

83008320
//------------------------------------------------------------------------

src/coreclr/jit/lowerarmarch.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,12 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode)
737737

738738
if (doCpObj)
739739
{
740+
// Try to use bulk copy helper
741+
if (TryLowerBlockStoreAsGcBulkCopyCall(blkNode))
742+
{
743+
return;
744+
}
745+
740746
assert((dstAddr->TypeGet() == TYP_BYREF) || (dstAddr->TypeGet() == TYP_I_IMPL));
741747
blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindCpObjUnroll;
742748
}

src/coreclr/jit/lowerloongarch64.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,12 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode)
370370
// CopyObj or CopyBlk
371371
if (doCpObj)
372372
{
373+
// Try to use bulk copy helper
374+
if (TryLowerBlockStoreAsGcBulkCopyCall(blkNode))
375+
{
376+
return;
377+
}
378+
373379
assert((dstAddr->TypeGet() == TYP_BYREF) || (dstAddr->TypeGet() == TYP_I_IMPL));
374380
blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindCpObjUnroll;
375381
}

src/coreclr/jit/lowerriscv64.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,12 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode)
319319
// CopyObj or CopyBlk
320320
if (doCpObj)
321321
{
322+
// Try to use bulk copy helper
323+
if (TryLowerBlockStoreAsGcBulkCopyCall(blkNode))
324+
{
325+
return;
326+
}
327+
322328
assert((dstAddr->TypeGet() == TYP_BYREF) || (dstAddr->TypeGet() == TYP_I_IMPL));
323329
blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindCpObjUnroll;
324330
}

src/coreclr/jit/lowerxarch.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,7 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode)
457457

458458
if (doCpObj)
459459
{
460+
// Try to use bulk copy helper
460461
if (TryLowerBlockStoreAsGcBulkCopyCall(blkNode))
461462
{
462463
return;

0 commit comments

Comments
 (0)