| 4325 | } |
| 4326 | |
| 4327 | BfTypedValue BfExprEvaluator::LoadLocal(BfLocalVariable* varDecl, bool allowRef) |
| 4328 | { |
| 4329 | if (!mModule->mIsInsideAutoComplete) |
| 4330 | varDecl->mReadFromId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++; |
| 4331 | |
| 4332 | // The Beef backend prefers readonly addrs since that reduces register pressure, whereas |
| 4333 | // LLVM prefers values to avoid memory loads. This only applies to primitive types... |
| 4334 | bool preferValue = (varDecl->mResolvedType->IsPrimitiveType()) && (!mModule->IsTargetingBeefBackend()); |
| 4335 | |
| 4336 | BfTypedValue localResult; |
| 4337 | if (varDecl->mIsThis) |
| 4338 | { |
| 4339 | return mModule->GetThis(); |
| 4340 | } |
| 4341 | else if (varDecl->mConstValue) |
| 4342 | { |
| 4343 | localResult = BfTypedValue(varDecl->mConstValue, varDecl->mResolvedType, false); |
| 4344 | } |
| 4345 | else if (varDecl->mIsSplat) |
| 4346 | { |
| 4347 | if (!varDecl->mResolvedType->IsValuelessType()) |
| 4348 | localResult = BfTypedValue(varDecl->mValue, varDecl->mResolvedType, BfTypedValueKind_SplatHead); |
| 4349 | else if ((varDecl->mResolvedType->IsRef()) && (!allowRef)) |
| 4350 | { |
| 4351 | BF_ASSERT(varDecl->mResolvedType->IsValuelessType()); |
| 4352 | localResult = BfTypedValue(varDecl->mValue, varDecl->mResolvedType->GetUnderlyingType()); |
| 4353 | } |
| 4354 | else |
| 4355 | localResult = BfTypedValue(varDecl->mValue, varDecl->mResolvedType); |
| 4356 | //BF_ASSERT(varDecl->mValue.IsArg()); |
| 4357 | } |
| 4358 | else if ((varDecl->mValue) && ((varDecl->mIsReadOnly && preferValue) || (!varDecl->mAddr))) |
| 4359 | { |
| 4360 | if ((varDecl->mResolvedType->IsRef()) && (!allowRef)) |
| 4361 | { |
| 4362 | BfRefType* refType = (BfRefType*)varDecl->mResolvedType; |
| 4363 | BfType* innerType = refType->mElementType; |
| 4364 | |
| 4365 | if (innerType->IsGenericParam()) |
| 4366 | { |
| 4367 | if (refType->mRefKind == BfRefType::RefKind_Mut) |
| 4368 | { |
| 4369 | localResult = BfTypedValue(varDecl->mValue, innerType, BfTypedValueKind_MutableValue); |
| 4370 | return localResult; |
| 4371 | } |
| 4372 | else |
| 4373 | { |
| 4374 | localResult = BfTypedValue(varDecl->mValue, innerType, BfTypedValueKind_Addr); |
| 4375 | return localResult; |
| 4376 | } |
| 4377 | } |
| 4378 | |
| 4379 | localResult = BfTypedValue(varDecl->mValue, innerType, varDecl->mIsReadOnly ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr); |
| 4380 | } |
| 4381 | else |
| 4382 | { |
| 4383 | BfTypedValueKind kind; |
| 4384 | if ((varDecl->mResolvedType->IsComposite()) && (varDecl->mValue.IsArg())) |
no test coverage detected