diff --git a/IDEHelper/Backend/BeMCContext.cpp b/IDEHelper/Backend/BeMCContext.cpp index 4fb95d39..52baddab 100644 --- a/IDEHelper/Backend/BeMCContext.cpp +++ b/IDEHelper/Backend/BeMCContext.cpp @@ -21,7 +21,7 @@ USING_NS_BF; const int BF_REP_MOV_LIMIT = 128; static const X64CPURegister gVolatileRegs[] = { X64Reg_RAX, X64Reg_RCX, X64Reg_RDX, X64Reg_R8, X64Reg_R9, X64Reg_R10, X64Reg_R11, - X64Reg_XMM0_f64, X64Reg_XMM1_f64, X64Reg_XMM2_f64, X64Reg_XMM3_f64, X64Reg_XMM4_f64, X64Reg_XMM5_f64}; + X64Reg_XMM0_f64, X64Reg_XMM1_f64, X64Reg_XMM2_f64, X64Reg_XMM3_f64, X64Reg_XMM4_f64, X64Reg_XMM5_f64 }; static const char* gOpName[] = { @@ -33,11 +33,11 @@ static const char* gOpName[] = "@DbgRangeStart", "@DbgRangeEnd", "@LifetimeExtend", - "@LifetimeStart", - "@LifetimeEnd", + "@LifetimeStart", + "@LifetimeEnd", "@ValueScopeSoftEnd", "@ValueScopeHardEnd", - "@Label", + "@Label", //"PhiValue", "CmpToBool", "MemSet", @@ -58,9 +58,9 @@ static const char* gOpName[] = "EnsureCodeAt", "DbgBreak", "MFence", - "Mov", + "Mov", "MovRaw", - "MovSX", + "MovSX", "XChg", "XAdd", "CmpXChg", @@ -70,7 +70,7 @@ static const char* gOpName[] = "Pop", "Neg", "Not", - "Add", + "Add", "Sub", "Mul", "IMul", @@ -86,8 +86,8 @@ static const char* gOpName[] = "Test", "CondBr", "Br", - "Ret", - "Call", + "Ret", + "Call", }; static_assert(BF_ARRAY_COUNT(gOpName) == (int)BeMCInstKind_COUNT, "gOpName incorrect size"); @@ -152,8 +152,8 @@ int BeVTrackingContext::GetBitsBytes() } int BeVTrackingContext::GetIdx(int baseIdx, BeTrackKind liveKind) -{ - return baseIdx + mNumItems*(int)liveKind; +{ + return baseIdx + mNumItems * (int)liveKind; } void BeVTrackingContext::Print(BeVTrackingList* list) @@ -195,18 +195,18 @@ BeVTrackingList* BeVTrackingContext::AddFiltered(BeVTrackingList* list, SizedArr allocBytes += sizeof(int) * (int)(list->mNumChanges + filteredAdds.size()); auto newList = (BeVTrackingList*)mAlloc.AllocBytes(allocBytes); mStats.mListBytes += allocBytes; - + { if (filteredAdds.size() > 1) - std::sort(filteredAdds.begin(), filteredAdds.end()); + std::sort(filteredAdds.begin(), filteredAdds.end()); - int addIdx = 0; + int addIdx = 0; int nextAdd; if (addIdx < (int)filteredAdds.size()) nextAdd = filteredAdds[addIdx++]; else nextAdd = 0x7FFFFFFF; - + int* outPtr = &newList->mEntries[0]; for (auto idx : *list) { @@ -226,11 +226,11 @@ BeVTrackingList* BeVTrackingContext::AddFiltered(BeVTrackingList* list, SizedArr if (addIdx >= (int)filteredAdds.size()) break; nextAdd = filteredAdds[addIdx++]; - } + } } newList->mSize = newSize; - + if (perserveChangeList) { for (int changeIdx = 0; changeIdx < list->mNumChanges; changeIdx++) @@ -247,7 +247,7 @@ BeVTrackingList* BeVTrackingContext::AddFiltered(BeVTrackingList* list, SizedArr } else newList->mNumChanges = 0; - + return newList; } @@ -261,11 +261,11 @@ BeVTrackingList* BeVTrackingContext::AddFiltered(BeVTrackingList* list, int idx, auto newList = (BeVTrackingList*)mAlloc.AllocBytes(allocBytes); mStats.mListBytes += allocBytes; - { + { int addIdx = 0; - int nextAdd; + int nextAdd; nextAdd = idx; - + int* outPtr = &newList->mEntries[0]; for (auto idx : *list) { @@ -291,8 +291,8 @@ BeVTrackingList* BeVTrackingContext::AddFiltered(BeVTrackingList* list, int idx, { newList->mEntries[newSize + changeIdx] = list->GetChange(changeIdx); } - - newList->mEntries[newSize + list->mNumChanges] = idx; + + newList->mEntries[newSize + list->mNumChanges] = idx; newList->mNumChanges = list->mNumChanges + (int)1; } else @@ -309,7 +309,7 @@ BeVTrackingList* BeVTrackingContext::Add(BeVTrackingList* list, const SizedArray { if (!IsSet(list, idx)) { - newIndices.push_back(idx); + newIndices.push_back(idx); } } if (newIndices.empty()) @@ -320,13 +320,13 @@ BeVTrackingList* BeVTrackingContext::Add(BeVTrackingList* list, const SizedArray BeVTrackingList* BeVTrackingContext::Add(BeVTrackingList* list, int idx, bool perserveChangeList) { if (IsSet(list, idx)) - return list; + return list; return AddFiltered(list, idx, perserveChangeList); } // Performs an 'add' for items that were in prevDest BeVTrackingList* BeVTrackingContext::SetChanges(BeVTrackingList* prevDestEntry, BeVTrackingList* mergeFrom) -{ +{ int removeCount = 0; int addCount = 0; @@ -342,7 +342,7 @@ BeVTrackingList* BeVTrackingContext::SetChanges(BeVTrackingList* prevDestEntry, bool done = false; while (mergeIdx < prevIdx) - { + { removeCount++; ++mergeFromItr; if (mergeFromItr == mergeFromEnd) @@ -506,24 +506,24 @@ BeVTrackingList* BeVTrackingContext::Modify(BeVTrackingList* list, const SizedAr for (int idx : inAdds) { if (!IsSet(list, idx)) - { - filteredAdds.push_back(idx); + { + filteredAdds.push_back(idx); } } - + for (int idx : inRemoves) { if (IsSet(list, idx)) { - filteredRemoves.push_back(idx); + filteredRemoves.push_back(idx); } } if ((filteredAdds.empty()) && (filteredRemoves.empty())) return list; - + int newSize = list->mSize - filteredRemoves.size() + filteredAdds.size(); - int changeSize; + int changeSize; if (preserveChanges) changeSize = list->mNumChanges; else @@ -532,13 +532,13 @@ BeVTrackingList* BeVTrackingContext::Modify(BeVTrackingList* list, const SizedAr int allocBytes = sizeof(int) * (2 + newSize + changeSize); auto newList = (BeVTrackingList*)mAlloc.AllocBytes(allocBytes); mStats.mListBytes += allocBytes; - + if (filteredAdds.size() > 1) std::sort(filteredAdds.begin(), filteredAdds.end()); if (filteredRemoves.size() > 1) std::sort(filteredRemoves.begin(), filteredRemoves.end()); - int addIdx = 0; + int addIdx = 0; int nextAdd; if (addIdx < (int)filteredAdds.size()) nextAdd = filteredAdds[addIdx++]; @@ -581,7 +581,7 @@ BeVTrackingList* BeVTrackingContext::Modify(BeVTrackingList* list, const SizedAr nextAdd = filteredAdds[addIdx++]; } BF_ASSERT(outPtr == &newList->mEntries[0] + newSize); - BF_ASSERT((nextAdd = 0x7FFFFFFF) && (nextRemove == 0x7FFFFFFF)); + BF_ASSERT((nextAdd = 0x7FFFFFFF) && (nextRemove == 0x7FFFFFFF)); if (preserveChanges) { @@ -600,7 +600,7 @@ BeVTrackingList* BeVTrackingContext::Modify(BeVTrackingList* list, const SizedAr } } newList->mSize = newSize; - newList->mNumChanges = changeSize; + newList->mNumChanges = changeSize; /// /*for (int i = 0; i < mNumEntries; i++) @@ -614,7 +614,7 @@ BeVTrackingList* BeVTrackingContext::Modify(BeVTrackingList* list, const SizedAr OutputDebugStrF("Modify %d %@\n", modifyItrIdx, newList);*/ /// - return newList; + return newList; } int BeVTrackingContext::FindIndex(BeVTrackingList* entry, int val) @@ -629,7 +629,7 @@ int BeVTrackingContext::FindIndex(BeVTrackingList* entry, int val) int c = midVal - val; if (c == 0) return i; if (c < 0) - lo = i + 1; + lo = i + 1; else hi = i - 1; } @@ -638,12 +638,12 @@ int BeVTrackingContext::FindIndex(BeVTrackingList* entry, int val) bool BeVTrackingContext::IsSet(BeVTrackingList* entry, int idx) { - return FindIndex(entry, idx) >= 0; + return FindIndex(entry, idx) >= 0; } bool BeVTrackingContext::IsSet(BeVTrackingList* entry, int idx, BeTrackKind trackKind) { - return IsSet(entry, GetIdx(idx, trackKind)); + return IsSet(entry, GetIdx(idx, trackKind)); } BeVTrackingList* BeVTrackingContext::Clear(BeVTrackingList* list, const SizedArrayImpl& indices) @@ -653,7 +653,7 @@ BeVTrackingList* BeVTrackingContext::Clear(BeVTrackingList* list, const SizedArr { if (IsSet(list, idx)) { - newIndices.push_back(idx); + newIndices.push_back(idx); } } if (newIndices.empty()) @@ -676,7 +676,7 @@ BeVTrackingList* BeVTrackingContext::Merge(BeVTrackingList* prevDestEntry, BeVTr return mergeFrom; int newSize = prevDestEntry->mSize; - auto prevItr = prevDestEntry->begin(); + auto prevItr = prevDestEntry->begin(); auto prevEnd = prevDestEntry->end(); auto mergeFromItr = mergeFrom->begin(); auto mergeFromEnd = mergeFrom->end(); @@ -726,13 +726,13 @@ BeVTrackingList* BeVTrackingContext::Merge(BeVTrackingList* prevDestEntry, BeVTr if (newSize == prevDestEntry->mSize) return prevDestEntry; - + int allocBytes = sizeof(int) * (2 + newSize); auto newList = (BeVTrackingList*)mAlloc.AllocBytes(allocBytes); mStats.mListBytes += allocBytes; int* outPtr = &newList->mEntries[0]; - prevItr = prevDestEntry->begin(); + prevItr = prevDestEntry->begin(); mergeFromItr = mergeFrom->begin(); while ((prevItr != prevEnd) && (mergeFromItr != mergeFromEnd)) { @@ -806,9 +806,9 @@ BeVTrackingList* BeVTrackingContext::MergeChanges(BeVTrackingList* prevDestEntry { // If there isn't already a change (whether and add or a remove) that refers to this same vreg, // then we add this change as well - int change = mergeFrom->GetChange(changeIdx); + int change = mergeFrom->GetChange(changeIdx); int negChange = -change - 1; - + /*if (((std::find(changes.begin(), changes.end(), change) == changes.end())) && ((std::find(changes.begin(), changes.end(), negChange) == changes.end())))*/ if ((!changes.Contains(change)) && (!changes.Contains(negChange))) @@ -817,27 +817,27 @@ BeVTrackingList* BeVTrackingContext::MergeChanges(BeVTrackingList* prevDestEntry } } - int newSize = prevDestEntry->mSize; + int newSize = prevDestEntry->mSize; int allocBytes = (int)(sizeof(int) * (2 + newSize + changes.size())); auto newList = (BeVTrackingList*)mAlloc.AllocBytes(allocBytes); - mStats.mListBytes += allocBytes; + mStats.mListBytes += allocBytes; memcpy(&newList->mEntries[0], &prevDestEntry->mEntries[0], newSize * sizeof(int)); for (int i = 0; i < (int)changes.size(); i++) { newList->mEntries[newSize + i] = changes[i]; - } + } newList->mSize = newSize; - newList->mNumChanges = (int)changes.size(); + newList->mNumChanges = (int)changes.size(); return newList; } BeVTrackingList * BeVTrackingContext::RemoveChange(BeVTrackingList* prevDestEntry, int idx) { - int newSize = prevDestEntry->mSize; + int newSize = prevDestEntry->mSize; int allocBytes = (int)(sizeof(int) * (2 + newSize + prevDestEntry->mNumChanges - 1)); auto newList = (BeVTrackingList*)mAlloc.AllocBytes(allocBytes); - mStats.mListBytes += allocBytes; + mStats.mListBytes += allocBytes; memcpy(&newList->mEntries[0], &prevDestEntry->mEntries[0], newSize * sizeof(int)); bool found = false; int outIdx = newSize; @@ -850,13 +850,13 @@ BeVTrackingList * BeVTrackingContext::RemoveChange(BeVTrackingList* prevDestEntr continue; } newList->mEntries[outIdx++] = change; - } + } if (!found) return prevDestEntry; //BF_ASSERT(found); newList->mSize = newSize; - newList->mNumChanges = prevDestEntry->mNumChanges - 1; + newList->mNumChanges = prevDestEntry->mNumChanges - 1; return newList; } @@ -865,7 +865,7 @@ BeVTrackingList * BeVTrackingContext::RemoveChange(BeVTrackingList* prevDestEntr BeMCColorizer::BeMCColorizer(BeMCContext* mcContext) { - mContext = mcContext; + mContext = mcContext; mReserveParamRegs = false; } @@ -886,12 +886,12 @@ void BeMCColorizer::Prepare() { BF_ASSERT(vregInfo->mIsExpr); - /*if ((vregInfo->IsDirectRelTo()) && (vregInfo->mRelTo.mKind == BeMCOperandKind_VReg)) + /*if ((vregInfo->IsDirectRelTo()) && (vregInfo->mRelTo.mKind == BeMCOperandKind_VReg)) node->mActualVRegIdx = vregInfo->mRelTo.mVRegIdx; */ - //node->mWantsReg = false; - //vregInfo->mReg = X64Reg_None; - //continue; + //node->mWantsReg = false; + //vregInfo->mReg = X64Reg_None; + //continue; } if ((vregInfo->mRefCount > 0) || (vregInfo->mIsRetVal)) @@ -899,9 +899,9 @@ void BeMCColorizer::Prepare() node->mWantsReg = ((vregInfo->mType->mSize > 0) && (!vregInfo->mRegNumPinned) && (!vregInfo->mSpilled) && (!vregInfo->mIsExpr) && (!vregInfo->mForceMem) && (vregInfo->mFrameOffset == INT_MIN)); } - -// if (vregInfo->mIsRetVal) -// node->mWantsReg = true; + + // if (vregInfo->mIsRetVal) + // node->mWantsReg = true; if (!node->mWantsReg) vregInfo->mReg = X64Reg_None; vregInfo->mVRegAffinity = -1; @@ -911,13 +911,13 @@ void BeMCColorizer::Prepare() BF_ASSERT(!vregInfo->mDisableR12); BF_ASSERT(!vregInfo->mDisableRDX); }*/ - if (vregInfo->mDisableR11) - node->AdjustRegCost(X64Reg_R11, 0x0FFFFFFF); + if (vregInfo->mDisableR11) + node->AdjustRegCost(X64Reg_R11, 0x0FFFFFFF); if (vregInfo->mDisableR12) node->AdjustRegCost(X64Reg_R12, 0x0FFFFFFF); if (vregInfo->mDisableR13) node->AdjustRegCost(X64Reg_R13, 0x0FFFFFFF); - if (vregInfo->mDisableRAX) + if (vregInfo->mDisableRAX) node->AdjustRegCost(X64Reg_RAX, 0x0FFFFFFF); if (vregInfo->mDisableRDX) node->AdjustRegCost(X64Reg_RDX, 0x0FFFFFFF); @@ -926,21 +926,21 @@ void BeMCColorizer::Prepare() for (int i = X64Reg_RSI; i <= X64Reg_R15; i++) node->AdjustRegCost((X64CPURegister)i, 0x0FFFFFFF); } - } + } } void BeMCColorizer::AddEdge(int vreg0, int vreg1) -{ +{ int checkVRegIdx0 = mContext->GetUnderlyingVReg(vreg0); int checkVRegIdx1 = mContext->GetUnderlyingVReg(vreg1); if (checkVRegIdx0 == checkVRegIdx1) return; - + auto node0 = &mNodes[checkVRegIdx0]; auto node1 = &mNodes[checkVRegIdx1]; - if ((node0->mWantsReg) && (node1->mWantsReg)) + if ((node0->mWantsReg) && (node1->mWantsReg)) { node0->mEdges.Add(checkVRegIdx1); node1->mEdges.Add(checkVRegIdx0); @@ -959,7 +959,7 @@ void BeMCColorizer::PropogateMemCost(const BeMCOperand & operand, int memCost) } void BeMCColorizer::GenerateRegCosts() -{ +{ bool doRegCost = true; // Disallow param reg cross-refs @@ -994,7 +994,7 @@ void BeMCColorizer::GenerateRegCosts() /*auto itr = std::find(paramRegsLeft.begin(), paramRegsLeft.end(), reg); if (itr != paramRegsLeft.end()) { - paramRegsLeft.erase(itr); + paramRegsLeft.erase(itr); if (paramRegsLeft.size() == 0) break; @@ -1007,22 +1007,22 @@ void BeMCColorizer::GenerateRegCosts() break; prevRegMovs.push_back(vregIdx); } - } + } } BF_ASSERT(paramRegsLeft.size() == 0); - } + } - int preserveDepth = 0; + int preserveDepth = 0; for (auto mcBlock : mContext->mBlocks) { int costMult = mcBlock->mIsLooped ? 4 : 1; - + for (int instIdx = (int)mcBlock->mInstructions.size() - 1; instIdx >= 0; instIdx--) { auto inst = mcBlock->mInstructions[instIdx]; - + // We could adjust register cost based on a possibility of cross-dependencies that won't allow us // to reorder the movs for param setup if (inst->mKind == BeMCInstKind_PreserveVolatiles) @@ -1032,7 +1032,7 @@ void BeMCColorizer::GenerateRegCosts() int preserveCost = 8 * costMult; if (inst->mArg0.mKind == BeMCOperandKind_PreserveFlag) - { + { // Just use a small cost for NoReturns, those are implied to be "unlikely" paths (ie: errors) // But at the least, the code is smaller if we don't need to save the regs so use a small cost if ((inst->mArg0.mPreserveFlag & BeMCPreserveFlag_NoRestore) != 0) @@ -1047,7 +1047,7 @@ void BeMCColorizer::GenerateRegCosts() // Any vregs alive during this call will incur a cost of saving/restoring if we allocate onto a volatile register. // If the vreg is either input-only or output-only (short lived temporary) then we can map it directly to a volatile register for (int vregIdx : *inst->mLiveness) - { + { if (vregIdx >= mContext->mLivenessContext.mNumItems) continue; auto checkVRegIdx = mContext->GetUnderlyingVReg(vregIdx); @@ -1056,10 +1056,10 @@ void BeMCColorizer::GenerateRegCosts() continue; if (mContext->mLivenessContext.IsSet(restoreInst->mLiveness, vregIdx)) - { + { auto node = &mNodes[checkVRegIdx]; if (inst->mArg0.IsNativeReg()) - { + { // Only one specific register used being preserved node->AdjustRegCost(inst->mArg0.mReg, preserveCost); } @@ -1067,7 +1067,7 @@ void BeMCColorizer::GenerateRegCosts() { // All volatile registers preserved for (auto reg : gVolatileRegs) - { + { node->AdjustRegCost(reg, preserveCost); } } @@ -1076,7 +1076,7 @@ void BeMCColorizer::GenerateRegCosts() } else if (inst->mKind == BeMCInstKind_RestoreVolatiles) { - preserveDepth--; + preserveDepth--; } if (inst->IsPsuedo()) @@ -1090,14 +1090,14 @@ void BeMCColorizer::GenerateRegCosts() auto vregInfo0 = mContext->mVRegInfo[inst->mArg0.mVRegIdx]; auto vregInfo1 = mContext->mVRegInfo[inst->mArg1.mVRegIdx]; if ((vregInfo0->mReg == X64Reg_None) && (vregInfo1->mReg == X64Reg_None)) - { + { Node* node0 = &mNodes[inst->mArg1.mVRegIdx]; Node* node1 = &mNodes[inst->mArg1.mVRegIdx]; node0->mMemCost += 4 * costMult; node1->mMemCost += 4 * costMult; } } - + if ((inst->mKind == BeMCInstKind_Div) || (inst->mKind == BeMCInstKind_IDiv)) { if (inst->mArg0.IsVReg()) @@ -1110,7 +1110,7 @@ void BeMCColorizer::GenerateRegCosts() // This has to be large enough to counteract the 'PreserveVolatile RAX' adjustCost -= 8; } - + node->AdjustRegCost(X64Reg_RAX, costMult * adjustCost); continue; } @@ -1141,7 +1141,7 @@ void BeMCColorizer::GenerateRegCosts() } if (inst->mKind == BeMCInstKind_Call) - { + { if (inst->mArg0.IsVRegAny()) { for (int checkInstIdx = instIdx - 1; checkInstIdx >= 0; checkInstIdx--) @@ -1178,7 +1178,7 @@ void BeMCColorizer::GenerateRegCosts() for (auto operand : operands) { if (operand->IsVRegAny()) - { + { Node* node = &mNodes[operand->mVRegIdx]; auto vregInfo = mContext->mVRegInfo[operand->mVRegIdx]; @@ -1197,7 +1197,7 @@ void BeMCColorizer::GenerateRegCosts() node = &mNodes[vregInfo->mRelTo.mVRegIdx]; vregInfo = mContext->mVRegInfo[vregInfo->mRelTo.mVRegIdx]; } - + node->mMemCost += 4 * costMult; if (vregInfo->mRelTo.IsVRegAny()) mNodes[vregInfo->mRelTo.mVRegIdx].mMemCost += 4 * costMult; @@ -1205,7 +1205,7 @@ void BeMCColorizer::GenerateRegCosts() mNodes[vregInfo->mRelOffset.mVRegIdx].mMemCost += 8 * costMult; if (inst->IsMov()) - { + { if (operand != &inst->mResult) { auto otherReg = X64Reg_None; @@ -1229,11 +1229,11 @@ void BeMCColorizer::GenerateRegCosts() if (otherReg != X64Reg_None) node->AdjustRegCost(mContext->ResizeRegister(otherReg, 8), -2 * costMult); } - } + } } } } - } + } for (int nodeIdx = 0; nodeIdx < (int)mNodes.size(); nodeIdx++) { @@ -1253,38 +1253,38 @@ void BeMCColorizer::GenerateRegCosts() } void BeMCColorizer::AssignRegs(RegKind regKind) -{ +{ X64CPURegister highestReg; - + int totalRegs32 = 0; int totalRegs16 = 0; SizedArray validRegs; if (regKind == BeMCColorizer::RegKind_Ints) { - highestReg = X64Reg_R15; - validRegs = { X64Reg_RAX, X64Reg_RBX, X64Reg_RCX, X64Reg_RDX, X64Reg_RSI, X64Reg_RDI, X64Reg_R8, + highestReg = X64Reg_R15; + validRegs = { X64Reg_RAX, X64Reg_RBX, X64Reg_RCX, X64Reg_RDX, X64Reg_RSI, X64Reg_RDI, X64Reg_R8, X64Reg_R9, X64Reg_R10, X64Reg_R11, X64Reg_R12, X64Reg_R13, X64Reg_R14, X64Reg_R15 }; } else { highestReg = X64Reg_XMM15_f64; - validRegs = { - X64Reg_XMM0_f64, X64Reg_XMM1_f64, X64Reg_XMM2_f64, X64Reg_XMM3_f64, - X64Reg_XMM4_f64, X64Reg_XMM5_f64, X64Reg_XMM6_f64, X64Reg_XMM7_f64, - X64Reg_XMM8_f64, X64Reg_XMM9_f64, X64Reg_XMM10_f64, X64Reg_XMM11_f64, + validRegs = { + X64Reg_XMM0_f64, X64Reg_XMM1_f64, X64Reg_XMM2_f64, X64Reg_XMM3_f64, + X64Reg_XMM4_f64, X64Reg_XMM5_f64, X64Reg_XMM6_f64, X64Reg_XMM7_f64, + X64Reg_XMM8_f64, X64Reg_XMM9_f64, X64Reg_XMM10_f64, X64Reg_XMM11_f64, X64Reg_XMM12_f64, X64Reg_XMM13_f64, X64Reg_XMM14_f64, X64Reg_XMM15_f64 }; } - + int totalRegs = (int)validRegs.size(); #define BF_DEQUE #ifdef BF_DEQUE - std::deque vregStack; + std::deque vregStack; #else std::vector vregStack; #endif - + //vregStack.reserve(mNodes.size()); SizedArray vregHiPriStack; vregHiPriStack.reserve(mNodes.size()); @@ -1352,21 +1352,21 @@ void BeMCColorizer::AssignRegs(RegKind regKind) { bool hadNewStackItem = false; #ifdef _DEBUG -// for (int graphIdx = 0; graphIdx < (int)vregGraph.size(); graphIdx++) -// { -// int validatedCount = 0; -// int vregIdx = vregGraph[graphIdx]; -// if (vregIdx == -1) -// continue; -// Node* node = &mNodes[vregIdx]; -// for (auto connNodeIdx : node->mEdges) -// { -// Node* connNode = &mNodes[connNodeIdx]; -// if (connNode->mInGraph) -// validatedCount++; -// } -// BF_ASSERT(validatedCount == node->mGraphEdgeCount); -// } + // for (int graphIdx = 0; graphIdx < (int)vregGraph.size(); graphIdx++) + // { + // int validatedCount = 0; + // int vregIdx = vregGraph[graphIdx]; + // if (vregIdx == -1) + // continue; + // Node* node = &mNodes[vregIdx]; + // for (auto connNodeIdx : node->mEdges) + // { + // Node* connNode = &mNodes[connNodeIdx]; + // if (connNode->mInGraph) + // validatedCount++; + // } + // BF_ASSERT(validatedCount == node->mGraphEdgeCount); + // } #endif for (int graphIdx = 0; graphIdx < (int)vregGraph.size(); graphIdx++) @@ -1388,17 +1388,17 @@ void BeMCColorizer::AssignRegs(RegKind regKind) Node* connNode = &mNodes[connNodeIdx]; connNode->mGraphEdgeCount--; } - + vregGraph[graphIdx] = -1; graphSize--; - + if (!node->mSpilled) { vregStack.push_back(vregIdx); hadNewStackItem = true; } else - { + { // We insert spills at the front so we can try to "optimistically" unspill them // after all the definite coloring is done #ifdef BF_DEQUE @@ -1415,7 +1415,7 @@ void BeMCColorizer::AssignRegs(RegKind regKind) BP_ZONE("Spill"); // We need to spill! - int bestSpillVReg = -1; + int bestSpillVReg = -1; for (int regPassIdx = 0; regPassIdx < 2; regPassIdx++) { while (!orderedSpillList.empty()) @@ -1429,7 +1429,7 @@ void BeMCColorizer::AssignRegs(RegKind regKind) } } if (bestSpillVReg != -1) - break; + break; // Order by mem cost orderedSpillList.reserve(vregGraph.size()); @@ -1447,7 +1447,7 @@ void BeMCColorizer::AssignRegs(RegKind regKind) std::sort(orderedSpillList.begin(), orderedSpillList.end(), [&](int lhs, int rhs) { return mNodes[lhs].mMemCost > mNodes[rhs].mMemCost; - }); + }); } /*int bestSpillVReg = -1; @@ -1465,7 +1465,7 @@ void BeMCColorizer::AssignRegs(RegKind regKind) bestSpillCost = vregInfo->mRefCount; bestSpillVReg = vregIdx; } - }*/ + }*/ if (bestSpillVReg != -1) { @@ -1503,10 +1503,10 @@ void BeMCColorizer::AssignRegs(RegKind regKind) dbgStr += StrFormat("VReg %d ", vregIdx); }*/ - + BeMCVRegInfo* vregInfo = mContext->mVRegInfo[vregIdx]; - Node* node = &mNodes[vregIdx]; - + Node* node = &mNodes[vregIdx]; + if (vregInfo->mVRegAffinity != -1) { auto affinityVRegInfo = mContext->mVRegInfo[vregInfo->mVRegAffinity]; @@ -1542,21 +1542,21 @@ void BeMCColorizer::AssignRegs(RegKind regKind) regUsedVec[(int)usedReg] = true; } } - auto bestReg = X64Reg_None; + auto bestReg = X64Reg_None; int bestRegCost = 0x07FFFFFF; // 0x0FFFFFFF is considered illegal for a reg, so set the mem cost to lower than that...; - + // This is the cost of just leaving the vreg as a memory access. In cases where we bind to a volatile // register, we need to consider the cost of preserving and restoring that register across calls, so // it cases where we have just a few accesses to this vreg but it spans a lot of calls then we just // leave it as memory if (!vregInfo->mForceReg) - bestRegCost = node->mMemCost; + bestRegCost = node->mMemCost; //for (auto validReg : validRegs) int validRegCount = (int)validRegs.size(); for (int regIdx = 0; regIdx < validRegCount; regIdx++) { - auto validReg = validRegs[regIdx]; + auto validReg = validRegs[regIdx]; if (!regUsedVec[(int)validReg]) { int checkCost = node->mRegCost[(int)validReg]; @@ -1588,15 +1588,15 @@ void BeMCColorizer::AssignRegs(RegKind regKind) { bestReg = validReg; bestRegCost = checkCost; - } + } } } - + if (mContext->mDebugging) { //auto itr = mContext->mDbgPreferredRegs.find(vregIdx); //if (itr != mContext->mDbgPreferredRegs.end()) - + X64CPURegister* regPtr = NULL; if (mContext->mDbgPreferredRegs.TryGetValue(vregIdx, ®Ptr)) { @@ -1621,7 +1621,7 @@ void BeMCColorizer::AssignRegs(RegKind regKind) // We managed to optimistically unspill vregInfo->mSpilled = false; } - } + } else { if (vregInfo->mForceReg) @@ -1639,7 +1639,7 @@ void BeMCColorizer::AssignRegs(RegKind regKind) { auto connVRegInfo = mContext->mVRegInfo[connNodeIdx]; auto usedReg = mContext->ResizeRegister(connVRegInfo->mReg, 8); - + if (connVRegInfo->mForceReg) continue; @@ -1649,13 +1649,13 @@ void BeMCColorizer::AssignRegs(RegKind regKind) { bestSpillCost = connVRegInfo->mRefCount; bestSpillVReg = connNodeIdx; - } + } } } } if (bestSpillVReg != -1) - { + { /*if (mContext->mDebugging) { dbgStr += StrFormat("StealingVReg %d ", bestSpillVReg); @@ -1686,12 +1686,12 @@ void BeMCColorizer::AssignRegs(RegKind regKind) BF_ASSERT((bestReg != X64Reg_None) /*|| (mReserveParamRegs)*/); } } - + vregInfo->mReg = mContext->ResizeRegister(bestReg, vregInfo->mType->mSize); if (bestReg != X64Reg_None) { node->mInGraph = true; - globalRegUsedVec[(int)bestReg] = true; + globalRegUsedVec[(int)bestReg] = true; for (auto connNodeIdx : node->mEdges) { Node* connNode = &mNodes[connNodeIdx]; @@ -1758,7 +1758,7 @@ bool BeMCColorizer::Validate() break; if (inst->IsMov()) - { + { if (inst->mArg1.IsNativeReg()) { BF_ASSERT(inst->mArg0.IsVReg()); @@ -1806,13 +1806,13 @@ BeMCLoopDetector::BeMCLoopDetector(BeMCContext* context) : mTrackingContext(cont void BeMCLoopDetector::DetectLoops(BeMCBlock* mcBlock, BeVTrackingList* predBlocksSeen) { mMCContext->mDetectLoopIdx++; - + auto node = &mNodes[mcBlock->mBlockIdx]; auto blocksSeen = mTrackingContext.Merge(node->mPredBlocksSeen, predBlocksSeen); if (blocksSeen == node->mPredBlocksSeen) return; node->mPredBlocksSeen = blocksSeen; - + //SizedArray addVec = { mcBlock->mBlockIdx }; //auto newBlocksSeen = mTrackingContext.Add(blocksSeen, addVec, false); @@ -1822,7 +1822,7 @@ void BeMCLoopDetector::DetectLoops(BeMCBlock* mcBlock, BeVTrackingList* predBloc // Our ID was already set, so this is a re-entry and thus we are looped mcBlock->mIsLooped = true; } - blocksSeen = newBlocksSeen; + blocksSeen = newBlocksSeen; for (auto succ : mcBlock->mSuccs) { @@ -1852,7 +1852,7 @@ void BeMCLoopDetector::DetectLoops() ////////////////////////////////////////////////////////////////////////// void BeMCBlock::AddPred(BeMCBlock* pred) -{ +{ if (!mPreds.Contains(pred)) { pred->mSuccs.push_back(this); @@ -1905,13 +1905,14 @@ BeMCContext::BeMCContext(BeCOFFObject* coffObject) : mOut(coffObject->mTextSect. mModule = NULL; mBeFunction = NULL; mActiveBeBlock = NULL; - mActiveBlock = NULL; + mActiveBlock = NULL; + mActiveInst = NULL; mDbgFunction = NULL; mCompositeRetVRegIdx = -1; mTLSVRegIdx = -1; mStackSize = 0; mCurLabelIdx = 0; - mCurPhiIdx = 0; + mCurPhiIdx = 0; mMaxCallParamCount = -1; mCurDbgLoc = NULL; mCurVRegsInit = NULL; @@ -1932,12 +1933,22 @@ void BeMCContext::NotImpl() void BeMCContext::Fail(const StringImpl& str) { - String errStr = StrFormat("Failure during codegen of %s in %s: %s", mBeFunction->mName.c_str(), mModule->mModuleName.c_str(), str.c_str()); + String errStr = StrFormat("Failure during codegen of %s in %s: %s", mBeFunction->mName.c_str(), mModule->mModuleName.c_str(), str.c_str()); + + if (mActiveBlock != NULL) + errStr += StrFormat("\n MCBlock: %s", mActiveBlock->mName); + if ((mActiveInst != NULL) && (mActiveInst->mDbgLoc != NULL)) + { + BeDumpContext dumpCtx; + errStr += "\n DbgLoc : "; + dumpCtx.ToString(errStr, mActiveInst->mDbgLoc); + } + BfpSystem_FatalError(errStr.c_str(), "FATAL ERROR"); } void BeMCContext::SoftFail(const StringImpl& str, BeDbgLoc* dbgLoc) -{ +{ if (mFailed) return; mFailed = true; @@ -1968,7 +1979,7 @@ String BeMCContext::ToString(const BeMCOperand& operand) String str; mModule->ToString(str, GetType(operand)); str += " "; - + if (operand.IsVRegAny()) { auto vregInfo = GetVRegInfo(operand); @@ -1979,12 +1990,12 @@ String BeMCContext::ToString(const BeMCOperand& operand) if (vregInfo->mDbgVariable != NULL) str += "#" + vregInfo->mDbgVariable->mName + StrFormat("/%d", operand.mVRegIdx); else - str += StrFormat("%%vreg%d", operand.mVRegIdx); - } - + str += StrFormat("%%vreg%d", operand.mVRegIdx); + } + if (vregInfo->mReg != X64Reg_None) { - str += "<"; + str += "<"; str += X64CPURegisters::GetRegisterName((int)vregInfo->mReg); str += ">"; } @@ -1992,7 +2003,7 @@ String BeMCContext::ToString(const BeMCOperand& operand) { str += ""; } - + if (vregInfo->mDisableR11) { str += ""; @@ -2021,7 +2032,7 @@ String BeMCContext::ToString(const BeMCOperand& operand) if (vregInfo->mForceMem) { str += ""; - } + } if (vregInfo->mIsRetVal) { @@ -2034,13 +2045,13 @@ String BeMCContext::ToString(const BeMCOperand& operand) } if (vregInfo->mRelTo) - { + { str += "("; - str += ToString(vregInfo->mRelTo); + str += ToString(vregInfo->mRelTo); if (vregInfo->mRelOffset) { str += "+"; - str += ToString(vregInfo->mRelOffset); + str += ToString(vregInfo->mRelOffset); } if (vregInfo->mRelOffsetScale != 1) str += StrFormat("*%d", vregInfo->mRelOffsetScale); @@ -2073,7 +2084,7 @@ String BeMCContext::ToString(const BeMCOperand& operand) case BeMCOperandKind_Immediate_f64_Packed128: return StrFormat("f64_packed %f", operand.mImmF64); } //if (operand.mImmediate < 10) - str += StrFormat("%lld", operand.mImmediate); + str += StrFormat("%lld", operand.mImmediate); /*else str += StrFormat("0x%llX", operand.mImmediate);*/ return str; @@ -2088,8 +2099,8 @@ String BeMCContext::ToString(const BeMCOperand& operand) { String result = StrFormat("%%CmpResult%d", operand.mCmpResultIdx); auto& cmpResult = mCmpResults[operand.mCmpResultIdx]; - if (cmpResult.mResultVRegIdx != -1) - result += StrFormat("", cmpResult.mResultVRegIdx); + if (cmpResult.mResultVRegIdx != -1) + result += StrFormat("", cmpResult.mResultVRegIdx); result += " "; result += BeDumpContext::ToString(cmpResult.mCmpKind); return result; @@ -2101,7 +2112,7 @@ String BeMCContext::ToString(const BeMCOperand& operand) result += ToString(mcResult); return result; } - if (operand.mKind == BeMCOperandKind_Symbol) + if (operand.mKind == BeMCOperandKind_Symbol) return mCOFFObject->mSymbols[operand.mSymbolIdx]->mName; if (operand.mKind == BeMCOperandKind_SymbolAddr) return "&" + mCOFFObject->mSymbols[operand.mSymbolIdx]->mName; @@ -2111,7 +2122,7 @@ String BeMCContext::ToString(const BeMCOperand& operand) return StrFormat("size=%d align=%d", operand.mMemCpyInfo.mSize, operand.mMemCpyInfo.mAlign); if (operand.mKind == BeMCOperandKind_VRegPair) { - String str = "("; + String str = "("; str += ToString(BeMCOperand::FromEncoded(operand.mVRegPair.mVRegIdx0)); str += ", "; str += ToString(BeMCOperand::FromEncoded(operand.mVRegPair.mVRegIdx1)); @@ -2143,199 +2154,199 @@ BeMCOperand BeMCContext::GetOperand(BeValue* value, bool allowMetaResult, bool a switch (value->GetTypeId()) { case BeGlobalVariable::TypeId: + { + auto globalVar = (BeGlobalVariable*)value; + if ((globalVar->mIsTLS) && (mTLSVRegIdx == -1)) { - auto globalVar = (BeGlobalVariable*)value; - if ((globalVar->mIsTLS) && (mTLSVRegIdx == -1)) - { - auto tlsVReg = AllocVirtualReg(mNativeIntType); - auto vregInfo = GetVRegInfo(tlsVReg); - vregInfo->mMustExist = true; - vregInfo->mForceReg = true; - mTLSVRegIdx = tlsVReg.mVRegIdx; - } - - auto sym = mCOFFObject->GetSymbol(globalVar); - if (sym != NULL) - { - BeMCOperand mcOperand; - mcOperand.mKind = BeMCOperandKind_SymbolAddr; - mcOperand.mSymbolIdx = sym->mIdx; - return mcOperand; - } + auto tlsVReg = AllocVirtualReg(mNativeIntType); + auto vregInfo = GetVRegInfo(tlsVReg); + vregInfo->mMustExist = true; + vregInfo->mForceReg = true; + mTLSVRegIdx = tlsVReg.mVRegIdx; } - break; - case BeCastConstant::TypeId: + + auto sym = mCOFFObject->GetSymbol(globalVar); + if (sym != NULL) { - auto constant = (BeCastConstant*)value; - BeMCOperand mcOperand; - auto relTo = GetOperand(constant->mTarget); - if (relTo.mKind == BeMCOperandKind_Immediate_Null) + mcOperand.mKind = BeMCOperandKind_SymbolAddr; + mcOperand.mSymbolIdx = sym->mIdx; + return mcOperand; + } + } + break; + case BeCastConstant::TypeId: + { + auto constant = (BeCastConstant*)value; + + BeMCOperand mcOperand; + auto relTo = GetOperand(constant->mTarget); + if (relTo.mKind == BeMCOperandKind_Immediate_Null) + { + mcOperand.mKind = BeMCOperandKind_Immediate_Null; + mcOperand.mType = constant->mType; + return mcOperand; + } + + mcOperand = AllocVirtualReg(constant->mType); + auto vregInfo = GetVRegInfo(mcOperand); + vregInfo->mDefOnFirstUse = true; + vregInfo->mRelTo = relTo; + vregInfo->mIsExpr = true; + + return mcOperand; + } + break; + case BeConstant::TypeId: + { + auto constant = (BeConstant*)value; + BeMCOperand mcOperand; + switch (constant->mType->mTypeCode) + { + case BeTypeCode_Boolean: + case BeTypeCode_Int8: mcOperand.mKind = BeMCOperandKind_Immediate_i8; break; + case BeTypeCode_Int16: mcOperand.mKind = BeMCOperandKind_Immediate_i16; break; + case BeTypeCode_Int32: mcOperand.mKind = BeMCOperandKind_Immediate_i32; break; + case BeTypeCode_Int64: mcOperand.mKind = BeMCOperandKind_Immediate_i64; break; + case BeTypeCode_Float: + mcOperand.mImmF32 = constant->mDouble; + mcOperand.mKind = BeMCOperandKind_Immediate_f32; + return mcOperand; + case BeTypeCode_Double: + mcOperand.mImmF64 = constant->mDouble; + mcOperand.mKind = BeMCOperandKind_Immediate_f64; + return mcOperand; + case BeTypeCode_Pointer: + { + if (constant->mTarget == NULL) { mcOperand.mKind = BeMCOperandKind_Immediate_Null; mcOperand.mType = constant->mType; return mcOperand; } + else + { + auto relTo = GetOperand(constant->mTarget); - mcOperand = AllocVirtualReg(constant->mType); - auto vregInfo = GetVRegInfo(mcOperand); - vregInfo->mDefOnFirstUse = true; - vregInfo->mRelTo = relTo; - vregInfo->mIsExpr = true; + if (relTo.mKind == BeMCOperandKind_Immediate_Null) + { + mcOperand.mKind = BeMCOperandKind_Immediate_Null; + mcOperand.mType = constant->mType; + return mcOperand; + } - return mcOperand; + mcOperand = AllocVirtualReg(constant->mType); + auto vregInfo = GetVRegInfo(mcOperand); + vregInfo->mDefOnFirstUse = true; + vregInfo->mRelTo = relTo; + vregInfo->mIsExpr = true; + + return mcOperand; + } } break; - case BeConstant::TypeId: - { - auto constant = (BeConstant*)value; - BeMCOperand mcOperand; - switch (constant->mType->mTypeCode) - { - case BeTypeCode_Boolean: - case BeTypeCode_Int8: mcOperand.mKind = BeMCOperandKind_Immediate_i8; break; - case BeTypeCode_Int16: mcOperand.mKind = BeMCOperandKind_Immediate_i16; break; - case BeTypeCode_Int32: mcOperand.mKind = BeMCOperandKind_Immediate_i32; break; - case BeTypeCode_Int64: mcOperand.mKind = BeMCOperandKind_Immediate_i64; break; - case BeTypeCode_Float: - mcOperand.mImmF32 = constant->mDouble; - mcOperand.mKind = BeMCOperandKind_Immediate_f32; - return mcOperand; - case BeTypeCode_Double: - mcOperand.mImmF64 = constant->mDouble; - mcOperand.mKind = BeMCOperandKind_Immediate_f64; - return mcOperand; - case BeTypeCode_Pointer: - { - if (constant->mTarget == NULL) - { - mcOperand.mKind = BeMCOperandKind_Immediate_Null; - mcOperand.mType = constant->mType; - return mcOperand; - } - else - { - auto relTo = GetOperand(constant->mTarget); - - if (relTo.mKind == BeMCOperandKind_Immediate_Null) - { - mcOperand.mKind = BeMCOperandKind_Immediate_Null; - mcOperand.mType = constant->mType; - return mcOperand; - } - - mcOperand = AllocVirtualReg(constant->mType); - auto vregInfo = GetVRegInfo(mcOperand); - vregInfo->mDefOnFirstUse = true; - vregInfo->mRelTo = relTo; - vregInfo->mIsExpr = true; - - return mcOperand; - } - } - break; - case BeTypeCode_Struct: - case BeTypeCode_SizedArray: - mcOperand.mImmediate = constant->mInt64; - mcOperand.mKind = BeMCOperandKind_Immediate_i64; - break; - default: - Fail("Unhandled constant type"); - } + case BeTypeCode_Struct: + case BeTypeCode_SizedArray: mcOperand.mImmediate = constant->mInt64; - return mcOperand; + mcOperand.mKind = BeMCOperandKind_Immediate_i64; + break; + default: + Fail("Unhandled constant type"); } - break; + mcOperand.mImmediate = constant->mInt64; + return mcOperand; + } + break; case BeStructConstant::TypeId: - { - auto structConstant = (BeStructConstant*)value; + { + auto structConstant = (BeStructConstant*)value; - BeMCOperand mcOperand; - mcOperand.mKind = BeMCOperandKind_ConstAgg; - mcOperand.mConstant = structConstant; - - return mcOperand; - } + BeMCOperand mcOperand; + mcOperand.mKind = BeMCOperandKind_ConstAgg; + mcOperand.mConstant = structConstant; + + return mcOperand; + } case BeGEPConstant::TypeId: - { + { auto gepConstant = (BeGEPConstant*)value; auto mcVal = GetOperand(gepConstant->mTarget); - BePointerType* ptrType = (BePointerType*)GetType(mcVal); - BF_ASSERT(ptrType->mTypeCode == BeTypeCode_Pointer); + BePointerType* ptrType = (BePointerType*)GetType(mcVal); + BF_ASSERT(ptrType->mTypeCode == BeTypeCode_Pointer); - auto result = mcVal; - - // We assume we never do both an idx0 and idx1 at once. Fix if we change that. - int byteOffset = 0; - BeType* elementType = NULL; - byteOffset += gepConstant->mIdx0 * ptrType->mElementType->mSize; + auto result = mcVal; - if (ptrType->mElementType->mTypeCode == BeTypeCode_Struct) - { - BeStructType* structType = (BeStructType*)ptrType->mElementType; - auto& structMember = structType->mMembers[gepConstant->mIdx1]; - elementType = structMember.mType; - byteOffset = structMember.mByteOffset; - } - else - { - BF_ASSERT(ptrType->mElementType->mTypeCode == BeTypeCode_SizedArray); - auto arrayType = (BeSizedArrayType*)ptrType->mElementType; - elementType = arrayType->mElementType; - byteOffset = gepConstant->mIdx1 * elementType->mSize; - } + // We assume we never do both an idx0 and idx1 at once. Fix if we change that. + int byteOffset = 0; + BeType* elementType = NULL; + byteOffset += gepConstant->mIdx0 * ptrType->mElementType->mSize; - auto elementPtrType = mModule->mContext->GetPointerTo(elementType); - 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 = BeMCOperandKind_VReg; - - return result; - } - break; - case BeExtractValueConstant::TypeId: + if (ptrType->mElementType->mTypeCode == BeTypeCode_Struct) { - // Note: this only handles zero-aggregates - auto extractConstant = (BeExtractValueConstant*)value; - auto elementType = extractConstant->GetType(); - - auto mcVal = GetOperand(extractConstant->mTarget); - auto valType = GetType(mcVal); - - BeConstant beConstant; - beConstant.mType = elementType; - beConstant.mUInt64 = 0; - return GetOperand(&beConstant); + BeStructType* structType = (BeStructType*)ptrType->mElementType; + auto& structMember = structType->mMembers[gepConstant->mIdx1]; + elementType = structMember.mType; + byteOffset = structMember.mByteOffset; } - break; + else + { + BF_ASSERT(ptrType->mElementType->mTypeCode == BeTypeCode_SizedArray); + auto arrayType = (BeSizedArrayType*)ptrType->mElementType; + elementType = arrayType->mElementType; + byteOffset = gepConstant->mIdx1 * elementType->mSize; + } + + auto elementPtrType = mModule->mContext->GetPointerTo(elementType); + 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 = BeMCOperandKind_VReg; + + return result; + } + break; + case BeExtractValueConstant::TypeId: + { + // Note: this only handles zero-aggregates + auto extractConstant = (BeExtractValueConstant*)value; + auto elementType = extractConstant->GetType(); + + auto mcVal = GetOperand(extractConstant->mTarget); + auto valType = GetType(mcVal); + + BeConstant beConstant; + beConstant.mType = elementType; + beConstant.mUInt64 = 0; + return GetOperand(&beConstant); + } + break; case BeFunction::TypeId: + { + auto sym = mCOFFObject->GetSymbol(value); + BF_ASSERT(sym != NULL); + if (sym != NULL) { - auto sym = mCOFFObject->GetSymbol(value); - BF_ASSERT(sym != NULL); - if (sym != NULL) - { - BeMCOperand mcOperand; - mcOperand.mKind = BeMCOperandKind_SymbolAddr; - mcOperand.mSymbolIdx = sym->mIdx; - return mcOperand; - } + BeMCOperand mcOperand; + mcOperand.mKind = BeMCOperandKind_SymbolAddr; + mcOperand.mSymbolIdx = sym->mIdx; + return mcOperand; } - break; + } + break; case BeCallInst::TypeId: - { - auto callInst = (BeCallInst*)value; - if (callInst->mInlineResult != NULL) - return GetOperand(callInst->mInlineResult); - } - break; + { + auto callInst = (BeCallInst*)value; + if (callInst->mInlineResult != NULL) + return GetOperand(callInst->mInlineResult); + } + break; case BeDbgVariable::TypeId: - { - - } + { + + } } BeMCOperand* operandPtr = NULL; @@ -2364,9 +2375,9 @@ BeMCOperand BeMCContext::GetOperand(BeValue* value, bool allowMetaResult, bool a auto operand = *operandPtr; if ((operand.mKind == BeMCOperandKind_Phi) && (!allowMetaResult)) - { + { auto phi = operand.mPhi; - + int phiInstIdx = 0; auto mcBlock = phi->mBlock; @@ -2374,29 +2385,29 @@ BeMCOperand BeMCContext::GetOperand(BeValue* value, bool allowMetaResult, bool a { auto inst = mcBlock->mInstructions[instIdx]; if (inst->mKind == BeMCInstKind_DefPhi) - { + { BF_ASSERT(inst->mArg0.mPhi == phi); phiInstIdx = instIdx; RemoveInst(mcBlock, phiInstIdx); break; } - } + } SetAndRestoreValue prevBlock(mActiveBlock, mcBlock); SetAndRestoreValue prevInstIdxRef(mInsertInstIdxRef, &phiInstIdx); auto resultType = value->GetType(); - auto result = AllocVirtualReg(resultType); + auto result = AllocVirtualReg(resultType); auto vregInfo = GetVRegInfo(result); vregInfo->mHasDynLife = true; // No specific 'def' location - mValueToOperand[value] = result; + mValueToOperand[value] = result; if (resultType->mTypeCode == BeTypeCode_Boolean) { - CreateDefineVReg(result); + CreateDefineVReg(result); BeMCOperand falseLabel = BeMCOperand::FromLabel(mCurLabelIdx++); - BeMCOperand trueLabel = BeMCOperand::FromLabel(mCurLabelIdx++); + BeMCOperand trueLabel = BeMCOperand::FromLabel(mCurLabelIdx++); BeMCOperand endLabel = BeMCOperand::FromLabel(mCurLabelIdx++); CreateCondBr(mActiveBlock, operand, trueLabel, falseLabel); @@ -2404,7 +2415,7 @@ BeMCOperand BeMCContext::GetOperand(BeValue* value, bool allowMetaResult, bool a AllocInst(BeMCInstKind_Mov, result, BeMCOperand::FromImmediate(0)); AllocInst(BeMCInstKind_Br, endLabel); AllocInst(BeMCInstKind_Label, trueLabel); - AllocInst(BeMCInstKind_Mov, result, BeMCOperand::FromImmediate(1)); + AllocInst(BeMCInstKind_Mov, result, BeMCOperand::FromImmediate(1)); AllocInst(BeMCInstKind_Label, endLabel); } else @@ -2414,7 +2425,7 @@ BeMCOperand BeMCContext::GetOperand(BeValue* value, bool allowMetaResult, bool a blockSearch.reserve(phi->mValues.size()); BeMCBlock* lowestBlock = NULL; for (auto& phiValue : phi->mValues) - { + { if ((lowestBlock == NULL) || (phiValue.mBlockFrom->mBlockIdx < lowestBlock->mBlockIdx)) lowestBlock = phiValue.mBlockFrom; blockSearch.push_back(phiValue.mBlockFrom); @@ -2439,13 +2450,13 @@ BeMCOperand BeMCContext::GetOperand(BeValue* value, bool allowMetaResult, bool a didWork = true; } } - } + } } if (allMatched) { SetAndRestoreValue prevActiveBlock(mActiveBlock, lowestBlock); - SetAndRestoreValue prevInstIdxRef(mInsertInstIdxRef, NULL); + SetAndRestoreValue prevInstIdxRef(mInsertInstIdxRef, NULL); auto inst = CreateDefineVReg(result); inst->mVRegsInitialized = NULL; inst->mDbgLoc = NULL; @@ -2468,7 +2479,7 @@ BeMCOperand BeMCContext::GetOperand(BeValue* value, bool allowMetaResult, bool a } } } - + if (nextLowestBlock == NULL) break; lowestBlock = nextLowestBlock; @@ -2482,12 +2493,12 @@ BeMCOperand BeMCContext::GetOperand(BeValue* value, bool allowMetaResult, bool a SetAndRestoreValue prevDbgLoc(mCurDbgLoc, NULL); AllocInst(BeMCInstKind_Label, doneLabel); } - + return result; } if ((operand.mKind == BeMCOperandKind_CmpResult) && (!allowMetaResult)) - { + { auto& cmpResult = mCmpResults[operand.mCmpResultIdx]; if (cmpResult.mResultVRegIdx == -1) { @@ -2523,7 +2534,7 @@ BeMCOperand BeMCContext::GetOperand(BeValue* value, bool allowMetaResult, bool a BeType* BeMCContext::GetType(const BeMCOperand& operand) { if (operand.mKind == BeMCOperandKind_NativeReg) - { + { if ((operand.mReg >= X64Reg_RAX) && (operand.mReg <= X64Reg_EFL)) return mModule->mContext->GetPrimitiveType(BeTypeCode_Int64); if ((operand.mReg >= X64Reg_EAX) && (operand.mReg <= X64Reg_R15D)) @@ -2540,8 +2551,8 @@ BeType* BeMCContext::GetType(const BeMCOperand& operand) if (operand.mKind == BeMCOperandKind_VReg) return mVRegInfo[operand.mVRegIdx]->mType; - if (operand.mKind == BeMCOperandKind_VRegAddr) - return mModule->mContext->GetPointerTo(mVRegInfo[operand.mVRegIdx]->mType); + if (operand.mKind == BeMCOperandKind_VRegAddr) + return mModule->mContext->GetPointerTo(mVRegInfo[operand.mVRegIdx]->mType); if (operand.mKind == BeMCOperandKind_VRegLoad) { auto type = mVRegInfo[operand.mVRegIdx]->mType; @@ -2554,11 +2565,11 @@ BeType* BeMCContext::GetType(const BeMCOperand& operand) case BeMCOperandKind_Immediate_i8: return mModule->mContext->GetPrimitiveType(BeTypeCode_Int8); break; case BeMCOperandKind_Immediate_i16: return mModule->mContext->GetPrimitiveType(BeTypeCode_Int16); break; case BeMCOperandKind_Immediate_i32: return mModule->mContext->GetPrimitiveType(BeTypeCode_Int32); break; - case BeMCOperandKind_Immediate_i64: return mModule->mContext->GetPrimitiveType(BeTypeCode_Int64); break; + case BeMCOperandKind_Immediate_i64: return mModule->mContext->GetPrimitiveType(BeTypeCode_Int64); break; case BeMCOperandKind_Immediate_Null: return operand.mType; break; - case BeMCOperandKind_Immediate_f32: + case BeMCOperandKind_Immediate_f32: case BeMCOperandKind_Immediate_f32_Packed128: return mModule->mContext->GetPrimitiveType(BeTypeCode_Float); break; - case BeMCOperandKind_Immediate_f64: + case BeMCOperandKind_Immediate_f64: case BeMCOperandKind_Immediate_f64_Packed128: return mModule->mContext->GetPrimitiveType(BeTypeCode_Double); break; } @@ -2609,7 +2620,7 @@ void BeMCContext::AddRelRefs(BeMCOperand& operand, int refCount) } int BeMCContext::FindSafeInstInsertPos(int instIdx, bool forceSafeCheck) -{ +{ auto inst = mActiveBlock->mInstructions[instIdx]; bool doSafeCheck = false; if (forceSafeCheck) @@ -2628,7 +2639,7 @@ int BeMCContext::FindSafeInstInsertPos(int instIdx, bool forceSafeCheck) int bestIdx = instIdx; while (bestIdx > 0) { - inst = mActiveBlock->mInstructions[bestIdx - 1]; + inst = mActiveBlock->mInstructions[bestIdx - 1]; bestIdx--; if (inst->mKind == BeMCInstKind_PreserveVolatiles) @@ -2652,14 +2663,14 @@ BeMCInst* BeMCContext::AllocInst(int insertIdx) else if ((insertIdx < mActiveBlock->mInstructions.mSize) && (mActiveBlock->mInstructions[insertIdx] == NULL)) mActiveBlock->mInstructions[insertIdx] = mcInst; else - mActiveBlock->mInstructions.Insert(insertIdx, mcInst); + mActiveBlock->mInstructions.Insert(insertIdx, mcInst); return mcInst; } BeMCInst* BeMCContext::AllocInst(BeMCInstKind instKind, int insertIdx) { auto mcInst = AllocInst(insertIdx); - mcInst->mKind = instKind; + mcInst->mKind = instKind; return mcInst; } @@ -2667,7 +2678,7 @@ BeMCInst* BeMCContext::AllocInst(BeMCInstKind instKind, const BeMCOperand& arg0, { auto mcInst = AllocInst(insertIdx); mcInst->mKind = instKind; - mcInst->mArg0 = arg0; + mcInst->mArg0 = arg0; return mcInst; } @@ -2686,12 +2697,12 @@ void BeMCContext::MergeInstFlags(BeMCInst* prevInst, BeMCInst* inst, BeMCInst* n if (prevInst->mVRegsInitialized == inst->mVRegsInitialized) return; - if ((inst->mVRegsInitialized != NULL) && (nextInst->mVRegsInitialized != NULL)) - nextInst->mVRegsInitialized = mVRegInitializedContext.MergeChanges(nextInst->mVRegsInitialized, inst->mVRegsInitialized); + if ((inst->mVRegsInitialized != NULL) && (nextInst->mVRegsInitialized != NULL)) + nextInst->mVRegsInitialized = mVRegInitializedContext.MergeChanges(nextInst->mVRegsInitialized, inst->mVRegsInitialized); } void BeMCContext::RemoveInst(BeMCBlock* block, int instIdx, bool needChangesMerged, bool removeFromList) -{ +{ // If neither the instruction before or after this one shares the vregsInitialized flags, then we need to // merge down our Changes to the next instruction auto inst = block->mInstructions[instIdx]; @@ -2721,29 +2732,29 @@ void BeMCContext::RemoveInst(BeMCBlock* block, int instIdx, bool needChangesMerg BeMCOperand BeMCContext::GetCallArgVReg(int argIdx, BeTypeCode typeCode) { - int pIdx = argIdx; + int pIdx = argIdx; BeMCNativeTypeCode vregType = BeMCNativeTypeCode_Int64; switch (typeCode) { - case BeTypeCode_Int8: + case BeTypeCode_Int8: vregType = BeMCNativeTypeCode_Int8; break; - case BeTypeCode_Int16: + case BeTypeCode_Int16: vregType = BeMCNativeTypeCode_Int16; break; - case BeTypeCode_Int32: + case BeTypeCode_Int32: vregType = BeMCNativeTypeCode_Int32; break; - case BeTypeCode_Int64: + case BeTypeCode_Int64: vregType = BeMCNativeTypeCode_Int64; break; - case BeTypeCode_Float: + case BeTypeCode_Float: vregType = BeMCNativeTypeCode_Float; break; - case BeTypeCode_Double: + case BeTypeCode_Double: vregType = BeMCNativeTypeCode_Double; - break; + break; default: typeCode = BeTypeCode_Int64; vregType = BeMCNativeTypeCode_Int64; @@ -2757,19 +2768,19 @@ BeMCOperand BeMCContext::GetCallArgVReg(int argIdx, BeTypeCode typeCode) { auto nativeType = mModule->mContext->GetPrimitiveType(typeCode); auto nativePtrType = mModule->mContext->GetPointerTo(nativeType); - auto mcArg = AllocVirtualReg(nativePtrType); + auto mcArg = AllocVirtualReg(nativePtrType); auto vregInfo = mVRegInfo[mcArg.mVRegIdx]; vregInfo->mMustExist = true; vregInfo->mIsExpr = true; vregInfo->mRelTo = BeMCOperand::FromReg(X64Reg_RSP); - vregInfo->mRelOffset = BeMCOperand::FromImmediate(argIdx * 8); + vregInfo->mRelOffset = BeMCOperand::FromImmediate(argIdx * 8); callArgVRegs[pIdx] = mcArg.mVRegIdx; mcArg.mKind = BeMCOperandKind_VRegLoad; return mcArg; } else { - auto mcArg = BeMCOperand::FromVReg(callArgVRegs[pIdx]); + auto mcArg = BeMCOperand::FromVReg(callArgVRegs[pIdx]); mcArg.mKind = BeMCOperandKind_VRegLoad; return mcArg; } @@ -2777,7 +2788,7 @@ BeMCOperand BeMCContext::GetCallArgVReg(int argIdx, BeTypeCode typeCode) BeMCOperand BeMCContext::CreateCall(const BeMCOperand &func, const SizedArrayImpl& args, BeType* retType, BfIRCallingConv callingConv, bool structRet, bool noReturn, bool isVarArg) { - SizedArray opArgs; + SizedArray opArgs; for (auto itr = args.begin(); itr != args.end(); ++itr) { auto& arg = *itr; @@ -2789,7 +2800,7 @@ BeMCOperand BeMCContext::CreateCall(const BeMCOperand &func, const SizedArrayImp BeMCOperand BeMCContext::CreateLoad(const BeMCOperand& mcTarget) { if (mcTarget.mKind == BeMCOperandKind_Immediate_Null) - { + { auto fakeType = GetType(mcTarget); auto fakePtr = AllocVirtualReg(fakeType); CreateDefineVReg(fakePtr); @@ -2801,7 +2812,7 @@ BeMCOperand BeMCContext::CreateLoad(const BeMCOperand& mcTarget) auto loadedTarget = BeMCOperand::ToLoad(mcTarget); auto targetType = GetType(loadedTarget); - result = AllocVirtualReg(targetType); + result = AllocVirtualReg(targetType); auto vregInfo = GetVRegInfo(result); vregInfo->mIsExpr = true; vregInfo->mRelTo = loadedTarget; @@ -2895,28 +2906,28 @@ void BeMCContext::CreateStore(BeMCInstKind instKind, const BeMCOperand& val, con } BeMCOperand BeMCContext::CreateCall(const BeMCOperand& func, const SizedArrayImpl& args, BeType* retType, BfIRCallingConv callingConv, bool structRet, bool noReturn, bool isVarArg) -{ +{ BeMCOperand mcResult; //TODO: Allow user to directly specify ret addr with "sret" attribute int argOfs = 0; X64CPURegister compositeRetReg = X64Reg_None; - bool flipFirstRegs = (structRet) && (callingConv == BfIRCallingConv_ThisCall); + bool flipFirstRegs = (structRet) && (callingConv == BfIRCallingConv_ThisCall); if ((retType != NULL) && (retType->IsComposite())) { mcResult = AllocVirtualReg(retType); auto vregInfo = GetVRegInfo(mcResult); vregInfo->mMustExist = true; - CreateDefineVReg(mcResult); + CreateDefineVReg(mcResult); // 'this' always goes in RCX, so push compositeRetReg out by one compositeRetReg = (callingConv == BfIRCallingConv_ThisCall) ? X64Reg_RDX : X64Reg_RCX; AllocInst(BeMCInstKind_Mov, BeMCOperand::FromReg(compositeRetReg), BeMCOperand::FromVRegAddr(mcResult.mVRegIdx)); argOfs = 1; - } - + } + bool didPreserveRegs = false; - auto _AddPreserveRegs = [&] () + auto _AddPreserveRegs = [&]() { if (noReturn) AllocInst(BeMCInstKind_PreserveVolatiles, BeMCOperand::FromPreserveFlag(BeMCPreserveFlag_NoRestore)); @@ -2924,11 +2935,11 @@ BeMCOperand BeMCContext::CreateCall(const BeMCOperand& func, const SizedArrayImp AllocInst(BeMCInstKind_PreserveVolatiles); didPreserveRegs = true; }; - + int argCount = (int)args.size() + argOfs; int dynStackSize = 0; - if (dynStackSize > 0) + if (dynStackSize > 0) AllocInst(BeMCInstKind_Sub, BeMCOperand::FromReg(X64Reg_RSP), BeMCOperand::FromImmediate(dynStackSize)); struct _ShadowReg @@ -2951,7 +2962,7 @@ BeMCOperand BeMCContext::CreateCall(const BeMCOperand& func, const SizedArrayImp auto argType = GetType(mcValue); X64CPURegister useReg = X64Reg_None; int useArgIdx = argIdx + argOfs; - + if (argType->IsFloat()) { switch (useArgIdx) @@ -2968,7 +2979,7 @@ BeMCOperand BeMCContext::CreateCall(const BeMCOperand& func, const SizedArrayImp case 3: useReg = (argType->mTypeCode == BeTypeCode_Float) ? X64Reg_XMM3_f32 : X64Reg_XMM3_f64; break; - } + } if (isVarArg) { @@ -2991,7 +3002,7 @@ BeMCOperand BeMCContext::CreateCall(const BeMCOperand& func, const SizedArrayImp if ((shadowReg != X64Reg_None) && (useReg != X64Reg_None)) { - shadowRegs.push_back(_ShadowReg { useReg, shadowReg} ); + shadowRegs.push_back(_ShadowReg{ useReg, shadowReg }); } } } @@ -3012,11 +3023,11 @@ BeMCOperand BeMCContext::CreateCall(const BeMCOperand& func, const SizedArrayImp useReg = X64Reg_R9; break; } - } + } if ((!argType->IsComposite()) && (!isVarArg)) // VarArg uses full 64 bits useReg = ResizeRegister(useReg, argType->mSize); - + if (mcValue.mKind == BeMCOperandKind_VRegAddr) { auto vregInfo = GetVRegInfo(mcValue); @@ -3033,10 +3044,10 @@ BeMCOperand BeMCContext::CreateCall(const BeMCOperand& func, const SizedArrayImp if (!didPreserveRegs) _AddPreserveRegs(); - AllocInst(BeMCInstKind_Mov, BeMCOperand::FromReg(useReg), mcValue); + AllocInst(BeMCInstKind_Mov, BeMCOperand::FromReg(useReg), mcValue); } else - { + { auto useTypeCode = argType->mTypeCode; if (isVarArg) { @@ -3049,32 +3060,32 @@ BeMCOperand BeMCContext::CreateCall(const BeMCOperand& func, const SizedArrayImp auto callArgVReg = GetCallArgVReg(useArgIdx, useTypeCode); // Do a 'def' for every usage, to clear out the 'init' at all paths CreateDefineVReg(BeMCOperand::FromVReg(callArgVReg.mVRegIdx)); - + if (argType->IsComposite()) { - BF_ASSERT(mcValue.mKind == BeMCOperandKind_VReg); + BF_ASSERT(mcValue.mKind == BeMCOperandKind_VReg); AllocInst(BeMCInstKind_Mov, callArgVReg, BeMCOperand::FromVRegAddr(mcValue.mVRegIdx)); } else AllocInst(BeMCInstKind_Mov, callArgVReg, mcValue); - } - } + } + } if (!didPreserveRegs) _AddPreserveRegs(); auto mcFunc = func; - - for (auto& shadowReg : shadowRegs ) // Do float shadowing - { - AllocInst(BeMCInstKind_MovRaw, BeMCOperand::FromReg(shadowReg.mIReg), BeMCOperand::FromReg(shadowReg.mFReg)); + + for (auto& shadowReg : shadowRegs) // Do float shadowing + { + AllocInst(BeMCInstKind_MovRaw, BeMCOperand::FromReg(shadowReg.mIReg), BeMCOperand::FromReg(shadowReg.mFReg)); } - AllocInst(BeMCInstKind_Call, mcFunc); + AllocInst(BeMCInstKind_Call, mcFunc); - if (dynStackSize > 0) + if (dynStackSize > 0) AllocInst(BeMCInstKind_Add, BeMCOperand::FromReg(X64Reg_RSP), BeMCOperand::FromImmediate(dynStackSize)); - + if ((!mcResult) && (retType != NULL) && (retType->mTypeCode != BeTypeCode_None)) { mcResult = AllocVirtualReg(retType); @@ -3090,11 +3101,11 @@ BeMCOperand BeMCContext::CreateCall(const BeMCOperand& func, const SizedArrayImp BF_ASSERT(retType->IsIntable()); resultReg = ResizeRegister(X64Reg_RAX, retType->mSize); } - + AllocInst(BeMCInstKind_Mov, mcResult, BeMCOperand::FromReg(resultReg)); } - if (noReturn) + if (noReturn) AllocInst(BeMCInstKind_RestoreVolatiles, BeMCOperand::FromPreserveFlag(BeMCPreserveFlag_NoRestore)); else AllocInst(BeMCInstKind_RestoreVolatiles); @@ -3102,9 +3113,9 @@ BeMCOperand BeMCContext::CreateCall(const BeMCOperand& func, const SizedArrayImp } void BeMCContext::CreateMemSet(const BeMCOperand& addr, uint8 val, int size, int align) -{ +{ if ((size == 8) || (size == 4) || (size == 2) || (size == 1)) - { + { BeType* type = NULL; BeMCOperand zeroVal; zeroVal.mImmediate = 0; @@ -3114,7 +3125,7 @@ void BeMCContext::CreateMemSet(const BeMCOperand& addr, uint8 val, int size, int case 8: type = mModule->mContext->GetPrimitiveType(BeTypeCode_Int64); zeroVal.mKind = BeMCOperandKind_Immediate_i64; - zeroVal.mImmediate = ((int64)val << 56) | ((int64)val << 48) | ((int64)val << 40) | ((int64)val << 32) | + zeroVal.mImmediate = ((int64)val << 56) | ((int64)val << 48) | ((int64)val << 40) | ((int64)val << 32) | (val << 24) | (val << 16) | (val << 8) | val; break; case 4: @@ -3144,12 +3155,12 @@ void BeMCContext::CreateMemSet(const BeMCOperand& addr, uint8 val, int size, int BeMCOperand dest; dest.mKind = BeMCOperandKind_VRegLoad; - dest.mVRegIdx = result.mVRegIdx; + dest.mVRegIdx = result.mVRegIdx; AllocInst(BeMCInstKind_Mov, dest, zeroVal); return; } - + if (addr.IsVRegAny()) { auto vregInfo = GetVRegInfo(addr); @@ -3159,9 +3170,9 @@ void BeMCContext::CreateMemSet(const BeMCOperand& addr, uint8 val, int size, int } if (size <= 256) - { - auto temp = addr; - + { + auto temp = addr; + BeMCOperand mcMemSetInfo; mcMemSetInfo.mKind = BeMCOperandKind_MemSetInfo; mcMemSetInfo.mMemSetInfo.mSize = size; @@ -3188,7 +3199,7 @@ void BeMCContext::CreateMemCpy(const BeMCOperand& dest, const BeMCOperand& src, return; if (size <= 256) - { + { int destIdx = -1; if (!GetEncodedOperand(dest, destIdx)) { @@ -3200,7 +3211,7 @@ void BeMCContext::CreateMemCpy(const BeMCOperand& dest, const BeMCOperand& src, vregInfo->mDisableR11 = true; destIdx = tempDest.mVRegIdx; } - + int srcIdx = -1; if (!GetEncodedOperand(src, srcIdx)) { @@ -3220,7 +3231,7 @@ void BeMCContext::CreateMemCpy(const BeMCOperand& dest, const BeMCOperand& src, AllocInst(BeMCInstKind_PreserveVolatiles, BeMCOperand::FromReg(X64Reg_R11)); BeMCOperand mcVRegPair; - mcVRegPair.mKind = BeMCOperandKind_VRegPair; + mcVRegPair.mKind = BeMCOperandKind_VRegPair; mcVRegPair.mVRegPair.mVRegIdx0 = destIdx; mcVRegPair.mVRegPair.mVRegIdx1 = srcIdx; AllocInst(BeMCInstKind_MemCpy, mcMemCpyInfo, mcVRegPair); @@ -3234,7 +3245,7 @@ void BeMCContext::CreateMemCpy(const BeMCOperand& dest, const BeMCOperand& src, } void BeMCContext::CreateTableSwitchSection(BeSwitchInst* switchInst, int startIdx, int endIdx) -{ +{ auto& sect = mCOFFObject->mRDataSect; auto defaultBlock = GetOperand(switchInst->mDefaultBlock); @@ -3242,18 +3253,18 @@ void BeMCContext::CreateTableSwitchSection(BeSwitchInst* switchInst, int startId auto int32Type = mModule->mContext->GetPrimitiveType(BeTypeCode_Int32); auto int32PtrType = mModule->mContext->GetPointerTo(int32Type); auto nativeType = mModule->mContext->GetPrimitiveType(BeTypeCode_Int64); - auto nativePtrType = mModule->mContext->GetPointerTo(nativeType); + auto nativePtrType = mModule->mContext->GetPointerTo(nativeType); int64 loVal = switchInst->mCases.front().mValue->mInt64; int64 hiVal = switchInst->mCases.back().mValue->mInt64; int numVals = switchInst->mCases.size(); - BeMCSymbol* sym = mCOFFObject->mSymbols.Alloc(); + BeMCSymbol* sym = mCOFFObject->mSymbols.Alloc(); sym->mType = int32Type; sym->mName = StrFormat("@jumpTab%d", mCOFFObject->mCurJumpTableIdx++); sym->mIsStatic = true; sym->mSymKind = BeMCSymbolKind_External; - sym->mIdx = (int)mCOFFObject->mSymbols.size() - 1; + sym->mIdx = (int)mCOFFObject->mSymbols.size() - 1; mCOFFObject->MarkSectionUsed(sect); sym->mSectionNum = sect.mSectionIdx + 1; @@ -3262,7 +3273,7 @@ void BeMCContext::CreateTableSwitchSection(BeSwitchInst* switchInst, int startId sym->mValue = sect.mData.GetSize(); auto mcValue = GetOperand(switchInst->mValue); - + auto beType = GetType(mcValue); auto mcOfsValue = AllocVirtualReg(nativeType); @@ -3275,10 +3286,10 @@ void BeMCContext::CreateTableSwitchSection(BeSwitchInst* switchInst, int startId AllocInst(BeMCInstKind_CondBr, defaultBlock, BeMCOperand::FromCmpKind(BeCmpKind_SLT)); AllocInst(BeMCInstKind_Cmp, mcOfsValue, BeMCOperand::FromImmediate(hiVal - loVal)); AllocInst(BeMCInstKind_CondBr, defaultBlock, BeMCOperand::FromCmpKind(BeCmpKind_SGT)); - + auto jumpVReg = AllocVirtualReg(nativeType); CreateDefineVReg(jumpVReg); - AllocInst(BeMCInstKind_Mov, jumpVReg, BeMCOperand::FromSymbolAddr(sym->mIdx)); + AllocInst(BeMCInstKind_Mov, jumpVReg, BeMCOperand::FromSymbolAddr(sym->mIdx)); auto jumpRelVReg = AllocVirtualReg(int32PtrType); CreateDefineVReg(jumpRelVReg); @@ -3289,16 +3300,16 @@ void BeMCContext::CreateTableSwitchSection(BeSwitchInst* switchInst, int startId vregInfo->mRelOffsetScale = 4; jumpRelVReg.mKind = BeMCOperandKind_VRegLoad; - AllocInst(BeMCInstKind_Mov, jumpVReg, jumpRelVReg); + AllocInst(BeMCInstKind_Mov, jumpVReg, jumpRelVReg); auto imageBaseSym = mCOFFObject->GetSymbolRef("__ImageBase"); - imageBaseSym->mType = nativeType; + imageBaseSym->mType = nativeType; auto baseVReg = AllocVirtualReg(nativeType); CreateDefineVReg(baseVReg); AllocInst(BeMCInstKind_Mov, baseVReg, BeMCOperand::FromSymbolAddr(imageBaseSym->mIdx)); AllocInst(BeMCInstKind_Add, jumpVReg, baseVReg); - AllocInst(BeMCInstKind_Br, jumpVReg); + AllocInst(BeMCInstKind_Br, jumpVReg); int64 lastVal = loVal - 1; @@ -3308,7 +3319,7 @@ void BeMCContext::CreateTableSwitchSection(BeSwitchInst* switchInst, int startId { auto& switchCase = switchInst->mCases[caseIdx]; int64 newVal = switchCase.mValue->mInt64; - + for (int64 val = lastVal + 1; val <= newVal; val++) { BeMCSwitchEntry switchEntry; @@ -3322,12 +3333,12 @@ void BeMCContext::CreateTableSwitchSection(BeSwitchInst* switchInst, int startId else { switchEntry.mBlock = defaultBlock.mBlock; - } + } mSwitchEntries.push_back(switchEntry); // Placeholder - sect.mData.Write((int32)0); + sect.mData.Write((int32)0); } lastVal = newVal; @@ -3335,30 +3346,30 @@ void BeMCContext::CreateTableSwitchSection(BeSwitchInst* switchInst, int startId } void BeMCContext::CreateBinarySwitchSection(BeSwitchInst* switchInst, int startIdx, int endIdx) -{ +{ // This is an empirically determined binary switching limit - if (endIdx - startIdx >= 18) - { - int gteLabel = mCurLabelIdx++; - - auto mcDefaultBlock = GetOperand(switchInst->mDefaultBlock); - - int midIdx = startIdx + (endIdx - startIdx) / 2; - auto& switchCase = switchInst->mCases[midIdx]; - auto switchBlock = GetOperand(switchCase.mBlock); - auto mcValue = GetOperand(switchInst->mValue); + if (endIdx - startIdx >= 18) + { + int gteLabel = mCurLabelIdx++; + + auto mcDefaultBlock = GetOperand(switchInst->mDefaultBlock); + + int midIdx = startIdx + (endIdx - startIdx) / 2; + auto& switchCase = switchInst->mCases[midIdx]; + auto switchBlock = GetOperand(switchCase.mBlock); + auto mcValue = GetOperand(switchInst->mValue); auto valueType = GetType(mcValue); - - AllocInst(BeMCInstKind_Cmp, mcValue, GetOperand(switchCase.mValue)); - AllocInst(BeMCInstKind_CondBr, BeMCOperand::FromLabel(gteLabel), BeMCOperand::FromCmpKind(BeCmpKind_SGE)); - switchBlock.mBlock->AddPred(mActiveBlock); - - CreateBinarySwitchSection(switchInst, startIdx, midIdx); - AllocInst(BeMCInstKind_Br, mcDefaultBlock); - CreateLabel(-1, gteLabel); - CreateBinarySwitchSection(switchInst, midIdx, endIdx); - return; - } + + AllocInst(BeMCInstKind_Cmp, mcValue, GetOperand(switchCase.mValue)); + AllocInst(BeMCInstKind_CondBr, BeMCOperand::FromLabel(gteLabel), BeMCOperand::FromCmpKind(BeCmpKind_SGE)); + switchBlock.mBlock->AddPred(mActiveBlock); + + CreateBinarySwitchSection(switchInst, startIdx, midIdx); + AllocInst(BeMCInstKind_Br, mcDefaultBlock); + CreateLabel(-1, gteLabel); + CreateBinarySwitchSection(switchInst, midIdx, endIdx); + return; + } for (int caseIdx = startIdx; caseIdx < endIdx; caseIdx++) { @@ -3368,11 +3379,11 @@ void BeMCContext::CreateBinarySwitchSection(BeSwitchInst* switchInst, int startI AllocInst(BeMCInstKind_Cmp, mcValue, GetOperand(switchCase.mValue)); AllocInst(BeMCInstKind_CondBr, switchBlock, BeMCOperand::FromCmpKind(BeCmpKind_EQ)); switchBlock.mBlock->AddPred(mActiveBlock); - } + } } void BeMCContext::CreateCondBr(BeMCBlock* mcBlock, BeMCOperand& testVal, const BeMCOperand& trueBlock, const BeMCOperand& falseBlock) -{ +{ if (testVal.IsImmediate()) { if (testVal.mImmediate != 0) @@ -3388,7 +3399,7 @@ void BeMCContext::CreateCondBr(BeMCBlock* mcBlock, BeMCOperand& testVal, const B AllocInst(BeMCInstKind_Br, falseBlock); } else if (testVal.mKind == BeMCOperandKind_Phi) - { + { auto phi = testVal.mPhi; auto phiBlock = phi->mBlock; @@ -3399,11 +3410,11 @@ void BeMCContext::CreateCondBr(BeMCBlock* mcBlock, BeMCOperand& testVal, const B { auto inst = phiBlock->mInstructions[instIdx]; if (inst->mKind == BeMCInstKind_Br) - { + { if (inst->mArg0 == phi->mBrTrue) inst->mArg0 = trueBlock; else if (inst->mArg0 == phi->mBrFalse) - inst->mArg0 = falseBlock; + inst->mArg0 = falseBlock; } } @@ -3442,14 +3453,14 @@ void BeMCContext::CreateCondBr(BeMCBlock* mcBlock, BeMCOperand& testVal, const B landinglabel = BeMCOperand::FromLabel(mCurLabelIdx++); AllocInst(BeMCInstKind_Label, landinglabel); } - + int brInstIdx = -1; bool isFalseCmpResult = false; if (landinglabel) { bool found = false; - - auto _CheckBlock = [&] (BeMCBlock* block) + + auto _CheckBlock = [&](BeMCBlock* block) { for (int checkIdx = (int)block->mInstructions.size() - 1; checkIdx >= 0; checkIdx--) { @@ -3474,7 +3485,7 @@ void BeMCContext::CreateCondBr(BeMCBlock* mcBlock, BeMCOperand& testVal, const B } } - } + } } }; @@ -3484,15 +3495,15 @@ void BeMCContext::CreateCondBr(BeMCBlock* mcBlock, BeMCOperand& testVal, const B } if (isFalseCmpResult) - { + { BF_ASSERT(phiVal.mValue.mKind == BeMCOperandKind_CmpResult); AllocInst(BeMCInstKind_Br, falseBlock); } - else if ((phiVal.mValue.IsImmediate()) || - (phiVal.mValue.mKind == BeMCOperandKind_CmpResult) || + else if ((phiVal.mValue.IsImmediate()) || + (phiVal.mValue.mKind == BeMCOperandKind_CmpResult) || (phiVal.mValue.mKind == BeMCOperandKind_Phi) || (phiVal.mValue.mKind == BeMCOperandKind_NotResult)) - { + { CreateCondBr(phiVal.mBlockFrom, phiVal.mValue, trueBlock, falseBlock); } else @@ -3532,14 +3543,14 @@ void BeMCContext::CreateCondBr(BeMCBlock* mcBlock, BeMCOperand& testVal, const B } void BeMCContext::CreatePhiAssign(BeMCBlock* mcBlock, const BeMCOperand& testVal, const BeMCOperand& result, const BeMCOperand& doneLabel) -{ +{ if (testVal.mKind == BeMCOperandKind_Phi) { auto phi = testVal.mPhi; for (auto& phiVal : phi->mValues) { - BeMCOperand landinglabel; + BeMCOperand landinglabel; if (phiVal.mValue.mKind == BeMCOperandKind_Phi) { // Remove PhiDef @@ -3562,7 +3573,7 @@ void BeMCContext::CreatePhiAssign(BeMCBlock* mcBlock, const BeMCOperand& testVal { bool found = false; - auto _CheckBlock = [&] (BeMCBlock* block) + auto _CheckBlock = [&](BeMCBlock* block) { SetAndRestoreValue prevActiveBlock(mActiveBlock, block); for (int checkIdx = (int)block->mInstructions.size() - 1; checkIdx >= 0; checkIdx--) @@ -3597,14 +3608,14 @@ void BeMCContext::CreatePhiAssign(BeMCBlock* mcBlock, const BeMCOperand& testVal }; _CheckBlock(phiVal.mBlockFrom); - - BF_ASSERT(found); + + BF_ASSERT(found); } if (landinglabel) { AllocInst(BeMCInstKind_Br, doneLabel); - } + } } } else @@ -3621,6 +3632,20 @@ BeMCOperand BeMCContext::GetImmediate(int64 val) return operand; } +BeMCOperand BeMCContext::OperandToAddr(const BeMCOperand& operand) +{ + BeMCOperand loadedOperand = operand; + if (loadedOperand.mKind == BeMCOperandKind_VRegLoad) + loadedOperand.mKind = BeMCOperandKind_VReg; + else if (loadedOperand.mKind == BeMCOperandKind_VReg) + loadedOperand.mKind = BeMCOperandKind_VRegAddr; + else if (loadedOperand.mKind == BeMCOperandKind_Symbol) + loadedOperand.mKind = BeMCOperandKind_SymbolAddr; + else + Fail("Invalid operand in OperandToAddr"); + return loadedOperand; +} + BeMCOperand BeMCContext::GetVReg(int regNum) { auto vregInfo = mVRegInfo[regNum]; @@ -3639,7 +3664,7 @@ BeMCOperand BeMCContext::AllocVirtualReg(BeType* type, int refCount, bool mustBe if (mustBeReg) { - BF_ASSERT(!type->IsComposite()); + BF_ASSERT(!type->IsComposite()); BF_ASSERT(type->mSize != 0); } @@ -3651,23 +3676,23 @@ BeMCOperand BeMCContext::AllocVirtualReg(BeType* type, int refCount, bool mustBe vregInfo->mForceReg = mustBeReg; mVRegInfo.push_back(vregInfo); - BeMCOperand mcOperand; + BeMCOperand mcOperand; mcOperand.mKind = BeMCOperandKind_VReg; - mcOperand.mVRegIdx = vregIdx++; + mcOperand.mVRegIdx = vregIdx++; if (mDebugging) { if (mcOperand.mVRegIdx == 97) { NOP; - } + } } return mcOperand; } int BeMCContext::GetUnderlyingVReg(int vregIdx) -{ +{ while (true) { auto vregInfo = mVRegInfo[vregIdx]; @@ -3722,7 +3747,7 @@ bool BeMCContext::OperandsEqual(const BeMCOperand& op0, const BeMCOperand& op1, return false; vregIdx1 = vregInfo->mRelTo.mVRegIdx; } - + return vregIdx0 == vregIdx1; } @@ -3749,7 +3774,7 @@ bool BeMCContext::ContainsNonOffsetRef(const BeMCOperand& checkOperand, const Be // in DoDefPass. That allows us to limit how long that vreg will hold onto a register, reducing register // contention. BeMCInst* BeMCContext::CreateDefineVReg(const BeMCOperand& vreg, int insertIdx) -{ +{ auto mcInst = AllocInst(insertIdx); mcInst->mKind = BeMCInstKind_Def; mcInst->mArg0 = vreg; @@ -3800,7 +3825,7 @@ bool BeMCContext::FindTarget(const BeMCOperand& loc, BeMCBlock*& outBlock, int& } BeMCOperand BeMCContext::AllocRelativeVirtualReg(BeType* type, const BeMCOperand& relTo, const BeMCOperand& relOffset, int relScale) -{ +{ if (!relTo.IsVRegAny()) { auto relToType = GetType(relTo); @@ -3811,9 +3836,9 @@ BeMCOperand BeMCContext::AllocRelativeVirtualReg(BeType* type, const BeMCOperand return AllocRelativeVirtualReg(type, tempRelTo, relOffset, relScale); } - BF_ASSERT(relTo.IsVRegAny()); + BF_ASSERT(relTo.IsVRegAny()); auto relToVRegInfo = GetVRegInfo(relTo); - + if ((relToVRegInfo->mRelTo) && (relToVRegInfo->mRelOffsetScale == 1) && (relToVRegInfo->mRelOffset.IsImmediate()) && (relOffset.IsImmediate()) && (relScale == 1)) { @@ -3823,7 +3848,7 @@ BeMCOperand BeMCContext::AllocRelativeVirtualReg(BeType* type, const BeMCOperand if (relToVRegInfo->mRelOffset) offset += relToVRegInfo->mRelOffset.mImmediate; return AllocRelativeVirtualReg(type, relToVRegInfo->mRelTo, GetImmediate(offset), 1); - } + } } if ((relTo.mKind == BeMCOperandKind_VRegAddr) && (!relToVRegInfo->mRelOffset) && (relOffset.IsZero()) && (relScale == 1)) @@ -3844,13 +3869,13 @@ BeMCOperand BeMCContext::AllocRelativeVirtualReg(BeType* type, const BeMCOperand vregInfo->mRelTo = relTo; if (!relOffset.IsZero()) vregInfo->mRelOffset = relOffset; - vregInfo->mRelOffsetScale = relScale; + vregInfo->mRelOffsetScale = relScale; mcVReg.mKind = BeMCOperandKind_VReg; return mcVReg; } BeMCVRegInfo* BeMCContext::GetVRegInfo(const BeMCOperand& operand) -{ +{ if (!operand.IsVRegAny()) return NULL; return mVRegInfo[operand.mVRegIdx]; @@ -3869,7 +3894,7 @@ bool BeMCContext::HasSymbolAddr(const BeMCOperand& operand) return true; if ((vregInfo->mRelOffset) && (HasSymbolAddr(vregInfo->mRelOffset))) return true; - + return false; } @@ -3877,9 +3902,9 @@ BeMCOperand BeMCContext::ReplaceWithNewVReg(BeMCOperand& operand, int& instIdx, { if ((isInput) && (operand.mKind == BeMCOperandKind_VRegLoad) && (preserveDeref)) { - BeMCOperand addrOperand = BeMCOperand::ToAddr(operand); + BeMCOperand addrOperand = OperandToAddr(operand); BeMCOperand scratchReg = AllocVirtualReg(GetType(addrOperand), 2, mustBeReg); - CreateDefineVReg(scratchReg, instIdx++); + CreateDefineVReg(scratchReg, instIdx++); AllocInst(BeMCInstKind_Mov, scratchReg, addrOperand, instIdx++); operand = BeMCOperand::ToLoad(scratchReg); return scratchReg; @@ -3900,7 +3925,7 @@ BeMCOperand BeMCContext::RemapOperand(BeMCOperand& operand, BeMCRemapper& regRem if (!operand.IsVRegAny()) return operand; - int regIdx = regRemaps.GetHead(operand.mVRegIdx); + int regIdx = regRemaps.GetHead(operand.mVRegIdx); if (regIdx < 0) { BeMCOperand newOperand; @@ -3918,7 +3943,7 @@ BeMCOperand BeMCContext::RemapOperand(BeMCOperand& operand, BeMCRemapper& regRem newOperand.mKind = operand.mKind; newOperand.mVRegIdx = regIdx; return newOperand; - } + } } bool BeMCContext::IsLive(BeVTrackingList* liveRegs, int origVRegIdx, BeMCRemapper& regRemaps) @@ -3937,7 +3962,7 @@ bool BeMCContext::IsLive(BeVTrackingList* liveRegs, int origVRegIdx, BeMCRemappe void BeMCContext::AddRegRemap(int from, int to, BeMCRemapper& regRemaps, bool allowRemapToDbgVar) { auto vregInfoFrom = mVRegInfo[from]; - auto vregInfoTo = mVRegInfo[to]; + auto vregInfoTo = mVRegInfo[to]; BF_ASSERT(vregInfoFrom->mDbgVariable == NULL); @@ -3957,12 +3982,12 @@ void BeMCContext::AddRegRemap(int from, int to, BeMCRemapper& regRemaps, bool al } bool BeMCContext::GetEncodedOperand(const BeMCOperand& operand, int& encodedVal) -{ +{ if (operand.mKind == BeMCOperandKind_VReg) { - auto vregInfo = mVRegInfo[operand.mVRegIdx]; + auto vregInfo = mVRegInfo[operand.mVRegIdx]; encodedVal = operand.mVRegIdx; - return true; + return true; } if (operand.mKind != BeMCOperandKind_VRegAddr) @@ -4028,7 +4053,7 @@ bool BeMCContext::AreOperandsEquivalent(const BeMCOperand& origOp0, const BeMCOp if ((!vregInfo0->mIsExpr) || (!vregInfo1->mIsExpr)) return false; - return + return (vregInfo0->mRelOffsetScale == vregInfo1->mRelOffsetScale) && (AreOperandsEquivalent(vregInfo0->mRelTo, vregInfo1->mRelTo, regRemaps)) && (AreOperandsEquivalent(vregInfo0->mRelOffset, vregInfo1->mRelOffset, regRemaps)); @@ -4049,7 +4074,7 @@ bool BeMCContext::CouldBeReg(const BeMCOperand& operand) if (vregInfo->mIsExpr) { if (vregInfo->mRelOffset) - return false; + return false; } return true; @@ -4069,14 +4094,14 @@ void BeMCContext::MarkLive(BeVTrackingList* liveRegs, SizedArrayImpl& newRe { int vregIdx = operand.mVRegIdx; auto vregInfo = mVRegInfo[vregIdx]; - + if (mLivenessContext.IsSet(liveRegs, operand.mVRegIdx)) return; - + for (auto newReg : newRegs) if (newReg == operand.mVRegIdx) return; - + if (!mColorizer.mNodes.empty()) { // Is new @@ -4093,7 +4118,7 @@ void BeMCContext::MarkLive(BeVTrackingList* liveRegs, SizedArrayImpl& newRe } if (vregInfo->mHasDynLife) - { + { if (!mVRegInitializedContext.IsSet(vregsInitialized, vregIdx)) { // This indicates that this is a 'def' usage, meaning the value wasn't actually set yet @@ -4111,19 +4136,19 @@ void BeMCContext::MarkLive(BeVTrackingList* liveRegs, SizedArrayImpl& newRe } BeVTrackingList* BeMCContext::MergeLiveRegs(BeVTrackingList* prevDestEntry, BeVTrackingList* mergeFrom) -{ +{ int vregIdx = -1; SizedArray newNodes; SizedArray prevExclusiveNodes; - + // Take nodes that were exclusive to the new set and add edges to nodes that were exclusive the old set /*while (true) { vregIdx = mLivenessContext.GetNextDiffSetIdx(prevDestEntry.mBits, mergeFrom, vregIdx); if (vregIdx == -1) break; - + newNodes.push_back(vregIdx); if (!mColorizer.mNodes.empty()) @@ -4139,7 +4164,7 @@ BeVTrackingList* BeMCContext::MergeLiveRegs(BeVTrackingList* prevDestEntry, BeVT } }*/ - auto prevItr = prevDestEntry->begin(); + auto prevItr = prevDestEntry->begin(); auto prevEnd = prevDestEntry->end(); auto mergeFromItr = mergeFrom->begin(); auto mergeFromEnd = mergeFrom->end(); @@ -4148,7 +4173,7 @@ BeVTrackingList* BeMCContext::MergeLiveRegs(BeVTrackingList* prevDestEntry, BeVT int prevIdx = *prevItr; int mergeIdx = *mergeFromItr; bool done = false; - + while (mergeIdx < prevIdx) { newNodes.push_back(mergeIdx); @@ -4205,7 +4230,7 @@ BeVTrackingList* BeMCContext::MergeLiveRegs(BeVTrackingList* prevDestEntry, BeVT } } - return mLivenessContext.Add(prevDestEntry, newNodes, false); + return mLivenessContext.Add(prevDestEntry, newNodes, false); } static void DedupPushBack(SizedArrayImpl& vec, int val) @@ -4220,13 +4245,13 @@ static int genLivenessIdx = 0; void BeMCContext::GenerateLiveness(BeMCBlock* block, BeVTrackingGenContext* genCtx, bool& modifiedBlockBefore, bool& modifiedBlockAfter) { genCtx->mBlocks[block->mBlockIdx].mGenerateCount++; - + modifiedBlockBefore = false; modifiedBlockAfter = false; genCtx->mCalls++; bool debugging = false; - //if (mDebugging) debugging = true; + //if (mDebugging) debugging = true; //if (mBeFunction->mName == "?Draw@DarkEditWidgetContent@dark@theme@Beefy@@UEAAXPEAVGraphics@gfx@4@@Z") //debugging = true; //"?DrawEntry@DrawContext@PerfView@BeefPerf@@QEAAXPEAVGraphics@gfx@Beefy@@PEAVTrackNodeEntry@23@MM@Z") @@ -4258,11 +4283,11 @@ void BeMCContext::GenerateLiveness(BeMCBlock* block, BeVTrackingGenContext* genC bool needsManualVRegInitDiff = true; for (int instIdx = (int)block->mInstructions.size() - 1; instIdx >= 0; instIdx--) - { + { genLivenessIdx++; - auto inst = block->mInstructions[instIdx]; + auto inst = block->mInstructions[instIdx]; auto prevLiveness = inst->mLiveness; - + genCtx->mInstructions++; SizedArray removeVec; @@ -4274,12 +4299,12 @@ void BeMCContext::GenerateLiveness(BeMCBlock* block, BeVTrackingGenContext* genC if ((inst->mVRegsInitialized != NULL) && (inst->mVRegsInitialized != vregsInitialized)) { - auto _VRegUninit = [&] (int vregIdxEx) + auto _VRegUninit = [&](int vregIdxEx) { - int vregIdx = vregIdxEx % mVRegInitializedContext.mNumItems; + int vregIdx = vregIdxEx % mVRegInitializedContext.mNumItems; auto vregInfo = mVRegInfo[vregIdx]; - + if (!vregInfo->mHasDynLife) return; @@ -4293,11 +4318,11 @@ void BeMCContext::GenerateLiveness(BeMCBlock* block, BeVTrackingGenContext* genC otherVRegIdxEx += mVRegInitializedContext.mNumItems; if (!mVRegInitializedContext.IsSet(inst->mVRegsInitialized, otherVRegIdxEx)) doClear = true; - } + } else - { + { // Only do liveness clear on 'init' clearing out - if (vregIdx < mVRegInitializedContext.mNumItems) + if (vregIdx < mVRegInitializedContext.mNumItems) doClear = true; } @@ -4357,7 +4382,7 @@ void BeMCContext::GenerateLiveness(BeMCBlock* block, BeVTrackingGenContext* genC break; } while (idx0 < vregsInit0->mSize) - { + { _VRegUninit(vregsInit0->mEntries[idx0++]); } } @@ -4373,8 +4398,8 @@ void BeMCContext::GenerateLiveness(BeMCBlock* block, BeVTrackingGenContext* genC // It's possible this vregsInitialized is equivalent to the one in 'inst', but also merged with another 'inst' // during legalization. We need to avoid uninitializing vregs if that's the case. // the entry above this - if (inst->mVRegsInitialized->ContainsChange(vregIdxEx)) - continue; + if (inst->mVRegsInitialized->ContainsChange(vregIdxEx)) + continue; _VRegUninit(vregIdxEx); } @@ -4386,27 +4411,27 @@ void BeMCContext::GenerateLiveness(BeMCBlock* block, BeVTrackingGenContext* genC needsManualVRegInitDiff = false; if (inst->mKind == BeMCInstKind_DbgDecl) - { + { if (!mVRegInitializedContext.IsSet(inst->mVRegsInitialized, inst->mArg0.mVRegIdx)) { // There are some rare cases with conditional branches where one branch will have a vreg marked as // initialized, which causes the variable to be marked as live, which propagates upward into the block // containing a variable declaration, before the actual def point - DedupPushBack(removeVec, inst->mArg0.mVRegIdx); - } + DedupPushBack(removeVec, inst->mArg0.mVRegIdx); + } liveRegs = mLivenessContext.Modify(liveRegs, addVec, removeVec, filteredAddVec, filteredRemoveVec); continue; } - + // This is used for clearing out things like usage of inline return values, which will be accessed after their // lifetime end (the lifetime ends inside the inlined method but the value is used afterward, in the inlining // function. This will emit as a load of a dbgVar, so we need to drill down into the relTo values if (inst->mKind == BeMCInstKind_LifetimeStart) - { + { BF_ASSERT(inst->mArg0.IsVRegAny()); - int vregIdx = inst->mArg0.mVRegIdx; + int vregIdx = inst->mArg0.mVRegIdx; while (true) - { + { DedupPushBack(removeVec, vregIdx); auto vregInfo = mVRegInfo[vregIdx]; if (!vregInfo->IsDirectRelTo()) @@ -4431,7 +4456,7 @@ void BeMCContext::GenerateLiveness(BeMCBlock* block, BeVTrackingGenContext* genC } if (inst->IsDef()) - { + { DedupPushBack(removeVec, inst->mArg0.mVRegIdx); liveRegs = mLivenessContext.Modify(liveRegs, addVec, removeVec, filteredAddVec, filteredRemoveVec); continue; @@ -4457,13 +4482,13 @@ void BeMCContext::GenerateLiveness(BeMCBlock* block, BeVTrackingGenContext* genC mcOperand = BeMCOperand::FromEncoded(operand->mVRegPair.mVRegIdx1); if (mcOperand.IsVRegAny()) MarkLive(liveRegs, addVec, vregsInitialized, mcOperand); - } + } if (operand->IsVRegAny()) - { + { MarkLive(liveRegs, addVec, vregsInitialized, *operand); } - } + } liveRegs = mLivenessContext.Modify(liveRegs, addVec, removeVec, filteredAddVec, filteredRemoveVec); @@ -4473,7 +4498,7 @@ void BeMCContext::GenerateLiveness(BeMCBlock* block, BeVTrackingGenContext* genC return; }*/ - inst->mLiveness = liveRegs; + inst->mLiveness = liveRegs; } if (block == mBlocks[0]) @@ -4500,9 +4525,9 @@ void BeMCContext::GenerateLiveness(BeMCBlock* block, BeVTrackingGenContext* genC else { SoftFail("VReg lifetime error"); - } + } } - } + } } } @@ -4515,14 +4540,14 @@ void BeMCContext::GenerateLiveness(BeMCBlock* block, BeVTrackingGenContext* genC if (newSuccLiveness == pred->mSuccLiveness) continue; pred->mSuccLiveness = newSuccLiveness; - + pred->mSuccVRegsInitialized = mVRegInitializedContext.Merge(pred->mSuccVRegsInitialized, vregsInitialized); - + if (pred->mBlockIdx > block->mBlockIdx) modifiedBlockAfter = true; else modifiedBlockBefore = true; - entry.mGenerateQueued = true; + entry.mGenerateQueued = true; } } @@ -4544,20 +4569,20 @@ void BeMCContext::GenerateLiveness() } #endif - BP_ZONE("BeMCContext::GenerateLiveness"); - + BP_ZONE("BeMCContext::GenerateLiveness"); + mLivenessContext.Clear(); mLivenessContext.Init((int)mVRegInfo.size()); - + auto emptyList = mLivenessContext.AllocEmptyList(); - BeVTrackingGenContext genCtx; + BeVTrackingGenContext genCtx; genCtx.mEmptyList = emptyList; genCtx.mBlocks.Resize(mBlocks.size()); for (auto mcBlock : mBlocks) - { - mcBlock->mSuccLiveness = emptyList; + { + mcBlock->mSuccLiveness = emptyList; mcBlock->mSuccVRegsInitialized = emptyList; if (mTLSVRegIdx != -1) @@ -4577,11 +4602,11 @@ void BeMCContext::GenerateLiveness() { auto& entry = genCtx.mBlocks[blockIdx]; if (entry.mGenerateQueued) - { + { entry.mGenerateQueued = false; didWork = true; - auto block = mBlocks[blockIdx]; - + auto block = mBlocks[blockIdx]; + bool modifiedBlockBefore; bool modifiedBlockAfter; GenerateLiveness(block, &genCtx, modifiedBlockBefore, modifiedBlockAfter); @@ -4595,7 +4620,7 @@ void BeMCContext::GenerateLiveness() { for (int blockIdx = (int)mBlocks.size() - 1; blockIdx >= 0; blockIdx--) { - auto& entry = genCtx.mBlocks[blockIdx]; + auto& entry = genCtx.mBlocks[blockIdx]; if (entry.mGenerateCount == 0) { didWork = true; @@ -4617,10 +4642,10 @@ void BeMCContext::GenerateLiveness() for (auto block : mBlocks) instCount += (int)block->mInstructions.size(); - BpEvent("GenerateLiveness Results", + BpEvent("GenerateLiveness Results", StrFormat("Blocks: %d\nInstructions: %d\nVRegs: %d\nCalls: %d\nHandled Calls: %d\nProcessed Instructions: %d\nLiveness Bytes: %d\n" "Temp Bytes: %d\nBits Bytes: %d\nList Bytes: %d\nSucc Bytes: %d", - mBlocks.size(), instCount, mVRegInfo.size(), genCtx.mCalls, genCtx.mHandledCalls, genCtx.mInstructions, mLivenessContext.mAlloc.GetAllocSize(), + mBlocks.size(), instCount, mVRegInfo.size(), genCtx.mCalls, genCtx.mHandledCalls, genCtx.mInstructions, mLivenessContext.mAlloc.GetAllocSize(), genCtx.mAlloc.GetAllocSize(), mLivenessContext.mStats.mBitsBytes, mLivenessContext.mStats.mListBytes, mLivenessContext.mStats.mSuccBytes).c_str()); } @@ -4631,7 +4656,7 @@ void BeMCContext::IntroduceVRegs(const BeMCOperand& newVReg, BeMCBlock* block, i /*BF_ASSERT((block->mInstructions[startInstIdx]->mKind == BeMCInstKind_Def) && (block->mInstructions[startInstIdx]->mArg0 == newVReg)); BF_ASSERT(mColorizer.mNodes.size() == newVReg.mVRegIdx); - mColorizer.mNodes.resize(mColorizer.mNodes.size() + 1); + mColorizer.mNodes.resize(mColorizer.mNodes.size() + 1); BeVTrackingBits* lastLiveness = NULL; @@ -4642,7 +4667,7 @@ void BeMCContext::IntroduceVRegs(const BeMCOperand& newVReg, BeMCBlock* block, i if (lastLiveness == NULL) { for (int vregIdx : *inst->mLiveness) - { + { if (vregIdx >= mLivenessContext.mNumItems) continue; mColorizer.AddEdge(newVReg.mVRegIdx, vregIdx); @@ -4688,7 +4713,7 @@ void BeMCContext::IntroduceVRegs(const BeMCOperand& newVReg, BeMCBlock* block, i bool BeMCContext::IsVolatileReg(X64CPURegister reg) { switch (ResizeRegister(reg, 8)) - { + { case X64Reg_RAX: case X64Reg_RCX: case X64Reg_RDX: @@ -4718,19 +4743,19 @@ X64CPURegister BeMCContext::ResizeRegister(X64CPURegister reg, int numBytes) if (numBytes == 8) { switch (reg) - { - case X64Reg_DIL: + { + case X64Reg_DIL: case X64Reg_DI: - case X64Reg_EDI: - case X64Reg_RDI: return X64Reg_RDI; + case X64Reg_EDI: + case X64Reg_RDI: return X64Reg_RDI; case X64Reg_SIL: case X64Reg_SI: - case X64Reg_ESI: + case X64Reg_ESI: case X64Reg_RSI: return X64Reg_RSI; case X64Reg_AL: case X64Reg_AH: case X64Reg_AX: - case X64Reg_EAX: + case X64Reg_EAX: case X64Reg_RAX: return X64Reg_RAX; case X64Reg_DL: case X64Reg_DH: @@ -4747,9 +4772,9 @@ X64CPURegister BeMCContext::ResizeRegister(X64CPURegister reg, int numBytes) case X64Reg_BX: case X64Reg_EBX: case X64Reg_RBX: return X64Reg_RBX; - case X64Reg_R8B: + case X64Reg_R8B: case X64Reg_R8W: - case X64Reg_R8D: + case X64Reg_R8D: case X64Reg_R8: return X64Reg_R8; case X64Reg_R9B: case X64Reg_R9W: @@ -4983,7 +5008,7 @@ X64CPURegister BeMCContext::ResizeRegister(X64CPURegister reg, int numBytes) if (numBytes == 1) { switch (reg) - { + { case X64Reg_DIL: case X64Reg_DI: case X64Reg_EDI: @@ -4993,22 +5018,22 @@ X64CPURegister BeMCContext::ResizeRegister(X64CPURegister reg, int numBytes) case X64Reg_ESI: case X64Reg_RSI: return X64Reg_SIL; case X64Reg_AH: return X64Reg_AH; - case X64Reg_AL: + case X64Reg_AL: case X64Reg_AX: case X64Reg_EAX: case X64Reg_RAX: return X64Reg_AL; case X64Reg_DH: return X64Reg_DH; - case X64Reg_DL: + case X64Reg_DL: case X64Reg_DX: case X64Reg_EDX: case X64Reg_RDX: return X64Reg_DL; case X64Reg_CH: return X64Reg_CH; - case X64Reg_CL: + case X64Reg_CL: case X64Reg_CX: case X64Reg_ECX: case X64Reg_RCX: return X64Reg_CL; case X64Reg_BH: return X64Reg_BH; - case X64Reg_BL: + case X64Reg_BL: case X64Reg_BX: case X64Reg_EBX: case X64Reg_RBX: return X64Reg_BL; @@ -5087,7 +5112,7 @@ void BeMCContext::FixOperand(BeMCOperand& operand) if ((operand.mKind != BeMCOperandKind_VReg) && (operand.mKind != BeMCOperandKind_VRegAddr)) return; - auto vregInfo = mVRegInfo[operand.mVRegIdx]; + auto vregInfo = mVRegInfo[operand.mVRegIdx]; if (vregInfo->mReg != X64Reg_None) { operand.mKind = BeMCOperandKind_NativeReg; @@ -5096,13 +5121,13 @@ void BeMCContext::FixOperand(BeMCOperand& operand) } if ((vregInfo->mIsRetVal) && (mCompositeRetVRegIdx != -1) && (mCompositeRetVRegIdx != operand.mVRegIdx)) - { + { BF_ASSERT(mCompositeRetVRegIdx != -1); BeMCOperand origOperand = operand; operand = BeMCOperand::FromVReg(mCompositeRetVRegIdx); if ((origOperand.mKind == BeMCOperandKind_VReg) && (vregInfo->mType->IsComposite())) operand.mKind = BeMCOperandKind_VRegLoad; - FixOperand(operand); + FixOperand(operand); //auto retVRegInfo = mVRegInfo[mCompositeRetVRegIdx]; //operand = BeMCOperand::FromReg(retVRegInfo->mReg); @@ -5111,15 +5136,15 @@ void BeMCContext::FixOperand(BeMCOperand& operand) if (vregInfo->IsDirectRelToAny()) { auto checkOperand = vregInfo->mRelTo; - if (checkOperand.IsVReg()) - FixOperand(checkOperand); + if (checkOperand.IsVReg()) + FixOperand(checkOperand); if (checkOperand.IsNativeReg()) { auto resizedReg = ResizeRegister(checkOperand.mReg, vregInfo->mType->mSize); if (resizedReg != X64Reg_None) operand = BeMCOperand::FromReg(resizedReg); - } + } else if (checkOperand.mKind == BeMCOperandKind_Symbol) { auto symbol = mCOFFObject->mSymbols[checkOperand.mSymbolIdx]; @@ -5127,7 +5152,7 @@ void BeMCContext::FixOperand(BeMCOperand& operand) { if (checkOperand.mKind == BeMCOperandKind_VRegAddr) { - operand = BeMCOperand::ToAddr(checkOperand); + operand = OperandToAddr(checkOperand); } else operand = checkOperand; @@ -5137,7 +5162,7 @@ void BeMCContext::FixOperand(BeMCOperand& operand) { operand = checkOperand; } - } + } } BeMCOperand BeMCContext::GetFixedOperand(const BeMCOperand& operand) @@ -5151,7 +5176,7 @@ uint8 BeMCContext::GetREX(const BeMCOperand& r, const BeMCOperand& rm, bool is64 { //bool is64Bit = false; bool is64BitExR = false; - bool is64BitExRM = false; + bool is64BitExRM = false; bool forceRex = false; if (r.mKind == BeMCOperandKind_NativeReg) { @@ -5172,7 +5197,7 @@ uint8 BeMCContext::GetREX(const BeMCOperand& r, const BeMCOperand& rm, bool is64 case X64Reg_XMM8_f32: case X64Reg_XMM9_f32: case X64Reg_XMM10_f32: case X64Reg_XMM11_f32: case X64Reg_XMM12_f32: case X64Reg_XMM13_f32: case X64Reg_XMM14_f32: case X64Reg_XMM15_f32: is64BitExR = true; - } + } } bool hasSibExRM = false; @@ -5188,8 +5213,8 @@ uint8 BeMCContext::GetREX(const BeMCOperand& r, const BeMCOperand& rm, bool is64 case X64Reg_R8D: case X64Reg_R9D: case X64Reg_R10D: case X64Reg_R11D: case X64Reg_R12D: case X64Reg_R13D: case X64Reg_R14D: case X64Reg_R15D: case X64Reg_R8W: case X64Reg_R9W: case X64Reg_R10W: case X64Reg_R11W: case X64Reg_R12W: case X64Reg_R13W: case X64Reg_R14W: case X64Reg_R15W: case X64Reg_R8B: case X64Reg_R9B: case X64Reg_R10B: case X64Reg_R11B: case X64Reg_R12B: case X64Reg_R13B: case X64Reg_R14B: case X64Reg_R15B: - case X64Reg_XMM8_f64: case X64Reg_XMM9_f64: case X64Reg_XMM10_f64: case X64Reg_XMM11_f64: - case X64Reg_XMM12_f64: case X64Reg_XMM13_f64: case X64Reg_XMM14_f64: case X64Reg_XMM15_f64: + case X64Reg_XMM8_f64: case X64Reg_XMM9_f64: case X64Reg_XMM10_f64: case X64Reg_XMM11_f64: + case X64Reg_XMM12_f64: case X64Reg_XMM13_f64: case X64Reg_XMM14_f64: case X64Reg_XMM15_f64: case X64Reg_XMM8_f32: case X64Reg_XMM9_f32: case X64Reg_XMM10_f32: case X64Reg_XMM11_f32: case X64Reg_XMM12_f32: case X64Reg_XMM13_f32: case X64Reg_XMM14_f32: case X64Reg_XMM15_f32: is64BitExRM = true; @@ -5197,10 +5222,10 @@ uint8 BeMCContext::GetREX(const BeMCOperand& r, const BeMCOperand& rm, bool is64 } else if (rm.IsVRegAny()) { - auto vregInfo = mVRegInfo[rm.mVRegIdx]; + auto vregInfo = mVRegInfo[rm.mVRegIdx]; if (vregInfo->IsDirectRelTo()) return GetREX(r, vregInfo->mRelTo, is64Bit); - + BeRMParamsInfo rmInfo; GetRMParams(rm, rmInfo); is64BitExRM |= ((rmInfo.mRegA >= X64Reg_R8) && (rmInfo.mRegA <= X64Reg_R15)) || ((rmInfo.mRegA >= X64Reg_R8D) && (rmInfo.mRegA <= X64Reg_R15D)); @@ -5221,12 +5246,12 @@ uint8 BeMCContext::GetREX(const BeMCOperand& r, const BeMCOperand& rm, bool is64 flags |= 8; if (is64BitExR) flags |= 4; - if (hasSibExRM) + if (hasSibExRM) flags |= 2; if (is64BitExRM) - flags |= 1; + flags |= 1; if ((flags != 0) || (forceRex)) - return (uint8)(0x40 | flags); + return (uint8)(0x40 | flags); return 0; } @@ -5244,7 +5269,7 @@ uint8 BeMCContext::EncodeRegNum(X64CPURegister regNum) case X64Reg_AL: case X64Reg_AX: case X64Reg_EAX: - case X64Reg_RAX: + case X64Reg_RAX: case X64Reg_R8: case X64Reg_R8D: case X64Reg_R8W: @@ -5298,9 +5323,9 @@ uint8 BeMCContext::EncodeRegNum(X64CPURegister regNum) case X64Reg_XMM11_f64: return 3; case X64Reg_None: // Useful for SIB/RM addr encodings - case X64Reg_AH: - //case X64Reg_SP: - //case X64Reg_ESP: + case X64Reg_AH: + //case X64Reg_SP: + //case X64Reg_ESP: case X64Reg_RSP: case X64Reg_R12: case X64Reg_R12D: @@ -5313,8 +5338,8 @@ uint8 BeMCContext::EncodeRegNum(X64CPURegister regNum) case X64Reg_XMM12_f64: return 4; case X64Reg_CH: - //case X64Reg_BP: - //case X64Reg_EBP: + //case X64Reg_BP: + //case X64Reg_EBP: case X64Reg_RBP: case X64Reg_R13: case X64Reg_R13D: @@ -5341,7 +5366,7 @@ uint8 BeMCContext::EncodeRegNum(X64CPURegister regNum) case X64Reg_XMM14_f32: case X64Reg_XMM14_f64: return 6; - case X64Reg_BH: + case X64Reg_BH: case X64Reg_DIL: case X64Reg_DI: case X64Reg_EDI: @@ -5401,7 +5426,7 @@ void BeMCContext::ValidateRMResult(const BeMCOperand& operand, BeRMParamsInfo& r { // We can't just swap the regs if we have a scale applied if (rmInfo.mBScale != 1) - { + { rmInfo.mErrorVReg = -2; // Scale error rmInfo.mMode = BeMCRMMode_Invalid; return; @@ -5415,7 +5440,7 @@ void BeMCContext::ValidateRMResult(const BeMCOperand& operand, BeRMParamsInfo& r void BeMCContext::GetRMParams(const BeMCOperand& operand, BeRMParamsInfo& rmInfo, bool doValidate) { - BeMCRMMode rmMode = BeMCRMMode_Invalid; + BeMCRMMode rmMode = BeMCRMMode_Invalid; if (operand.mKind == BeMCOperandKind_NativeReg) { if (rmInfo.mRegA == X64Reg_None) @@ -5436,12 +5461,12 @@ void BeMCContext::GetRMParams(const BeMCOperand& operand, BeRMParamsInfo& rmInfo rmInfo.mMode = BeMCRMMode_Direct; return ValidateRMResult(operand, rmInfo, doValidate); } - + if (operand.mKind == BeMCOperandKind_VReg) - { + { auto vregInfo = mVRegInfo[operand.mVRegIdx]; if (!vregInfo->mIsExpr) - { + { auto reg = vregInfo->mReg; if (reg != X64Reg_None) { @@ -5458,27 +5483,27 @@ void BeMCContext::GetRMParams(const BeMCOperand& operand, BeRMParamsInfo& rmInfo return ValidateRMResult(operand, rmInfo, doValidate); } - GetRMParams(BeMCOperand::ToAddr(operand), rmInfo, doValidate); + GetRMParams(OperandToAddr(operand), rmInfo, doValidate); if (rmInfo.mMode == BeMCRMMode_Invalid) return; BF_ASSERT(rmInfo.mMode == BeMCRMMode_Direct); rmInfo.mMode = BeMCRMMode_Deref; - return ValidateRMResult(BeMCOperand::ToAddr(operand), rmInfo, doValidate); + return ValidateRMResult(OperandToAddr(operand), rmInfo, doValidate); } // Fall through } else if (operand.mKind == BeMCOperandKind_VRegAddr) - { + { auto vregInfo = mVRegInfo[operand.mVRegIdx]; - + if (vregInfo->mIsExpr) { if (vregInfo->IsDirectRelToAny()) { if (vregInfo->mRelTo.mKind == BeMCOperandKind_VReg) return GetRMParams(BeMCOperand::FromVRegAddr(vregInfo->mRelTo.mVRegIdx), rmInfo, doValidate); - else if (vregInfo->mRelTo.mKind == BeMCOperandKind_VRegLoad) - return GetRMParams(BeMCOperand::FromVReg(vregInfo->mRelTo.mVRegIdx), rmInfo, doValidate); + else if (vregInfo->mRelTo.mKind == BeMCOperandKind_VRegLoad) + return GetRMParams(BeMCOperand::FromVReg(vregInfo->mRelTo.mVRegIdx), rmInfo, doValidate); } rmInfo.mErrorVReg = operand.mVRegIdx; @@ -5489,12 +5514,12 @@ void BeMCContext::GetRMParams(const BeMCOperand& operand, BeRMParamsInfo& rmInfo BF_ASSERT(!vregInfo->mIsExpr); BF_ASSERT(vregInfo->mReg == X64Reg_None); X64CPURegister reg = X64Reg_None; - + if ((vregInfo->mIsRetVal) && (mCompositeRetVRegIdx != -1) && (mCompositeRetVRegIdx != operand.mVRegIdx)) - { + { return GetRMParams(BeMCOperand::FromVReg(mCompositeRetVRegIdx), rmInfo, doValidate); } - + reg = mUseBP ? X64Reg_RBP : X64Reg_RSP; rmInfo.mDisp = mStackSize + vregInfo->mFrameOffset; @@ -5512,7 +5537,7 @@ void BeMCContext::GetRMParams(const BeMCOperand& operand, BeRMParamsInfo& rmInfo { auto reg = vregInfo->mReg; if (reg == X64Reg_None) - { + { rmInfo.mErrorVReg = operand.mVRegIdx; rmInfo.mMode = BeMCRMMode_Invalid; return; @@ -5530,7 +5555,7 @@ void BeMCContext::GetRMParams(const BeMCOperand& operand, BeRMParamsInfo& rmInfo rmInfo.mMode = BeMCRMMode_Invalid; return; } - + auto vregInfo = mVRegInfo[operand.mVRegIdx]; BF_ASSERT(vregInfo->mIsExpr); @@ -5539,20 +5564,20 @@ void BeMCContext::GetRMParams(const BeMCOperand& operand, BeRMParamsInfo& rmInfo auto oldRegA = rmInfo.mRegA; GetRMParams(vregInfo->mRelTo, rmInfo, false); if (rmInfo.mMode == BeMCRMMode_Invalid) - { + { if (rmInfo.mErrorVReg == -1) - { + { rmInfo.mErrorVReg = operand.mVRegIdx; } return; } - + if (rmInfo.mMode == BeMCRMMode_Deref) { // A deref can only stand alone, and no double-derefs if ((vregInfo->mRelOffset) || (vregInfo->mRelOffsetScale != 1) || (operand.mKind == BeMCOperandKind_VRegLoad)) { - + BF_ASSERT(vregInfo->mRelTo.IsVRegAny()); rmInfo.mErrorVReg = vregInfo->mRelTo.mVRegIdx; // For some reason we had changed this to: @@ -5572,7 +5597,7 @@ void BeMCContext::GetRMParams(const BeMCOperand& operand, BeRMParamsInfo& rmInfo return ValidateRMResult(vregInfo->mRelTo, rmInfo, doValidate); } else - NotImpl(); + NotImpl(); } } @@ -5584,7 +5609,7 @@ void BeMCContext::GetRMParams(const BeMCOperand& operand, BeRMParamsInfo& rmInfo bool relToComplicated = (rmInfo.mRegB != X64Reg_None) || (rmInfo.mBScale != 1); GetRMParams(vregInfo->mRelOffset, rmInfo, false); if (rmInfo.mMode == BeMCRMMode_Invalid) - { + { // Pick the "most complicated" between relOffset and relTo? if (relToComplicated) { @@ -5595,12 +5620,12 @@ void BeMCContext::GetRMParams(const BeMCOperand& operand, BeRMParamsInfo& rmInfo { BF_ASSERT(vregInfo->mRelOffset.IsVRegAny()); rmInfo.mErrorVReg = vregInfo->mRelOffset.mVRegIdx; - } + } rmInfo.mMode = BeMCRMMode_Invalid; return; } if (rmInfo.mMode == BeMCRMMode_Deref) // Deref only allowed on relTo - { + { BF_ASSERT(vregInfo->mRelOffset.IsVRegAny()); rmInfo.mErrorVReg = vregInfo->mRelOffset.mVRegIdx; rmInfo.mMode = BeMCRMMode_Invalid; @@ -5665,7 +5690,7 @@ void BeMCContext::DisableRegister(const BeMCOperand& operand, X64CPURegister reg default: NotImpl(); } - + if (vregInfo->mRelTo) DisableRegister(vregInfo->mRelTo, reg); if (vregInfo->mRelOffset) @@ -5705,7 +5730,7 @@ BeMCRMMode BeMCContext::GetRMForm(const BeMCOperand& operand, bool& isMulti) } void BeMCContext::GetValAddr(const BeMCOperand& operand, X64CPURegister& reg, int& offset) -{ +{ if (operand.IsNativeReg()) { reg = operand.mReg; @@ -5737,23 +5762,23 @@ void BeMCContext::GetValAddr(const BeMCOperand& operand, X64CPURegister& reg, in { BF_ASSERT(mCompositeRetVRegIdx != -1); GetValAddr(BeMCOperand::FromVRegAddr(mCompositeRetVRegIdx), reg, offset); - return; + return; } while (vregInfo->IsDirectRelTo()) { vregInfo = GetVRegInfo(vregInfo->mRelTo); - } - + } + reg = mUseBP ? X64Reg_RBP : X64Reg_RSP; - offset = mStackSize + vregInfo->mFrameOffset; + offset = mStackSize + vregInfo->mFrameOffset; } int BeMCContext::GetHighestVRegRef(const BeMCOperand& operand) { if (!operand.IsVRegAny()) - return -1; + return -1; int highestIdx = operand.mVRegIdx; auto vregInfo = mVRegInfo[operand.mVRegIdx]; if (vregInfo->mRelTo) @@ -5791,7 +5816,7 @@ uint8 BeMCContext::GetJumpOpCode(BeCmpKind cmpKind, bool isLong) return 0x8D; case BeCmpKind_UGE: // JAE return 0x83; - } + } } else { @@ -5884,22 +5909,22 @@ void BeMCContext::EmitModRMRel(int rx, X64CPURegister regA, X64CPURegister regB, else { // Do no-offset version UNLESS we have a base of R13, which has its representation stolen by '[--][--]+disp32', - // so we must use the longer +disp8 version in that case + // so we must use the longer +disp8 version in that case if ((relOffset == 0) && (regA != X64Reg_R13)) { modRM |= (0x0 << 6) | (0x4); // [--][--] mOut.Write(modRM); uint8 sib = ((bScale == 2) ? 1 : (bScale == 4) ? 2 : (bScale == 8) ? 3 : 0) << 6; sib |= (EncodeRegNum(regB) << 3) | EncodeRegNum(regA); - mOut.Write(sib); + mOut.Write(sib); return; } else if ((relOffset >= -0x80) && (relOffset <= 0x7F)) { modRM |= (0x1 << 6) | (0x4); // [--][--]+disp8 mOut.Write(modRM); - uint8 sib = ((bScale == 2) ? 1 : (bScale == 4) ? 2 : (bScale == 8) ? 3 : 0) << 6; - sib |= (EncodeRegNum(regB) << 3) | EncodeRegNum(regA); + uint8 sib = ((bScale == 2) ? 1 : (bScale == 4) ? 2 : (bScale == 8) ? 3 : 0) << 6; + sib |= (EncodeRegNum(regB) << 3) | EncodeRegNum(regA); mOut.Write(sib); mOut.Write((uint8)relOffset); return; @@ -5914,7 +5939,7 @@ void BeMCContext::EmitModRMRel(int rx, X64CPURegister regA, X64CPURegister regB, mOut.Write((int32)relOffset); return; } - } + } } void BeMCContext::EmitModRMRelStack(int rx, int regOffset, int scale) @@ -5936,12 +5961,12 @@ void BeMCContext::EmitModRM(int rx, BeMCOperand rm, int relocOfs) { BeMCRelocation reloc; - + auto sym = mCOFFObject->mSymbols[rm.mSymbolIdx]; if (sym->mIsTLS) { auto vregInfo = mVRegInfo[mTLSVRegIdx]; - modRM |= (2<<6) | EncodeRegNum(vregInfo->mReg); + modRM |= (2 << 6) | EncodeRegNum(vregInfo->mReg); reloc.mKind = BeMCRelocationKind_SECREL; relocOfs = 0; } @@ -5949,10 +5974,10 @@ void BeMCContext::EmitModRM(int rx, BeMCOperand rm, int relocOfs) { modRM |= 0x5; // RIP + reloc.mKind = BeMCRelocationKind_REL32; - } - + } + Emit(modRM); - + reloc.mOffset = mOut.GetPos(); reloc.mSymTableIdx = rm.mSymbolIdx; mCOFFObject->mTextSect.mRelocs.push_back(reloc); @@ -5966,7 +5991,7 @@ void BeMCContext::EmitModRM(int rx, BeMCOperand rm, int relocOfs) modRM |= (0x3 << 6) | (EncodeRegNum(rm.mReg)); } else if (rm.IsVRegAny()) - { + { auto vregInfo = mVRegInfo[rm.mVRegIdx]; if ((vregInfo->mRelTo.mKind == BeMCOperandKind_SymbolAddr) && (vregInfo->mRelOffset.IsImmediateInt()) && @@ -5996,7 +6021,7 @@ void BeMCContext::EmitModRM(BeMCOperand r, BeMCOperand rm, int relocOfs) { uint8 modRM = 0; BF_ASSERT(r.mKind == BeMCOperandKind_NativeReg); - EmitModRM(EncodeRegNum(r.mReg), rm, relocOfs); + EmitModRM(EncodeRegNum(r.mReg), rm, relocOfs); } void BeMCContext::EmitModRM_Addr(BeMCOperand r, BeMCOperand rm) @@ -6013,7 +6038,7 @@ void BeMCContext::EmitModRM_Addr(BeMCOperand r, BeMCOperand rm) { EmitModRM(r, rm); return; - } + } else if (rm.mKind == BeMCOperandKind_VReg) { auto vregInfo = mVRegInfo[rm.mVRegIdx]; @@ -6031,26 +6056,26 @@ void BeMCContext::EmitModRM_Addr(BeMCOperand r, BeMCOperand rm) if (vregInfo->mRelTo.IsNativeReg()) { - relToReg = vregInfo->mRelTo.mReg; + relToReg = vregInfo->mRelTo.mReg; } else if (vregInfo->mRelTo.IsVRegAny()) { - auto relVRegInfo = GetVRegInfo(vregInfo->mRelTo); + auto relVRegInfo = GetVRegInfo(vregInfo->mRelTo); if (relVRegInfo->mRelTo) { BeRMParamsInfo rmInfo; GetRMParams(rm, rmInfo); - BF_ASSERT(rmInfo.mMode != BeMCRMMode_Invalid); + BF_ASSERT(rmInfo.mMode != BeMCRMMode_Invalid); EmitModRMRel(EncodeRegNum(r.mReg), rmInfo.mRegA, rmInfo.mRegB, rmInfo.mBScale, rmInfo.mDisp); return; } else - NotImpl(); + NotImpl(); } else NotImpl(); EmitModRMRel(EncodeRegNum(r.mReg), relToReg, X64Reg_None, 1, regOffset); - return; + return; } else { @@ -6065,7 +6090,7 @@ void BeMCContext::EmitModRM_Addr(BeMCOperand r, BeMCOperand rm) scaleVal = 0x2; else if (vregInfo->mRelOffsetScale == 8) scaleVal = 0x3; - + modRM |= (0x0 << 6) | (0x4); // [--][--] mOut.Write(modRM); uint8 sib = (scaleVal << 6) | (EncodeRegNum(vregInfo->mRelTo.mReg) << 3) | (0x5); // [* + imm32] @@ -6088,28 +6113,28 @@ void BeMCContext::EmitModRM_Addr(BeMCOperand r, BeMCOperand rm) } void BeMCContext::EmitModRM_XMM_IMM(int rx, BeMCOperand & imm) -{ +{ Emit((rx << 3) | (0x5)); // RIP + BeMCSymbol* sym = NULL; if (imm.mKind == BeMCOperandKind_Immediate_f32) - { + { String name = StrFormat("__real@%08x", *(int*)&imm.mImmF32); sym = mCOFFObject->GetCOMDAT(name, &imm.mImmF32, 4, 4); } else if (imm.mKind == BeMCOperandKind_Immediate_f64) - { + { String name = StrFormat("__real@%016llx", *(int64*)&imm.mImmF64); sym = mCOFFObject->GetCOMDAT(name, &imm.mImmF64, 8, 8); } else if (imm.mKind == BeMCOperandKind_Immediate_f32_Packed128) - { + { String name = StrFormat("__real@%08x_packed", *(int*)&imm.mImmF32); float data[4] = { imm.mImmF32, 0, 0, 0 }; sym = mCOFFObject->GetCOMDAT(name, data, 16, 16); } else if (imm.mKind == BeMCOperandKind_Immediate_f64_Packed128) - { + { String name = StrFormat("__real@%016llx_packed", *(int64*)&imm.mImmF64); double data[2] = { imm.mImmF64, 0 }; sym = mCOFFObject->GetCOMDAT(name, data, 16, 16); @@ -6128,7 +6153,7 @@ void BeMCContext::EmitModRM_XMM_IMM(int rx, BeMCOperand & imm) } void BeMCContext::VRegSetInitialized(BeMCBlock* mcBlock, BeMCInst* inst, const BeMCOperand& operand, SizedArrayImpl& addVec, SizedArrayImpl& removeVec, bool deepSet, bool doSet) -{ +{ if (operand.IsSymbol()) { auto sym = mCOFFObject->mSymbols[operand.mSymbolIdx]; @@ -6151,13 +6176,13 @@ void BeMCContext::VRegSetInitialized(BeMCBlock* mcBlock, BeMCInst* inst, const B { VRegSetInitialized(mcBlock, inst, BeMCOperand::FromVReg(operand.mVRegPair.mVRegIdx0), addVec, removeVec, deepSet, doSet); VRegSetInitialized(mcBlock, inst, BeMCOperand::FromVReg(operand.mVRegPair.mVRegIdx1), addVec, removeVec, deepSet, doSet); - } + } if (!operand.IsVRegAny()) - return; + return; auto vregInfo = mVRegInfo[operand.mVRegIdx]; - + if (vregInfo->mDefOnFirstUse) { int insertIdx = FindSafeInstInsertPos(*mInsertInstIdxRef); @@ -6166,17 +6191,17 @@ void BeMCContext::VRegSetInitialized(BeMCBlock* mcBlock, BeMCInst* inst, const B if (insertIdx <= *mInsertInstIdxRef) (*mInsertInstIdxRef)++; } - + if (vregInfo->mRelTo) VRegSetInitialized(mcBlock, inst, vregInfo->mRelTo, addVec, removeVec, deepSet, doSet && deepSet); if (vregInfo->mRelOffset) VRegSetInitialized(mcBlock, inst, vregInfo->mRelOffset, addVec, removeVec, deepSet, doSet && deepSet); - + if (doSet) { if (!removeVec.Contains(operand.mVRegIdx)) addVec.push_back(operand.mVRegIdx); - removeVec.push_back(mVRegInitializedContext.GetIdx(operand.mVRegIdx, BeTrackKind_Uninitialized)); + removeVec.push_back(mVRegInitializedContext.GetIdx(operand.mVRegIdx, BeTrackKind_Uninitialized)); } } @@ -6201,16 +6226,16 @@ BeMCInst* BeMCContext::FindSafePreBranchInst(BeMCBlock* mcBlock) inst = checkInst; instIdx--; } - + break; } } - return mcBlock->mInstructions[0]; + return mcBlock->mInstructions[0]; } void BeMCContext::InitializedPassHelper(BeMCBlock* mcBlock, BeVTrackingGenContext* genCtx, bool& modifiedBlockBefore, bool& modifiedBlockAfter) -{ +{ modifiedBlockBefore = false; modifiedBlockAfter = false; @@ -6218,35 +6243,35 @@ void BeMCContext::InitializedPassHelper(BeMCBlock* mcBlock, BeVTrackingGenContex genCtx->mCalls++; genCtx->mHandledCalls++; - + BeMDNode* curDbgScope = NULL; BeVTrackingList* vregsInitialized = mcBlock->mPredVRegsInitialized; - + //OutputDebugStrF("InitializedPassHelper %@\n", vregsInitialized.mList); - mActiveBlock = mcBlock; + mActiveBlock = mcBlock; for (int instIdx = 0; instIdx < (int)mcBlock->mInstructions.size(); instIdx++) { genCtx->mInstructions++; mInsertInstIdxRef = &instIdx; auto inst = mcBlock->mInstructions[instIdx]; - + inst->mVRegsInitialized = vregsInitialized; bool deepSet = false; if (inst->mKind == BeMCInstKind_LifetimeStart) - continue; - + continue; + SizedArray removeVec; SizedArray addVec; SizedArray filteredRemoveVec; SizedArray filteredAddVec; - + // - { + { auto checkLastUseRecord = inst->mVRegLastUseRecord; while (checkLastUseRecord != NULL) { @@ -6256,7 +6281,7 @@ void BeMCContext::InitializedPassHelper(BeMCBlock* mcBlock, BeVTrackingGenContex } if ((inst->mKind == BeMCInstKind_ValueScopeSoftEnd) || (inst->mKind == BeMCInstKind_ValueScopeHardEnd)) - { + { bool isSoft = inst->mKind == BeMCInstKind_ValueScopeSoftEnd; int startVRegIdx = (int)inst->mArg0.mImmediate; @@ -6265,7 +6290,7 @@ void BeMCContext::InitializedPassHelper(BeMCBlock* mcBlock, BeVTrackingGenContex int listIdx = mVRegInitializedContext.FindIndex(vregsInitialized, startVRegIdx); if (listIdx < 0) listIdx = ~listIdx; - for ( ; listIdx < vregsInitialized->mSize; listIdx++) + for (; listIdx < vregsInitialized->mSize; listIdx++) { int vregIdx = vregsInitialized->mEntries[listIdx]; if (vregIdx >= endVRegIdx) @@ -6274,7 +6299,7 @@ void BeMCContext::InitializedPassHelper(BeMCBlock* mcBlock, BeVTrackingGenContex auto vregInfo = mVRegInfo[vregIdx]; if (isSoft) - { + { if (vregInfo->mValueScopeRetainedKind >= BeMCValueScopeRetainKind_Soft) continue; } @@ -6288,9 +6313,9 @@ void BeMCContext::InitializedPassHelper(BeMCBlock* mcBlock, BeVTrackingGenContex } } - + if ((inst->mResult) && (inst->mResult.mKind == BeMCOperandKind_CmpResult)) - { + { auto& cmpResult = mCmpResults[inst->mResult.mCmpResultIdx]; if (cmpResult.mResultVRegIdx != -1) { @@ -6299,12 +6324,12 @@ void BeMCContext::InitializedPassHelper(BeMCBlock* mcBlock, BeVTrackingGenContex } inst->mResult = BeMCOperand(); - } + } if (inst->mKind == BeMCInstKind_DbgDecl) - { + { if (!mVRegInitializedContext.IsSet(vregsInitialized, inst->mArg0.mVRegIdx)) - { + { auto vregInfo = mVRegInfo[inst->mArg0.mVRegIdx]; if (vregInfo->mIsExpr) // For shadowed inlined params, set as initialized addVec.push_back(inst->mArg0.mVRegIdx); @@ -6332,14 +6357,14 @@ void BeMCContext::InitializedPassHelper(BeMCBlock* mcBlock, BeVTrackingGenContex auto relVRegInfo = GetVRegInfo(vregInfo->mRelTo); if ((relVRegInfo->mDbgVariable != NULL) && (!mVRegInitializedContext.IsSet(vregsInitialized, vregInfo->mRelTo.mVRegIdx))) relVRegInfo->mHasAmbiguousInitialization = true; - } + } } if (inst->mKind == BeMCInstKind_LifetimeEnd) { // In some cases we can have a dbg variable that actually points to a global variable (due to macros/inlining/etc), so this check is for that case: - if (inst->mArg0.IsVRegAny()) + if (inst->mArg0.IsVRegAny()) { DedupPushBack(removeVec, inst->mArg0.mVRegIdx); DedupPushBack(removeVec, mVRegInitializedContext.GetIdx(inst->mArg0.mVRegIdx, BeTrackKind_Uninitialized)); @@ -6361,10 +6386,10 @@ void BeMCContext::InitializedPassHelper(BeMCBlock* mcBlock, BeVTrackingGenContex } if (inst->IsMov()) - { + { // This is also an address-taking operation, OR it's just a usage of an explicitly-undefined value if (inst->mArg1.IsVRegAny()) - { + { auto srcRegInfo = GetVRegInfo(inst->mArg1); if ((srcRegInfo->mDbgVariable != NULL) && (!mVRegInitializedContext.IsSet(vregsInitialized, inst->mArg1.mVRegIdx))) srcRegInfo->mHasAmbiguousInitialization = true; @@ -6374,8 +6399,8 @@ void BeMCContext::InitializedPassHelper(BeMCBlock* mcBlock, BeVTrackingGenContex int cpyDestVRegIdx = -1; if ((inst->mKind == BeMCInstKind_MemCpy) || (inst->mKind == BeMCInstKind_MemSet)) { - cpyDestVRegIdx = inst->mArg1.mVRegPair.mVRegIdx0; - } + cpyDestVRegIdx = inst->mArg1.mVRegPair.mVRegIdx0; + } //deepSet = true; auto destArg = inst->GetDest(); @@ -6394,7 +6419,7 @@ void BeMCContext::InitializedPassHelper(BeMCBlock* mcBlock, BeVTrackingGenContex auto vregInfo = mVRegInfo[vregIdx]; if (vregInfo->mChainLifetimeEnd) { - auto mcCheck = vregInfo->mRelTo; + auto mcCheck = vregInfo->mRelTo; while (mcCheck.IsVRegAny()) { auto checkInfo = mVRegInfo[mcCheck.mVRegIdx]; @@ -6411,7 +6436,7 @@ void BeMCContext::InitializedPassHelper(BeMCBlock* mcBlock, BeVTrackingGenContex mActiveBlock = NULL; for (int succIdx = 0; succIdx < (int)mcBlock->mSuccs.size(); succIdx++) - { + { BeMCBlock* succ = mcBlock->mSuccs[succIdx]; auto& entry = genCtx->mBlocks[succ->mBlockIdx]; @@ -6452,7 +6477,7 @@ void BeMCContext::InitializedPassHelper(BeMCBlock* mcBlock, BeVTrackingGenContex }*/ succ->mPredVRegsInitialized = newPredVRegsInitialized; - + //TODO: This was a bad comparison // if (succ->mBlockIdx > succ->mBlockIdx) // modifiedBlockAfter = true; @@ -6460,10 +6485,10 @@ void BeMCContext::InitializedPassHelper(BeMCBlock* mcBlock, BeVTrackingGenContex // modifiedBlockBefore = true; // What does this do? - if (succ->mBlockIdx > mcBlock->mBlockIdx) - modifiedBlockAfter = true; - else - modifiedBlockBefore = true; + if (succ->mBlockIdx > mcBlock->mBlockIdx) + modifiedBlockAfter = true; + else + modifiedBlockBefore = true; entry.mGenerateQueued = true; } @@ -6490,7 +6515,7 @@ void BeMCContext::SetVTrackingValue(BeMCOperand& operand, BeVTrackingValue& vTra void BeMCContext::DoInitInjectionPass() { - BP_ZONE("BeMCContext::DoInitInjectionPass"); + BP_ZONE("BeMCContext::DoInitInjectionPass"); for (auto mcBlock : mBlocks) { @@ -6517,11 +6542,11 @@ void BeMCContext::DoInitInjectionPass() } } } - + if (pendingInitKind != BfIRInitType_NotNeeded) - { - int vregIdx = inst->mArg0.mVRegIdx; - auto dbgVar = mVRegInfo[vregIdx]->mDbgVariable; + { + int vregIdx = inst->mArg0.mVRegIdx; + auto dbgVar = mVRegInfo[vregIdx]->mDbgVariable; auto varType = mVRegInfo[vregIdx]->mType; auto initType = dbgVar->mPendingInitType; @@ -6554,7 +6579,7 @@ void BeMCContext::DoInitInjectionPass() instIdx++; uint8 val = (initType == BfIRInitType_Uninitialized) ? 0xCC : 0; CreateMemSet(BeMCOperand::FromVRegAddr(vregIdx), val, varType->mSize, varType->mAlign); - instIdx--; + instIdx--; } else { @@ -6590,20 +6615,20 @@ void BeMCContext::SimpleInitializedPass() void BeMCContext::GenerateVRegInitFlags(BeVTrackingGenContext& genCtx) { - BP_ZONE("BeMCContext::GenerateVRegInitFlags"); + BP_ZONE("BeMCContext::GenerateVRegInitFlags"); mVRegInitializedContext.Clear(); mVRegInitializedContext.Init((int)mVRegInfo.size()); auto emptyList = mVRegInitializedContext.AllocEmptyList(); - + genCtx.mEmptyList = emptyList; genCtx.mBlocks.Resize(mBlocks.size()); for (int blockIdx = 0; blockIdx < (int)mBlocks.size(); blockIdx++) { - auto mcBlock = mBlocks[blockIdx]; - mcBlock->mPredVRegsInitialized = emptyList; + auto mcBlock = mBlocks[blockIdx]; + mcBlock->mPredVRegsInitialized = emptyList; } SimpleInitializedPass(); @@ -6611,7 +6636,7 @@ void BeMCContext::GenerateVRegInitFlags(BeVTrackingGenContext& genCtx) bool modifiedBlockBefore; bool modifiedBlockAfter; InitializedPassHelper(mBlocks[0], &genCtx, modifiedBlockBefore, modifiedBlockAfter); - + while (true) { bool didWork = false; @@ -6661,7 +6686,7 @@ void BeMCContext::GenerateVRegInitFlags(BeVTrackingGenContext& genCtx) if ((fromInst == NULL) || (fromInst->mVRegsInitialized == NULL) || (toInst == NULL) || (toInst->mVRegsInitialized == NULL)) continue; - + auto prevVRegsInit = toInst->mVRegsInitialized; auto newVRegsInit = mVRegInitializedContext.SetChanges(toInst->mVRegsInitialized, fromInst->mVRegsInitialized);; @@ -6671,50 +6696,50 @@ void BeMCContext::GenerateVRegInitFlags(BeVTrackingGenContext& genCtx) if (inst->mVRegsInitialized != prevVRegsInit) break; inst->mVRegsInitialized = newVRegsInit; - } + } } int instCount = 0; for (auto block : mBlocks) instCount += (int)block->mInstructions.size(); - BpEvent("GenerateVRegInitFlags Results", + BpEvent("GenerateVRegInitFlags Results", StrFormat("Blocks: %d\nInstructions: %d\nVRegs: %d\nCalls: %d\nHandled Calls: %d\nProcessed Instructions: %d\nVRegInit Bytes: %d\nTemp Bytes: %d", - (int)mBlocks.size(), instCount, (int)mVRegInfo.size(), genCtx.mCalls, genCtx.mHandledCalls, genCtx.mInstructions, mVRegInitializedContext.mAlloc.GetAllocSize(), genCtx.mAlloc.GetAllocSize()).c_str()); + (int)mBlocks.size(), instCount, (int)mVRegInfo.size(), genCtx.mCalls, genCtx.mHandledCalls, genCtx.mInstructions, mVRegInitializedContext.mAlloc.GetAllocSize(), genCtx.mAlloc.GetAllocSize()).c_str()); } bool BeMCContext::DoInitializedPass() { - BP_ZONE("BeMCContext::DoInitializedPass"); + BP_ZONE("BeMCContext::DoInitializedPass"); BeVTrackingGenContext genCtx; GenerateVRegInitFlags(genCtx); - + // Search blocks for instances of ambiguous initialization for (int blockIdx = 0; blockIdx < (int)mBlocks.size(); blockIdx++) { - auto mcBlock = mBlocks[blockIdx]; + auto mcBlock = mBlocks[blockIdx]; // If mPredVRegsInitialized is NULL, this blocks is unreachable. It could still be in some other block's preds so we don't // completely erase it, just empty it if (genCtx.mBlocks[mcBlock->mBlockIdx].mGenerateCount == 0) - { + { // Unused block - clear almost all instructions int newIdx = 0; -// for (int instIdx = 0; instIdx < (int)mcBlock->mInstructions.size(); instIdx++) -// { -// auto inst = mcBlock->mInstructions[instIdx]; -// if (inst->mKind == BeMCInstKind_ValueScopeHardEnd) -// { -// mcBlock->mInstructions[newIdx++] = inst; -// } -// } + // for (int instIdx = 0; instIdx < (int)mcBlock->mInstructions.size(); instIdx++) + // { + // auto inst = mcBlock->mInstructions[instIdx]; + // if (inst->mKind == BeMCInstKind_ValueScopeHardEnd) + // { + // mcBlock->mInstructions[newIdx++] = inst; + // } + // } mcBlock->mInstructions.mSize = newIdx; continue; } - + for (int vregIdx : *mcBlock->mPredVRegsInitialized) - { + { if (vregIdx >= mVRegInitializedContext.mNumItems) continue; @@ -6726,7 +6751,7 @@ bool BeMCContext::DoInitializedPass() // checked against usage of unassigned variables -- unless overridden with a "?" uninitialized expression, in which case // one could argue that 0xCC would be a more useful value, but we go with the argument for the "less confusing" zero in this case. auto vregInfo = mVRegInfo[vregIdx]; - vregInfo->mHasAmbiguousInitialization = true; + vregInfo->mHasAmbiguousInitialization = true; } } } @@ -6734,13 +6759,13 @@ bool BeMCContext::DoInitializedPass() bool needsReRun = false; bool hasInits = false; - for (int vregIdx = 0; vregIdx < (int)mVRegInfo.size(); vregIdx++) + for (int vregIdx = 0; vregIdx < (int)mVRegInfo.size(); vregIdx++) { auto vregInfo = mVRegInfo[vregIdx]; if (vregInfo->mDbgVariable != NULL) { auto initType = vregInfo->mDbgVariable->mInitType; - + if (initType == BfIRInitType_NotSet) { if (vregInfo->mHasAmbiguousInitialization) @@ -6757,18 +6782,18 @@ bool BeMCContext::DoInitializedPass() if (vregInfo->mDbgVariable->mPendingInitType == initType) continue; - + if ((initType != BfIRInitType_NotNeeded) || (vregInfo->mDbgVariable->mPendingInitType == BfIRInitType_NotSet)) { vregInfo->mDbgVariable->mPendingInitType = initType; - } + } if ((initType != BfIRInitType_NotNeeded) && (initType != BfIRInitType_NotNeeded_AliveOnDecl)) { - vregInfo->mDbgVariable->mPendingInitDef = true; + vregInfo->mDbgVariable->mPendingInitDef = true; BF_ASSERT(vregInfo->mHasDynLife); - vregInfo->mDoConservativeLife = true; + vregInfo->mDoConservativeLife = true; hasInits = true; } } @@ -6781,7 +6806,7 @@ bool BeMCContext::DoInitializedPass() // We need to re-execute the init flag generation BeVTrackingGenContext genCtx; GenerateVRegInitFlags(genCtx); - } + } return !needsReRun; } @@ -6805,21 +6830,21 @@ void BeMCContext::DoTLSSetup() continue; if ((inst->mKind == BeMCInstKind_Mov) && (inst->mArg1.IsNativeReg())) continue; - + auto int32Type = mModule->mContext->GetPrimitiveType(BeTypeCode_Int32); auto intType = mModule->mContext->GetPrimitiveType(BeTypeCode_Int64); auto intPtrType = mModule->mContext->GetPointerTo(intType); - + auto mcTlsIndex = AllocVirtualReg(intType); CreateDefineVReg(mcTlsIndex, instIdx++); - + auto sym = mCOFFObject->GetSymbolRef("_tls_index"); if (sym->mType == NULL) sym->mType = int32Type; AllocInst(BeMCInstKind_Mov, mcTlsIndex, BeMCOperand::FromSymbol(sym->mIdx), instIdx++); AllocInst(BeMCInstKind_Def, BeMCOperand::FromVReg(mTLSVRegIdx), instIdx++); - AllocInst(BeMCInstKind_TLSSetup, BeMCOperand::FromVReg(mTLSVRegIdx), BeMCOperand::FromImmediate(0), instIdx++); + AllocInst(BeMCInstKind_TLSSetup, BeMCOperand::FromVReg(mTLSVRegIdx), BeMCOperand::FromImmediate(0), instIdx++); auto mcTlsVal = AllocVirtualReg(intPtrType); CreateDefineVReg(mcTlsVal, instIdx++); @@ -6827,7 +6852,7 @@ void BeMCContext::DoTLSSetup() tlsValInfo->mIsExpr = true; tlsValInfo->mRelTo = BeMCOperand::FromVReg(mTLSVRegIdx); tlsValInfo->mRelOffset = mcTlsIndex; - tlsValInfo->mRelOffsetScale = 8; + tlsValInfo->mRelOffsetScale = 8; auto mcLoadVal = mcTlsVal; mcLoadVal.mKind = BeMCOperandKind_VRegLoad; @@ -6852,15 +6877,15 @@ void BeMCContext::DoChainedBlockMerge() auto lastInst = mcBlock->mInstructions.back(); // Last instruction of current block is an unconditional branch to the next block if ((lastInst->mKind == BeMCInstKind_Br) && (lastInst->mArg0.mBlock == nextMcBlock)) - { + { mcBlock->mSuccs.Remove(nextMcBlock); for (auto succ : nextMcBlock->mSuccs) - { + { if (!mcBlock->mSuccs.Contains(succ)) { mcBlock->mSuccs.push_back(succ); succ->mPreds.push_back(mcBlock); - } + } succ->mPreds.Remove(nextMcBlock); } @@ -6879,22 +6904,22 @@ void BeMCContext::DoChainedBlockMerge() } void BeMCContext::DoSplitLargeBlocks() -{ +{ Dictionary blockEndRemap; - int splitSize = 4096; - int maxBlockSize = splitSize + splitSize/4; + int splitSize = 4096; + int maxBlockSize = splitSize + splitSize / 4; bool hadSplits = false; - + for (int blockIdx = 0; blockIdx < mBlocks.size(); blockIdx++) - { + { int blockBreakIdx = 0; auto srcBlock = mBlocks[blockIdx]; if (srcBlock->mInstructions.size() < maxBlockSize) continue; hadSplits = true; - int extensionCount = srcBlock->mInstructions.size() / splitSize; + int extensionCount = srcBlock->mInstructions.size() / splitSize; // Don't allow the last block to have too few instructions if (srcBlock->mInstructions.size() % splitSize < splitSize / 4) extensionCount--; @@ -6913,21 +6938,21 @@ void BeMCContext::DoSplitLargeBlocks() extBlock->mInstructions.Insert(0, &srcBlock->mInstructions[startIdx], endIdx - startIdx); extBlock->mPreds.Add(mBlocks[blockIdx + extIdx]); - + if (extIdx > 0) { auto prevBlock = mBlocks[blockIdx + extIdx]; - mActiveBlock = prevBlock; + mActiveBlock = prevBlock; AllocInst(BeMCInstKind_Br, BeMCOperand::FromBlock(extBlock)); mActiveBlock = NULL; mBlocks[blockIdx + extIdx]->mSuccs.Add(extBlock); - } - + } + if (extIdx == extensionCount - 1) { blockEndRemap[blockIdx] = blockIdx + extIdx + 1; - + for (auto succ : srcBlock->mSuccs) { succ->mPreds.Remove(srcBlock); @@ -6936,29 +6961,29 @@ void BeMCContext::DoSplitLargeBlocks() extBlock->mSuccs = srcBlock->mSuccs; srcBlock->mSuccs.Clear(); srcBlock->mSuccs.Add(mBlocks[blockIdx + 1]); - } + } } mActiveBlock = srcBlock; - srcBlock->mInstructions.RemoveRange(splitSize, (int)srcBlock->mInstructions.size() - splitSize); + srcBlock->mInstructions.RemoveRange(splitSize, (int)srcBlock->mInstructions.size() - splitSize); AllocInst(BeMCInstKind_Br, BeMCOperand::FromBlock(mBlocks[blockIdx + 1])); mActiveBlock = NULL; } - + if (!hadSplits) return; -// for (int blockIdx = 0; blockIdx < mBlocks.size(); blockIdx++) -// { -// auto mcBlock = mBlocks[blockIdx]; -// for (auto inst : mcBlock->mInstructions) -// { -// if (inst->mResult.mKind == BeMCOperandKind_Phi) -// { -// inst->mResult.mP -// } -// } -// } + // for (int blockIdx = 0; blockIdx < mBlocks.size(); blockIdx++) + // { + // auto mcBlock = mBlocks[blockIdx]; + // for (auto inst : mcBlock->mInstructions) + // { + // if (inst->mResult.mKind == BeMCOperandKind_Phi) + // { + // inst->mResult.mP + // } + // } + // } for (int blockIdx = 0; blockIdx < mBlocks.size(); blockIdx++) mBlocks[blockIdx]->mBlockIdx = blockIdx; @@ -6985,7 +7010,7 @@ void BeMCContext::DetectLoops() } void BeMCContext::DoLastUsePassHelper(BeMCInst* inst, const BeMCOperand& operand) -{ +{ if (operand.mKind == BeMCOperandKind_VRegPair) { auto mcOperand = BeMCOperand::FromEncoded(operand.mVRegPair.mVRegIdx0); @@ -6998,7 +7023,7 @@ void BeMCContext::DoLastUsePassHelper(BeMCInst* inst, const BeMCOperand& operand } if (!operand.IsVRegAny()) - return; + return; int vregIdx = operand.mVRegIdx; auto vregInfo = mVRegInfo[vregIdx]; @@ -7061,13 +7086,13 @@ void BeMCContext::RefreshRefCounts() mVRegInfo[op.mVRegIdx]->mRefCount++; if (op.mKind == BeMCOperandKind_VRegPair) { - auto vreg0 = BeMCOperand::FromEncoded(op.mVRegPair.mVRegIdx0); + auto vreg0 = BeMCOperand::FromEncoded(op.mVRegPair.mVRegIdx0); if (vreg0.IsVRegAny()) { mVRegInfo[vreg0.mVRegIdx]->mRefCount++; mVRegInfo[vreg0.mVRegIdx]->mAssignCount++; } - + auto vreg1 = BeMCOperand::FromEncoded(op.mVRegPair.mVRegIdx1); if (vreg1.IsVRegAny()) mVRegInfo[vreg1.mVRegIdx]->mRefCount++; @@ -7076,13 +7101,13 @@ void BeMCContext::RefreshRefCounts() if (inst->IsAssignment()) { - if (inst->mArg0.IsVRegAny()) - mVRegInfo[inst->mArg0.mVRegIdx]->mAssignCount++; + if (inst->mArg0.IsVRegAny()) + mVRegInfo[inst->mArg0.mVRegIdx]->mAssignCount++; } if (inst->mResult) { - if (inst->mResult.IsVRegAny()) - mVRegInfo[inst->mResult.mVRegIdx]->mAssignCount++; + if (inst->mResult.IsVRegAny()) + mVRegInfo[inst->mResult.mVRegIdx]->mAssignCount++; } } } @@ -7111,16 +7136,16 @@ bool BeMCContext::CheckVRegEqualityRange(BeMCBlock* mcBlock, int instIdx, const return true; } - if ((checkInst->mKind == BeMCInstKind_LifetimeEnd) && + if ((checkInst->mKind == BeMCInstKind_LifetimeEnd) && ((checkInst->mArg0.mVRegIdx == vreg0.mVRegIdx) || (checkInst->mArg0.mVRegIdx == vreg1.mVRegIdx))) - { + { if (checkInstIdx == (int)mcBlock->mInstructions.size() - 1) { // There are cases where this might be the last instruction in a block, so we won't see the mLiveness change // so this catches that case return true; } - + // We have cases like when have a "defer delete val;", val will get used by the dtor after the LifetimeEnd return false; } @@ -7156,21 +7181,21 @@ bool BeMCContext::CheckVRegEqualityRange(BeMCBlock* mcBlock, int instIdx, const void BeMCContext::DoInstCombinePass() { - BP_ZONE("BeMCContext::DoInstCombinePass"); + BP_ZONE("BeMCContext::DoInstCombinePass"); BeMCRemapper regRemaps; regRemaps.Init((int)mVRegInfo.size()); BeVTrackingValue vTrackingVal((int)mVRegInfo.size()); HashSet wantUnwrapVRegs; - + for (auto mcBlock : mBlocks) { BeDbgLoc* curDbgLoc = NULL; int safeMergeLocStart = 0; bool lastDefDidMerge = false; for (int instIdx = 0; instIdx < (int)mcBlock->mInstructions.size(); instIdx++) - { + { bool reprocessInst = false; auto inst = mcBlock->mInstructions[instIdx]; @@ -7183,7 +7208,7 @@ void BeMCContext::DoInstCombinePass() safeMergeLocStart = instIdx; curDbgLoc = inst->mDbgLoc; } - + if ((inst->mKind == BeMCInstKind_Call) || (inst->mKind == BeMCInstKind_MemCpy) || (inst->mKind == BeMCInstKind_MemSet)) { // Don't merge anything across callsites or memory writes @@ -7225,7 +7250,7 @@ void BeMCContext::DoInstCombinePass() // Handle movs into .addrs if (inst->mKind == BeMCInstKind_Mov) { - auto vregInfoDest = GetVRegInfo(inst->mArg0); + auto vregInfoDest = GetVRegInfo(inst->mArg0); if (vregInfoDest != NULL) { auto vregInfoSrc = GetVRegInfo(inst->mArg1); @@ -7234,7 +7259,7 @@ void BeMCContext::DoInstCombinePass() vregInfoSrc->mForceMerge = false; if ((vregInfoDest->mDbgVariable != NULL) && (vregInfoSrc->CanEliminate())) { - BF_ASSERT(!mVRegInitializedContext.IsSet(inst->mVRegsInitialized, inst->mArg0.mVRegIdx)); + BF_ASSERT(!mVRegInitializedContext.IsSet(inst->mVRegsInitialized, inst->mArg0.mVRegIdx)); AddRegRemap(inst->mArg1.mVRegIdx, inst->mArg0.mVRegIdx, regRemaps); // Remove any LifetimeStarts since our source may have been alive before us //if (inst->mArg1.mVRegIdx < inst->mArg0.mVRegIdx) @@ -7243,7 +7268,7 @@ void BeMCContext::DoInstCombinePass() } } } - + // The following code only applies when we aren't on the last instruction int nextIdx = instIdx + 1; BeMCInst* nextInst = NULL; @@ -7258,7 +7283,7 @@ void BeMCContext::DoInstCombinePass() } if (nextInst == NULL) continue; - + // The following code only applies when we have at least 2 more instructions // Find a non-Def instruction int nextNextIdx = nextIdx + 1; @@ -7278,7 +7303,7 @@ void BeMCContext::DoInstCombinePass() auto arg1 = RemapOperand(inst->mArg1, regRemaps); if (inst->IsDef()) - { + { auto vregInfo = mVRegInfo[inst->mArg0.mVRegIdx]; if (vregInfo->mIsExpr) { @@ -7289,7 +7314,7 @@ void BeMCContext::DoInstCombinePass() { auto checkArg0 = RemapOperand(checkInst->mArg0, regRemaps); auto checkVRegInfo = mVRegInfo[checkArg0.mVRegIdx]; - + if (checkVRegInfo->mIsExpr) { // Remap to use the earlier definition of this expression @@ -7313,7 +7338,7 @@ void BeMCContext::DoInstCombinePass() } if (!hadBadWrite) - { + { auto vregInfoFrom = GetVRegInfo(inst->mArg0); if (vregInfoFrom->mDbgVariable == NULL) AddRegRemap(inst->mArg0.mVRegIdx, checkArg0.mVRegIdx, regRemaps, true); @@ -7336,7 +7361,7 @@ void BeMCContext::DoInstCombinePass() if (inst->mKind == BeMCInstKind_DefLoad) { auto vregInfoDest = GetVRegInfo(inst->mArg0); - + auto mcLoaded = inst->mArg0; auto mcAddr = vregInfoDest->mRelTo; @@ -7344,7 +7369,7 @@ void BeMCContext::DoInstCombinePass() bool mapToDef = false; if (mcAddr.mKind == BeMCOperandKind_VReg) { - auto vregInfo = mVRegInfo[inst->mArg0.mVRegIdx]; + auto vregInfo = mVRegInfo[inst->mArg0.mVRegIdx]; // We do 'onlyCheckFirstLifetime' because we have cases like when have a "defer delete val;", because val will get used by the dtor after the LiftimeEnd if ((vregInfo->IsDirectRelTo()) && (vregInfo->mDbgVariable == NULL) && (CheckVRegEqualityRange(mcBlock, instIdx, mcLoaded, mcAddr, regRemaps, true))) { @@ -7362,7 +7387,7 @@ void BeMCContext::DoInstCombinePass() //wantUnwrapVRegs.Add(inst->mArg0.mVRegIdx); continue; } - + bool hadPointerDeref = false; for (int checkInstIdx = instIdx + 1; checkInstIdx < (int)mcBlock->mInstructions.size(); checkInstIdx++) { @@ -7375,7 +7400,7 @@ void BeMCContext::DoInstCombinePass() if ((mcAddr.IsVRegAny()) && (!IsLive(checkInst->mLiveness, mcAddr.mVRegIdx, regRemaps))) break; - + if (hadPointerDeref) { // Pointer deref is okay as long as liveness ends one instruction afterwards @@ -7383,7 +7408,7 @@ void BeMCContext::DoInstCombinePass() } auto mcDest = checkInst->GetDest(); - if ((mcDest != NULL) && + if ((mcDest != NULL) && ((mcDest->mKind == BeMCOperandKind_VReg) || (mcDest->mKind == mcAddr.mKind))) { // Any assignment to either of these regs ends our remapping loop @@ -7398,7 +7423,7 @@ void BeMCContext::DoInstCombinePass() // Delay the 'return false' until we determine if our liveness ends on the next instruction. // If it does, then this is okay because it didn't affect the source of any operations hadPointerDeref = true; - } + } } if (checkInst->IsInformational()) @@ -7429,7 +7454,7 @@ void BeMCContext::DoInstCombinePass() operand->mVRegIdx = mcAddr.mVRegIdx; } } - } + } } } @@ -7446,21 +7471,21 @@ void BeMCContext::DoInstCombinePass() (!destRelTo->mIsExpr) && (!srcRelTo->mIsExpr)) { mCompositeRetVRegIdx = vregInfoDest->mRelTo.mVRegIdx; - RemoveInst(mcBlock, instIdx); - srcRelTo->SetRetVal(); + RemoveInst(mcBlock, instIdx); + srcRelTo->SetRetVal(); instIdx--; continue; } } } - + // For the form: // @Def %vreg0 // [%result] = %vreg0, %vreg1 // Remap %vreg0 to %vreg1 if this is the only assignment, and thus an immutable definition, and vreg1 doesn't change - if ((nextDestOperand) && + if ((nextDestOperand) && (((inst->mKind == BeMCInstKind_Def) && (arg0 == nextDestOperand)) || - ((inst->mKind == BeMCInstKind_LifetimeStart) && (BeMCOperand::ToLoad(arg0) == nextDestOperand)))) + ((inst->mKind == BeMCInstKind_LifetimeStart) && (BeMCOperand::ToLoad(arg0) == nextDestOperand)))) { lastDefDidMerge = false; @@ -7480,12 +7505,12 @@ void BeMCContext::DoInstCombinePass() // We can only remap to LHS checkArg1 = false; } - } + } for (int argCheckIdx = (nextInst->mResult ? 0 : 1); argCheckIdx < (checkArg1 ? 2 : 1); argCheckIdx++) - { + { BeMCOperand origCheckOperand; - + if (argCheckIdx == 0) origCheckOperand = nextInst->mArg0; else @@ -7511,7 +7536,7 @@ void BeMCContext::DoInstCombinePass() continue; } } - + // We have a special retVal case where we can allow the __returnVal to share an address with the // actual 'ret' param. This is most useful when returning structs by value, to avoid a copy. // The only downside is that editing the return value in the debugger will also show the value @@ -7523,7 +7548,7 @@ void BeMCContext::DoInstCombinePass() if (!AreTypesEquivalent(vregInfoCheck->mType, vregInfoDest->mType)) continue; - bool canMerge = false; + bool canMerge = false; if ((nextInst->IsMov()) && (allowCoexist)) { if ((vregInfoCheck->mForceMerge) || (vregInfoCheck->mIsRetVal)) @@ -7537,12 +7562,12 @@ void BeMCContext::DoInstCombinePass() // be different after the instruction, so we can only map them if the incoming vreg will be dead // afterwards. If both are dbgVariables then we can't allow them to coeexist because the user // could edit one of the values in the debugger and we don't want the other one changing. - if ((nextNextInst != NULL) && + if ((nextNextInst != NULL) && (!IsLive(nextNextInst->mLiveness, origCheckOperand.mVRegIdx, regRemaps)) && (!IsLive(nextNextInst->mLiveness, checkOperand.mVRegIdx, regRemaps))) canMerge = true; - } - + } + if (canMerge) { if (vregInfoCheck->mForceMerge) @@ -7550,7 +7575,7 @@ void BeMCContext::DoInstCombinePass() lastDefDidMerge = true; if (vregInfoDest->mIsRetVal) - { + { // We don't do a remap for this return value optimization, because we want both vregs // to still show in the debugger - even though they will point to the same address // now (in the case of a struct return) @@ -7585,7 +7610,7 @@ void BeMCContext::DoInstCombinePass() if (vregInfoCheck->CanEliminate()) { if (vregInfoCheck->mIsRetVal) - { + { vregInfoDest->SetRetVal(); //BF_ASSERT(mCompositeRetVRegIdx != -1); //vregInfoCheck->mRelTo = BeMCOperand::FromVReg(mCompositeRetVRegIdx); @@ -7597,7 +7622,7 @@ void BeMCContext::DoInstCombinePass() break; } } - } + } } } @@ -7610,12 +7635,12 @@ void BeMCContext::DoInstCombinePass() // Where vreg0 has no other references, convert to // , &vreg1 if ((inst->mKind == BeMCInstKind_Def) && (nextInst->mKind == BeMCInstKind_Mov) && (nextNextInst != NULL)) - { + { auto vregInfo = GetVRegInfo(inst->mArg0); if ((vregInfo->mRefCount == 2) && (inst->mArg0 == nextInst->mArg0) && (!nextInst->mArg1.IsNativeReg()) && (nextNextInst->mArg0 != nextInst->mArg0) && (nextNextInst->mArg1 == nextInst->mArg0) && (AreTypesEquivalent(GetType(inst->mArg0), GetType(nextInst->mArg1)))) - { + { nextNextInst->mArg1 = nextInst->mArg1; RemoveInst(mcBlock, instIdx); RemoveInst(mcBlock, instIdx); @@ -7653,7 +7678,7 @@ void BeMCContext::DoInstCombinePass() // If %vreg2 has no other references, combine into // %vreg3 = %vreg0, %vreg1 if ((nextInst->IsMov()) && (result == nextArg1)) - { + { // We purposely check inst->mResult here rather than 'result', because that ref count is our // indication of whether the result was actually used again auto vregInfo = GetVRegInfo(inst->mResult); @@ -7683,15 +7708,15 @@ void BeMCContext::DoInstCombinePass() { if ((nextInst->IsMov()) && (arg1 == nextArg0) && (result == nextArg1)) { - break; + break; } } - + // For the form: // %vreg2 = %vreg0, %vreg1 // If %vreg0 ends its life on this instruction, // Replace all instances of %vreg2 with %vreg0 - if ((inst->mResult.mKind == BeMCOperandKind_VReg) && (inst->mArg0.mKind == BeMCOperandKind_VReg) && + if ((inst->mResult.mKind == BeMCOperandKind_VReg) && (inst->mArg0.mKind == BeMCOperandKind_VReg) && (inst->mResult != inst->mArg0)) { // Check liveness against both the orig arg0 and the remap @@ -7707,9 +7732,9 @@ void BeMCContext::DoInstCombinePass() { AddRegRemap(inst->mResult.mVRegIdx, arg0.mVRegIdx, regRemaps); } - } + } } - } + } } if (inst->mKind == BeMCInstKind_RestoreVolatiles) @@ -7720,14 +7745,14 @@ void BeMCContext::DoInstCombinePass() for (int checkInstIdx = instIdx + 1; checkInstIdx < (int)mcBlock->mInstructions.size(); checkInstIdx++) { auto checkInst = mcBlock->mInstructions[checkInstIdx]; - + if ((checkInst->mKind != BeMCInstKind_DbgDecl) && (checkInst->mKind != BeMCInstKind_EnsureInstructionAt) && (checkInst->mKind != BeMCInstKind_Ret)) { hadInvalidInst = true; break; - } + } } if (!hadInvalidInst) @@ -7753,16 +7778,16 @@ void BeMCContext::DoInstCombinePass() // Test &veg0, 1 // CondBr