1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 04:22:20 +02:00

Win32 lowering fixes

This commit is contained in:
Brian Fiete 2020-12-28 10:50:04 -08:00
parent a8d4d085c2
commit 91b046b6d7
4 changed files with 152 additions and 61 deletions

View file

@ -5660,8 +5660,13 @@ void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl<BfIRValue>& ir
{
disableLowering = true;
auto argTypeInstance = argVal.mType->ToTypeInstance();
if ((!disableSplat) && (int)irArgs.size() + argVal.mType->GetSplatCount() <= mModule->mCompiler->mOptions.mMaxSplatRegs)
if (!disableSplat)
{
if ((argTypeInstance != NULL) && (argTypeInstance->mIsCRepr))
wantSplat = true;
else if ((int)irArgs.size() + argVal.mType->GetSplatCount() <= mModule->mCompiler->mOptions.mMaxSplatRegs)
wantSplat = true;
}
}
if (wantSplat)

View file

@ -15539,9 +15539,14 @@ BfIRCallingConv BfModule::GetIRCallingConvention(BfMethodInstance* methodInstanc
return BfIRCallingConv_StdCall;
if (methodInstance->mCallingConvention == BfCallingConvention_Fastcall)
return BfIRCallingConv_FastCall;
if ((!methodDef->mIsStatic) && (!owner->IsValuelessType()) &&
if (!methodDef->mIsStatic)
{
if (owner->mIsCRepr)
return BfIRCallingConv_ThisCall;
if ((!owner->IsValuelessType()) &&
((!owner->IsSplattable()) || (methodDef->HasNoThisSplat())))
return BfIRCallingConv_ThisCall;
}
return BfIRCallingConv_CDecl;
//return GetIRCallingConvention(owner, methodInstance->mMethodDef);
@ -15629,10 +15634,16 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func
// crepr splat is always splattable
isSplattable = true;
}
else
{
auto resolvedTypeInst = resolvedTypeRef->ToTypeInstance();
if ((resolvedTypeInst != NULL) && (resolvedTypeInst->mIsCRepr))
isSplattable = true;
else if (resolvedTypeRef->GetSplatCount() + argIdx <= mCompiler->mOptions.mMaxSplatRegs)
isSplattable = true;
}
}
}
if (tryLowering)
{
@ -16880,6 +16891,11 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
else if ((!mIsConstModule) && (resolvedType->IsComposite()) && (resolvedType->IsSplattable()))
{
if (methodInstance->AllowsSplatting(paramIdx))
{
auto resolveTypeInst = resolvedType->ToTypeInstance();
if ((resolveTypeInst != NULL) && (resolveTypeInst->mIsCRepr))
paramVar->mIsSplat = true;
else
{
int splatCount = resolvedType->GetSplatCount();
if (argIdx + splatCount <= mCompiler->mOptions.mMaxSplatRegs)
@ -16887,6 +16903,7 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
}
}
}
}
else
{
paramVar->mIsSplat = true; // Treat skipped (valueless) as a splat
@ -21597,8 +21614,14 @@ genericParam->mExternType = GetPrimitiveType(BfTypeCode_Var);
PopulateType(checkType, BfPopulateType_Data);
if (checkType->IsSplattable())
{
bool isSplat = false;
auto checkTypeInstance = checkType->ToTypeInstance();
if ((checkTypeInstance != NULL) && (checkTypeInstance->mIsCRepr))
isSplat = true;
int splatCount = checkType->GetSplatCount();
if (checkArgIdx + splatCount <= mCompiler->mOptions.mMaxSplatRegs)
isSplat = true;
if (isSplat)
{
methodParam.mIsSplat = true;
argIdx += splatCount;

View file

@ -3701,6 +3701,11 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
if (isCRepr)
{
if ((mCompiler->mOptions.mMachineType == BfMachineType_x86) && (mCompiler->mOptions.mPlatformType == BfPlatformType_Windows))
{
typeInstance->mIsSplattable = (dataCount <= 4) && (!hadNonSplattable) && (dataPos > 4);
}
else
typeInstance->mIsSplattable = false;
}
else

View file

@ -754,6 +754,28 @@ bool BfMethodInstance::HasSelf()
bool BfMethodInstance::GetLoweredReturnType(BfTypeCode* loweredTypeCode, BfTypeCode* loweredTypeCode2)
{
// Win32 handler
if ((mMethodDef->mIsStatic) && (mReturnType->IsComposite()) &&
((mReturnType->mSize == 4) || (mReturnType->mSize == 8)))
{
auto returnTypeInst = mReturnType->ToTypeInstance();
if ((returnTypeInst != NULL) && (returnTypeInst->mIsCRepr))
{
auto module = GetOwner()->mModule;
auto compiler = module->mCompiler;
if ((compiler->mOptions.mMachineType == BfMachineType_x86) && (compiler->mOptions.mPlatformType == BfPlatformType_Windows))
{
if (loweredTypeCode != NULL)
{
*loweredTypeCode = BfTypeCode_Int32;
if (mReturnType->mSize == 8)
*loweredTypeCode = BfTypeCode_Int64;
}
return true;
}
}
}
return mReturnType->GetLoweredType(mMethodDef->mIsStatic ? BfTypeUsage_Return_Static : BfTypeUsage_Return_NonStatic, loweredTypeCode, loweredTypeCode2);
}
@ -1738,6 +1760,8 @@ bool BfTypeInstance::GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCo
if (mHasUnderlyingArray)
return false;
bool deepCheck = false;
if (mModule->mCompiler->mOptions.mPlatformType == BfPlatformType_Windows)
{
// Odd Windows rule: composite returns for non-static methods are always sret
@ -1746,9 +1770,23 @@ bool BfTypeInstance::GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCo
}
else
{
// Non-Windows systems allow lowered splitting of composites over two int params
// Non-Win64 systems allow lowered splitting of composites over multiple params
if (mModule->mSystem->mPtrSize == 8)
deepCheck = true;
else
{
// We know this is correct for Linux x86 and Android armv7
if (mModule->mCompiler->mOptions.mPlatformType == BfPlatformType_Linux)
{
if ((typeUsage == BfTypeUsage_Return_NonStatic) || (typeUsage == BfTypeUsage_Return_Static))
return false;
}
}
}
if (deepCheck)
{
if ((mInstSize >= 4) && (mInstSize <= 16))
{
BfTypeCode types[4] = { BfTypeCode_None };
@ -1788,6 +1826,35 @@ bool BfTypeInstance::GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCo
bool handled = false;
if (mModule->mCompiler->mOptions.mPlatformType == BfPlatformType_Windows)
{
bool hasFloat = false;
for (int type = 0; type < 4; type++)
{
if ((types[type] == BfTypeCode_Float) ||
(types[type] == BfTypeCode_Double))
hasFloat = false;
}
if (!hasFloat)
{
if (mInstSize == 4)
{
if (outTypeCode != NULL)
*outTypeCode = BfTypeCode_Int32;
return true;
}
if (mInstSize == 8)
{
if (outTypeCode != NULL)
*outTypeCode = BfTypeCode_Int64;
return true;
}
}
}
else
{
if (mInstSize >= 8)
{
if (outTypeCode != NULL)
@ -1861,15 +1928,6 @@ bool BfTypeInstance::GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCo
return true;
}
}
else
{
// We know this is correct for Linux x86 and Android armv7
if (mModule->mCompiler->mOptions.mPlatformType == BfPlatformType_Linux)
{
if ((typeUsage == BfTypeUsage_Return_NonStatic) || (typeUsage == BfTypeUsage_Return_Static))
return false;
}
}
}
BfTypeCode typeCode = BfTypeCode_None;