diff --git a/llvm/lib/ProfileData/SampleProfWriter.cpp b/llvm/lib/ProfileData/SampleProfWriter.cpp --- a/llvm/lib/ProfileData/SampleProfWriter.cpp +++ b/llvm/lib/ProfileData/SampleProfWriter.cpp @@ -361,7 +361,7 @@ std::error_code SampleProfileWriterText::writeSample(const FunctionSamples &S) { auto &OS = *OutputStream; if (FunctionSamples::ProfileIsCS) - OS << "[" << S.getNameWithContext() << "]:" << S.getTotalSamples(); + OS << S.getNameWithContext(true) << ":" << S.getTotalSamples(); else OS << S.getName() << ":" << S.getTotalSamples(); if (Indent == 0) diff --git a/llvm/test/tools/llvm-profgen/cs-extbinary.test b/llvm/test/tools/llvm-profgen/cs-extbinary.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-profgen/cs-extbinary.test @@ -0,0 +1,14 @@ +; test for dwarf-based cs profile +; RUN: llvm-profgen --format=extbinary --perfscript=%S/Inputs/recursion-compression-noprobe.perfscript --binary=%S/Inputs/recursion-compression-noprobe.perfbin --output=%t1 --csprof-cold-thres=0 +; RUN: llvm-profdata merge --sample --text --output=%t2 %t1 +; RUN: FileCheck %S/recursion-compression-noprobe.test --input-file %t2 +; RUN: llvm-profdata merge --sample --extbinary --output=%t3 %t2 && llvm-profdata merge --sample --text --output=%t4 %t3 +; RUN: diff -b %t2 %t4 + + +; test for probe-based cs profile +; RUN: llvm-profgen --format=extbinary --perfscript=%S/Inputs/recursion-compression-pseudoprobe.perfscript --binary=%S/Inputs/recursion-compression-pseudoprobe.perfbin --output=%t5 --csprof-cold-thres=0 +; RUN: llvm-profdata merge --sample --text --output=%t6 %t5 +; RUN: FileCheck %S/recursion-compression-pseudoprobe.test --input-file %t6 +; RUN: llvm-profdata merge --sample --extbinary --output=%t7 %t6 && llvm-profdata merge --sample --text --output=%t8 %t7 +; RUN: diff -b %t6 %t8 diff --git a/llvm/test/tools/llvm-profgen/inline-cs-noprobe.test b/llvm/test/tools/llvm-profgen/inline-cs-noprobe.test --- a/llvm/test/tools/llvm-profgen/inline-cs-noprobe.test +++ b/llvm/test/tools/llvm-profgen/inline-cs-noprobe.test @@ -10,17 +10,16 @@ ; CHECK: 1: 14 ; CHECK-UNWINDER: Binary(inline-cs-noprobe.perfbin)'s Range Counter: -; CHECK-UNWINDER: main:1 @ foo +; CHECK-UNWINDER: [main:1 @ foo:3.2 @ bar] +; CHECK-UNWINDER: (6af, 6bb): 14 +; CHECK-UNWINDER: [main:1 @ foo] ; CHECK-UNWINDER: (670, 6ad): 1 ; CHECK-UNWINDER: (67e, 69b): 1 ; CHECK-UNWINDER: (67e, 6ad): 13 ; CHECK-UNWINDER: (6bd, 6c8): 14 -; CHECK-UNWINDER: main:1 @ foo:3.2 @ bar -; CHECK-UNWINDER: (6af, 6bb): 14 - ; CHECK-UNWINDER: Binary(inline-cs-noprobe.perfbin)'s Branch Counter: -; CHECK-UNWINDER: main:1 @ foo +; CHECK-UNWINDER: [main:1 @ foo] ; CHECK-UNWINDER: (69b, 670): 1 ; CHECK-UNWINDER: (6c8, 67e): 15 diff --git a/llvm/test/tools/llvm-profgen/noinline-cs-noprobe.test b/llvm/test/tools/llvm-profgen/noinline-cs-noprobe.test --- a/llvm/test/tools/llvm-profgen/noinline-cs-noprobe.test +++ b/llvm/test/tools/llvm-profgen/noinline-cs-noprobe.test @@ -12,25 +12,27 @@ ; CHECK: 3: 3 bar:3 ; CHECK-UNWINDER: Binary(noinline-cs-noprobe.perfbin)'s Range Counter: -; CHECK-UNWINDER: main:1 @ foo -; CHECK-UNWINDER: (5ff, 62f): 3 -; CHECK-UNWINDER: (634, 637): 3 -; CHECK-UNWINDER: (645, 645): 3 -; CHECK-UNWINDER: main:1 @ foo:3 @ bar +; CHECK-UNWINDER: [main:1 @ foo:3 @ bar] ; CHECK-UNWINDER: (5b0, 5c8): 1 ; CHECK-UNWINDER: (5b0, 5d7): 2 ; CHECK-UNWINDER: (5dc, 5e9): 1 ; CHECK-UNWINDER: (5e5, 5e9): 2 +; CHECK-UNWINDER: [main:1 @ foo] +; CHECK-UNWINDER: (5ff, 62f): 3 +; CHECK-UNWINDER: (634, 637): 3 +; CHECK-UNWINDER: (645, 645): 3 + ; CHECK-UNWINDER: Binary(noinline-cs-noprobe.perfbin)'s Branch Counter: -; CHECK-UNWINDER: main:1 @ foo -; CHECK-UNWINDER: (62f, 5b0): 3 -; CHECK-UNWINDER: (637, 645): 3 -; CHECK-UNWINDER: (645, 5ff): 3 -; CHECK-UNWINDER: main:1 @ foo:3 @ bar +; CHECK-UNWINDER: [main:1 @ foo:3 @ bar] ; CHECK-UNWINDER: (5c8, 5dc): 2 ; CHECK-UNWINDER: (5d7, 5e5): 2 ; CHECK-UNWINDER: (5e9, 634): 3 +; CHECK-UNWINDER: [main:1 @ foo] +; CHECK-UNWINDER: (62f, 5b0): 3 +; CHECK-UNWINDER: (637, 645): 3 +; CHECK-UNWINDER: (645, 5ff): 3 + diff --git a/llvm/test/tools/llvm-profgen/recursion-compression-noprobe.test b/llvm/test/tools/llvm-profgen/recursion-compression-noprobe.test --- a/llvm/test/tools/llvm-profgen/recursion-compression-noprobe.test +++ b/llvm/test/tools/llvm-profgen/recursion-compression-noprobe.test @@ -10,16 +10,17 @@ ; CHECK-UNCOMPRESS:[main:1 @ foo:3 @ fa:2 @ fb]:12:0 ; CHECK-UNCOMPRESS: 1: 11 ; CHECK-UNCOMPRESS: 2: 1 fa:1 -; CHECK-UNCOMPRESS:[main:1 @ foo:3 @ fa:2 @ fb:2 @ fa]:3:0 -; CHECK-UNCOMPRESS: 1: 1 -; CHECK-UNCOMPRESS: 2: 2 fb:1 ; CHECK-UNCOMPRESS:[main:1 @ foo]:3:0 ; CHECK-UNCOMPRESS: 2: 1 ; CHECK-UNCOMPRESS: 3: 2 fa:1 -; CHECK-UNCOMPRESS:[main:1 @ foo:3 @ fa:2 @ fb:2 @ fa:2 @ fb:2 @ fa]:1:0 -; CHECK-UNCOMPRESS: 4: 1 +; CHECK-UNCOMPRESS:[main:1 @ foo:3 @ fa:2 @ fb:2 @ fa]:3:0 +; CHECK-UNCOMPRESS: 1: 1 +; CHECK-UNCOMPRESS: 2: 2 fb:1 ; CHECK-UNCOMPRESS:[main:1 @ foo:3 @ fa:2 @ fb:2 @ fa:2 @ fb]:1:0 ; CHECK-UNCOMPRESS: 2: 1 fa:1 +; CHECK-UNCOMPRESS:[main:1 @ foo:3 @ fa:2 @ fb:2 @ fa:2 @ fb:2 @ fa]:1:0 +; CHECK-UNCOMPRESS: 4: 1 + ; CHECK: [main:1 @ foo:3 @ fa]:14:0 ; CHECK: 1: 1 diff --git a/llvm/test/tools/llvm-profgen/recursion-compression-pseudoprobe.test b/llvm/test/tools/llvm-profgen/recursion-compression-pseudoprobe.test --- a/llvm/test/tools/llvm-profgen/recursion-compression-pseudoprobe.test +++ b/llvm/test/tools/llvm-profgen/recursion-compression-pseudoprobe.test @@ -4,11 +4,11 @@ ; RUN: llvm-profgen --perfscript=%S/Inputs/recursion-compression-pseudoprobe.perfscript --binary=%S/Inputs/recursion-compression-pseudoprobe.perfbin --output=%t --show-unwinder-output --csprof-cold-thres=0 | FileCheck %s --check-prefix=CHECK-UNWINDER ; RUN: FileCheck %s --input-file %t -; CHECK-UNCOMPRESS: [main:2 @ foo:5 @ fa:8 @ fa:7 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:6 @ fa:8 @ fa:7 @ fb:6 @ fa]:4:1 +; CHECK-UNCOMPRESS: [main:2 @ foo:5 @ fa:8 @ fa:7 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:6 @ fa]:4:1 ; CHECK-UNCOMPRESS: 1: 1 ; CHECK-UNCOMPRESS: 3: 1 -; CHECK-UNCOMPRESS: 4: 1 -; CHECK-UNCOMPRESS: 7: 1 fb:1 +; CHECK-UNCOMPRESS: 5: 1 +; CHECK-UNCOMPRESS: 8: 1 fa:1 ; CHECK-UNCOMPRESS: !CFGChecksum: 120515930909 ; CHECK-UNCOMPRESS: [main:2 @ foo:5 @ fa:8 @ fa:7 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:6 @ fa:8 @ fa]:4:1 ; CHECK-UNCOMPRESS: 1: 1 @@ -16,28 +16,13 @@ ; CHECK-UNCOMPRESS: 4: 1 ; CHECK-UNCOMPRESS: 7: 1 fb:1 ; CHECK-UNCOMPRESS: !CFGChecksum: 120515930909 -; CHECK-UNCOMPRESS: [main:2 @ foo:5 @ fa:8 @ fa:7 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:6 @ fa]:4:1 +; CHECK-UNCOMPRESS: [main:2 @ foo:5 @ fa:8 @ fa:7 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:6 @ fa:8 @ fa:7 @ fb:6 @ fa]:4:1 ; CHECK-UNCOMPRESS: 1: 1 ; CHECK-UNCOMPRESS: 3: 1 -; CHECK-UNCOMPRESS: 5: 1 -; CHECK-UNCOMPRESS: 8: 1 fa:1 +; CHECK-UNCOMPRESS: 4: 1 +; CHECK-UNCOMPRESS: 7: 1 fb:1 ; CHECK-UNCOMPRESS: !CFGChecksum: 120515930909 -; CHECK-UNCOMPRESS: [main:2 @ foo:5 @ fa:8 @ fa:7 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:6 @ fa:8 @ fa:7 @ fb:6 @ fa:7 @ fb]:3:1 -; CHECK-UNCOMPRESS: 1: 1 -; CHECK-UNCOMPRESS: 3: 1 -; CHECK-UNCOMPRESS: 6: 1 fa:1 -; CHECK-UNCOMPRESS: !CFGChecksum: 72617220756 -; CHECK-UNCOMPRESS: [main:2 @ foo:5 @ fa:8 @ fa:7 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:6 @ fa:8 @ fa:7 @ fb]:3:1 -; CHECK-UNCOMPRESS: 1: 1 -; CHECK-UNCOMPRESS: 3: 1 -; CHECK-UNCOMPRESS: 6: 1 fa:1 -; CHECK-UNCOMPRESS: !CFGChecksum: 72617220756 -; CHECK-UNCOMPRESS: [main:2 @ foo:5 @ fa:8 @ fa:7 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb]:3:1 -; CHECK-UNCOMPRESS: 1: 1 -; CHECK-UNCOMPRESS: 3: 1 -; CHECK-UNCOMPRESS: 6: 1 fa:1 -; CHECK-UNCOMPRESS: !CFGChecksum: 72617220756 -; CHECK-UNCOMPRESS: [main:2 @ foo:5 @ fa:8 @ fa:7 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb]:3:1 +; CHECK-UNCOMPRESS: [main:2 @ foo:5 @ fa:8 @ fa:7 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb]:3:1 ; CHECK-UNCOMPRESS: 1: 1 ; CHECK-UNCOMPRESS: 2: 1 ; CHECK-UNCOMPRESS: 5: 1 fb:1 @@ -47,11 +32,26 @@ ; CHECK-UNCOMPRESS: 2: 1 ; CHECK-UNCOMPRESS: 5: 1 fb:1 ; CHECK-UNCOMPRESS: !CFGChecksum: 72617220756 -; CHECK-UNCOMPRESS: [main:2 @ foo:5 @ fa:8 @ fa:7 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb]:3:1 +; CHECK-UNCOMPRESS: [main:2 @ foo:5 @ fa:8 @ fa:7 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb]:3:1 ; CHECK-UNCOMPRESS: 1: 1 ; CHECK-UNCOMPRESS: 2: 1 ; CHECK-UNCOMPRESS: 5: 1 fb:1 ; CHECK-UNCOMPRESS: !CFGChecksum: 72617220756 +; CHECK-UNCOMPRESS: [main:2 @ foo:5 @ fa:8 @ fa:7 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb]:3:1 +; CHECK-UNCOMPRESS: 1: 1 +; CHECK-UNCOMPRESS: 3: 1 +; CHECK-UNCOMPRESS: 6: 1 fa:1 +; CHECK-UNCOMPRESS: !CFGChecksum: 72617220756 +; CHECK-UNCOMPRESS: [main:2 @ foo:5 @ fa:8 @ fa:7 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:6 @ fa:8 @ fa:7 @ fb]:3:1 +; CHECK-UNCOMPRESS: 1: 1 +; CHECK-UNCOMPRESS: 3: 1 +; CHECK-UNCOMPRESS: 6: 1 fa:1 +; CHECK-UNCOMPRESS: !CFGChecksum: 72617220756 +; CHECK-UNCOMPRESS: [main:2 @ foo:5 @ fa:8 @ fa:7 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:6 @ fa:8 @ fa:7 @ fb:6 @ fa:7 @ fb]:3:1 +; CHECK-UNCOMPRESS: 1: 1 +; CHECK-UNCOMPRESS: 3: 1 +; CHECK-UNCOMPRESS: 6: 1 fa:1 +; CHECK-UNCOMPRESS: !CFGChecksum: 72617220756 ; CHECK-UNCOMPRESS: [main:2 @ foo:5 @ fa:8 @ fa:7 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:6 @ fa:8 @ fa:7 @ fb:6 @ fa:7 @ fb:6 @ fa]:2:1 ; CHECK-UNCOMPRESS: 1: 1 ; CHECK-UNCOMPRESS: 3: 1 @@ -74,30 +74,31 @@ ; CHECK: 4: 1 ; CHECK: 7: 1 fb:1 ; CHECK: !CFGChecksum: 120515930909 -; CHECK: [main:2 @ foo:5 @ fa:8 @ fa:7 @ fb:5 @ fb:6 @ fa:8 @ fa]:4:1 -; CHECK: 1: 1 -; CHECK: 3: 1 -; CHECK: 4: 1 -; CHECK: 7: 1 fb:1 -; CHECK: !CFGChecksum: 120515930909 ; CHECK: [main:2 @ foo:5 @ fa:8 @ fa:7 @ fb:5 @ fb:6 @ fa]:4:1 ; CHECK: 1: 1 ; CHECK: 3: 1 ; CHECK: 5: 1 ; CHECK: 8: 1 fa:1 ; CHECK: !CFGChecksum: 120515930909 -; CHECK: [main:2 @ foo:5 @ fa:8 @ fa:7 @ fb:5 @ fb:6 @ fa:8 @ fa:7 @ fb:6 @ fa:7 @ fb]:3:1 +; CHECK: [main:2 @ foo:5 @ fa:8 @ fa:7 @ fb:5 @ fb:6 @ fa:8 @ fa]:4:1 +; CHECK: 1: 1 +; CHECK: 3: 1 +; CHECK: 4: 1 +; CHECK: 7: 1 fb:1 +; CHECK: !CFGChecksum: 120515930909 +; CHECK: [main:2 @ foo:5 @ fa:8 @ fa:7 @ fb:5 @ fb:6 @ fa:8 @ fa:7 @ fb]:3:1 ; CHECK: 1: 1 ; CHECK: 3: 1 ; CHECK: 6: 1 fa:1 ; CHECK: !CFGChecksum: 72617220756 -; CHECK: [main:2 @ foo:5 @ fa:8 @ fa:7 @ fb:5 @ fb:6 @ fa:8 @ fa:7 @ fb]:3:1 +; CHECK: [main:2 @ foo:5 @ fa:8 @ fa:7 @ fb:5 @ fb:6 @ fa:8 @ fa:7 @ fb:6 @ fa:7 @ fb]:3:1 ; CHECK: 1: 1 ; CHECK: 3: 1 ; CHECK: 6: 1 fa:1 ; CHECK: !CFGChecksum: 72617220756 + ; CHECK-UNWINDER: Binary(recursion-compression-pseudoprobe.perfbin)'s Range Counter: ; CHECK-UNWINDER: main:2 @ foo:5 @ fa:8 @ fa:7 @ fb:5 ; CHECK-UNWINDER: (7a0, 7a7): 1 diff --git a/llvm/tools/llvm-profgen/ProfileGenerator.cpp b/llvm/tools/llvm-profgen/ProfileGenerator.cpp --- a/llvm/tools/llvm-profgen/ProfileGenerator.cpp +++ b/llvm/tools/llvm-profgen/ProfileGenerator.cpp @@ -268,16 +268,18 @@ CalleeName, Count); // Record head sample for called target(callee) - // TODO: Cleanup ' @ ' - std::string CalleeContextId = - getCallSite(LeafLoc) + " @ " + CalleeName.str(); + std::ostringstream OCalleeCtxStr; if (ContextId.find(" @ ") != StringRef::npos) { - CalleeContextId = - ContextId.rsplit(" @ ").first.str() + " @ " + CalleeContextId; + OCalleeCtxStr << ContextId.rsplit(" @ ").first.str(); + OCalleeCtxStr << " @ "; + } else { + OCalleeCtxStr << "["; } + OCalleeCtxStr << getCallSite(LeafLoc) << " @ " << CalleeName.str(); + OCalleeCtxStr << "]"; FunctionSamples &CalleeProfile = - getFunctionProfileForContext(CalleeContextId); + getFunctionProfileForContext(OCalleeCtxStr.str()); assert(Count != 0 && "Unexpected zero weight branch"); CalleeProfile.addHeadSamples(Count); } @@ -285,6 +287,7 @@ static FrameLocation getCallerContext(StringRef CalleeContext, StringRef &CallerNameWithContext) { + CalleeContext = CalleeContext.substr(1, CalleeContext.size() - 2); StringRef CallerContext = CalleeContext.rsplit(" @ ").first; CallerNameWithContext = CallerContext.rsplit(':').first; auto ContextSplit = CallerContext.rsplit(" @ "); @@ -314,9 +317,10 @@ continue; // Infer Caller's frame loc and context ID through string splitting - StringRef CallerContextId; + StringRef CxtWithoutBracket; FrameLocation &&CallerLeafFrameLoc = - getCallerContext(CalleeContext, CallerContextId); + getCallerContext(CalleeContext, CxtWithoutBracket); + std::string CallerContextId = "[" + CxtWithoutBracket.str() + "]"; // It's possible that we haven't seen any sample directly in the caller, // in which case CallerProfile will not exist. But we can't modify @@ -362,8 +366,8 @@ // Remove the code profile from ProfileMap and merge them into BaseProileMap StringMap BaseProfileMap; for (const auto &I : ToRemoveVec) { - auto Ret = - BaseProfileMap.try_emplace(I.second->getName(), FunctionSamples()); + auto Ret = BaseProfileMap.try_emplace("[" + I.second->getName().str() + "]", + FunctionSamples()); FunctionSamples &BaseProfile = Ret.first->second; BaseProfile.merge(*I.second); ProfileMap.erase(I.first); @@ -483,10 +487,11 @@ // context id to infer caller's context id to ensure they share the // same context prefix. StringRef CalleeContextId = - FunctionProfile.getContext().getNameWithContext(); - StringRef CallerContextId; + FunctionProfile.getContext().getNameWithContext(true); + StringRef CxtWithoutBracket; FrameLocation &&CallerLeafFrameLoc = - getCallerContext(CalleeContextId, CallerContextId); + getCallerContext(CalleeContextId, CxtWithoutBracket); + std::string CallerContextId = "[" + CxtWithoutBracket.str() + "]"; uint64_t CallerIndex = CallerLeafFrameLoc.second.LineOffset; FunctionSamples &CallerProfile = getFunctionProfileForContext(CallerContextId); @@ -534,18 +539,19 @@ CSProfileGenerator::compressRecursionContext(ContextStrStack); std::ostringstream OContextStr; + OContextStr << "["; for (uint32_t I = 0; I < ContextStrStack.size(); I++) { - if (OContextStr.str().size()) + if (OContextStr.str().size() > 1) OContextStr << " @ "; OContextStr << ContextStrStack[I]; } // For leaf inlined context with the top frame, we should strip off the top // frame's probe id, like: // Inlined stack: [foo:1, bar:2], the ContextId will be "foo:1 @ bar" - if (OContextStr.str().size()) + if (OContextStr.str().size() > 1) OContextStr << " @ "; OContextStr << StringRef(LeafFrame).split(":").first.str(); - + OContextStr << "]"; FunctionSamples &FunctionProile = getFunctionProfileForContext(OContextStr.str()); FunctionProile.setFunctionHash(LeafFuncDesc->FuncHash); diff --git a/llvm/tools/llvm-profgen/ProfiledBinary.cpp b/llvm/tools/llvm-profgen/ProfiledBinary.cpp --- a/llvm/tools/llvm-profgen/ProfiledBinary.cpp +++ b/llvm/tools/llvm-profgen/ProfiledBinary.cpp @@ -146,16 +146,18 @@ CSProfileGenerator::compressRecursionContext(ContextVec); std::ostringstream OContextStr; + OContextStr << "["; for (uint32_t I = 0; I < (uint32_t)ContextVec.size(); I++) { - if (OContextStr.str().size()) { + if (OContextStr.str().size() > 1) { OContextStr << " @ "; } OContextStr << ContextVec[I]; } // Only keep the function name for the leaf frame - if (OContextStr.str().size()) + if (OContextStr.str().size() > 1) OContextStr << " @ "; OContextStr << StringRef(LeafFrame).split(":").first.str(); + OContextStr << "]"; return OContextStr.str(); }