mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
Expanded const aggregate compatibility
This commit is contained in:
parent
13b943855e
commit
f665388e91
17 changed files with 452 additions and 134 deletions
|
@ -130,7 +130,8 @@ public:
|
|||
ResolveKind_ResolvingVarType,
|
||||
ResolveKind_UnionInnerType,
|
||||
ResolveKind_LocalVariable,
|
||||
ResolveKind_Attributes
|
||||
ResolveKind_Attributes,
|
||||
ResolveKind_ConstField
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
|
@ -1330,6 +1330,7 @@ BfTypedValue BfMethodMatcher::ResolveArgTypedValue(BfResolvedArg& resolvedArg, B
|
|||
auto prevBlock = mModule->mBfIRBuilder->GetInsertBlock();
|
||||
|
||||
BfExprEvaluator exprEvaluator(mModule);
|
||||
exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_Comptime);
|
||||
exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_AllowIntUnknown | BfEvalExprFlags_NoAutoComplete);
|
||||
if ((resolvedArg.mArgFlags & BfArgFlag_ParamsExpr) != 0)
|
||||
exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_AllowParamsExpr);
|
||||
|
@ -4465,7 +4466,13 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar
|
|||
}
|
||||
|
||||
if (fieldInstance->mConstIdx == -1)
|
||||
{
|
||||
{
|
||||
if ((mBfEvalExprFlags & BfEvalExprFlags_DeclType) != 0)
|
||||
{
|
||||
// We don't need a real value
|
||||
return BfTypedValue(mModule->GetDefaultValue(resolvedFieldType), resolvedFieldType);
|
||||
}
|
||||
|
||||
curCheckType->mModule->ResolveConstField(curCheckType, fieldInstance, field);
|
||||
if (fieldInstance->mConstIdx == -1)
|
||||
return BfTypedValue(mModule->GetDefaultValue(resolvedFieldType), resolvedFieldType);
|
||||
|
@ -5353,7 +5360,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
|||
else
|
||||
{
|
||||
CeEvalFlags evalFlags = CeEvalFlags_None;
|
||||
auto constRet = mModule->mCompiler->mCEMachine->Call(targetSrc, mModule, methodInstance, irArgs, evalFlags, mExpectingType);
|
||||
auto constRet = mModule->mCompiler->mCEMachine->Call(targetSrc, mModule, methodInstance, irArgs, evalFlags, mExpectingType);
|
||||
if (constRet)
|
||||
{
|
||||
BF_ASSERT(!constRet.mType->IsVar());
|
||||
|
@ -5624,7 +5631,9 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
|||
|
||||
if (returnType->IsComposite())
|
||||
mModule->mBfIRBuilder->PopulateType(returnType);
|
||||
|
||||
|
||||
methodInstance->mMethodInstanceGroup->mHasEmittedReference = true;
|
||||
|
||||
BfIRValue callInst;
|
||||
int callIRArgCount = (int)irArgs.size();
|
||||
if (sret != NULL)
|
||||
|
@ -7118,6 +7127,13 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
|||
mModule->CheckStaticAccess(targetTypeInst);
|
||||
}
|
||||
|
||||
if (methodInstance->mReturnType == NULL)
|
||||
{
|
||||
mModule->AssertErrorState();
|
||||
mModule->Fail("Circular reference in method instance", targetSrc);
|
||||
return BfTypedValue();
|
||||
}
|
||||
|
||||
auto func = moduleMethodInstance.mFunc;
|
||||
BfTypedValue callResult = CreateCall(targetSrc, methodInstance, func, bypassVirtual, irArgs);
|
||||
|
||||
|
@ -7237,7 +7253,11 @@ BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBou
|
|||
// There should always be a constructor
|
||||
BF_ASSERT(methodMatcher.mBestMethodDef != NULL);
|
||||
|
||||
auto moduleMethodInstance = mModule->GetMethodInstance(methodMatcher.mBestMethodTypeInstance, methodMatcher.mBestMethodDef, methodMatcher.mBestMethodGenericArguments);
|
||||
auto moduleMethodInstance = mModule->GetMethodInstance(methodMatcher.mBestMethodTypeInstance, methodMatcher.mBestMethodDef, methodMatcher.mBestMethodGenericArguments);
|
||||
if (!mModule->CheckUseMethodInstance(moduleMethodInstance.mMethodInstance, targetSrc))
|
||||
{
|
||||
return BfTypedValue();
|
||||
}
|
||||
|
||||
BfAutoComplete* autoComplete = GetAutoComplete();
|
||||
if (autoComplete != NULL)
|
||||
|
@ -7321,7 +7341,7 @@ BfTypedValue BfExprEvaluator::ResolveArgValue(BfResolvedArg& resolvedArg, BfType
|
|||
{
|
||||
BfExprEvaluator exprEvaluator(mModule);
|
||||
exprEvaluator.mReceivingValue = receivingValue;
|
||||
BfEvalExprFlags flags = (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_NoAutoComplete) | BfEvalExprFlags_NoCast);
|
||||
BfEvalExprFlags flags = (BfEvalExprFlags)((mBfEvalExprFlags & (BfEvalExprFlags_NoAutoComplete | BfEvalExprFlags_Comptime)) | BfEvalExprFlags_NoCast);
|
||||
if ((paramKind == BfParamKind_Params) || (paramKind == BfParamKind_DelegateParam))
|
||||
flags = (BfEvalExprFlags)(flags | BfEvalExprFlags_AllowParamsExpr);
|
||||
|
||||
|
@ -8556,7 +8576,9 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
|||
prevBindResult.mPrevVal->mCheckedMultipleMethods = true;
|
||||
|
||||
BfModuleMethodInstance moduleMethodInstance = GetSelectedMethod(targetSrc, curTypeInst, methodDef, methodMatcher);
|
||||
|
||||
if (!mModule->CheckUseMethodInstance(moduleMethodInstance.mMethodInstance, targetSrc))
|
||||
return BfTypedValue();
|
||||
|
||||
if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized))
|
||||
{
|
||||
if (methodMatcher.mHasVarArguments)
|
||||
|
@ -14851,6 +14873,10 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
|
|||
mModule->Fail("Failed to get selected mixin", targetSrc);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mModule->CheckUseMethodInstance(moduleMethodInstance.mMethodInstance, targetSrc))
|
||||
return;
|
||||
|
||||
auto methodInstance = moduleMethodInstance.mMethodInstance;
|
||||
PerformCallChecks(methodInstance, targetSrc);
|
||||
|
||||
|
@ -17959,6 +17985,8 @@ void BfExprEvaluator::InitializedSizedArray(BfSizedArrayType* arrayType, BfToken
|
|||
|
||||
if (expr != NULL)
|
||||
{
|
||||
auto evalFlags = (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_Comptime);
|
||||
|
||||
bool tryDefer = false;
|
||||
if ((checkArrayType->IsComposite()) &&
|
||||
((expr->IsA<BfInvocationExpression>()) || (expr->IsExact<BfTupleExpression>())))
|
||||
|
@ -17966,12 +17994,12 @@ void BfExprEvaluator::InitializedSizedArray(BfSizedArrayType* arrayType, BfToken
|
|||
// We evaluate with a new scope because this expression may create variables that we don't want to be visible to other
|
||||
// non-deferred evaluations (since the value may actually be a FakeVal)
|
||||
SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
|
||||
elementValue = mModule->CreateValueFromExpression(expr, checkArrayType->mElementType, BfEvalExprFlags_CreateConditionalScope);
|
||||
elementValue = mModule->CreateValueFromExpression(expr, checkArrayType->mElementType, (BfEvalExprFlags)(evalFlags | BfEvalExprFlags_CreateConditionalScope));
|
||||
deferredValue = !prevIgnoreWrites.mPrevVal && elementValue.mValue.IsFake();
|
||||
}
|
||||
else
|
||||
{
|
||||
elementValue = mModule->CreateValueFromExpression(expr, checkArrayType->mElementType);
|
||||
elementValue = mModule->CreateValueFromExpression(expr, checkArrayType->mElementType, evalFlags);
|
||||
}
|
||||
|
||||
if (!elementValue)
|
||||
|
@ -17981,8 +18009,8 @@ void BfExprEvaluator::InitializedSizedArray(BfSizedArrayType* arrayType, BfToken
|
|||
elementValue = mModule->GetDefaultTypedValue(checkArrayType->mElementType);
|
||||
|
||||
// For now, we can't properly create const-valued non-size-aligned composites
|
||||
if (checkArrayType->mElementType->NeedsExplicitAlignment())
|
||||
isAllConst = false;
|
||||
// if (checkArrayType->mElementType->NeedsExplicitAlignment())
|
||||
// isAllConst = false;
|
||||
if (!elementValue.mValue.IsConst())
|
||||
isAllConst = false;
|
||||
if (elementValue.IsAddr())
|
||||
|
@ -18173,14 +18201,8 @@ void BfExprEvaluator::InitializedSizedArray(BfSizedArrayType* arrayType, BfToken
|
|||
auto allocArrayType = checkArrayType;
|
||||
if (checkArrayType->IsUndefSizedArray())
|
||||
allocArrayType = mModule->CreateSizedArrayType(checkArrayType->GetUnderlyingType(), (int)members.size());
|
||||
|
||||
if (checkArrayType->mElementType->IsStruct())
|
||||
{
|
||||
// This fixed cases where we have non-size-aligned initializers. Assume zero-initialized
|
||||
return mModule->mBfIRBuilder->CreateConstStructZero(mModule->mBfIRBuilder->MapType(checkArrayType));
|
||||
}
|
||||
else
|
||||
return mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(checkArrayType), members);
|
||||
|
||||
return mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(checkArrayType), members);
|
||||
};
|
||||
|
||||
_GetValues(arrayType, openToken, valueExprs, commas, closeToken, false);
|
||||
|
@ -18390,6 +18412,12 @@ void BfExprEvaluator::Visit(BfTupleExpression* tupleExpr)
|
|||
continue;
|
||||
irValues[fieldInstance->mDataIdx] = typedValues[fieldIdx].mValue;
|
||||
}
|
||||
|
||||
for (auto& val : irValues)
|
||||
{
|
||||
if (!val)
|
||||
val = mModule->mBfIRBuilder->CreateConstArrayZero(0);
|
||||
}
|
||||
|
||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(tupleType), irValues), tupleType);
|
||||
return;
|
||||
|
|
|
@ -666,6 +666,10 @@ BfIRValue BfIRConstHolder::CreateConst(BfConstant* fromConst, BfIRConstHolder* f
|
|||
return GetUndefConstValue(BfIRValue());
|
||||
return GetUndefConstValue(constUndef->mType);
|
||||
}
|
||||
else if (fromConst->mConstType == BfConstType_ArrayZero8)
|
||||
{
|
||||
return CreateConstArrayZero(fromConst->mInt32);
|
||||
}
|
||||
else if ((IsInt(fromConst->mTypeCode)) || (fromConst->mTypeCode == BfTypeCode_Boolean) || (fromConst->mTypeCode == BfTypeCode_StringId))
|
||||
{
|
||||
return CreateConst(fromConst->mTypeCode, fromConst->mUInt64);
|
||||
|
@ -1287,6 +1291,10 @@ String BfIRBuilder::ToString(BfIRValue irValue)
|
|||
{
|
||||
return StrFormat("Constant %lld", constant->mInt64);
|
||||
}
|
||||
else if (constant->mTypeCode == BfTypeCode_StringId)
|
||||
{
|
||||
return StrFormat("StringId %d", constant->mInt64);
|
||||
}
|
||||
else if (constant->mConstType == BfConstType_GlobalVar)
|
||||
{
|
||||
if (mBfIRCodeGen != NULL)
|
||||
|
@ -1299,8 +1307,17 @@ String BfIRBuilder::ToString(BfIRValue irValue)
|
|||
strStream.flush();
|
||||
return outStr;
|
||||
}
|
||||
else if (mBeIRCodeGen != NULL)
|
||||
{
|
||||
auto gvConst = (BfGlobalVar*)constant;
|
||||
auto val = mBeIRCodeGen->GetBeValue(gvConst->mStreamId);
|
||||
String outStr;
|
||||
BeDumpContext dumpCtx;
|
||||
dumpCtx.ToString(outStr, val);
|
||||
return outStr;
|
||||
}
|
||||
else
|
||||
return "???";
|
||||
return "GlobalVar???";
|
||||
}
|
||||
else if (constant->mConstType == BfConstType_BitCast)
|
||||
{
|
||||
|
@ -1344,7 +1361,7 @@ String BfIRBuilder::ToString(BfIRValue irValue)
|
|||
str += ", ";
|
||||
str += ToString(constAgg->mValues[i]);
|
||||
}
|
||||
str += ");";
|
||||
str += ")";
|
||||
return str;
|
||||
}
|
||||
else if (constant->mConstType == BfConstType_AggZero)
|
||||
|
@ -1390,7 +1407,7 @@ String BfIRBuilder::ToString(BfIRValue irValue)
|
|||
return str;
|
||||
}
|
||||
else
|
||||
return "???";
|
||||
return "Value???";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2369,7 +2386,7 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine)
|
|||
}
|
||||
|
||||
irType = CreateStructType(name);
|
||||
StructSetBody(irType, members, false);
|
||||
StructSetBody(irType, members, type->mSize, type->mAlign, false);
|
||||
}
|
||||
else if (type->IsSizedArray())
|
||||
{
|
||||
|
@ -2390,10 +2407,12 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine)
|
|||
|
||||
if (arrayType->mElementType->IsValuelessType())
|
||||
irType = elementIrType;
|
||||
else if (arrayType->mElementType->IsSizeAligned())
|
||||
irType = GetSizedArrayType(MapType(arrayType->mElementType), BF_MAX(arrayType->mElementCount, 0));
|
||||
else
|
||||
irType = GetSizedArrayType(MapType(mModule->GetPrimitiveType(BfTypeCode_Int8)), BF_MAX(arrayType->mSize, 0));
|
||||
irType = GetSizedArrayType(MapType(arrayType->mElementType), BF_MAX(arrayType->mElementCount, 0));
|
||||
// else if (arrayType->mElementType->IsSizeAligned())
|
||||
// irType = GetSizedArrayType(MapType(arrayType->mElementType), BF_MAX(arrayType->mElementCount, 0));
|
||||
// else
|
||||
// irType = GetSizedArrayType(MapType(mModule->GetPrimitiveType(BfTypeCode_Int8)), BF_MAX(arrayType->mSize, 0));
|
||||
|
||||
if (wantDIData)
|
||||
diType = DbgCreateArrayType((int64)arrayType->mSize * 8, arrayType->mAlign * 8, DbgGetType(arrayType->mElementType), arrayType->mElementCount);
|
||||
|
@ -2734,10 +2753,18 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
|
|||
|
||||
if (fieldInstance->mConstIdx != -1)
|
||||
{
|
||||
if (fieldInstance->GetFieldDef()->mName == "mMembers")
|
||||
{
|
||||
NOP;
|
||||
}
|
||||
|
||||
constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
|
||||
staticValue = mModule->ConstantToCurrent(constant, typeInstance->mConstHolder, resolvedFieldType);
|
||||
}
|
||||
|
||||
if (fieldInstance->mResolvedType->IsComposite())
|
||||
PopulateType(fieldInstance->mResolvedType);
|
||||
|
||||
BfIRMDNode constDIType;
|
||||
if (resolvedFieldType->IsTypedPrimitive())
|
||||
constDIType = DbgGetType(resolvedFieldType->GetUnderlyingType());//resolvedFieldType->GetUnderlyingType()->mDIType ;
|
||||
|
@ -2806,7 +2833,8 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
|
|||
}
|
||||
else
|
||||
{
|
||||
mModule->FatalError(StrFormat("Invalid constant type for %s", staticVarName.c_str()));
|
||||
// Ignore other types (for now)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2835,8 +2863,9 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
|
|||
{
|
||||
int flags = 0;
|
||||
String fieldName = fieldDef->mName;
|
||||
if (constant != NULL)
|
||||
{
|
||||
if ((constant != NULL) &&
|
||||
((IsInt(constant->mTypeCode)) || (IsFloat(constant->mTypeCode))))
|
||||
{
|
||||
int64 writeVal = constant->mInt64;
|
||||
if (constant->mTypeCode == BfTypeCode_Float)
|
||||
{
|
||||
|
@ -3308,7 +3337,7 @@ void BfIRBuilder::CreateTypeDefinition_Data(BfModule* populateModule, BfTypeInst
|
|||
}
|
||||
|
||||
if (!typeInstance->IsTypedPrimitive())
|
||||
StructSetBody(MapTypeInst(typeInstance), irFieldTypes, /*isPacked || !isCRepr*/true);
|
||||
StructSetBody(MapTypeInst(typeInstance), irFieldTypes, typeInstance->mInstSize, typeInstance->mInstAlign, true);
|
||||
|
||||
if (typeInstance->IsNullable())
|
||||
{
|
||||
|
@ -3568,9 +3597,9 @@ BfIRType BfIRBuilder::CreateStructType(const BfSizedArray<BfIRType>& memberTypes
|
|||
return retType;
|
||||
}
|
||||
|
||||
void BfIRBuilder::StructSetBody(BfIRType type, const BfSizedArray<BfIRType>& memberTypes, bool isPacked)
|
||||
void BfIRBuilder::StructSetBody(BfIRType type, const BfSizedArray<BfIRType>& memberTypes, int size, int align, bool isPacked)
|
||||
{
|
||||
WriteCmd(BfIRCmd_StructSetBody, type, memberTypes, isPacked);
|
||||
WriteCmd(BfIRCmd_StructSetBody, type, memberTypes, size, align, isPacked);
|
||||
NEW_CMD_INSERTED;
|
||||
}
|
||||
|
||||
|
|
|
@ -588,7 +588,7 @@ struct BfIRTypeData
|
|||
TypeKind_TypeId,
|
||||
TypeKind_TypeCode,
|
||||
TypeKind_TypeInstId,
|
||||
TypeKind_TypeInstPtrId,
|
||||
TypeKind_TypeInstPtrId,
|
||||
TypeKind_Stream,
|
||||
TypeKind_SizedArray
|
||||
};
|
||||
|
@ -1141,7 +1141,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);
|
||||
void StructSetBody(BfIRType type, const BfSizedArray<BfIRType>& memberTypes, int size, int align, bool isPacked);
|
||||
BfIRType MapType(BfType* type, BfIRPopulateType populateType = BfIRPopulateType_Declaration);
|
||||
BfIRType MapTypeInst(BfTypeInstance* typeInst, BfIRPopulateType populateType = BfIRPopulateType_Declaration);
|
||||
BfIRType MapTypeInstPtr(BfTypeInstance* typeInst);
|
||||
|
|
|
@ -712,7 +712,7 @@ void BfIRCodeGen::Read(BfIRTypeEntry*& type)
|
|||
type = &GetTypeEntry(typeId);
|
||||
}
|
||||
|
||||
void BfIRCodeGen::Read(llvm::Type*& llvmType)
|
||||
void BfIRCodeGen::Read(llvm::Type*& llvmType, BfIRTypeEntry** outTypeEntry)
|
||||
{
|
||||
BfIRType::TypeKind typeKind = (BfIRType::TypeKind)mStream->Read();
|
||||
if (typeKind == BfIRType::TypeKind::TypeKind_None)
|
||||
|
@ -759,6 +759,8 @@ void BfIRCodeGen::Read(llvm::Type*& llvmType)
|
|||
llvmType = typeEntry.mInstLLVMType;
|
||||
else if (typeKind == BfIRType::TypeKind::TypeKind_TypeInstPtrId)
|
||||
llvmType = typeEntry.mInstLLVMType->getPointerTo();
|
||||
if (outTypeEntry != NULL)
|
||||
*outTypeEntry = &typeEntry;
|
||||
}
|
||||
|
||||
void BfIRCodeGen::Read(llvm::FunctionType*& llvmType)
|
||||
|
@ -769,7 +771,7 @@ void BfIRCodeGen::Read(llvm::FunctionType*& llvmType)
|
|||
llvmType = (llvm::FunctionType*)result.mLLVMType;
|
||||
}
|
||||
|
||||
void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry)
|
||||
void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry, bool wantSizeAligned)
|
||||
{
|
||||
BfIRParamType paramType = (BfIRParamType)mStream->Read();
|
||||
if (paramType == BfIRParamType_None)
|
||||
|
@ -903,10 +905,20 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry)
|
|||
llvmValue = llvm::ConstantAggregateZero::get(type);
|
||||
return;
|
||||
}
|
||||
else if (constType == BfConstType_ArrayZero8)
|
||||
{
|
||||
CMD_PARAM(int, count);
|
||||
auto arrType = llvm::ArrayType::get(llvm::Type::getInt8Ty(*mLLVMContext), count);
|
||||
llvmValue = llvm::ConstantAggregateZero::get(arrType);
|
||||
return;
|
||||
}
|
||||
else if (constType == BfConstType_Agg)
|
||||
{
|
||||
CMD_PARAM(llvm::Type*, type);
|
||||
CMD_PARAM(CmdParamVec<llvm::Constant*>, values);
|
||||
BfIRTypeEntry* typeEntry = NULL;
|
||||
llvm::Type* type = NULL;
|
||||
Read(type, &typeEntry);
|
||||
CmdParamVec<llvm::Constant*> values;
|
||||
Read(values, type->isArrayTy());
|
||||
|
||||
if (auto arrayType = llvm::dyn_cast<llvm::ArrayType>(type))
|
||||
{
|
||||
|
@ -921,7 +933,31 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry)
|
|||
}
|
||||
else if (auto structType = llvm::dyn_cast<llvm::StructType>(type))
|
||||
{
|
||||
llvmValue = llvm::ConstantStruct::get(structType, values);
|
||||
for (int i = 0; i < (int)values.size(); i++)
|
||||
{
|
||||
if (values[i]->getType() != structType->getElementType(i))
|
||||
{
|
||||
auto valArrayType = llvm::dyn_cast<llvm::ArrayType>(values[i]->getType());
|
||||
auto structArrayType = llvm::dyn_cast<llvm::ArrayType>(structType->getElementType(i));
|
||||
if ((valArrayType != NULL) && (structArrayType != NULL))
|
||||
{
|
||||
if ((valArrayType->getNumElements() == 0) && (valArrayType->getElementType() == structArrayType->getElementType()))
|
||||
{
|
||||
values[i] = llvm::ConstantAggregateZero::get(structArrayType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((wantSizeAligned) && (typeEntry != NULL))
|
||||
{
|
||||
auto alignedType = llvm::dyn_cast<llvm::StructType>(GetSizeAlignedType(typeEntry));
|
||||
if (type != alignedType)
|
||||
values.push_back(llvm::ConstantAggregateZero::get(alignedType->getElementType(alignedType->getNumElements() - 1)));
|
||||
llvmValue = llvm::ConstantStruct::get(alignedType, values);
|
||||
}
|
||||
else
|
||||
llvmValue = llvm::ConstantStruct::get(structType, values);
|
||||
}
|
||||
else if (auto vecType = llvm::dyn_cast<llvm::VectorType>(type))
|
||||
{
|
||||
|
@ -1046,10 +1082,10 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry)
|
|||
}
|
||||
}
|
||||
|
||||
void BfIRCodeGen::Read(llvm::Constant*& llvmConstant)
|
||||
void BfIRCodeGen::Read(llvm::Constant*& llvmConstant, bool wantSizeAligned)
|
||||
{
|
||||
llvm::Value* value;
|
||||
Read(value);
|
||||
Read(value, NULL, wantSizeAligned);
|
||||
if (value == NULL)
|
||||
{
|
||||
llvmConstant = NULL;
|
||||
|
@ -1312,6 +1348,54 @@ bool BfIRCodeGen::TryVectorCpy(llvm::Value* ptr, llvm::Value* val)
|
|||
return true;
|
||||
}
|
||||
|
||||
llvm::Type* BfIRCodeGen::GetSizeAlignedType(BfIRTypeEntry* typeEntry)
|
||||
{
|
||||
if ((typeEntry->mAlignLLVMType == NULL) && ((typeEntry->mSize & (typeEntry->mAlign - 1)) != 0))
|
||||
{
|
||||
auto structType = llvm::dyn_cast<llvm::StructType>(typeEntry->mLLVMType);
|
||||
if (structType != NULL)
|
||||
{
|
||||
BF_ASSERT(structType->isPacked());
|
||||
|
||||
auto alignType = llvm::StructType::create(*mLLVMContext, (structType->getName().str() + "_ALIGNED").c_str());
|
||||
llvm::SmallVector<llvm::Type*, 8> members;
|
||||
for (int elemIdx = 0; elemIdx < (int)structType->getNumElements(); elemIdx++)
|
||||
{
|
||||
members.push_back(structType->getElementType(elemIdx));
|
||||
}
|
||||
int alignSize = BF_ALIGN(typeEntry->mSize, typeEntry->mAlign);
|
||||
int fillSize = alignSize - typeEntry->mSize;
|
||||
members.push_back(llvm::ArrayType::get(llvm::Type::getInt8Ty(*mLLVMContext), fillSize));
|
||||
alignType->setBody(members, structType->isPacked());
|
||||
|
||||
typeEntry->mAlignLLVMType = alignType;
|
||||
mAlignedTypeToNormalType[alignType] = structType;
|
||||
}
|
||||
}
|
||||
|
||||
if (typeEntry->mAlignLLVMType != NULL)
|
||||
return typeEntry->mAlignLLVMType;
|
||||
|
||||
return typeEntry->mLLVMType;
|
||||
}
|
||||
|
||||
llvm::Value* BfIRCodeGen::FixGEP(llvm::Value* fromValue, llvm::Value* result)
|
||||
{
|
||||
if (auto ptrType = llvm::dyn_cast<llvm::PointerType>(fromValue->getType()))
|
||||
{
|
||||
if (auto arrayType = llvm::dyn_cast<llvm::ArrayType>(ptrType->getElementType()))
|
||||
{
|
||||
llvm::Type* normalType = NULL;
|
||||
if (mAlignedTypeToNormalType.TryGetValue(arrayType->getElementType(), &normalType))
|
||||
{
|
||||
return mIRBuilder->CreateBitCast(result, normalType->getPointerTo());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void BfIRCodeGen::CreateMemSet(llvm::Value* addr, llvm::Value* val, llvm::Value* size, int alignment, bool isVolatile)
|
||||
{
|
||||
auto sizeConst = llvm::dyn_cast<llvm::ConstantInt>(size);
|
||||
|
@ -1604,15 +1688,26 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
SetResult(curId, llvm::StructType::create(*mLLVMContext, typeName.c_str()));
|
||||
}
|
||||
break;
|
||||
case BfIRCmd_StructSetBody:
|
||||
case BfIRCmd_StructSetBody:
|
||||
{
|
||||
CMD_PARAM(llvm::Type*, type);
|
||||
llvm::Type* type = NULL;
|
||||
BfIRTypeEntry* typeEntry = NULL;
|
||||
|
||||
Read(type, &typeEntry);
|
||||
CMD_PARAM(CmdParamVec<llvm::Type*>, members);
|
||||
CMD_PARAM(int, instSize);
|
||||
CMD_PARAM(int, instAlign);
|
||||
CMD_PARAM(bool, isPacked);
|
||||
|
||||
BF_ASSERT(llvm::isa<llvm::StructType>(type));
|
||||
auto structType = (llvm::StructType*)type;
|
||||
if (structType->isOpaque())
|
||||
structType->setBody(members, isPacked);
|
||||
if (typeEntry != NULL)
|
||||
{
|
||||
typeEntry->mSize = instSize;
|
||||
typeEntry->mAlign = instAlign;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BfIRCmd_Type:
|
||||
|
@ -1655,9 +1750,15 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
break;
|
||||
case BfIRCmd_GetSizedArrayType:
|
||||
{
|
||||
CMD_PARAM(llvm::Type*, elementType);
|
||||
llvm::Type* elementType = NULL;
|
||||
BfIRTypeEntry* elementTypeEntry = NULL;
|
||||
|
||||
Read(elementType, &elementTypeEntry);
|
||||
CMD_PARAM(int, length);
|
||||
SetResult(curId, llvm::ArrayType::get(elementType, length));
|
||||
if (elementTypeEntry != NULL)
|
||||
SetResult(curId, llvm::ArrayType::get(GetSizeAlignedType(elementTypeEntry), length));
|
||||
else
|
||||
SetResult(curId, llvm::ArrayType::get(elementType, length));
|
||||
}
|
||||
break;
|
||||
case BfIRCmd_GetVectorType:
|
||||
|
@ -2056,7 +2157,7 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
CMD_PARAM(llvm::Value*, val);
|
||||
CMD_PARAM(int, idx0);
|
||||
CMD_PARAM(int, idx1);
|
||||
SetResult(curId, mIRBuilder->CreateConstInBoundsGEP2_32(NULL, val, idx0, idx1));
|
||||
SetResult(curId, FixGEP(val, mIRBuilder->CreateConstInBoundsGEP2_32(NULL, val, idx0, idx1)));
|
||||
}
|
||||
break;
|
||||
case BfIRCmd_InBoundsGEP1:
|
||||
|
@ -2072,7 +2173,7 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
CMD_PARAM(llvm::Value*, idx0);
|
||||
CMD_PARAM(llvm::Value*, idx1);
|
||||
llvm::Value* indices[2] = { idx0, idx1 };
|
||||
SetResult(curId, mIRBuilder->CreateInBoundsGEP(val, llvm::makeArrayRef(indices)));
|
||||
SetResult(curId, FixGEP(val, mIRBuilder->CreateInBoundsGEP(val, llvm::makeArrayRef(indices))));
|
||||
}
|
||||
break;
|
||||
case BfIRCmd_IsNull:
|
||||
|
|
|
@ -60,18 +60,24 @@ class BfIRTypeEntry
|
|||
{
|
||||
public:
|
||||
int mTypeId;
|
||||
int mSize;
|
||||
int mAlign;
|
||||
llvm::DIType* mDIType;
|
||||
llvm::DIType* mInstDIType;
|
||||
llvm::Type* mLLVMType;
|
||||
llvm::Type* mAlignLLVMType;
|
||||
llvm::Type* mInstLLVMType;
|
||||
|
||||
public:
|
||||
BfIRTypeEntry()
|
||||
{
|
||||
mTypeId = -1;
|
||||
mSize = -1;
|
||||
mAlign = -1;
|
||||
mDIType = NULL;
|
||||
mInstDIType = NULL;
|
||||
mLLVMType = NULL;
|
||||
mAlignLLVMType = NULL;
|
||||
mInstLLVMType = NULL;
|
||||
}
|
||||
};
|
||||
|
@ -109,6 +115,7 @@ public:
|
|||
Array<llvm::Constant*> mConfigConsts32;
|
||||
Array<llvm::Constant*> mConfigConsts64;
|
||||
Dictionary<llvm::Type*, llvm::Value*> mReflectDataMap;
|
||||
Dictionary<llvm::Type*, llvm::Type*> mAlignedTypeToNormalType;
|
||||
|
||||
public:
|
||||
void InitTarget();
|
||||
|
@ -127,6 +134,8 @@ public:
|
|||
llvm::Type* GetElemType(llvm::Value* value);
|
||||
bool TryMemCpy(llvm::Value* ptr, llvm::Value* val);
|
||||
bool TryVectorCpy(llvm::Value* ptr, llvm::Value* val);
|
||||
llvm::Type* GetSizeAlignedType(BfIRTypeEntry* typeEntry);
|
||||
llvm::Value* FixGEP(llvm::Value* fromValue, llvm::Value* result);
|
||||
|
||||
public:
|
||||
BfIRCodeGen();
|
||||
|
@ -146,10 +155,10 @@ public:
|
|||
void Read(Val128& i);
|
||||
void Read(bool& val);
|
||||
void Read(BfIRTypeEntry*& type);
|
||||
void Read(llvm::Type*& llvmType);
|
||||
void Read(llvm::Type*& llvmType, BfIRTypeEntry** outTypeEntry = NULL);
|
||||
void Read(llvm::FunctionType*& llvmType);
|
||||
void Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry = NULL);
|
||||
void Read(llvm::Constant*& llvmConstant);
|
||||
void Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry = NULL, bool wantSizeAligned = false);
|
||||
void Read(llvm::Constant*& llvmConstant, bool wantSizeAligned = false);
|
||||
void Read(llvm::Function*& llvmFunc);
|
||||
void Read(llvm::BasicBlock*& llvmBlock);
|
||||
void Read(llvm::MDNode*& llvmMD);
|
||||
|
@ -167,6 +176,28 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void Read(llvm::SmallVectorImpl<llvm::Value*>& vec, bool wantSizeAligned = false)
|
||||
{
|
||||
int len = (int)ReadSLEB128();
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
llvm::Value* result;
|
||||
Read(result, NULL, wantSizeAligned);
|
||||
vec.push_back(result);
|
||||
}
|
||||
}
|
||||
|
||||
void Read(llvm::SmallVectorImpl<llvm::Constant*>& vec, bool wantSizeAligned = false)
|
||||
{
|
||||
int len = (int)ReadSLEB128();
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
llvm::Constant* result;
|
||||
Read(result, wantSizeAligned);
|
||||
vec.push_back(result);
|
||||
}
|
||||
}
|
||||
|
||||
void HandleNextCmd() override;
|
||||
void SetCodeGenOptions(BfCodeGenOptions codeGenOptions);
|
||||
void SetConfigConst(int idx, int value) override;
|
||||
|
|
|
@ -4203,12 +4203,12 @@ BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance,
|
|||
if (mCompiler->mCEMachine != NULL)
|
||||
ceExecuteId = mCompiler->mCEMachine->mExecuteId;
|
||||
|
||||
BfTypeState typeState;
|
||||
BfTypeState typeState;
|
||||
typeState.mTypeInstance = mCurTypeInstance;
|
||||
typeState.mCurTypeDef = fieldDef->mDeclaringType;
|
||||
typeState.mCurFieldDef = fieldDef;
|
||||
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
|
||||
|
||||
|
||||
BfConstResolver constResolver(this);
|
||||
if (fieldType->IsVar())
|
||||
return constResolver.Resolve(initializer);
|
||||
|
@ -4224,7 +4224,7 @@ BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance,
|
|||
}
|
||||
UpdateSrcPos(initializer);
|
||||
auto result = constResolver.Resolve(initializer, fieldType, resolveFlags);
|
||||
if (mCompiler->mCEMachine != NULL)
|
||||
if ((mCompiler->mCEMachine != NULL) && (fieldInstance != NULL))
|
||||
{
|
||||
if (mCompiler->mCEMachine->mExecuteId != ceExecuteId)
|
||||
fieldInstance->mHadConstEval = true;
|
||||
|
@ -4588,19 +4588,21 @@ void BfModule::CreateValueTypeEqualsMethod(bool strictEquals)
|
|||
auto _SizedIndex = [&](BfIRValue target, BfIRValue index)
|
||||
{
|
||||
BfTypedValue result;
|
||||
if (sizedArrayType->mElementType->IsSizeAligned())
|
||||
{
|
||||
auto ptrType = CreatePointerType(sizedArrayType->mElementType);
|
||||
auto ptrValue = mBfIRBuilder->CreateBitCast(target, mBfIRBuilder->MapType(ptrType));
|
||||
auto gepResult = mBfIRBuilder->CreateInBoundsGEP(ptrValue, index);
|
||||
result = BfTypedValue(gepResult, sizedArrayType->mElementType, BfTypedValueKind_Addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if (sizedArrayType->mElementType->IsSizeAligned())
|
||||
// {
|
||||
// auto ptrType = CreatePointerType(sizedArrayType->mElementType);
|
||||
// auto ptrValue = mBfIRBuilder->CreateBitCast(target, mBfIRBuilder->MapType(ptrType));
|
||||
// auto gepResult = mBfIRBuilder->CreateInBoundsGEP(ptrValue, index);
|
||||
// result = BfTypedValue(gepResult, sizedArrayType->mElementType, BfTypedValueKind_Addr);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// auto indexResult = CreateIndexedValue(sizedArrayType->mElementType, target, index);
|
||||
// result = BfTypedValue(indexResult, sizedArrayType->mElementType, BfTypedValueKind_Addr);
|
||||
// }
|
||||
|
||||
auto indexResult = CreateIndexedValue(sizedArrayType->mElementType, target, index);
|
||||
result = BfTypedValue(indexResult, sizedArrayType->mElementType, BfTypedValueKind_Addr);
|
||||
}
|
||||
auto indexResult = CreateIndexedValue(sizedArrayType->mElementType, target, index, true);
|
||||
result = BfTypedValue(indexResult, sizedArrayType->mElementType, BfTypedValueKind_Addr);
|
||||
|
||||
if (!result.mType->IsValueType())
|
||||
result = LoadValue(result);
|
||||
|
@ -10732,6 +10734,12 @@ BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* con
|
|||
newVals[fieldInstance.mDataIdx] = memberVal;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& val : newVals)
|
||||
{
|
||||
if (!val)
|
||||
val = mBfIRBuilder->CreateConstArrayZero(0);
|
||||
}
|
||||
}
|
||||
|
||||
return mBfIRBuilder->CreateConstAgg(mBfIRBuilder->MapType(wantType, BfIRPopulateType_Identity), newVals);
|
||||
|
@ -12034,21 +12042,26 @@ BfIRValue BfModule::ExtractValue(BfTypedValue typedValue, int dataIdx)
|
|||
|
||||
BfIRValue BfModule::CreateIndexedValue(BfType* elementType, BfIRValue value, BfIRValue indexValue, bool isElementIndex)
|
||||
{
|
||||
if (elementType->IsSizeAligned())
|
||||
{
|
||||
if (isElementIndex)
|
||||
return mBfIRBuilder->CreateInBoundsGEP(value, GetConstValue(0), indexValue);
|
||||
else
|
||||
return mBfIRBuilder->CreateInBoundsGEP(value, indexValue);
|
||||
}
|
||||
|
||||
auto ptrType = CreatePointerType(elementType);
|
||||
auto ofsVal = mBfIRBuilder->CreateNumericCast(indexValue, true, BfTypeCode_IntPtr);
|
||||
auto ofsScaledVal = mBfIRBuilder->CreateMul(ofsVal, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, elementType->GetStride()));
|
||||
auto i8PtrType = mBfIRBuilder->GetPointerTo(mBfIRBuilder->GetPrimitiveType(BfTypeCode_Int8));
|
||||
BfIRValue origPtrValue = mBfIRBuilder->CreateBitCast(value, i8PtrType);
|
||||
BfIRValue newPtrValue = mBfIRBuilder->CreateInBoundsGEP(origPtrValue, ofsScaledVal);
|
||||
return mBfIRBuilder->CreateBitCast(newPtrValue, mBfIRBuilder->MapType(ptrType));
|
||||
if (isElementIndex)
|
||||
return mBfIRBuilder->CreateInBoundsGEP(value, GetConstValue(0), indexValue);
|
||||
else
|
||||
return mBfIRBuilder->CreateInBoundsGEP(value, indexValue);
|
||||
|
||||
// if (elementType->IsSizeAligned())
|
||||
// {
|
||||
// if (isElementIndex)
|
||||
// return mBfIRBuilder->CreateInBoundsGEP(value, GetConstValue(0), indexValue);
|
||||
// else
|
||||
// return mBfIRBuilder->CreateInBoundsGEP(value, indexValue);
|
||||
// }
|
||||
//
|
||||
// auto ptrType = CreatePointerType(elementType);
|
||||
// auto ofsVal = mBfIRBuilder->CreateNumericCast(indexValue, true, BfTypeCode_IntPtr);
|
||||
// auto ofsScaledVal = mBfIRBuilder->CreateMul(ofsVal, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, elementType->GetStride()));
|
||||
// auto i8PtrType = mBfIRBuilder->GetPointerTo(mBfIRBuilder->GetPrimitiveType(BfTypeCode_Int8));
|
||||
// BfIRValue origPtrValue = mBfIRBuilder->CreateBitCast(value, i8PtrType);
|
||||
// BfIRValue newPtrValue = mBfIRBuilder->CreateInBoundsGEP(origPtrValue, ofsScaledVal);
|
||||
// return mBfIRBuilder->CreateBitCast(newPtrValue, mBfIRBuilder->MapType(ptrType));
|
||||
}
|
||||
|
||||
BfIRValue BfModule::CreateIndexedValue(BfType* elementType, BfIRValue value, int indexValue, bool isElementIndex)
|
||||
|
@ -13345,6 +13358,14 @@ void BfModule::SetupMethodIdHash(BfMethodInstance* methodInstance)
|
|||
methodInstance->mIdHash = (int64)hashCtx.Finish64();
|
||||
}
|
||||
|
||||
bool BfModule::CheckUseMethodInstance(BfMethodInstance* methodInstance, BfAstNode* refNode)
|
||||
{
|
||||
if (methodInstance->mHasBeenDeclared)
|
||||
return true;
|
||||
Fail(StrFormat("Circular reference in method instance '%s'", MethodToString(methodInstance).c_str()), refNode);
|
||||
return false;
|
||||
}
|
||||
|
||||
BfIRValue BfModule::GetInterfaceSlotNum(BfTypeInstance* ifaceType)
|
||||
{
|
||||
BfIRValue globalValue;
|
||||
|
@ -21220,6 +21241,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
|||
if (mCurMethodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NoDecl_AwaitingReference)
|
||||
mCurMethodInstance->mMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingReference;
|
||||
|
||||
defer({ mCurMethodInstance->mHasBeenDeclared = true; });
|
||||
|
||||
// If we are doing this then we may end up creating methods when var types are unknown still, failing on splat/zero-sized info
|
||||
BF_ASSERT((!mCurTypeInstance->mResolvingVarField) || (mBfIRBuilder->mIgnoreWrites));
|
||||
|
@ -21246,7 +21268,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
|||
StackOverflow();
|
||||
|
||||
if (typeInstance->IsClosure())
|
||||
{
|
||||
{
|
||||
if (methodDef->mName == "Invoke")
|
||||
return;
|
||||
}
|
||||
|
@ -22511,7 +22533,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
|||
}
|
||||
|
||||
mCompiler->mStats.mMethodDeclarations++;
|
||||
mCompiler->UpdateCompletion();
|
||||
mCompiler->UpdateCompletion();
|
||||
}
|
||||
|
||||
void BfModule::UniqueSlotVirtualMethod(BfMethodInstance* methodInstance)
|
||||
|
@ -23430,7 +23452,8 @@ void BfModule::DbgFinish()
|
|||
{
|
||||
if ((methodInstGroup.IsImplemented()) && (methodInstGroup.mDefault != NULL) &&
|
||||
(!methodInstGroup.mDefault->mMethodDef->mIsStatic) && (methodInstGroup.mDefault->mIsReified) && (!methodInstGroup.mDefault->mAlwaysInline) &&
|
||||
((methodInstGroup.mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude) || (methodInstGroup.mOnDemandKind == BfMethodOnDemandKind_Referenced)))
|
||||
((methodInstGroup.mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude) || (methodInstGroup.mOnDemandKind == BfMethodOnDemandKind_Referenced)) &&
|
||||
(methodInstGroup.mHasEmittedReference))
|
||||
{
|
||||
hasConfirmedReference = true;
|
||||
}
|
||||
|
|
|
@ -76,7 +76,8 @@ enum BfEvalExprFlags
|
|||
BfEvalExprFlags_DisallowComptime = 0x100000,
|
||||
BfEvalExprFlags_InCascade = 0x200000,
|
||||
BfEvalExprFlags_InferReturnType = 0x400000,
|
||||
BfEvalExprFlags_WasMethodRef = 0x800000
|
||||
BfEvalExprFlags_WasMethodRef = 0x800000,
|
||||
BfEvalExprFlags_DeclType = 0x1000000,
|
||||
};
|
||||
|
||||
enum BfCastFlags
|
||||
|
@ -1918,6 +1919,7 @@ public:
|
|||
BfModuleMethodInstance GetMethodInstance(BfMethodInstance* methodInstance, BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None);
|
||||
BfMethodInstance* GetOuterMethodInstance(BfMethodInstance* methodInstance); // Only useful for local methods
|
||||
void SetupMethodIdHash(BfMethodInstance* methodInstance);
|
||||
bool CheckUseMethodInstance(BfMethodInstance* methodInstance, BfAstNode* refNode);
|
||||
|
||||
// Type Data
|
||||
BfIRValue CreateClassVDataGlobal(BfTypeInstance* typeInstance, int* outNumElements = NULL, String* outMangledName = NULL);
|
||||
|
|
|
@ -1216,7 +1216,7 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType
|
|||
}
|
||||
if (arrayType->mElementCount > 0)
|
||||
{
|
||||
arrayType->mSize = (arrayType->mElementType->GetStride() * ((int)arrayType->mElementCount - 1)) + arrayType->mElementType->mSize;
|
||||
arrayType->mSize = (int)(arrayType->mElementType->GetStride() * arrayType->mElementCount);
|
||||
arrayType->mAlign = std::max((int32)arrayType->mElementType->mAlign, 1);
|
||||
}
|
||||
else if (arrayType->mElementCount < 0)
|
||||
|
|
|
@ -3440,7 +3440,7 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
|||
}
|
||||
else
|
||||
{
|
||||
result = ctx->mModule->CreateValueFromExpression(exprModTypeRef->mTarget);
|
||||
result = ctx->mModule->CreateValueFromExpression(exprModTypeRef->mTarget, NULL, BfEvalExprFlags_DeclType);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -817,7 +817,8 @@ public:
|
|||
bool mIsUnspecialized:1;
|
||||
bool mIsUnspecializedVariation:1;
|
||||
bool mIsReified:1;
|
||||
bool mHasBeenProcessed:1;
|
||||
bool mHasBeenDeclared:1;
|
||||
bool mHasBeenProcessed:1;
|
||||
bool mHasFailed:1;
|
||||
bool mFailedConstraints:1;
|
||||
bool mMangleWithIdx:1;
|
||||
|
@ -856,6 +857,7 @@ public:
|
|||
mIsUnspecialized = false;
|
||||
mIsUnspecializedVariation = false;
|
||||
mIsReified = true;
|
||||
mHasBeenDeclared = false;
|
||||
mHasBeenProcessed = false;
|
||||
mHasFailed = false;
|
||||
mFailedConstraints = false;
|
||||
|
@ -1256,6 +1258,7 @@ public:
|
|||
int mRefCount; // External references from BfMethodRefType
|
||||
BfMethodOnDemandKind mOnDemandKind;
|
||||
bool mExplicitlyReflected;
|
||||
bool mHasEmittedReference;
|
||||
|
||||
public:
|
||||
BfMethodInstanceGroup()
|
||||
|
@ -1267,6 +1270,7 @@ public:
|
|||
mOnDemandKind = BfMethodOnDemandKind_NotSet;
|
||||
mRefCount = 0;
|
||||
mExplicitlyReflected = false;
|
||||
mHasEmittedReference = false;
|
||||
}
|
||||
|
||||
~BfMethodInstanceGroup();
|
||||
|
|
|
@ -238,7 +238,7 @@ bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfSc
|
|||
instSize = dataPos;
|
||||
|
||||
deferIRType = mBfIRBuilder->CreateStructType(typeName);
|
||||
mBfIRBuilder->StructSetBody(deferIRType, llvmTypes, false);
|
||||
mBfIRBuilder->StructSetBody(deferIRType, llvmTypes, instSize, instAlign, false);
|
||||
|
||||
auto prevInsertPoint = mBfIRBuilder->GetInsertBlock();
|
||||
if (!isLooped)
|
||||
|
@ -356,7 +356,7 @@ bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfSc
|
|||
deferredMethodCallData->mAlign = instAlign;
|
||||
deferredMethodCallData->mSize = instSize;
|
||||
deferredMethodCallData->mDeferType = mBfIRBuilder->CreateStructType(typeName);
|
||||
mBfIRBuilder->StructSetBody(deferredMethodCallData->mDeferType, llvmTypes, false);
|
||||
mBfIRBuilder->StructSetBody(deferredMethodCallData->mDeferType, llvmTypes, instSize, instAlign, false);
|
||||
deferredMethodCallData->mDeferTypePtr = mBfIRBuilder->GetPointerTo(deferredMethodCallData->mDeferType);
|
||||
}
|
||||
|
||||
|
@ -6572,10 +6572,8 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
|
|||
}
|
||||
else
|
||||
{
|
||||
BfIRValue ptrValue = mBfIRBuilder->CreateBitCast(target.mValue, mBfIRBuilder->MapType(ptrType));
|
||||
arrayItem = BfTypedValue(CreateIndexedValue(arrayType->mElementType, ptrValue, itrVal), arrayType->mElementType, true);
|
||||
if (isRefExpression)
|
||||
arrayItem = BfTypedValue(arrayItem.mValue, CreateRefType(arrayItem.mType));
|
||||
target = MakeAddressable(target);
|
||||
arrayItem = BfTypedValue(CreateIndexedValue(arrayType->mElementType, target.mValue, itrVal, true), arrayType->mElementType, true);
|
||||
}
|
||||
arrayItem = Cast(forEachStmt->mCollectionExpression, arrayItem, varType, BfCastFlags_Explicit);
|
||||
if ((arrayItem) && (!arrayItem.mValue.IsFake()))
|
||||
|
|
|
@ -978,7 +978,7 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme
|
|||
BF_ASSERT(ptrType->mElementType->mTypeCode == BeTypeCode_SizedArray);
|
||||
auto arrayType = (BeSizedArrayType*)ptrType->mElementType;
|
||||
elementType = arrayType->mElementType;
|
||||
byteOffset = gepConstant->mIdx1 * elementType->mSize;
|
||||
byteOffset = gepConstant->mIdx1 * elementType->GetStride();
|
||||
}
|
||||
|
||||
auto elementPtrType = mCeMachine->GetBeContext()->GetPointerTo(elementType);
|
||||
|
@ -987,13 +987,7 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme
|
|||
EmitFrameOffset(result);
|
||||
EmitFrameOffset(mcVal);
|
||||
Emit(&byteOffset, mPtrSize);
|
||||
|
||||
// result = AllocRelativeVirtualReg(elementPtrType, result, GetImmediate(byteOffset), 1);
|
||||
// // The def is primary to create a single 'master location' for the GEP vreg to become legalized before use
|
||||
// auto vregInfo = GetVRegInfo(result);
|
||||
// vregInfo->mDefOnFirstUse = true;
|
||||
// result.mKind = CeOperandKind_VReg;
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
|
@ -1843,9 +1837,12 @@ void CeBuilder::Build()
|
|||
if (castedInst->mRetValue != NULL)
|
||||
{
|
||||
auto mcVal = GetOperand(castedInst->mRetValue);
|
||||
BF_ASSERT(mReturnVal.mKind == CeOperandKind_AllocaAddr);
|
||||
EmitSizedOp(CeOp_Move_8, mcVal, NULL, true);
|
||||
Emit((int32)mReturnVal.mFrameOfs);
|
||||
if (mcVal.mType->mSize > 0)
|
||||
{
|
||||
BF_ASSERT(mReturnVal.mKind == CeOperandKind_AllocaAddr);
|
||||
EmitSizedOp(CeOp_Move_8, mcVal, NULL, true);
|
||||
Emit((int32)mReturnVal.mFrameOfs);
|
||||
}
|
||||
}
|
||||
|
||||
if (instType == BeRetInst::TypeId)
|
||||
|
@ -1974,7 +1971,7 @@ void CeBuilder::Build()
|
|||
Emit((CeOp)(CeOp_AddConst_I32));
|
||||
EmitFrameOffset(result);
|
||||
EmitFrameOffset(ceVal);
|
||||
Emit((int32)(ceIdx1.mImmediate * arrayType->mElementType->mSize));
|
||||
Emit((int32)(ceIdx1.mImmediate * arrayType->mElementType->GetStride()));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -2012,7 +2009,7 @@ void CeBuilder::Build()
|
|||
auto mcElementSize = FrameAlloc(mIntPtrType);
|
||||
Emit(CeOp_Const_32);
|
||||
EmitFrameOffset(mcElementSize);
|
||||
Emit((int32)arrayType->mElementType->mSize);
|
||||
Emit((int32)arrayType->mElementType->GetStride());
|
||||
|
||||
auto ofsValue = FrameAlloc(mIntPtrType);
|
||||
Emit(CeOp_Mul_I32);
|
||||
|
@ -2030,7 +2027,7 @@ void CeBuilder::Build()
|
|||
auto mcElementSize = FrameAlloc(mIntPtrType);
|
||||
Emit(CeOp_Const_64);
|
||||
EmitFrameOffset(mcElementSize);
|
||||
Emit((int64)arrayType->mElementType->mSize);
|
||||
Emit((int64)arrayType->mElementType->GetStride());
|
||||
|
||||
auto ofsValue = FrameAlloc(mIntPtrType);
|
||||
Emit(CeOp_Mul_I64);
|
||||
|
@ -2064,13 +2061,13 @@ void CeBuilder::Build()
|
|||
{
|
||||
auto arrayType = (BeSizedArrayType*)ptrType->mElementType;
|
||||
elementType = arrayType->mElementType;
|
||||
byteOffset = ceIdx1.mImmediate * elementType->mSize;
|
||||
byteOffset = ceIdx1.mImmediate * elementType->GetStride();
|
||||
}
|
||||
else if (ptrType->mElementType->mTypeCode == BeTypeCode_Vector)
|
||||
{
|
||||
auto arrayType = (BeVectorType*)ptrType->mElementType;
|
||||
elementType = arrayType->mElementType;
|
||||
byteOffset = ceIdx1.mImmediate * elementType->mSize;
|
||||
byteOffset = ceIdx1.mImmediate * elementType->GetStride();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2099,7 +2096,7 @@ void CeBuilder::Build()
|
|||
int relScale = 1;
|
||||
if (ceIdx0.IsImmediate())
|
||||
{
|
||||
int byteOffset = ceIdx0.mImmediate * ptrType->mElementType->mSize;
|
||||
int byteOffset = ceIdx0.mImmediate * ptrType->mElementType->GetStride();
|
||||
if (byteOffset != 0)
|
||||
{
|
||||
result = FrameAlloc(ptrType);
|
||||
|
@ -2117,7 +2114,7 @@ void CeBuilder::Build()
|
|||
auto mcElementSize = FrameAlloc(mIntPtrType);
|
||||
Emit(CeOp_Const_32);
|
||||
EmitFrameOffset(mcElementSize);
|
||||
Emit((int32)ptrType->mElementType->mSize);
|
||||
Emit((int32)ptrType->mElementType->GetStride());
|
||||
|
||||
auto ofsValue = FrameAlloc(mIntPtrType);
|
||||
Emit(CeOp_Mul_I32);
|
||||
|
@ -2135,7 +2132,7 @@ void CeBuilder::Build()
|
|||
auto mcElementSize = FrameAlloc(mIntPtrType);
|
||||
Emit(CeOp_Const_64);
|
||||
EmitFrameOffset(mcElementSize);
|
||||
Emit((int64)ptrType->mElementType->mSize);
|
||||
Emit((int64)ptrType->mElementType->GetStride());
|
||||
|
||||
auto ofsValue = FrameAlloc(mIntPtrType);
|
||||
Emit(CeOp_Mul_I64);
|
||||
|
@ -2232,7 +2229,7 @@ void CeBuilder::Build()
|
|||
{
|
||||
auto sizedArray = (BeSizedArrayType*)aggType;
|
||||
memberType = sizedArray->mElementType;
|
||||
byteOffset = BF_ALIGN(memberType->mSize, memberType->mAlign) * castedInst->mIdx;
|
||||
byteOffset = memberType->GetStride() * castedInst->mIdx;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3348,6 +3345,7 @@ BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType
|
|||
{
|
||||
auto ceModule = mCeMachine->mCeModule;
|
||||
BfIRBuilder* irBuilder = module->mBfIRBuilder;
|
||||
int32 ptrSize = module->mSystem->mPtrSize;
|
||||
|
||||
uint8* memStart = mMemory.mVals;
|
||||
int memSize = mMemory.mSize;
|
||||
|
@ -3443,6 +3441,33 @@ BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType
|
|||
CE_CREATECONST_CHECKPTR(charPtr, lenVal);
|
||||
String str(charPtr, lenVal);
|
||||
return module->GetStringObjectValue(str);
|
||||
|
||||
}
|
||||
|
||||
if (typeInst->IsInstanceOf(mCeMachine->mCompiler->mStringViewTypeDef))
|
||||
{
|
||||
char* charPtr = (char*)memStart + *(addr_ce*)(ptr);
|
||||
int32 lenVal = *(int32*)(ptr + ptrSize);
|
||||
|
||||
CE_CREATECONST_CHECKPTR(charPtr, lenVal);
|
||||
String str(charPtr, lenVal);
|
||||
|
||||
auto stringViewType = ceModule->ResolveTypeDef(mCeMachine->mCompiler->mStringViewTypeDef, BfPopulateType_Data)->ToTypeInstance();
|
||||
auto spanType = stringViewType->mBaseType;
|
||||
auto valueTypeType = spanType->mBaseType;
|
||||
|
||||
SizedArray<BfIRValue, 1> valueTypeValues;
|
||||
BfIRValue valueTypeVal = irBuilder->CreateConstAgg(irBuilder->MapType(valueTypeType, BfIRPopulateType_Full), valueTypeValues);
|
||||
|
||||
SizedArray<BfIRValue, 3> spanValues;
|
||||
spanValues.Add(valueTypeVal);
|
||||
spanValues.Add(module->GetStringCharPtr(str));
|
||||
spanValues.Add(irBuilder->CreateConst(BfTypeCode_IntPtr, lenVal));
|
||||
BfIRValue spanVal = irBuilder->CreateConstAgg(irBuilder->MapType(spanType, BfIRPopulateType_Full), spanValues);
|
||||
|
||||
SizedArray<BfIRValue, 1> stringViewValues;
|
||||
stringViewValues.Add(spanVal);
|
||||
return irBuilder->CreateConstAgg(irBuilder->MapType(stringViewType, BfIRPopulateType_Full), stringViewValues);
|
||||
}
|
||||
|
||||
SizedArray<BfIRValue, 8> fieldVals;
|
||||
|
@ -3499,13 +3524,7 @@ BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType
|
|||
Fail(StrFormat("Reference type '%s' return value not allowed", module->TypeToString(typeInst).c_str()));
|
||||
return BfIRValue();
|
||||
}
|
||||
|
||||
if (typeInst->IsPointer())
|
||||
{
|
||||
Fail(StrFormat("Pointer type '%s' return value not allowed", module->TypeToString(typeInst).c_str()));
|
||||
return BfIRValue();
|
||||
}
|
||||
|
||||
|
||||
if (typeInst->mBaseType != NULL)
|
||||
{
|
||||
auto result = CreateConstant(module, instData, typeInst->mBaseType);
|
||||
|
@ -3513,7 +3532,7 @@ BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType
|
|||
return BfIRValue();
|
||||
fieldVals.Add(result);
|
||||
}
|
||||
|
||||
|
||||
for (int fieldIdx = 0; fieldIdx < typeInst->mFieldInstances.size(); fieldIdx++)
|
||||
{
|
||||
auto& fieldInstance = typeInst->mFieldInstances[fieldIdx];
|
||||
|
@ -3526,7 +3545,7 @@ BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType
|
|||
if (fieldInstance.mResolvedType->IsInteger())
|
||||
fieldVals.Add(irBuilder->CreatePtrToInt(vdataPtr, ((BfPrimitiveType*)fieldInstance.mResolvedType)->mTypeDef->mTypeCode));
|
||||
else
|
||||
fieldVals.Add(vdataPtr);
|
||||
fieldVals.Add(vdataPtr);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -3535,19 +3554,48 @@ BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType
|
|||
return BfIRValue();
|
||||
|
||||
if (fieldInstance.mDataIdx == fieldVals.mSize)
|
||||
fieldVals.Add(result);
|
||||
{
|
||||
fieldVals.Add(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (fieldInstance.mDataIdx >= fieldVals.mSize)
|
||||
fieldVals.Add(BfIRValue());
|
||||
fieldVals[fieldInstance.mDataIdx] = result;
|
||||
fieldVals[fieldInstance.mDataIdx] = result;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& fieldVal : fieldVals)
|
||||
{
|
||||
if (!fieldVal)
|
||||
fieldVal = irBuilder->CreateConstArrayZero(0);
|
||||
}
|
||||
|
||||
auto instResult = irBuilder->CreateConstAgg(irBuilder->MapTypeInst(typeInst, BfIRPopulateType_Full), fieldVals);
|
||||
return instResult;
|
||||
}
|
||||
|
||||
if (bfType->IsPointer())
|
||||
{
|
||||
Fail(StrFormat("Pointer type '%s' return value not allowed", module->TypeToString(bfType).c_str()));
|
||||
return BfIRValue();
|
||||
}
|
||||
|
||||
if ((bfType->IsSizedArray()) && (!bfType->IsUnknownSizedArrayType()))
|
||||
{
|
||||
SizedArray<BfIRValue, 8> values;
|
||||
auto sizedArrayType = (BfSizedArrayType*)bfType;
|
||||
for (int i = 0; i < sizedArrayType->mElementCount; i++)
|
||||
{
|
||||
auto elemValue = CreateConstant(module, ptr + i * sizedArrayType->mElementType->GetStride(), sizedArrayType->mElementType);
|
||||
if (!elemValue)
|
||||
return BfIRValue();
|
||||
values.Add(elemValue);
|
||||
}
|
||||
|
||||
return irBuilder->CreateConstAgg(irBuilder->MapType(sizedArrayType, BfIRPopulateType_Full), values);
|
||||
}
|
||||
|
||||
return BfIRValue();
|
||||
}
|
||||
|
||||
|
@ -6085,7 +6133,7 @@ CeErrorKind CeMachine::WriteConstant(CeConstStructData& data, BeConstant* constV
|
|||
else if (globalVar->mType->mTypeCode == BeTypeCode_SizedArray)
|
||||
{
|
||||
auto arrayType = (BeSizedArrayType*)globalVar->mType;
|
||||
dataOfs = arrayType->mElementType->mSize * constGep->mIdx1;
|
||||
dataOfs = arrayType->mElementType->GetStride() * constGep->mIdx1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue