mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 04:22:20 +02:00
Fixed some lowering of Win32 structs by value
This commit is contained in:
parent
611ab328d2
commit
686050a68b
4 changed files with 81 additions and 10 deletions
|
@ -4564,10 +4564,19 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
|
||||||
//byval
|
//byval
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_NoCapture);
|
|
||||||
mModule->PopulateType(paramType, BfPopulateType_Data);
|
mModule->PopulateType(paramType, BfPopulateType_Data);
|
||||||
addDeref = paramType->mSize;
|
|
||||||
|
auto typeInst = paramType->ToTypeInstance();
|
||||||
|
if ((typeInst != NULL) && (typeInst->mIsCRepr) && (typeInst->IsSplattable()))
|
||||||
|
{
|
||||||
|
// We're splatting
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_NoCapture);
|
||||||
|
addDeref = paramType->mSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (paramType->IsPrimitiveType())
|
else if (paramType->IsPrimitiveType())
|
||||||
|
@ -4822,9 +4831,15 @@ void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl<BfIRValue>& ir
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool wantSplat = false;
|
bool wantSplat = false;
|
||||||
if ((argVal.mType->IsSplattable()) && (!disableSplat))
|
if (argVal.mType->IsSplattable())
|
||||||
{
|
{
|
||||||
if ((int)irArgs.size() + argVal.mType->GetSplatCount() <= mModule->mCompiler->mOptions.mMaxSplatRegs)
|
auto argTypeInstance = argVal.mType->ToTypeInstance();
|
||||||
|
if ((argTypeInstance != NULL) && (argTypeInstance->mIsCRepr))
|
||||||
|
{
|
||||||
|
// Always splat for crepr splattables
|
||||||
|
wantSplat = true;
|
||||||
|
}
|
||||||
|
else if ((!disableSplat) && (int)irArgs.size() + argVal.mType->GetSplatCount() <= mModule->mCompiler->mOptions.mMaxSplatRegs)
|
||||||
wantSplat = true;
|
wantSplat = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5495,7 +5495,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
BfIRType fieldDataPtrType = mBfIRBuilder->GetPointerTo(reflectFieldDataIRType);
|
BfIRType fieldDataPtrType = mBfIRBuilder->GetPointerTo(reflectFieldDataIRType);
|
||||||
if (fieldTypes.size() == 0)
|
if (fieldTypes.size() == 0)
|
||||||
{
|
{
|
||||||
if ((type->IsSplattable()) && (type->IsStruct()) && (!type->IsValuelessType()))
|
if ((type->IsSplattable()) && (type->IsStruct()) && (!type->IsValuelessType()) && (!typeInstance->mIsCRepr))
|
||||||
{
|
{
|
||||||
BfTypeInstance* reflectFieldSplatDataType = ResolveTypeDef(mCompiler->mReflectFieldSplatDataDef)->ToTypeInstance();
|
BfTypeInstance* reflectFieldSplatDataType = ResolveTypeDef(mCompiler->mReflectFieldSplatDataDef)->ToTypeInstance();
|
||||||
|
|
||||||
|
@ -14067,7 +14067,13 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func
|
||||||
isSplattable = true;
|
isSplattable = true;
|
||||||
else if (resolvedTypeRef->IsSplattable())
|
else if (resolvedTypeRef->IsSplattable())
|
||||||
{
|
{
|
||||||
if (resolvedTypeRef->GetSplatCount() + argIdx <= mCompiler->mOptions.mMaxSplatRegs)
|
auto resolvedTypeInst = resolvedTypeRef->ToTypeInstance();
|
||||||
|
if ((resolvedTypeInst != NULL) && (resolvedTypeInst->mIsCRepr))
|
||||||
|
{
|
||||||
|
// crepr splat is always splattable
|
||||||
|
isSplattable = true;
|
||||||
|
}
|
||||||
|
else if (resolvedTypeRef->GetSplatCount() + argIdx <= mCompiler->mOptions.mMaxSplatRegs)
|
||||||
isSplattable = true;
|
isSplattable = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15148,9 +15154,18 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
|
||||||
}
|
}
|
||||||
else if (resolvedType->IsComposite() && resolvedType->IsSplattable())
|
else if (resolvedType->IsComposite() && resolvedType->IsSplattable())
|
||||||
{
|
{
|
||||||
int splatCount = resolvedType->GetSplatCount();
|
auto resolvedTypeInst = resolvedType->ToTypeInstance();
|
||||||
if (argIdx + splatCount <= mCompiler->mOptions.mMaxSplatRegs)
|
if ((resolvedTypeInst != NULL) && (resolvedTypeInst->mIsCRepr))
|
||||||
|
{
|
||||||
|
// crepr splat is always splat
|
||||||
paramVar->mIsSplat = true;
|
paramVar->mIsSplat = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int splatCount = resolvedType->GetSplatCount();
|
||||||
|
if (argIdx + splatCount <= mCompiler->mOptions.mMaxSplatRegs)
|
||||||
|
paramVar->mIsSplat = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -2980,7 +2980,40 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
splatIterate(typeInstance);
|
splatIterate(typeInstance);
|
||||||
|
|
||||||
if (isCRepr)
|
if (isCRepr)
|
||||||
|
{
|
||||||
typeInstance->mIsSplattable = false;
|
typeInstance->mIsSplattable = false;
|
||||||
|
|
||||||
|
if ((mCompiler->mOptions.mPlatformType == BfPlatformType_Windows) && (mCompiler->mSystem->mPtrSize == 4))
|
||||||
|
{
|
||||||
|
// Win32 splat rules
|
||||||
|
if ((typeInstance->mBaseType->mInstSize == 0) && (typeInstance->mInstSize <= 16))
|
||||||
|
{
|
||||||
|
typeInstance->mIsSplattable = true;
|
||||||
|
|
||||||
|
for (int fieldIdx = 0; fieldIdx < (int)typeInstance->mFieldInstances.size(); fieldIdx++)
|
||||||
|
{
|
||||||
|
auto fieldInstance = (BfFieldInstance*)&typeInstance->mFieldInstances[fieldIdx];
|
||||||
|
if (fieldInstance->mDataIdx >= 0)
|
||||||
|
{
|
||||||
|
if (!fieldInstance->mResolvedType->IsPrimitiveType())
|
||||||
|
typeInstance->mIsSplattable = false;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto primType = (BfPrimitiveType*)fieldInstance->mResolvedType;
|
||||||
|
if ((primType->mTypeDef->mTypeCode != BfTypeCode_Int32) &&
|
||||||
|
(primType->mTypeDef->mTypeCode != BfTypeCode_UInt32) &&
|
||||||
|
(primType->mTypeDef->mTypeCode != BfTypeCode_IntPtr) &&
|
||||||
|
(primType->mTypeDef->mTypeCode != BfTypeCode_UIntPtr) &&
|
||||||
|
(primType->mTypeDef->mTypeCode != BfTypeCode_Pointer) &&
|
||||||
|
(primType->mTypeDef->mTypeCode != BfTypeCode_Single) &&
|
||||||
|
(primType->mTypeDef->mTypeCode != BfTypeCode_Double))
|
||||||
|
typeInstance->mIsSplattable = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
typeInstance->mIsSplattable = (dataCount <= 3) && (!hadNonSplattable);
|
typeInstance->mIsSplattable = (dataCount <= 3) && (!hadNonSplattable);
|
||||||
}
|
}
|
||||||
|
|
|
@ -949,7 +949,15 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
|
||||||
int splatCount = checkType->GetSplatCount();
|
int splatCount = checkType->GetSplatCount();
|
||||||
doSplat = ((checkType->IsSplattable()) && ((paramIdx != -1) || (!mMethodDef->mIsMutating)));
|
doSplat = ((checkType->IsSplattable()) && ((paramIdx != -1) || (!mMethodDef->mIsMutating)));
|
||||||
if ((int)paramTypes.size() + splatCount > module->mCompiler->mOptions.mMaxSplatRegs)
|
if ((int)paramTypes.size() + splatCount > module->mCompiler->mOptions.mMaxSplatRegs)
|
||||||
doSplat = false;
|
{
|
||||||
|
auto checkTypeInst = checkType->ToTypeInstance();
|
||||||
|
if ((checkTypeInst != NULL) && (checkTypeInst->mIsCRepr))
|
||||||
|
{
|
||||||
|
// CRepr splat means always splat
|
||||||
|
}
|
||||||
|
else
|
||||||
|
doSplat = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto _AddType = [&](BfType* type)
|
auto _AddType = [&](BfType* type)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue