1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-07-04 23:36:00 +02:00

Interop fixes and tests, fixing xplat struct passing issues

This commit is contained in:
Brian Fiete 2020-06-10 07:12:07 -07:00
parent 4cf6af53bd
commit 5da74382d4
31 changed files with 1569 additions and 239 deletions

View file

@ -3470,6 +3470,8 @@ void BfCompiler::VisitSourceExteriorNodes()
if (parser->mAwaitingDelete)
return;
if (parser->mParserData == NULL)
return;
if (parser->mParserData->mExteriorNodesCheckIdx == mSystem->mTypeMapVersion)
return;

View file

@ -2496,6 +2496,8 @@ void MsDemangleScanner::Process(const StringImpl& mangledName)
String BfDemangler::Demangle(const StringImpl& mangledName, DbgLanguage language, Flags flags)
{
if (mangledName.IsEmpty())
return "";
if (mangledName[0] == '?')
{
MsDemangler demangler;

View file

@ -4484,7 +4484,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
}
else
{
auto val = mModule->GetDefaultTypedValue(returnType, true, methodInstance->HasStructRet() ? BfDefaultValueKind_Addr : BfDefaultValueKind_Value);
auto val = mModule->GetDefaultTypedValue(returnType, true, (methodInstance->GetStructRetIdx() != -1) ? BfDefaultValueKind_Addr : BfDefaultValueKind_Value);
if (val.mKind == BfTypedValueKind_Addr)
val.mKind = BfTypedValueKind_TempAddr;
return val;
@ -4492,7 +4492,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
};
mModule->PopulateType(origReturnType, BfPopulateType_Data);
if (methodInstance->HasStructRet())
if (methodInstance->GetStructRetIdx() != -1)
{
// We need to ensure that mReceivingValue has the correct type, otherwise it's possible that a conversion operator needs to be applied
// This happens for returning Result<T>'s with a 'T' value
@ -4756,13 +4756,23 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
mModule->mBfIRBuilder->PopulateType(returnType);
BfIRValue callInst;
int callIRArgCount = (int)irArgs.size();
if (sret != NULL)
{
SizedArray<BfIRValue, 8> sretIRArgs;
sretIRArgs.push_back(sret->mValue);
if (!irArgs.IsEmpty())
sretIRArgs.Insert(sretIRArgs.size(), &irArgs[0], irArgs.size());
int sretIdx = methodInstance->GetStructRetIdx();
int inIdx = 0;
for (int outIdx = 0; outIdx < irArgs.size() + 1; outIdx++)
{
if (outIdx == sretIdx)
{
sretIRArgs.Add(sret->mValue);
continue;
}
sretIRArgs.Add(irArgs[inIdx++]);
}
callInst = mModule->mBfIRBuilder->CreateCall(funcCallInst, sretIRArgs);
callIRArgCount++;
}
else
{
@ -4780,18 +4790,23 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
int paramIdx = 0;
bool doingThis = !methodDef->mIsStatic;
int argIdx = 0;
if (sret != NULL)
if (methodInstance->mIdHash == 1140)
{
mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_StructRet);
argIdx++;
NOP;
}
int paramCount = methodInstance->GetParamCount();
for ( ; argIdx < (int)irArgs.size(); /*argIdx++*/)
for ( ; argIdx < callIRArgCount ; )
{
if (argIdx >= paramCount)
break;
if (argIdx == methodInstance->GetStructRetIdx())
{
mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_StructRet);
argIdx++;
continue;
}
auto _HandleParamType = [&] (BfType* paramType)
{
@ -4799,10 +4814,13 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
{
if ((!doingThis) || (!methodDef->mIsMutating && methodInstance->AllowsSplatting()))
{
auto loweredTypeCode = paramType->GetLoweredType();
if (loweredTypeCode != BfTypeCode_None)
BfTypeCode loweredTypeCode = BfTypeCode_None;
BfTypeCode loweredTypeCode2 = BfTypeCode_None;
if (paramType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2))
{
argIdx++;
if (loweredTypeCode2 != BfTypeCode_None)
argIdx++;
return; // Lowering never requires attributes
}
}
@ -4818,8 +4836,9 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
if ((addDeref <= 0) && (!elementType->IsValuelessType()))
mModule->AssertErrorState();
}
if ((paramType->IsComposite()) && (!paramType->IsTypedPrimitive()))
{
{
if (mModule->mCompiler->mOptions.mAllowStructByVal)
{
//byval
@ -4835,8 +4854,15 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
}
else
{
mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_NoCapture);
addDeref = paramType->mSize;
if (doingThis)
{
mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_NoCapture);
addDeref = paramType->mSize;
}
else
{
mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_ByVal, mModule->mSystem->mPtrSize);
}
}
}
}
@ -4876,13 +4902,28 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
}
else
{
if (paramIdx >= methodInstance->GetParamCount())
break;
paramType = methodInstance->GetParamType(paramIdx);
BfTypeCode loweredTypeCode = BfTypeCode_None;
BfTypeCode loweredTypeCode2 = BfTypeCode_None;
if (paramType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2))
{
argIdx++;
paramIdx++;
if (loweredTypeCode2 != BfTypeCode_None)
argIdx++;
continue;
}
if ((paramType->IsValuelessType()) && (!paramType->IsMethodRef()))
{
paramIdx++;
continue;
}
//if (resolvedTypeRef->IsSplattable())
if (methodInstance->GetParamIsSplat(paramIdx))
{
BfTypeUtils::SplatIterate(_HandleParamType, paramType);
@ -4893,8 +4934,6 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
_HandleParamType(methodInstance->GetParamType(paramIdx));
}
if (doingThis)
doingThis = false;
else
@ -4936,13 +4975,14 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
result = *sret;
else if (hasResult)
{
if (methodInstance->mReturnType->GetLoweredType() != BfTypeCode_None)
BfTypeCode loweredRetType = BfTypeCode_None;
BfTypeCode loweredRetType2 = BfTypeCode_None;
if (methodInstance->GetLoweredReturnType(&loweredRetType, &loweredRetType2))
{
auto loweredType = mModule->GetPrimitiveType(methodInstance->mReturnType->GetLoweredType());
auto loweredPtrType = mModule->CreatePointerType(loweredType);
auto retVal = mModule->CreateAlloca(methodInstance->mReturnType);
auto castedRetVal = mModule->mBfIRBuilder->CreateBitCast(retVal, mModule->mBfIRBuilder->MapType(loweredPtrType));
BfIRType loweredIRType = mModule->GetIRLoweredType(loweredRetType, loweredRetType2);
loweredIRType = mModule->mBfIRBuilder->GetPointerTo(loweredIRType);
auto castedRetVal = mModule->mBfIRBuilder->CreateBitCast(retVal, loweredIRType);
mModule->mBfIRBuilder->CreateStore(callInst, castedRetVal);
result = BfTypedValue(retVal, methodInstance->mReturnType, BfTypedValueKind_TempAddr);
}
@ -5116,14 +5156,40 @@ void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl<BfIRValue>& ir
if (!disableLowering)
{
auto loweredTypeCode = argVal.mType->GetLoweredType();
if (loweredTypeCode != BfTypeCode_None)
BfTypeCode loweredTypeCode = BfTypeCode_None;
BfTypeCode loweredTypeCode2 = BfTypeCode_None;
if (argVal.mType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2))
{
auto primType = mModule->GetPrimitiveType(loweredTypeCode);
auto ptrType = mModule->CreatePointerType(primType);
BfIRValue primPtrVal = mModule->mBfIRBuilder->CreateBitCast(argVal.mValue, mModule->mBfIRBuilder->MapType(ptrType));
// auto primType = mModule->GetPrimitiveType(loweredTypeCode);
// auto ptrType = mModule->CreatePointerType(primType);
// BfIRValue primPtrVal = mModule->mBfIRBuilder->CreateBitCast(argVal.mValue, mModule->mBfIRBuilder->MapType(ptrType));
// auto primVal = mModule->mBfIRBuilder->CreateLoad(primPtrVal);
// irArgs.push_back(primVal);
//
// if (loweredTypeCode2 != BfTypeCode_None)
// {
// auto primType2 = mModule->GetPrimitiveType(loweredTypeCode2);
// auto ptrType2 = mModule->CreatePointerType(primType2);
// BfIRValue primPtrVal2 = mModule->mBfIRBuilder->CreateBitCast(mModule->mBfIRBuilder->CreateInBoundsGEP(primPtrVal, 1), mModule->mBfIRBuilder->MapType(ptrType2));
// auto primVal2 = mModule->mBfIRBuilder->CreateLoad(primPtrVal2);
// irArgs.push_back(primVal2);
// }
auto primType = mModule->mBfIRBuilder->GetPrimitiveType(loweredTypeCode);
auto ptrType = mModule->mBfIRBuilder->GetPointerTo(primType);
BfIRValue primPtrVal = mModule->mBfIRBuilder->CreateBitCast(argVal.mValue, ptrType);
auto primVal = mModule->mBfIRBuilder->CreateLoad(primPtrVal);
irArgs.push_back(primVal);
if (loweredTypeCode2 != BfTypeCode_None)
{
auto primType2 = mModule->mBfIRBuilder->GetPrimitiveType(loweredTypeCode2);
auto ptrType2 = mModule->mBfIRBuilder->GetPointerTo(primType2);
BfIRValue primPtrVal2 = mModule->mBfIRBuilder->CreateBitCast(mModule->mBfIRBuilder->CreateInBoundsGEP(primPtrVal, 1), ptrType2);
auto primVal2 = mModule->mBfIRBuilder->CreateLoad(primPtrVal2);
irArgs.push_back(primVal2);
}
return;
}
}
@ -5244,7 +5310,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
if (!mModule->mCompiler->mIsResolveOnly)
sCallIdx++;
int callIdx = sCallIdx;
if (callIdx == 4348)
if (callIdx == 1177)
{
NOP;
}
@ -5436,9 +5502,10 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
}
else
{
wantsSplat = methodInstance->GetParamIsSplat(paramIdx);
wantsSplat = methodInstance->GetParamIsSplat(paramIdx);
if (methodInstance->IsImplicitCapture(paramIdx))
{
auto paramType = methodInstance->GetParamType(paramIdx);
if (mModule->mCurMethodInstance->IsMixin())
{
// Don't bother, also- can fail on captures
@ -5461,10 +5528,12 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
{
SplatArgs(lookupVal, irArgs);
}
else
else if (paramType->IsRef())
{
irArgs.push_back(lookupVal.mValue);
}
else
PushArg(lookupVal, irArgs, true);
}
}
paramIdx++;
@ -5549,7 +5618,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
bool hadMissingArg = false;
int argExprIdx = argIdx;
if ((methodDef->mMethodType == BfMethodType_Extension))
if (methodDef->mMethodType == BfMethodType_Extension)
{
argExprIdx--;
if (argExprIdx == -1)
@ -5718,12 +5787,8 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
{
if (methodRefType->WantsDataPassedAsSplat(dataIdx))
SplatArgs(lookupVal, irArgs);
else if (lookupVal.mType->IsComposite())
{
irArgs.push_back(lookupVal.mValue);
}
else
irArgs.push_back(lookupVal.mValue);
irArgs.push_back(lookupVal.mValue);
}
}
@ -6814,11 +6879,6 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
methodMatcher.CheckType(lookupTypeInst, target, true);
}
if ((methodMatcher.mBestMethodDef != NULL) && (methodMatcher.mBestMethodDef->mName == "Zorf"))
{
NOP;
}
BfTypedValue staticResult;
methodMatcher.TryDevirtualizeCall(target, &origTarget, &staticResult);
if (staticResult)
@ -9909,8 +9969,10 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
if (hasCaptures)
{
hasThis = true;
methodInstance->GetIRFunctionInfo(mModule, irReturnType, irParamTypes);
int thisIdx = methodInstance->HasStructRet() ? 1 : 0;
methodInstance->GetIRFunctionInfo(mModule, irReturnType, irParamTypes);
int thisIdx = 0;
if (methodInstance->GetStructRetIdx() == 0)
thisIdx = 1;
irParamTypes[thisIdx] = mModule->mBfIRBuilder->MapType(useTypeInstance);
}
else
@ -9927,10 +9989,10 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
auto funcType = mModule->mBfIRBuilder->CreateFunctionType(irReturnType, irParamTypes);
funcValue = mModule->mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_External, methodName);
if (methodInstance->HasStructRet())
{
mModule->mBfIRBuilder->Func_AddAttribute(funcValue, 1, BfIRAttribute_NoAlias);
mModule->mBfIRBuilder->Func_AddAttribute(funcValue, 1, BfIRAttribute_StructRet);
if (methodInstance->GetStructRetIdx() != -1)
{
mModule->mBfIRBuilder->Func_AddAttribute(funcValue, methodInstance->GetStructRetIdx() + 1, BfIRAttribute_NoAlias);
mModule->mBfIRBuilder->Func_AddAttribute(funcValue, methodInstance->GetStructRetIdx() + 1, BfIRAttribute_StructRet);
}
auto srcCallingConv = mModule->GetIRCallingConvention(methodInstance);
@ -9947,10 +10009,18 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
fieldIdx = 0;
SizedArray<BfIRValue, 8> irArgs;
int argIdx = 0;
if (methodInstance->HasStructRet())
irArgs.push_back(mModule->mBfIRBuilder->GetArgument(argIdx++));
if (methodInstance->mIdHash == 775)
{
NOP;
}
int argIdx = 0;
if (bindMethodInstance->GetStructRetIdx() == 0)
{
irArgs.push_back(mModule->mBfIRBuilder->GetArgument(methodInstance->GetStructRetIdx()));
argIdx++;
}
for (int implicitParamIdx = bindMethodInstance->HasThis() ? -1 : 0; implicitParamIdx < implicitParamCount; implicitParamIdx++)
{
auto fieldInst = &useTypeInstance->mFieldInstances[fieldIdx];
@ -9965,7 +10035,10 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
disableSplat = true;
}
}
int thisIdx = methodInstance->HasStructRet() ? 1 : 0;
int thisIdx = 0;
if (methodInstance->GetStructRetIdx() == 0)
thisIdx = 1;
auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mModule->mBfIRBuilder->GetArgument(thisIdx), 0, gepIdx);
BfTypedValue typedVal(fieldPtr, fieldType, true);
PushArg(typedVal, irArgs, disableSplat);
@ -9974,6 +10047,12 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
if (hasThis)
argIdx++;
if (bindMethodInstance->GetStructRetIdx() == 1)
{
irArgs.push_back(mModule->mBfIRBuilder->GetArgument(methodInstance->GetStructRetIdx()));
argIdx++;
}
for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++)
{
@ -9992,12 +10071,12 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
if (mModule->mCompiler->mOptions.mAllowHotSwapping)
bindFuncVal = mModule->mBfIRBuilder->RemapBindFunction(bindFuncVal);
auto callInst = mModule->mBfIRBuilder->CreateCall(bindFuncVal, irArgs);
if (methodInstance->HasStructRet())
mModule->mBfIRBuilder->Call_AddAttribute(callInst, 1, BfIRAttribute_StructRet);
if (bindMethodInstance->GetStructRetIdx() != -1)
mModule->mBfIRBuilder->Call_AddAttribute(callInst, bindMethodInstance->GetStructRetIdx() + 1, BfIRAttribute_StructRet);
auto destCallingConv = mModule->GetIRCallingConvention(bindMethodInstance);
if (destCallingConv != BfIRCallingConv_CDecl)
mModule->mBfIRBuilder->SetCallCallingConv(callInst, destCallingConv);
if ((methodInstance->mReturnType->IsValuelessType()) || (methodInstance->HasStructRet()))
if ((methodInstance->mReturnType->IsValuelessType()) || (methodInstance->GetStructRetIdx() != -1))
{
mModule->mBfIRBuilder->CreateRetVoid();
}
@ -10783,14 +10862,17 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam
origReturnType = mModule->mBfIRBuilder->MapType(mModule->GetPrimitiveType(BfTypeCode_None));
}
SizedArray<BfIRType, 3> newTypes;
if ((invokeMethodInstance != NULL) && (invokeMethodInstance->HasStructRet()))
SizedArray<BfIRType, 3> newTypes;
if ((invokeMethodInstance != NULL) && (invokeMethodInstance->GetStructRetIdx() == 0))
newTypes.push_back(origParamTypes[0]);
if (!methodDef->mIsStatic)
newTypes.push_back(mModule->mBfIRBuilder->MapType(useTypeInstance));
if ((invokeMethodInstance != NULL) && (invokeMethodInstance->GetStructRetIdx() == 1))
newTypes.push_back(origParamTypes[1]);
int paramStartIdx = 0;
if ((invokeMethodInstance != NULL) && (invokeMethodInstance->HasStructRet()))
if ((invokeMethodInstance != NULL) && (invokeMethodInstance->GetStructRetIdx() != -1))
paramStartIdx++;
if (!methodDef->mIsStatic)
paramStartIdx++;
@ -14585,6 +14667,11 @@ BfTypedValue BfExprEvaluator::GetResult(bool clearResult, bool resolveGenericTyp
return mResult;
}
if (matchedMethod->mName == "get__CultureName")
{
NOP;
}
auto methodInstance = GetPropertyMethodInstance(matchedMethod);
if (methodInstance.mMethodInstance == NULL)
return mResult;
@ -14662,7 +14749,7 @@ BfTypedValue BfExprEvaluator::GetResult(bool clearResult, bool resolveGenericTyp
}
else
{
auto val = mModule->GetDefaultTypedValue(returnType, true, methodInstance.mMethodInstance->HasStructRet() ? BfDefaultValueKind_Addr : BfDefaultValueKind_Value);
auto val = mModule->GetDefaultTypedValue(returnType, true, (methodInstance.mMethodInstance->GetStructRetIdx() != -1) ? BfDefaultValueKind_Addr : BfDefaultValueKind_Value);
if (val.mKind == BfTypedValueKind_Addr)
val.mKind = BfTypedValueKind_TempAddr;
return val;

View file

@ -3305,6 +3305,13 @@ BfIRType BfIRBuilder::CreateStructType(const StringImpl& name)
return retType;
}
BfIRType BfIRBuilder::CreateStructType(const BfSizedArray<BfIRType>& memberTypes)
{
BfIRType retType = WriteCmd(BfIRCmd_CreateAnonymousStruct, memberTypes);
NEW_CMD_INSERTED_IRTYPE;
return retType;
}
void BfIRBuilder::StructSetBody(BfIRType type, const BfSizedArray<BfIRType>& memberTypes, bool isPacked)
{
WriteCmd(BfIRCmd_StructSetBody, type, memberTypes, isPacked);
@ -4421,6 +4428,11 @@ BfIRFunction BfIRBuilder::CreateFunction(BfIRFunctionType funcType, BfIRLinkageT
NEW_CMD_INSERTED_IRVALUE;
mFunctionMap[name] = retVal;
if (name == "?TestStructRetCapture$Rt@Lambdas@Tests@bf@@QEAA?AUStructA@123@XZ")
{
NOP;
}
//BfLogSys(mModule->mSystem, "BfIRBuilder::CreateFunction: %d %s Module:%p\n", retVal.mId, name.c_str(), mModule);
return retVal;

View file

@ -94,10 +94,20 @@ enum BfTypeCode : uint8
BfTypeCode_UInt8,
BfTypeCode_Int16,
BfTypeCode_UInt16,
BfTypeCode_Int24,
BfTypeCode_UInt24,
BfTypeCode_Int32,
BfTypeCode_UInt32,
BfTypeCode_Int40,
BfTypeCode_UInt40,
BfTypeCode_Int48,
BfTypeCode_UInt48,
BfTypeCode_Int56,
BfTypeCode_UInt56,
BfTypeCode_Int64,
BfTypeCode_UInt64,
BfTypeCode_UInt64,
BfTypeCode_Int128,
BfTypeCode_UInt128,
BfTypeCode_IntPtr,
BfTypeCode_UIntPtr,
BfTypeCode_IntUnknown,
@ -152,6 +162,7 @@ enum BfIRCmd : uint8
BfIRCmd_SetType,
BfIRCmd_SetInstType,
BfIRCmd_PrimitiveType,
BfIRCmd_CreateAnonymousStruct,
BfIRCmd_CreateStruct,
BfIRCmd_StructSetBody,
BfIRCmd_Type,
@ -1050,6 +1061,7 @@ public:
BfIRType GetPrimitiveType(BfTypeCode typeCode);
BfIRType CreateStructType(const StringImpl& name);
BfIRType CreateStructType(const BfSizedArray<BfIRType>& memberTypes);
void StructSetBody(BfIRType type, const BfSizedArray<BfIRType>& memberTypes, bool isPacked);
BfIRType MapType(BfType* type, BfIRPopulateType populateType = BfIRPopulateType_Declaration);
BfIRType MapTypeInst(BfTypeInstance* typeInst, BfIRPopulateType populateType = BfIRPopulateType_Declaration);

View file

@ -434,17 +434,42 @@ llvm::Type* BfIRCodeGen::GetLLVMType(BfTypeCode typeCode, bool& isSigned)
case BfTypeCode_UInt16:
case BfTypeCode_Char16:
return llvm::Type::getInt16Ty(*mLLVMContext);
case BfTypeCode_Int24:
isSigned = true;
return llvm::Type::getIntNTy(*mLLVMContext, 24);
case BfTypeCode_UInt24:
return llvm::Type::getIntNTy(*mLLVMContext, 24);
case BfTypeCode_Int32:
isSigned = true;
return llvm::Type::getInt32Ty(*mLLVMContext);
case BfTypeCode_UInt32:
case BfTypeCode_Char32:
return llvm::Type::getInt32Ty(*mLLVMContext);
case BfTypeCode_Int40:
isSigned = true;
return llvm::Type::getIntNTy(*mLLVMContext, 40);
case BfTypeCode_UInt40:
return llvm::Type::getIntNTy(*mLLVMContext, 40);
case BfTypeCode_Int48:
isSigned = true;
return llvm::Type::getIntNTy(*mLLVMContext, 48);
case BfTypeCode_UInt48:
return llvm::Type::getIntNTy(*mLLVMContext, 48);
case BfTypeCode_Int56:
isSigned = true;
return llvm::Type::getIntNTy(*mLLVMContext, 56);
case BfTypeCode_UInt56:
return llvm::Type::getIntNTy(*mLLVMContext, 56);
case BfTypeCode_Int64:
isSigned = true;
return llvm::Type::getInt64Ty(*mLLVMContext);
case BfTypeCode_UInt64:
return llvm::Type::getInt64Ty(*mLLVMContext);
case BfTypeCode_Int128:
isSigned = true;
return llvm::Type::getInt128Ty(*mLLVMContext);
case BfTypeCode_UInt128:
return llvm::Type::getInt128Ty(*mLLVMContext);
case BfTypeCode_IntPtr:
BF_FATAL("Illegal");
/*isSigned = true;
@ -1116,12 +1141,19 @@ void BfIRCodeGen::HandleNextCmd()
SetResult(curId, GetLLVMType(typeCode, isSigned));
}
break;
case BfIRCmd_CreateAnonymousStruct:
{
CMD_PARAM(CmdParamVec<llvm::Type*>, members);
llvm::StructType* structType = llvm::StructType::get(*mLLVMContext, members);
SetResult(curId, structType);
}
break;
case BfIRCmd_CreateStruct:
{
CMD_PARAM(String, typeName);
SetResult(curId, llvm::StructType::create(*mLLVMContext, typeName.c_str()));
}
break;
break;
case BfIRCmd_StructSetBody:
{
CMD_PARAM(llvm::Type*, type);
@ -2621,6 +2653,15 @@ void BfIRCodeGen::HandleNextCmd()
{
((llvm::CallInst*)callInst)->addDereferenceableAttr(argIdx, arg);
}
else if (attribute == BfIRAttribute_ByVal)
{
llvm::AttrBuilder B;
B.addAttribute(llvm::Attribute::ByVal);
B.addAlignmentAttr(arg);
auto attrList = ((llvm::CallInst*)callInst)->getAttributes();
attrList = attrList.addAttributes(*mLLVMContext, argIdx, B);
((llvm::CallInst*)callInst)->setAttributes(attrList);
}
}
}
break;
@ -2655,6 +2696,15 @@ void BfIRCodeGen::HandleNextCmd()
{
((llvm::Function*)func)->addDereferenceableAttr(argIdx, arg);
}
else if (attribute == BfIRAttribute_ByVal)
{
llvm::AttrBuilder B;
B.addAttribute(llvm::Attribute::ByVal);
B.addAlignmentAttr(arg);
auto attrList = ((llvm::Function*)func)->getAttributes();
attrList = attrList.addAttributes(*mLLVMContext, argIdx, B);
((llvm::Function*)func)->setAttributes(attrList);
}
}
break;
case BfIRCmd_Func_SetParamName:

View file

@ -82,7 +82,7 @@ public:
Dictionary<int, BfIRCodeGenEntry> mResults;
Dictionary<int, BfIRTypeEntry> mTypes;
Dictionary<int, llvm::Function*> mIntrinsicMap;
Dictionary<llvm::Function*, int> mIntrinsicReverseMap;
Dictionary<llvm::Function*, int> mIntrinsicReverseMap;
Array<llvm::Constant*> mConfigConsts32;
Array<llvm::Constant*> mConfigConsts64;

View file

@ -1566,7 +1566,7 @@ void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType*
}
}
else if (type->IsTypeInstance())
{
{
auto typeInstance = (BfTypeInstance*)type;
auto typeDef = typeInstance->mTypeDef;
@ -1577,7 +1577,7 @@ void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType*
name += "E";
name += "A";
}
else if (((type->IsGenericTypeInstance()) || (type->IsTuple()) || (type->IsEnum())) && (mangleContext.mInRet))
else if (((type->IsGenericTypeInstance()) || (type->IsComposite()) || (type->IsEnum())) && (mangleContext.mInRet))
name += "?A";
Mangle(mangleContext, name, typeInstance, false);

View file

@ -1088,7 +1088,7 @@ void BfModule::EnsureIRBuilder(bool dbgVerifyCodeGen)
}
}
else if (!mIsReified)
{
{
mBfIRBuilder->mIgnoreWrites = true;
}
else
@ -1097,10 +1097,9 @@ void BfModule::EnsureIRBuilder(bool dbgVerifyCodeGen)
// code as we walk the AST
//mBfIRBuilder->mDbgVerifyCodeGen = true;
if (
(mModuleName == "-")
//|| (mModuleName == "Blurg")
//|| (mModuleName == "System_Int32")
//|| (mModuleName == "Hey_Dude_Bro_TestClass")
(mModuleName == "-")
//|| (mModuleName == "Tests_FuncRefs_Class")
//|| (mModuleName == "Tests_FuncRefs")
)
mBfIRBuilder->mDbgVerifyCodeGen = true;
@ -3993,7 +3992,7 @@ void BfModule::CreateFakeCallerMethod(const String& funcName)
SizedArray<BfIRValue, 8> args;
BfExprEvaluator exprEvaluator(this);
if (mCurMethodInstance->HasStructRet())
if (mCurMethodInstance->GetStructRetIdx() != -1)
{
auto retPtrType = CreatePointerType(mCurMethodInstance->mReturnType);
exprEvaluator.PushArg(GetDefaultTypedValue(retPtrType, true, BfDefaultValueKind_Const), args);
@ -4001,7 +4000,7 @@ void BfModule::CreateFakeCallerMethod(const String& funcName)
if (mCurMethodInstance->HasThis())
{
auto thisValue = GetDefaultTypedValue(mCurMethodInstance->GetOwner(), true);
auto thisValue = GetDefaultTypedValue(mCurMethodInstance->GetOwner(), true, mCurTypeInstance->IsComposite() ? BfDefaultValueKind_Addr : BfDefaultValueKind_Const);
exprEvaluator.PushThis(NULL, thisValue, mCurMethodInstance, args);
}
@ -12705,7 +12704,7 @@ void BfModule::CreateDIRetVal()
{
BfType* dbgType = mCurMethodInstance->mReturnType;
BfIRValue dbgValue = mCurMethodState->mRetVal.mValue;
if (mCurMethodInstance->HasStructRet())
if (mCurMethodInstance->GetStructRetIdx() != -1)
{
BF_ASSERT(mCurMethodState->mRetValAddr);
dbgType = CreatePointerType(dbgType);
@ -13207,11 +13206,11 @@ void BfModule::MarkScopeLeft(BfScopeData* scopeData)
void BfModule::CreateReturn(BfIRValue val)
{
if (mCurMethodInstance->HasStructRet())
if (mCurMethodInstance->GetStructRetIdx() != -1)
{
// Store to sret
BF_ASSERT(val);
mBfIRBuilder->CreateStore(val, mBfIRBuilder->GetArgument(0));
mBfIRBuilder->CreateStore(val, mBfIRBuilder->GetArgument(mCurMethodInstance->GetStructRetIdx()));
mBfIRBuilder->CreateRetVoid();
}
else
@ -13222,14 +13221,18 @@ void BfModule::CreateReturn(BfIRValue val)
}
else if (mCurMethodInstance->mReturnType->IsStruct())
{
auto loweredType = GetPrimitiveType(mCurMethodInstance->mReturnType->GetLoweredType());
auto ptrReturnType = CreatePointerType(mCurMethodInstance->mReturnType);
auto ptrLoweredValue = CreateAlloca(loweredType);
auto ptrReturnValue = mBfIRBuilder->CreateBitCast(ptrLoweredValue, mBfIRBuilder->MapType(ptrReturnType));
mBfIRBuilder->CreateStore(val, ptrReturnValue);
BfTypeCode loweredReturnType = BfTypeCode_None;
BfTypeCode loweredReturnType2 = BfTypeCode_None;
mCurMethodInstance->GetLoweredReturnType(&loweredReturnType, &loweredReturnType2);
auto loadedLoweredValue = mBfIRBuilder->CreateLoad(ptrLoweredValue);
mBfIRBuilder->CreateRet(loadedLoweredValue);
auto retVal = CreateAlloca(mCurMethodInstance->mReturnType);
mBfIRBuilder->CreateStore(val, retVal);
auto irRetType = GetIRLoweredType(loweredReturnType, loweredReturnType2);
irRetType = mBfIRBuilder->GetPointerTo(irRetType);
auto ptrReturnValue = mBfIRBuilder->CreateBitCast(retVal, irRetType);
auto loadedReturnValue = mBfIRBuilder->CreateLoad(ptrReturnValue);
mBfIRBuilder->CreateRet(loadedReturnValue);
}
else
{
@ -13286,7 +13289,7 @@ void BfModule::EmitDefaultReturn()
{
if (mCurMethodInstance->mReturnType->IsVoid())
mBfIRBuilder->CreateRetVoid();
else if (!mCurMethodInstance->HasStructRet())
else if (mCurMethodInstance->GetStructRetIdx() == -1)
mBfIRBuilder->CreateRet(GetDefaultValue(mCurMethodInstance->mReturnType));
}
@ -13394,16 +13397,20 @@ void BfModule::CreateDelegateInvokeMethod()
if (mCurMethodInstance->mReturnType->IsValueType())
mBfIRBuilder->PopulateType(mCurMethodInstance->mReturnType, BfIRPopulateType_Full);
if (mCurMethodInstance->GetStructRetIdx() != 0)
memberFuncArgs.push_back(BfIRValue()); // Push 'target'
int thisIdx = 0;
if (mCurMethodInstance->HasStructRet())
{
thisIdx = 1;
staticFuncArgs.push_back(mBfIRBuilder->GetArgument(0));
memberFuncArgs.push_back(mBfIRBuilder->GetArgument(0));
if (mCurMethodInstance->GetStructRetIdx() != -1)
{
thisIdx = mCurMethodInstance->GetStructRetIdx() ^ 1;
staticFuncArgs.push_back(mBfIRBuilder->GetArgument(mCurMethodInstance->GetStructRetIdx()));
memberFuncArgs.push_back(mBfIRBuilder->GetArgument(mCurMethodInstance->GetStructRetIdx()));
}
memberFuncArgs.push_back(BfIRValue()); // Push 'target'
if (mCurMethodInstance->GetStructRetIdx() == 0)
memberFuncArgs.push_back(BfIRValue()); // Push 'target'
mCurMethodInstance->GetIRFunctionInfo(this, origReturnType, staticParamTypes, true);
@ -13441,8 +13448,8 @@ void BfModule::CreateDelegateInvokeMethod()
auto funcPtrPtr = mBfIRBuilder->CreateBitCast(fieldPtr, memberFuncPtrPtr);
auto funcPtr = mBfIRBuilder->CreateLoad(funcPtrPtr);
nonStaticResult = mBfIRBuilder->CreateCall(funcPtr, memberFuncArgs);
if (mCurMethodInstance->HasStructRet())
mBfIRBuilder->Call_AddAttribute(nonStaticResult, 1, BfIRAttribute_StructRet);
if (mCurMethodInstance->GetStructRetIdx() != -1)
mBfIRBuilder->Call_AddAttribute(nonStaticResult, mCurMethodInstance->GetStructRetIdx() + 1, BfIRAttribute_StructRet);
if (callingConv != BfIRCallingConv_CDecl)
mBfIRBuilder->SetCallCallingConv(nonStaticResult, callingConv);
mCurMethodState->SetHadReturn(false);
@ -13459,8 +13466,11 @@ void BfModule::CreateDelegateInvokeMethod()
auto funcPtrPtr = mBfIRBuilder->CreateBitCast(fieldPtr, staticFuncPtrPtr);
auto funcPtr = mBfIRBuilder->CreateLoad(funcPtrPtr);
staticResult = mBfIRBuilder->CreateCall(funcPtr, staticFuncArgs);
if (mCurMethodInstance->HasStructRet())
mBfIRBuilder->Call_AddAttribute(staticResult, 1, BfIRAttribute_StructRet);
if (mCurMethodInstance->GetStructRetIdx() != -1)
{
// Note: since this is a forced static invocation, we know the sret will be the first parameter
mBfIRBuilder->Call_AddAttribute(staticResult, 0 + 1, BfIRAttribute_StructRet);
}
if (callingConv == BfIRCallingConv_ThisCall)
callingConv = BfIRCallingConv_CDecl;
if (callingConv != BfIRCallingConv_CDecl)
@ -13473,16 +13483,20 @@ void BfModule::CreateDelegateInvokeMethod()
mBfIRBuilder->AddBlock(doneBB);
mBfIRBuilder->SetInsertPoint(doneBB);
if ((mCurMethodInstance->mReturnType->IsValuelessType()) || (mCurMethodInstance->HasStructRet()))
if ((mCurMethodInstance->mReturnType->IsValuelessType()) || (mCurMethodInstance->GetStructRetIdx() != -1))
{
mBfIRBuilder->CreateRetVoid();
}
else
{
auto loweredReturnType = mCurMethodInstance->mReturnType;
if (loweredReturnType->GetLoweredType() != BfTypeCode_None)
loweredReturnType = GetPrimitiveType(loweredReturnType->GetLoweredType());
auto phi = mBfIRBuilder->CreatePhi(mBfIRBuilder->MapType(loweredReturnType), 2);
BfIRType loweredIRReturnType;
BfTypeCode loweredTypeCode = BfTypeCode_None;
BfTypeCode loweredTypeCode2 = BfTypeCode_None;
if (mCurMethodInstance->GetLoweredReturnType(&loweredTypeCode, &loweredTypeCode2))
loweredIRReturnType = GetIRLoweredType(loweredTypeCode, loweredTypeCode2);
else
loweredIRReturnType = mBfIRBuilder->MapType(mCurMethodInstance->mReturnType);
auto phi = mBfIRBuilder->CreatePhi(loweredIRReturnType, 2);
mBfIRBuilder->AddPhiIncoming(phi, nonStaticResult, trueBB);
mBfIRBuilder->AddPhiIncoming(phi, staticResult, falseBB);
mBfIRBuilder->CreateRet(phi);
@ -14364,22 +14378,25 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func
}
int argCount = methodInstance->GetIRFunctionParamCount(this);
if (methodInstance->HasStructRet())
{
mBfIRBuilder->Func_AddAttribute(func, argIdx + 1, BfIRAttribute_NoAlias);
mBfIRBuilder->Func_AddAttribute(func, argIdx + 1, BfIRAttribute_StructRet);
argIdx++;
}
while (argIdx < argCount)
{
if (argIdx == methodInstance->GetStructRetIdx())
{
mBfIRBuilder->Func_AddAttribute(func, argIdx + 1, BfIRAttribute_NoAlias);
mBfIRBuilder->Func_AddAttribute(func, argIdx + 1, BfIRAttribute_StructRet);
argIdx++;
continue;
}
while ((paramIdx != -1) && (methodInstance->IsParamSkipped(paramIdx)))
paramIdx++;
BfType* resolvedTypeRef = NULL;
BfType* resolvedTypeRef2 = NULL;
String paramName;
bool isSplattable = false;
bool tryLowering = true;
bool isThis = paramIdx == -1;
if (isThis)
{
@ -14389,6 +14406,7 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func
else
resolvedTypeRef = methodInstance->GetOwner();
isSplattable = (resolvedTypeRef->IsSplattable()) && (methodInstance->AllowsThisSplatting());
tryLowering = methodInstance->AllowsThisSplatting();
}
else
{
@ -14409,11 +14427,24 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func
}
}
//
if (tryLowering)
{
auto loweredTypeCode = resolvedTypeRef->GetLoweredType();
if (loweredTypeCode != BfTypeCode_None)
resolvedTypeRef = GetPrimitiveType(loweredTypeCode);
BfTypeCode loweredTypeCode = BfTypeCode_None;
BfTypeCode loweredTypeCode2 = BfTypeCode_None;
if (resolvedTypeRef->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2))
{
mBfIRBuilder->Func_SetParamName(func, argIdx + 1, paramName + "__1");
argIdx++;
if (loweredTypeCode2 != BfTypeCode_None)
{
mBfIRBuilder->Func_SetParamName(func, argIdx + 1, paramName + "__2");
argIdx++;
}
paramIdx++;
continue;
}
}
auto _SetupParam = [&](const StringImpl& paramName, BfType* resolvedTypeRef)
@ -14432,16 +14463,17 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func
}
if ((resolvedTypeRef->IsComposite()) && (!resolvedTypeRef->IsTypedPrimitive()))
{
if (mCompiler->mOptions.mAllowStructByVal)
{
mBfIRBuilder->Func_AddAttribute(func, argIdx + 1, BfIRAttribute_ByVal);
}
else
if (paramIdx == -1)
{
mBfIRBuilder->Func_AddAttribute(func, argIdx + 1, BfIRAttribute_NoCapture);
PopulateType(resolvedTypeRef, BfPopulateType_Data);
addDeref = resolvedTypeRef->mSize;
}
else
{
mBfIRBuilder->PopulateType(resolvedTypeRef);
mBfIRBuilder->Func_AddAttribute(func, argIdx + 1, BfIRAttribute_ByVal, mSystem->mPtrSize);
}
}
else if (resolvedTypeRef->IsPrimitiveType())
{
@ -14521,8 +14553,9 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func
}
_SetupParam(paramName, resolvedTypeRef);
//argIdx++;
if (resolvedTypeRef2 != NULL)
_SetupParam(paramName, resolvedTypeRef2);
paramIdx++;
}
}
@ -15412,11 +15445,15 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
isThisStruct = thisType->IsStruct() && !thisType->IsTypedPrimitive();
int argIdx = 0;
if (methodInstance->HasStructRet())
if (argIdx == methodInstance->GetStructRetIdx())
argIdx++;
if (!methodDef->mIsStatic)
{
BfTypeCode loweredTypeCode = BfTypeCode_None;
BfTypeCode loweredTypeCode2 = BfTypeCode_None;
BfLocalVariable* paramVar = new BfLocalVariable();
paramVar->mResolvedType = thisType;
paramVar->mName = "this";
@ -15431,7 +15468,7 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
paramVar->mIsSplat = true;
}
else if ((!methodDef->mIsMutating) && (methodInstance->mCallingConvention == BfCallingConvention_Unspecified))
paramVar->mIsLowered = thisType->GetLoweredType() != BfTypeCode_None;
paramVar->mIsLowered = thisType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2) != BfTypeCode_None;
auto thisTypeInst = thisType->ToTypeInstance();
paramVar->mIsStruct = isThisStruct;
@ -15472,19 +15509,28 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
argIdx++;
}
}
if (loweredTypeCode2 != BfTypeCode_None)
argIdx++;
}
if (argIdx == methodInstance->GetStructRetIdx())
argIdx++;
bool hadParams = false;
bool hasDefault = false;
int compositeVariableIdx = -1;
int paramIdx = 0;
for (paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++)
{
{
// We already issues a type error for this param if we had one in declaration processing
SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, true);
BfLocalVariable* paramVar = new BfLocalVariable();
BfTypeCode loweredTypeCode = BfTypeCode_None;
BfTypeCode loweredTypeCode2 = BfTypeCode_None;
bool isParamSkipped = methodInstance->IsParamSkipped(paramIdx);
BfType* unresolvedType = methodInstance->GetParamType(paramIdx, false);
@ -15529,7 +15575,7 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
paramVar->mIsSplat = true; // Treat skipped (valueless) as a splat
paramVar->mValue = mBfIRBuilder->GetFakeVal();
}
paramVar->mIsLowered = resolvedType->GetLoweredType() != BfTypeCode_None;
paramVar->mIsLowered = resolvedType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2) != BfTypeCode_None;
paramVar->mIsStruct = resolvedType->IsComposite() && !resolvedType->IsTypedPrimitive();
paramVar->mParamIdx = paramIdx;
paramVar->mIsImplicitParam = methodInstance->IsImplicitCapture(paramIdx);
@ -15639,6 +15685,9 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
{
argIdx++;
}
if (loweredTypeCode2 != BfTypeCode_None)
argIdx++;
}
}
@ -16754,10 +16803,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
{
int localIdx = 0;
int argIdx = 0;
if (methodInstance->HasStructRet())
argIdx++;
Array<BfIRValue> splatAddrValues;
for ( ; argIdx < irParamCount; localIdx++)
@ -16766,6 +16812,13 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
if ((isThis) && (thisType->IsValuelessType()))
isThis = false;
if (methodInstance->GetStructRetIdx() == argIdx)
{
argIdx++;
if (argIdx == irParamCount)
break;
}
BfLocalVariable* paramVar = NULL;
while (true)
{
@ -16782,7 +16835,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
paramVar->mIsReadOnly = true;
}
bool wantsAddr = (wantsDIVariables) || (!paramVar->mIsReadOnly) || (paramVar->mResolvedType->GetLoweredType() != BfTypeCode_None);
bool wantsAddr = (wantsDIVariables) || (!paramVar->mIsReadOnly) || (paramVar->mResolvedType->GetLoweredType(BfTypeUsage_Parameter));
if (paramVar->mResolvedType->IsMethodRef())
wantsAddr = false;
@ -16895,6 +16948,15 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
{
BfTypeUtils::SplatIterate([&](BfType* checkType) { argIdx++; }, paramVar->mResolvedType);
}
else if (paramVar->mIsLowered)
{
BfTypeCode loweredTypeCode = BfTypeCode_None;
BfTypeCode loweredTypeCode2 = BfTypeCode_None;
paramVar->mResolvedType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2);
argIdx++;
if (loweredTypeCode2 != BfTypeCode_None)
argIdx++;
}
else
{
argIdx++;
@ -16909,12 +16971,13 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
int declArgIdx = 0;
localIdx = 0;
argIdx = 0;
if (methodInstance->HasStructRet())
argIdx++;
int splatAddrIdx = 0;
while (localIdx < (int)methodState.mLocals.size())
{
if (argIdx == methodInstance->GetStructRetIdx())
argIdx++;
int curLocalIdx = localIdx++;
BfLocalVariable* paramVar = methodState.mLocals[curLocalIdx];
if (!paramVar->IsParam())
@ -17010,19 +17073,34 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
bool handled = false;
if (paramVar->mIsLowered)
{
auto loweredTypeCode = paramVar->mResolvedType->GetLoweredType();
BF_ASSERT(loweredTypeCode != BfTypeCode_None);
if (loweredTypeCode != BfTypeCode_None)
BfTypeCode loweredTypeCode = BfTypeCode_None;
BfTypeCode loweredTypeCode2 = BfTypeCode_None;
if (paramVar->mResolvedType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2))
{
// We have a lowered type coming in, so we have to cast the .addr before storing
auto primType = GetPrimitiveType(loweredTypeCode);
auto primPtrType = CreatePointerType(primType);
auto primPtrVal = mBfIRBuilder->CreateBitCast(paramVar->mAddr, mBfIRBuilder->MapType(primPtrType));
mBfIRBuilder->CreateAlignedStore(paramVar->mValue, primPtrVal, paramVar->mResolvedType->mSize);
auto primType = mBfIRBuilder->GetPrimitiveType(loweredTypeCode);
auto primPtrType = mBfIRBuilder->GetPointerTo(primType);
auto primPtrVal = mBfIRBuilder->CreateBitCast(paramVar->mAddr, primPtrType);
mBfIRBuilder->CreateStore(paramVar->mValue, primPtrVal);
if (loweredTypeCode2 != BfTypeCode_None)
{
declArgIdx++;
auto primType2 = mBfIRBuilder->GetPrimitiveType(loweredTypeCode2);
auto primPtrType2 = mBfIRBuilder->GetPointerTo(primType2);
auto primPtrVal2 = mBfIRBuilder->CreateBitCast(mBfIRBuilder->CreateInBoundsGEP(primPtrVal, 1), primPtrType2);
mBfIRBuilder->CreateStore(mBfIRBuilder->GetArgument(argIdx + 1), primPtrVal2);
}
// We don't want to allow directly using value
paramVar->mValue = BfIRValue();
handled = true;
}
else
{
BF_ASSERT("Expected lowered");
}
}
if (!handled)
@ -17190,6 +17268,15 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
{
BfTypeUtils::SplatIterate([&](BfType* checkType) { argIdx++; }, paramVar->mResolvedType);
}
else if (paramVar->mIsLowered)
{
argIdx++;
BfTypeCode loweredTypeCode = BfTypeCode_None;
BfTypeCode loweredTypeCode2 = BfTypeCode_None;
paramVar->mResolvedType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2);
if (loweredTypeCode != BfTypeCode_None)
argIdx++;
}
else if (!paramVar->mResolvedType->IsValuelessType())
{
argIdx++;
@ -17322,10 +17409,10 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
{
BF_ASSERT(innerType->IsUnspecializedType());
}
else if (methodInstance->HasStructRet())
else if (methodInstance->GetStructRetIdx() != -1)
{
mBfIRBuilder->PopulateType(methodInstance->mReturnType);
auto returnType = BfTypedValue(mBfIRBuilder->GetArgument(0), methodInstance->mReturnType, true);
auto returnType = BfTypedValue(mBfIRBuilder->GetArgument(methodInstance->GetStructRetIdx()), methodInstance->mReturnType, true);
exprEvaluator.mReceivingValue = &returnType;
auto retVal = exprEvaluator.CreateCall(innerMethodInstance.mMethodInstance, innerMethodInstance.mFunc, true, innerParams, NULL, true);
BF_ASSERT(exprEvaluator.mReceivingValue == NULL); // Ensure it was actually used
@ -17692,11 +17779,11 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
{
mBfIRBuilder->PopulateType(mCurMethodInstance->mReturnType);
if (mCurMethodInstance->HasStructRet())
if (mCurMethodInstance->GetStructRetIdx() != -1)
{
auto ptrType = CreatePointerType(mCurMethodInstance->mReturnType);
auto allocaInst = AllocLocalVariable(ptrType, "__return.addr", false);
auto storeInst = mBfIRBuilder->CreateStore(mBfIRBuilder->GetArgument(0), allocaInst);
auto storeInst = mBfIRBuilder->CreateStore(mBfIRBuilder->GetArgument(mCurMethodInstance->GetStructRetIdx()), allocaInst);
mBfIRBuilder->ClearDebugLocation(storeInst);
mCurMethodState->mRetValAddr = allocaInst;
}
@ -17886,7 +17973,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
if (mCurMethodState->mIRExitBlock)
{
if ((mCurMethodState->mRetVal) && (!mCurMethodInstance->HasStructRet()))
if ((mCurMethodState->mRetVal) && (mCurMethodInstance->GetStructRetIdx() == -1))
{
auto loadedVal = mBfIRBuilder->CreateLoad(mCurMethodState->mRetVal.mValue);
@ -19913,9 +20000,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
}
int argIdx = 0;
PopulateType(methodInstance->mReturnType, BfPopulateType_Data);
if (methodInstance->HasStructRet())
argIdx++;
PopulateType(methodInstance->mReturnType, BfPopulateType_Data);
if (!methodDef->mIsStatic)
{
if (methodInstance->GetParamIsSplat(-1))
@ -19923,6 +20008,10 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
else if (!methodInstance->GetOwner()->IsValuelessType())
argIdx++;
}
if (methodInstance->GetStructRetIdx() != -1)
argIdx++;
for (auto& methodParam : mCurMethodInstance->mParams)
{
if (methodParam.mResolvedType->IsMethodRef())

View file

@ -1631,6 +1631,7 @@ public:
BfTypeInstance* GetWrappedStructType(BfType* type, bool allowSpecialized = true);
BfTypeInstance* GetPrimitiveStructType(BfTypeCode typeCode);
BfPrimitiveType* GetPrimitiveType(BfTypeCode typeCode);
BfIRType GetIRLoweredType(BfTypeCode loweredTypeCode, BfTypeCode loweredTypeCode2);
BfMethodRefType* CreateMethodRefType(BfMethodInstance* methodInstance, bool mustAlreadyExist = false);
BfType* FixIntUnknown(BfType* type);
void FixIntUnknown(BfTypedValue& typedVal, BfType* matchType = NULL);

View file

@ -3136,37 +3136,6 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
if (isCRepr)
{
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
typeInstance->mIsSplattable = (dataCount <= 3) && (!hadNonSplattable);
@ -4736,6 +4705,18 @@ BfPrimitiveType* BfModule::GetPrimitiveType(BfTypeCode typeCode)
return primType;
}
BfIRType BfModule::GetIRLoweredType(BfTypeCode loweredTypeCode, BfTypeCode loweredTypeCode2)
{
BF_ASSERT(loweredTypeCode != BfTypeCode_None);
if (loweredTypeCode2 == BfTypeCode_None)
return mBfIRBuilder->GetPrimitiveType(loweredTypeCode);
SizedArray<BfIRType, 2> types;
types.push_back(mBfIRBuilder->GetPrimitiveType(loweredTypeCode));
types.push_back(mBfIRBuilder->GetPrimitiveType(loweredTypeCode2));
return mBfIRBuilder->CreateStructType(types);
}
BfMethodRefType* BfModule::CreateMethodRefType(BfMethodInstance* methodInstance, bool mustAlreadyExist)
{
auto methodRefType = new BfMethodRefType();
@ -7803,6 +7784,10 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
genericTypeInst = new BfTypeInstance();
genericTypeInst->mGenericTypeInfo = new BfGenericTypeInfo();
genericTypeInst->mTypeDef = typeDef;
if (parentGenericTypeInstance->mGenericTypeInfo->mGenericParams.IsEmpty())
PopulateType(parentGenericTypeInstance, BfPopulateType_Declaration);
for (int i = 0; i < numParentGenericParams; i++)
{
genericTypeInst->mGenericTypeInfo->mGenericParams.push_back(parentGenericTypeInstance->mGenericTypeInfo->mGenericParams[i]->AddRef());

View file

@ -7370,7 +7370,8 @@ BfObjectCreateExpression* BfReducer::CreateObjectCreateExpression(BfAstNode* all
SetAndRestoreValue<BfVisitorPos> prevVisitorPos(mVisitorPos, BfVisitorPos(block));
ReadArguments(objectCreateExpr, objectCreateExpr, &arguments, &commas, BfToken_None, true);
}
MEMBER_SET(objectCreateExpr, mCloseToken, block->mCloseBrace);
if (block->mCloseBrace != NULL)
MEMBER_SET(objectCreateExpr, mCloseToken, block->mCloseBrace);
return objectCreateExpr;
}

View file

@ -611,9 +611,24 @@ bool BfMethodInstance::HasParamsArray()
return GetParamKind((int)mParams.size() - 1) == BfParamKind_Params;
}
bool BfMethodInstance::HasStructRet()
int BfMethodInstance::GetStructRetIdx()
{
return (mReturnType->IsComposite()) && (!mReturnType->IsValuelessType()) && (mReturnType->GetLoweredType() == BfTypeCode_None);
if ((mReturnType->IsComposite()) && (!mReturnType->IsValuelessType()) && (!GetLoweredReturnType()))
{
auto owner = mMethodInstanceGroup->mOwner;
if (owner->mModule->mCompiler->mOptions.mPlatformType != BfPlatformType_Windows)
return 0;
if (!HasThis())
return 0;
if (!owner->IsValueType())
return 1;
if ((mMethodDef->mIsMutating) || ((!AllowsSplatting()) && (!owner->GetLoweredType(BfTypeUsage_Parameter))))
return 1;
return 0;
}
return -1;
}
bool BfMethodInstance::HasSelf()
@ -626,6 +641,11 @@ bool BfMethodInstance::HasSelf()
return false;
}
bool BfMethodInstance::GetLoweredReturnType(BfTypeCode* loweredTypeCode, BfTypeCode* loweredTypeCode2)
{
return mReturnType->GetLoweredType(mMethodDef->mIsStatic ? BfTypeUsage_Return_Static : BfTypeUsage_Return_NonStatic, loweredTypeCode, loweredTypeCode2);
}
bool BfMethodInstance::IsSkipCall(bool bypassVirtual)
{
if ((mMethodDef->mIsSkipCall) &&
@ -743,7 +763,7 @@ BfType* BfMethodInstance::GetParamType(int paramIdx, bool useResolvedType)
return mMethodInfoEx->mClosureInstanceInfo->mThisOverride;
BF_ASSERT(!mMethodDef->mIsStatic);
auto owner = mMethodInstanceGroup->mOwner;
if ((owner->IsValueType()) && ((mMethodDef->mIsMutating) || (!AllowsSplatting())) && (owner->GetLoweredType() == BfTypeCode_None))
if ((owner->IsValueType()) && ((mMethodDef->mIsMutating) || (!AllowsSplatting())) && (!owner->GetLoweredType(BfTypeUsage_Parameter)))
return owner->mModule->CreatePointerType(owner);
return owner;
}
@ -849,8 +869,6 @@ BfIdentifierNode* BfMethodInstance::GetParamNameNode(int paramIdx)
BfParameterDef* paramDef = mMethodDef->mParams[methodParam->mParamDefIdx];
if (paramDef->mParamDeclaration != NULL)
return BfNodeDynCast<BfIdentifierNode>(paramDef->mParamDeclaration->mNameNode);
// else if ((mClosureInstanceInfo != NULL) && (paramIdx < (int)mClosureInstanceInfo->mCaptureNodes.size()))
// return mClosureInstanceInfo->mCaptureNodes[paramIdx];
return NULL;
}
@ -894,37 +912,39 @@ int BfMethodInstance::DbgGetVirtualMethodNum()
}
void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType, SizedArrayImpl<BfIRType>& paramTypes, bool forceStatic)
{
{
module->PopulateType(mReturnType);
BfType* loweredReturnType = mReturnType;
auto loweredReturnTypeCode = mReturnType->GetLoweredType();
if (loweredReturnTypeCode != BfTypeCode_None)
loweredReturnType = module->GetPrimitiveType(loweredReturnTypeCode);
if (loweredReturnType->IsValuelessType())
BfTypeCode loweredReturnTypeCode = BfTypeCode_None;
BfTypeCode loweredReturnTypeCode2 = BfTypeCode_None;
if (GetLoweredReturnType(&loweredReturnTypeCode, &loweredReturnTypeCode2))
{
auto irReturnType = module->GetIRLoweredType(loweredReturnTypeCode, loweredReturnTypeCode2);
returnType = irReturnType;
}
else if (mReturnType->IsValuelessType())
{
auto voidType = module->GetPrimitiveType(BfTypeCode_None);
returnType = module->mBfIRBuilder->MapType(voidType);
}
else if (loweredReturnType->IsComposite())
else if (mReturnType->IsComposite())
{
auto voidType = module->GetPrimitiveType(BfTypeCode_None);
returnType = module->mBfIRBuilder->MapType(voidType);
auto typeInst = loweredReturnType->ToTypeInstance();
auto typeInst = mReturnType->ToTypeInstance();
if (typeInst != NULL)
{
paramTypes.push_back(module->mBfIRBuilder->MapTypeInstPtr(typeInst));
}
else
{
auto ptrType = module->CreatePointerType(loweredReturnType);
auto ptrType = module->CreatePointerType(mReturnType);
paramTypes.push_back(module->mBfIRBuilder->MapType(ptrType));
}
}
else
{
returnType = module->mBfIRBuilder->MapType(loweredReturnType);
returnType = module->mBfIRBuilder->MapType(mReturnType);
}
for (int paramIdx = -1; paramIdx < GetParamCount(); paramIdx++)
@ -972,11 +992,18 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
checkLowered = true;
}
BfType* checkType2 = NULL;
if (checkLowered)
{
auto loweredTypeCode = checkType->GetLoweredType();
if (loweredTypeCode != BfTypeCode_None)
checkType = module->GetPrimitiveType(loweredTypeCode);
BfTypeCode loweredTypeCode = BfTypeCode_None;
BfTypeCode loweredTypeCode2 = BfTypeCode_None;
if (checkType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2))
{
paramTypes.push_back(module->mBfIRBuilder->GetPrimitiveType(loweredTypeCode));
if (loweredTypeCode2 != BfTypeCode_None)
paramTypes.push_back(module->mBfIRBuilder->GetPrimitiveType(loweredTypeCode2));
continue;
}
}
if ((paramIdx == 0) && (GetParamName(0) == "this") && (checkType->IsPointer()))
@ -1032,8 +1059,15 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
}, checkType);
}
else
_AddType(checkType);
_AddType(checkType);
if (checkType2 != NULL)
_AddType(checkType2);
}
if ((GetStructRetIdx() == 1) && (!forceStatic))
{
BF_SWAP(paramTypes[0], paramTypes[1]);
}
}
@ -1414,19 +1448,100 @@ BfPrimitiveType* BfTypeInstance::GetDiscriminatorType(int* outDataIdx)
return (BfPrimitiveType*)fieldInstance.mResolvedType;
}
BfTypeCode BfTypeInstance::GetLoweredType()
{
if ((mTypeDef->mTypeCode != BfTypeCode_Struct) || (mIsSplattable))
return BfTypeCode_None;
bool BfTypeInstance::GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCode, BfTypeCode* outTypeCode2)
{
if ((mTypeDef->mTypeCode != BfTypeCode_Struct) || (IsBoxed()) || (mIsSplattable))
return false;
if (mModule->mCompiler->mOptions.mPlatformType == BfPlatformType_Windows)
{
// Odd Windows rule: composite returns for non-static methods are always sret
if (typeUsage == BfTypeUsage_Return_NonStatic)
return false;
}
else
{
// Non-Windows systems allow lowered splitting of composites over two int params
if (mModule->mSystem->mPtrSize == 8)
{
if (mInstSize == 12)
{
if (outTypeCode != NULL)
*outTypeCode = BfTypeCode_Int64;
if (outTypeCode2 != NULL)
*outTypeCode2 = BfTypeCode_Int32;
return true;
}
if (mInstSize == 16)
{
if (outTypeCode != NULL)
*outTypeCode = BfTypeCode_Int64;
if (outTypeCode2 != NULL)
*outTypeCode2 = BfTypeCode_Int64;
return true;
}
}
}
BfTypeCode typeCode = BfTypeCode_None;
BfTypeCode pow2TypeCode = BfTypeCode_None;
switch (mInstSize)
{
case 1: return BfTypeCode_Int8;
case 2: return BfTypeCode_Int16;
case 4: return BfTypeCode_Int32;
case 8: if (mModule->mSystem->mPtrSize == 8) return BfTypeCode_Int64;
case 1:
pow2TypeCode = BfTypeCode_Int8;
break;
case 2:
pow2TypeCode = BfTypeCode_Int16;
break;
case 3:
typeCode = BfTypeCode_Int24;
break;
case 4:
pow2TypeCode = BfTypeCode_Int32;
break;
case 5:
typeCode = BfTypeCode_Int40;
break;
case 6:
typeCode = BfTypeCode_Int48;
break;
case 7:
typeCode = BfTypeCode_Int56;
break;
case 8:
if (mModule->mSystem->mPtrSize == 8)
{
pow2TypeCode = BfTypeCode_Int64;
break;
}
if (typeUsage == BfTypeUsage_Return_Static)
{
pow2TypeCode = BfTypeCode_Int64;
break;
}
break;
}
return BfTypeCode_None;
if (pow2TypeCode != BfTypeCode_None)
{
if (outTypeCode != NULL)
*outTypeCode = pow2TypeCode;
return true;
}
if (mModule->mCompiler->mOptions.mPlatformType != BfPlatformType_Windows)
{
if (typeCode != BfTypeCode_None)
{
if (outTypeCode != NULL)
*outTypeCode = typeCode;
return true;
}
}
return false;
}
bool BfTypeInstance::HasEquivalentLayout(BfTypeInstance* compareTo)

View file

@ -428,6 +428,14 @@ public:
}
};
enum BfTypeUsage
{
BfTypeUsage_Unspecified,
BfTypeUsage_Return_Static,
BfTypeUsage_Return_NonStatic,
BfTypeUsage_Parameter,
};
class BfType
{
public:
@ -539,7 +547,7 @@ public:
virtual bool IsConstExprValue() { return false; }
virtual bool IsDependentOnUnderlyingType() { return false; }
virtual bool WantsGCMarking() { return false; }
virtual BfTypeCode GetLoweredType() { return BfTypeCode_None; }
virtual bool GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCode = NULL, BfTypeCode* outTypeCode2 = NULL) { return false; }
virtual BfType* GetUnderlyingType() { return NULL; }
virtual bool HasWrappedRepresentation() { return IsWrappableType(); }
virtual bool IsTypeMemberIncluded(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef = NULL, BfModule* module = NULL) { return true; } // May be 'false' only for generic extensions with constraints
@ -852,8 +860,9 @@ public:
bool IsSpecializedByAutoCompleteMethod();
bool HasThis();
bool HasParamsArray();
bool HasStructRet();
int GetStructRetIdx();
bool HasSelf();
bool GetLoweredReturnType(BfTypeCode* loweredTypeCode = NULL, BfTypeCode* loweredTypeCode2 = NULL);
bool IsAutocompleteMethod() { /*return mIdHash == -1;*/ return mIsAutocompleteMethod; }
bool IsSkipCall(bool bypassVirtual = false);
bool IsVarArgs();
@ -1827,11 +1836,11 @@ public:
virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef) override;
virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfProject* curProject) override;
virtual bool WantsGCMarking() override;
virtual BfTypeCode GetLoweredType() override;
virtual bool GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCode = NULL, BfTypeCode* outTypeCode2 = NULL) override;
BfGenericTypeInfo* GetGenericTypeInfo() { return mGenericTypeInfo; }
virtual BfTypeInstance* ToGenericTypeInstance() { return (mGenericTypeInfo != NULL) ? this : NULL; }
virtual BfTypeInstance* ToGenericTypeInstance() override { return (mGenericTypeInfo != NULL) ? this : NULL; }
virtual bool IsGenericTypeInstance() override { return mGenericTypeInfo != NULL; }
virtual bool IsSpecializedType() override { return (mGenericTypeInfo != NULL) && (!mGenericTypeInfo->mIsUnspecialized); }
virtual bool IsSpecializedByAutoCompleteMethod() override;
@ -2020,7 +2029,7 @@ public:
virtual bool IsUnspecializedType() override { return mIsUnspecializedType; }
virtual bool IsUnspecializedTypeVariation() override { return mIsUnspecializedTypeVariation; }
virtual BfDelegateInfo* GetDelegateInfo() { return &mDelegateInfo; }
virtual BfDelegateInfo* GetDelegateInfo() override { return &mDelegateInfo; }
};
class BfTupleType : public BfTypeInstance

View file

@ -4885,12 +4885,12 @@ void BfModule::Visit(BfReturnStatement* returnStmt)
BfType* origType;
BfExprEvaluator exprEvaluator(this);
bool alreadyWritten = false;
if (mCurMethodInstance->HasStructRet())
if (mCurMethodInstance->GetStructRetIdx() != -1)
exprEvaluator.mReceivingValue = &mCurMethodState->mRetVal;
if (mCurMethodInstance->mMethodDef->mIsReadOnly)
exprEvaluator.mAllowReadOnlyReference = true;
auto retValue = CreateValueFromExpression(exprEvaluator, returnStmt->mExpression, expectingReturnType, BfEvalExprFlags_AllowRefExpr, &origType);
if (mCurMethodInstance->HasStructRet())
if (mCurMethodInstance->GetStructRetIdx() != -1)
alreadyWritten = exprEvaluator.mReceivingValue == NULL;
MarkScopeLeft(&mCurMethodState->mHeadScope);