diff --git a/llvm/lib/Analysis/MemoryProfileInfo.cpp b/llvm/lib/Analysis/MemoryProfileInfo.cpp index 92a5b6f378aab..b09f4ed78ca7e 100644 --- a/llvm/lib/Analysis/MemoryProfileInfo.cpp +++ b/llvm/lib/Analysis/MemoryProfileInfo.cpp @@ -241,9 +241,13 @@ static MDNode *createMIBNode(LLVMContext &Ctx, ArrayRef MIBCallStack, ColdBytes += TotalSize; // If we have the max cold context size from summary information and have // requested identification of contexts above a percentage of the max, see - // if this context qualifies. - if (MaxColdSize > 0 && MinPercentMaxColdSize < 100 && - TotalSize * 100 >= MaxColdSize * MinPercentMaxColdSize) + // if this context qualifies. We should assume this is large if we rebuilt + // the trie from existing metadata (i.e. to update after inlining), in + // which case we don't have a MaxSize from the profile - we assume any + // context size info in existence on the metadata should be propagated. + if (BuiltFromExistingMetadata || + (MaxColdSize > 0 && MinPercentMaxColdSize < 100 && + TotalSize * 100 >= MaxColdSize * MinPercentMaxColdSize)) LargeColdContext = true; } // Only add the context size info as metadata if we need it in the thin diff --git a/llvm/unittests/Analysis/MemoryProfileInfoTest.cpp b/llvm/unittests/Analysis/MemoryProfileInfoTest.cpp index d1c0f643f5cd7..113b05299252b 100644 --- a/llvm/unittests/Analysis/MemoryProfileInfoTest.cpp +++ b/llvm/unittests/Analysis/MemoryProfileInfoTest.cpp @@ -638,7 +638,7 @@ declare dso_local noalias noundef i8* @malloc(i64 noundef) !0 = !{!1, !3, !5, !7, !9, !11} !1 = !{!2, !"cold"} !2 = !{i64 1, i64 2, i64 3} -!3 = !{!4, !"cold"} +!3 = !{!4, !"cold", !13} !4 = !{i64 1, i64 2, i64 4} !5 = !{!6, !"notcold"} !6 = !{i64 1, i64 5, i64 6} @@ -648,6 +648,7 @@ declare dso_local noalias noundef i8* @malloc(i64 noundef) !10 = !{i64 1, i64 8, i64 9} !11 = !{!12, !"hot"} !12 = !{i64 1, i64 8, i64 10} +!13 = !{i64 123, i64 456} )IR"); Function *Func = M->getFunction("test"); @@ -683,10 +684,25 @@ declare dso_local noalias noundef i8* @malloc(i64 noundef) auto *StackId = mdconst::dyn_extract(StackMD->getOperand(0)); EXPECT_EQ(StackId->getZExtValue(), 1u); StackId = mdconst::dyn_extract(StackMD->getOperand(1)); - if (StackId->getZExtValue() == 2u) + if (StackId->getZExtValue() == 2u) { EXPECT_EQ(getMIBAllocType(MIB), AllocationType::Cold); - else if (StackId->getZExtValue() == 5u) + // We should propagate the single context size info from the second cold + // context above onto the new merged/trimmed context. + ASSERT_EQ(MIB->getNumOperands(), 3u); + MDNode *ContextSizePair = dyn_cast(MIB->getOperand(2)); + assert(ContextSizePair->getNumOperands() == 2); + EXPECT_EQ( + mdconst::dyn_extract(ContextSizePair->getOperand(0)) + ->getZExtValue(), + 123u); + EXPECT_EQ( + mdconst::dyn_extract(ContextSizePair->getOperand(1)) + ->getZExtValue(), + 456u); + } else if (StackId->getZExtValue() == 5u) { EXPECT_EQ(getMIBAllocType(MIB), AllocationType::NotCold); + ASSERT_EQ(MIB->getNumOperands(), 2u); + } } }