@@ -730,50 +730,54 @@ bool DataAggregator::doInterBranch(BinaryFunction *FromFunc,
730
730
return true ;
731
731
}
732
732
733
+ bool DataAggregator::checkReturn (uint64_t Addr) {
734
+ auto isReturn = [&](auto MI) { return MI && BC->MIB ->isReturn (*MI); };
735
+ if (llvm::is_contained (Returns, Addr))
736
+ return true ;
737
+
738
+ BinaryFunction *Func = getBinaryFunctionContainingAddress (Addr);
739
+ if (!Func)
740
+ return false ;
741
+
742
+ const uint64_t Offset = Addr - Func->getAddress ();
743
+ if (Func->hasInstructions ()
744
+ ? isReturn (Func->getInstructionAtOffset (Offset))
745
+ : isReturn (Func->disassembleInstructionAtOffset (Offset))) {
746
+ Returns.emplace (Addr);
747
+ return true ;
748
+ }
749
+ return false ;
750
+ }
751
+
733
752
bool DataAggregator::doBranch (uint64_t From, uint64_t To, uint64_t Count,
734
753
uint64_t Mispreds) {
735
- // Returns whether \p Offset in \p Func contains a return instruction.
736
- auto checkReturn = [&](const BinaryFunction &Func, const uint64_t Offset) {
737
- auto isReturn = [&](auto MI) { return MI && BC->MIB ->isReturn (*MI); };
738
- return Func.hasInstructions ()
739
- ? isReturn (Func.getInstructionAtOffset (Offset))
740
- : isReturn (Func.disassembleInstructionAtOffset (Offset));
741
- };
742
-
743
754
// Mutates \p Addr to an offset into the containing function, performing BAT
744
755
// offset translation and parent lookup.
745
756
//
746
- // Returns the containing function (or BAT parent) and whether the address
747
- // corresponds to a return (if \p IsFrom) or a call continuation (otherwise).
757
+ // Returns the containing function (or BAT parent).
748
758
auto handleAddress = [&](uint64_t &Addr, bool IsFrom) {
749
759
BinaryFunction *Func = getBinaryFunctionContainingAddress (Addr);
750
760
if (!Func) {
751
761
Addr = 0 ;
752
- return std::pair{ Func, false } ;
762
+ return Func;
753
763
}
754
764
755
765
Addr -= Func->getAddress ();
756
766
757
- bool IsRet = IsFrom && checkReturn (*Func, Addr);
758
-
759
767
if (BAT)
760
768
Addr = BAT->translate (Func->getAddress (), Addr, IsFrom);
761
769
762
770
if (BinaryFunction *ParentFunc = getBATParentFunction (*Func))
763
- Func = ParentFunc;
771
+ return ParentFunc;
764
772
765
- return std::pair{ Func, IsRet} ;
773
+ return Func;
766
774
};
767
775
768
- auto [ FromFunc, IsReturn] = handleAddress (From, /* IsFrom*/ true );
769
- auto [ ToFunc, _] = handleAddress (To, /* IsFrom*/ false );
776
+ BinaryFunction * FromFunc = handleAddress (From, /* IsFrom*/ true );
777
+ BinaryFunction * ToFunc = handleAddress (To, /* IsFrom*/ false );
770
778
if (!FromFunc && !ToFunc)
771
779
return false ;
772
780
773
- // Ignore returns.
774
- if (IsReturn)
775
- return true ;
776
-
777
781
// Treat recursive control transfers as inter-branches.
778
782
if (FromFunc == ToFunc && To != 0 ) {
779
783
recordBranch (*FromFunc, From, To, Count, Mispreds);
@@ -783,7 +787,8 @@ bool DataAggregator::doBranch(uint64_t From, uint64_t To, uint64_t Count,
783
787
return doInterBranch (FromFunc, ToFunc, From, To, Count, Mispreds);
784
788
}
785
789
786
- bool DataAggregator::doTrace (const Trace &Trace, uint64_t Count) {
790
+ bool DataAggregator::doTrace (const Trace &Trace, uint64_t Count,
791
+ bool IsReturn) {
787
792
const uint64_t From = Trace.From , To = Trace.To ;
788
793
BinaryFunction *FromFunc = getBinaryFunctionContainingAddress (From);
789
794
BinaryFunction *ToFunc = getBinaryFunctionContainingAddress (To);
@@ -808,8 +813,8 @@ bool DataAggregator::doTrace(const Trace &Trace, uint64_t Count) {
808
813
const uint64_t FuncAddress = FromFunc->getAddress ();
809
814
std::optional<BoltAddressTranslation::FallthroughListTy> FTs =
810
815
BAT && BAT->isBATFunction (FuncAddress)
811
- ? BAT->getFallthroughsInTrace (FuncAddress, From, To)
812
- : getFallthroughsInTrace (*FromFunc, Trace, Count);
816
+ ? BAT->getFallthroughsInTrace (FuncAddress, From - IsReturn , To)
817
+ : getFallthroughsInTrace (*FromFunc, Trace, Count, IsReturn );
813
818
if (!FTs) {
814
819
LLVM_DEBUG (dbgs () << " Invalid trace " << Trace << ' \n ' );
815
820
NumInvalidTraces += Count;
@@ -831,7 +836,7 @@ bool DataAggregator::doTrace(const Trace &Trace, uint64_t Count) {
831
836
832
837
std::optional<SmallVector<std::pair<uint64_t , uint64_t >, 16 >>
833
838
DataAggregator::getFallthroughsInTrace (BinaryFunction &BF, const Trace &Trace,
834
- uint64_t Count) const {
839
+ uint64_t Count, bool IsReturn ) const {
835
840
SmallVector<std::pair<uint64_t , uint64_t >, 16 > Branches;
836
841
837
842
BinaryContext &BC = BF.getBinaryContext ();
@@ -865,9 +870,13 @@ DataAggregator::getFallthroughsInTrace(BinaryFunction &BF, const Trace &Trace,
865
870
866
871
// Adjust FromBB if the first LBR is a return from the last instruction in
867
872
// the previous block (that instruction should be a call).
868
- if (Trace.Branch != Trace::FT_ONLY && !BF.containsAddress (Trace.Branch ) &&
869
- From == FromBB->getOffset () && !FromBB->isEntryPoint () &&
870
- !FromBB->isLandingPad ()) {
873
+ if (IsReturn) {
874
+ if (From)
875
+ FromBB = BF.getBasicBlockContainingOffset (From - 1 );
876
+ else
877
+ LLVM_DEBUG (dbgs () << " return to the function start: " << Trace << ' \n ' );
878
+ } else if (Trace.Branch == Trace::EXTERNAL && From == FromBB->getOffset () &&
879
+ !FromBB->isEntryPoint () && !FromBB->isLandingPad ()) {
871
880
const BinaryBasicBlock *PrevBB =
872
881
BF.getLayout ().getBlock (FromBB->getIndex () - 1 );
873
882
if (PrevBB->getSuccessor (FromBB->getLabel ())) {
@@ -1557,11 +1566,13 @@ void DataAggregator::processBranchEvents() {
1557
1566
TimerGroupName, TimerGroupDesc, opts::TimeAggregator);
1558
1567
1559
1568
for (const auto &[Trace, Info] : Traces) {
1560
- if (Trace.Branch != Trace::FT_ONLY &&
1569
+ bool IsReturn = checkReturn (Trace.Branch );
1570
+ // Ignore returns.
1571
+ if (!IsReturn && Trace.Branch != Trace::FT_ONLY &&
1561
1572
Trace.Branch != Trace::FT_EXTERNAL_ORIGIN)
1562
1573
doBranch (Trace.Branch , Trace.From , Info.TakenCount , Info.MispredCount );
1563
1574
if (Trace.To != Trace::BR_ONLY)
1564
- doTrace (Trace, Info.TakenCount );
1575
+ doTrace (Trace, Info.TakenCount , IsReturn );
1565
1576
}
1566
1577
printBranchSamplesDiagnostics ();
1567
1578
}
0 commit comments