From f665388e91a451d69f85079341e7207d01891ed9 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Mon, 18 Jan 2021 14:09:16 -0800 Subject: [PATCH] Expanded const aggregate compatibility --- BeefySysLib/util/SizedArray.h | 22 ++++ IDEHelper/Backend/BeContext.cpp | 4 +- IDEHelper/Backend/BeContext.h | 5 + IDEHelper/Backend/BeIRCodeGen.cpp | 40 +++++-- IDEHelper/Compiler/BfContext.h | 3 +- IDEHelper/Compiler/BfExprEvaluator.cpp | 64 ++++++++--- IDEHelper/Compiler/BfIRBuilder.cpp | 55 ++++++--- IDEHelper/Compiler/BfIRBuilder.h | 4 +- IDEHelper/Compiler/BfIRCodeGen.cpp | 127 ++++++++++++++++++--- IDEHelper/Compiler/BfIRCodeGen.h | 37 +++++- IDEHelper/Compiler/BfModule.cpp | 89 +++++++++------ IDEHelper/Compiler/BfModule.h | 4 +- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 2 +- IDEHelper/Compiler/BfResolvedTypeUtils.cpp | 2 +- IDEHelper/Compiler/BfResolvedTypeUtils.h | 6 +- IDEHelper/Compiler/BfStmtEvaluator.cpp | 10 +- IDEHelper/Compiler/CeMachine.cpp | 112 ++++++++++++------ 17 files changed, 452 insertions(+), 134 deletions(-) diff --git a/BeefySysLib/util/SizedArray.h b/BeefySysLib/util/SizedArray.h index 093fc164..091646b1 100644 --- a/BeefySysLib/util/SizedArray.h +++ b/BeefySysLib/util/SizedArray.h @@ -485,6 +485,28 @@ public: this->mSize--; } + void RemoveAll(const std::function& func) + { + int outIdx = 0; + for (int i = 0; i < this->mSize; i++) + { + if (func(this->mVals[i])) + { + this->mVals[i].~T(); + } + else + { + if (i != outIdx) + { + new (&this->mVals[outIdx]) T(this->mVals[i]); + } + + outIdx++; + } + } + this->mSize = outIdx; + } + void RemoveRange(intptr idx, intptr length) { BF_ASSERT( diff --git a/IDEHelper/Backend/BeContext.cpp b/IDEHelper/Backend/BeContext.cpp index 0e78b879..21c7c707 100644 --- a/IDEHelper/Backend/BeContext.cpp +++ b/IDEHelper/Backend/BeContext.cpp @@ -161,7 +161,7 @@ BeSizedArrayType* BeContext::CreateSizedArrayType(BeType* type, int length) arrayType->mTypeCode = BeTypeCode_SizedArray; arrayType->mElementType = type; arrayType->mLength = length; - arrayType->mSize = type->mSize * length; + arrayType->mSize = type->GetStride() * length; arrayType->mAlign = type->mAlign; return arrayType; } @@ -173,7 +173,7 @@ BeVectorType* BeContext::CreateVectorType(BeType* type, int length) arrayType->mTypeCode = BeTypeCode_Vector; arrayType->mElementType = type; arrayType->mLength = length; - arrayType->mSize = type->mSize * length; + arrayType->mSize = type->GetStride() * length; arrayType->mAlign = type->mAlign; return arrayType; } diff --git a/IDEHelper/Backend/BeContext.h b/IDEHelper/Backend/BeContext.h index 467f6a98..20d24152 100644 --- a/IDEHelper/Backend/BeContext.h +++ b/IDEHelper/Backend/BeContext.h @@ -91,6 +91,11 @@ public: } + int GetStride() + { + return BF_ALIGN(mSize, mAlign); + } + bool IsPointer() { return (mTypeCode == BeTypeCode_Pointer) || (mTypeCode == BeTypeCode_NullPtr); diff --git a/IDEHelper/Backend/BeIRCodeGen.cpp b/IDEHelper/Backend/BeIRCodeGen.cpp index 67967e0f..58566745 100644 --- a/IDEHelper/Backend/BeIRCodeGen.cpp +++ b/IDEHelper/Backend/BeIRCodeGen.cpp @@ -649,7 +649,7 @@ void BeIRCodeGen::Read(BeType*& beType) else if (typeKind == BfIRType::TypeKind::TypeKind_TypeInstId) beType = typeEntry.mInstBeType; else if (typeKind == BfIRType::TypeKind::TypeKind_TypeInstPtrId) - beType = mBeContext->GetPointerTo(typeEntry.mInstBeType); + beType = mBeContext->GetPointerTo(typeEntry.mInstBeType); BE_MEM_END("BeType"); } @@ -838,28 +838,50 @@ void BeIRCodeGen::Read(BeValue*& beValue) for (int i = 0; i < (int)values.size(); i++) { auto val = values[i]; - BeConstant* constant = BeValueDynCast(val); - constStruct->mMemberValues.push_back(constant); + BeConstant* constant = BeValueDynCast(val); #ifdef _DEBUG if (type->IsSizedArray()) { auto arrayType = (BeSizedArrayType*)type; auto memberType = constant->GetType(); - BF_ASSERT(memberType == arrayType->mElementType); + if (memberType != arrayType->mElementType) + Fail("ConstAgg array member type mismatch"); } else if (type->IsVector()) { auto vecType = (BeVectorType*)type; auto memberType = constant->GetType(); - BF_ASSERT(memberType == vecType->mElementType); + if (memberType != vecType->mElementType) + Fail("ConstAgg vector member type mismatch"); } else { BF_ASSERT(type->IsStruct()); auto structType = (BeStructType*)type; - auto memberType = constant->GetType(); - BF_ASSERT(memberType == structType->mMembers[i].mType); + auto valType = constant->GetType(); + if (structType->mIsOpaque) + { + Fail("ConstAgg with opaque struct"); + } + else if (valType != structType->mMembers[i].mType) + { + if ((valType->IsSizedArray()) && (structType->mMembers[i].mType->IsSizedArray())) + { + auto valSizedType = (BeSizedArrayType*)valType; + auto memberSizedType = (BeSizedArrayType*)structType->mMembers[i].mType; + if ((valSizedType->mSize == 0) && (valSizedType->mElementType == memberSizedType->mElementType)) + { + constant->mType = memberSizedType; + constStruct->mMemberValues.Add(constant); + continue; + } + } + + Fail("ConstAgg struct member type mismatch"); + } } + + constStruct->mMemberValues.Add(constant); #endif } beValue = constStruct; @@ -1151,10 +1173,14 @@ void BeIRCodeGen::HandleNextCmd() { CMD_PARAM(BeType*, type); CMD_PARAM(CmdParamVec, members); + CMD_PARAM(int, instSize); + CMD_PARAM(int, instAlign); CMD_PARAM(bool, isPacked); BF_ASSERT(type->mTypeCode == BeTypeCode_Struct); auto structType = (BeStructType*)type; mBeContext->SetStructBody(structType, members, isPacked); + structType->mSize = instSize; + structType->mAlign = instAlign; } break; case BfIRCmd_Type: diff --git a/IDEHelper/Compiler/BfContext.h b/IDEHelper/Compiler/BfContext.h index e210cb0c..be023b87 100644 --- a/IDEHelper/Compiler/BfContext.h +++ b/IDEHelper/Compiler/BfContext.h @@ -130,7 +130,8 @@ public: ResolveKind_ResolvingVarType, ResolveKind_UnionInnerType, ResolveKind_LocalVariable, - ResolveKind_Attributes + ResolveKind_Attributes, + ResolveKind_ConstField }; public: diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index fca3028e..7873bc03 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -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()) || (expr->IsExact()))) @@ -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 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; diff --git a/IDEHelper/Compiler/BfIRBuilder.cpp b/IDEHelper/Compiler/BfIRBuilder.cpp index 964cdaf2..6b44f9a1 100644 --- a/IDEHelper/Compiler/BfIRBuilder.cpp +++ b/IDEHelper/Compiler/BfIRBuilder.cpp @@ -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& memberTypes return retType; } -void BfIRBuilder::StructSetBody(BfIRType type, const BfSizedArray& memberTypes, bool isPacked) +void BfIRBuilder::StructSetBody(BfIRType type, const BfSizedArray& memberTypes, int size, int align, bool isPacked) { - WriteCmd(BfIRCmd_StructSetBody, type, memberTypes, isPacked); + WriteCmd(BfIRCmd_StructSetBody, type, memberTypes, size, align, isPacked); NEW_CMD_INSERTED; } diff --git a/IDEHelper/Compiler/BfIRBuilder.h b/IDEHelper/Compiler/BfIRBuilder.h index 4ee05a34..212614ff 100644 --- a/IDEHelper/Compiler/BfIRBuilder.h +++ b/IDEHelper/Compiler/BfIRBuilder.h @@ -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& memberTypes); - void StructSetBody(BfIRType type, const BfSizedArray& memberTypes, bool isPacked); + void StructSetBody(BfIRType type, const BfSizedArray& 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); diff --git a/IDEHelper/Compiler/BfIRCodeGen.cpp b/IDEHelper/Compiler/BfIRCodeGen.cpp index 9c2a41a6..8aca6db6 100644 --- a/IDEHelper/Compiler/BfIRCodeGen.cpp +++ b/IDEHelper/Compiler/BfIRCodeGen.cpp @@ -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, values); + BfIRTypeEntry* typeEntry = NULL; + llvm::Type* type = NULL; + Read(type, &typeEntry); + CmdParamVec values; + Read(values, type->isArrayTy()); if (auto arrayType = llvm::dyn_cast(type)) { @@ -921,7 +933,31 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry) } else if (auto structType = llvm::dyn_cast(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(values[i]->getType()); + auto structArrayType = llvm::dyn_cast(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(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(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(typeEntry->mLLVMType); + if (structType != NULL) + { + BF_ASSERT(structType->isPacked()); + + auto alignType = llvm::StructType::create(*mLLVMContext, (structType->getName().str() + "_ALIGNED").c_str()); + llvm::SmallVector 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(fromValue->getType())) + { + if (auto arrayType = llvm::dyn_cast(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(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, members); + CMD_PARAM(int, instSize); + CMD_PARAM(int, instAlign); CMD_PARAM(bool, isPacked); + BF_ASSERT(llvm::isa(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: diff --git a/IDEHelper/Compiler/BfIRCodeGen.h b/IDEHelper/Compiler/BfIRCodeGen.h index 5b60164c..f09f9688 100644 --- a/IDEHelper/Compiler/BfIRCodeGen.h +++ b/IDEHelper/Compiler/BfIRCodeGen.h @@ -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 mConfigConsts32; Array mConfigConsts64; Dictionary mReflectDataMap; + Dictionary 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& 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& 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; diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 96611b3b..e8cbd43d 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -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 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; } diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index b37a5dfc..0d2c350b 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -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); diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 7c6ce0d4..54ec74f4 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -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) diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index ec969725..bdf7d6db 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -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); } } diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.h b/IDEHelper/Compiler/BfResolvedTypeUtils.h index 929acfc9..2ad3403a 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.h +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.h @@ -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(); diff --git a/IDEHelper/Compiler/BfStmtEvaluator.cpp b/IDEHelper/Compiler/BfStmtEvaluator.cpp index 656e0af6..f0a088cb 100644 --- a/IDEHelper/Compiler/BfStmtEvaluator.cpp +++ b/IDEHelper/Compiler/BfStmtEvaluator.cpp @@ -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())) diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index b79045c2..64e61ff6 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -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 valueTypeValues; + BfIRValue valueTypeVal = irBuilder->CreateConstAgg(irBuilder->MapType(valueTypeType, BfIRPopulateType_Full), valueTypeValues); + + SizedArray 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 stringViewValues; + stringViewValues.Add(spanVal); + return irBuilder->CreateConstAgg(irBuilder->MapType(stringViewType, BfIRPopulateType_Full), stringViewValues); } SizedArray 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 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 {