Skip to content

Commit 5f48b92

Browse files
committed
repurpose for the fix of call cont discontinuity
Created using spr 1.3.4
1 parent e713939 commit 5f48b92

File tree

3 files changed

+46
-70
lines changed

3 files changed

+46
-70
lines changed

bolt/include/bolt/Profile/DataAggregator.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,8 @@ class DataAggregator : public DataReader {
202202
/// Return a vector of offsets corresponding to a trace in a function
203203
/// if the trace is valid, std::nullopt otherwise.
204204
std::optional<SmallVector<std::pair<uint64_t, uint64_t>, 16>>
205-
getFallthroughsInTrace(BinaryFunction &BF, const LBREntry &First,
206-
const LBREntry &Second, uint64_t Count = 1) const;
205+
getFallthroughsInTrace(BinaryFunction &BF, uint64_t From, uint64_t To,
206+
uint64_t Count = 1) const;
207207

208208
/// Record external entry into the function \p BF.
209209
///
@@ -268,9 +268,8 @@ class DataAggregator : public DataReader {
268268
/// Register a \p Branch.
269269
bool doBranch(uint64_t From, uint64_t To, uint64_t Count, uint64_t Mispreds);
270270

271-
/// Register a trace between two LBR entries supplied in execution order.
272-
bool doTrace(const LBREntry &First, const LBREntry &Second,
273-
uint64_t Count = 1);
271+
/// Register a trace between two addresses.
272+
bool doTrace(const uint64_t From, const uint64_t To, uint64_t Count = 1);
274273

275274
/// Parser helpers
276275
/// Return false if we exhausted our parser buffer and finished parsing

bolt/lib/Profile/DataAggregator.cpp

Lines changed: 41 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -804,9 +804,10 @@ bool DataAggregator::doBranch(uint64_t From, uint64_t To, uint64_t Count,
804804
};
805805

806806
BinaryFunction *FromFunc = handleAddress(From, /*IsFrom=*/true);
807-
// Ignore returns.
807+
// Record returns as call->call continuation fall-through.
808808
if (IsReturn)
809-
return true;
809+
return doTrace(To - 1, To, Count);
810+
810811
BinaryFunction *ToFunc = handleAddress(To, /*IsFrom=*/false);
811812
if (!FromFunc && !ToFunc)
812813
return false;
@@ -820,16 +821,24 @@ bool DataAggregator::doBranch(uint64_t From, uint64_t To, uint64_t Count,
820821
return doInterBranch(FromFunc, ToFunc, From, To, Count, Mispreds);
821822
}
822823

823-
bool DataAggregator::doTrace(const LBREntry &First, const LBREntry &Second,
824+
bool DataAggregator::doTrace(const uint64_t From, const uint64_t To,
824825
uint64_t Count) {
825-
BinaryFunction *FromFunc = getBinaryFunctionContainingAddress(First.To);
826-
BinaryFunction *ToFunc = getBinaryFunctionContainingAddress(Second.From);
826+
BinaryFunction *FromFunc = getBinaryFunctionContainingAddress(From);
827+
BinaryFunction *ToFunc = getBinaryFunctionContainingAddress(To);
827828
if (!FromFunc || !ToFunc) {
828829
LLVM_DEBUG({
829-
dbgs() << "Out of range trace starting in " << FromFunc->getPrintName()
830-
<< formatv(" @ {0:x}", First.To - FromFunc->getAddress())
831-
<< " and ending in " << ToFunc->getPrintName()
832-
<< formatv(" @ {0:x}\n", Second.From - ToFunc->getAddress());
830+
dbgs() << "Out of range trace starting in ";
831+
if (FromFunc)
832+
dbgs() << formatv("{0} @ {1:x}", *FromFunc,
833+
From - FromFunc->getAddress());
834+
else
835+
dbgs() << Twine::utohexstr(From);
836+
dbgs() << " and ending in ";
837+
if (ToFunc)
838+
dbgs() << formatv("{0} @ {1:x}", *ToFunc, To - ToFunc->getAddress());
839+
else
840+
dbgs() << Twine::utohexstr(To);
841+
dbgs() << '\n';
833842
});
834843
NumLongRangeTraces += Count;
835844
return false;
@@ -838,32 +847,30 @@ bool DataAggregator::doTrace(const LBREntry &First, const LBREntry &Second,
838847
NumInvalidTraces += Count;
839848
LLVM_DEBUG({
840849
dbgs() << "Invalid trace starting in " << FromFunc->getPrintName()
841-
<< formatv(" @ {0:x}", First.To - FromFunc->getAddress())
850+
<< formatv(" @ {0:x}", From - FromFunc->getAddress())
842851
<< " and ending in " << ToFunc->getPrintName()
843-
<< formatv(" @ {0:x}\n", Second.From - ToFunc->getAddress());
852+
<< formatv(" @ {0:x}\n", To - ToFunc->getAddress());
844853
});
845854
return false;
846855
}
847856

848857
std::optional<BoltAddressTranslation::FallthroughListTy> FTs =
849-
BAT ? BAT->getFallthroughsInTrace(FromFunc->getAddress(), First.To,
850-
Second.From)
851-
: getFallthroughsInTrace(*FromFunc, First, Second, Count);
858+
BAT ? BAT->getFallthroughsInTrace(FromFunc->getAddress(), From, To)
859+
: getFallthroughsInTrace(*FromFunc, From, To, Count);
852860
if (!FTs) {
853861
LLVM_DEBUG(
854862
dbgs() << "Invalid trace starting in " << FromFunc->getPrintName()
855-
<< " @ " << Twine::utohexstr(First.To - FromFunc->getAddress())
863+
<< " @ " << Twine::utohexstr(From - FromFunc->getAddress())
856864
<< " and ending in " << ToFunc->getPrintName() << " @ "
857865
<< ToFunc->getPrintName() << " @ "
858-
<< Twine::utohexstr(Second.From - ToFunc->getAddress()) << '\n');
866+
<< Twine::utohexstr(To - ToFunc->getAddress()) << '\n');
859867
NumInvalidTraces += Count;
860868
return false;
861869
}
862870

863871
LLVM_DEBUG(dbgs() << "Processing " << FTs->size() << " fallthroughs for "
864-
<< FromFunc->getPrintName() << ":"
865-
<< Twine::utohexstr(First.To) << " to "
866-
<< Twine::utohexstr(Second.From) << ".\n");
872+
<< FromFunc->getPrintName() << ":" << Twine::utohexstr(From)
873+
<< " to " << Twine::utohexstr(To) << ".\n");
867874
BinaryFunction *ParentFunc = getBATParentFunction(*FromFunc);
868875
for (auto [From, To] : *FTs) {
869876
if (BAT) {
@@ -877,10 +884,8 @@ bool DataAggregator::doTrace(const LBREntry &First, const LBREntry &Second,
877884
}
878885

879886
std::optional<SmallVector<std::pair<uint64_t, uint64_t>, 16>>
880-
DataAggregator::getFallthroughsInTrace(BinaryFunction &BF,
881-
const LBREntry &FirstLBR,
882-
const LBREntry &SecondLBR,
883-
uint64_t Count) const {
887+
DataAggregator::getFallthroughsInTrace(BinaryFunction &BF, uint64_t From,
888+
uint64_t To, uint64_t Count) const {
884889
SmallVector<std::pair<uint64_t, uint64_t>, 16> Branches;
885890

886891
BinaryContext &BC = BF.getBinaryContext();
@@ -891,8 +896,8 @@ DataAggregator::getFallthroughsInTrace(BinaryFunction &BF,
891896
assert(BF.hasCFG() && "can only record traces in CFG state");
892897

893898
// Offsets of the trace within this function.
894-
const uint64_t From = FirstLBR.To - BF.getAddress();
895-
const uint64_t To = SecondLBR.From - BF.getAddress();
899+
From = From - BF.getAddress();
900+
To = To - BF.getAddress();
896901

897902
if (From > To)
898903
return std::nullopt;
@@ -903,24 +908,6 @@ DataAggregator::getFallthroughsInTrace(BinaryFunction &BF,
903908
if (!FromBB || !ToBB)
904909
return std::nullopt;
905910

906-
// Adjust FromBB if the first LBR is a return from the last instruction in
907-
// the previous block (that instruction should be a call).
908-
if (From == FromBB->getOffset() && !BF.containsAddress(FirstLBR.From) &&
909-
!FromBB->isEntryPoint() && !FromBB->isLandingPad()) {
910-
const BinaryBasicBlock *PrevBB =
911-
BF.getLayout().getBlock(FromBB->getIndex() - 1);
912-
if (PrevBB->getSuccessor(FromBB->getLabel())) {
913-
const MCInst *Instr = PrevBB->getLastNonPseudoInstr();
914-
if (Instr && BC.MIB->isCall(*Instr))
915-
FromBB = PrevBB;
916-
else
917-
LLVM_DEBUG(dbgs() << "invalid incoming LBR (no call): " << FirstLBR
918-
<< '\n');
919-
} else {
920-
LLVM_DEBUG(dbgs() << "invalid incoming LBR: " << FirstLBR << '\n');
921-
}
922-
}
923-
924911
// Fill out information for fall-through edges. The From and To could be
925912
// within the same basic block, e.g. when two call instructions are in the
926913
// same block. In this case we skip the processing.
@@ -937,8 +924,8 @@ DataAggregator::getFallthroughsInTrace(BinaryFunction &BF,
937924
// Check for bad LBRs.
938925
if (!BB->getSuccessor(NextBB->getLabel())) {
939926
LLVM_DEBUG(dbgs() << "no fall-through for the trace:\n"
940-
<< " " << FirstLBR << '\n'
941-
<< " " << SecondLBR << '\n');
927+
<< " " << From << '\n'
928+
<< " " << To << '\n');
942929
return std::nullopt;
943930
}
944931

@@ -1595,16 +1582,11 @@ void DataAggregator::processBranchEvents() {
15951582
NamedRegionTimer T("processBranch", "Processing branch events",
15961583
TimerGroupName, TimerGroupDesc, opts::TimeAggregator);
15971584

1598-
for (const auto &AggrLBR : FallthroughLBRs) {
1599-
const Trace &Loc = AggrLBR.first;
1600-
const FTInfo &Info = AggrLBR.second;
1601-
LBREntry First{Loc.From, Loc.From, false};
1602-
LBREntry Second{Loc.To, Loc.To, false};
1585+
for (const auto &[Loc, Info]: FallthroughLBRs) {
16031586
if (Info.InternCount)
1604-
doTrace(First, Second, Info.InternCount);
1587+
doTrace(Loc.From, Loc.To, Info.InternCount);
16051588
if (Info.ExternCount) {
1606-
First.From = 0;
1607-
doTrace(First, Second, Info.ExternCount);
1589+
doTrace(0, Loc.To, Info.ExternCount);
16081590
}
16091591
}
16101592

@@ -1768,21 +1750,16 @@ void DataAggregator::processPreAggregated() {
17681750
TimerGroupName, TimerGroupDesc, opts::TimeAggregator);
17691751

17701752
uint64_t NumTraces = 0;
1771-
for (const AggregatedLBREntry &AggrEntry : AggregatedLBRs) {
1772-
switch (AggrEntry.EntryType) {
1753+
for (const auto &[From, To, Count, Mispreds, Type]: AggregatedLBRs) {
1754+
bool IsExternalOrigin = Type == AggregatedLBREntry::FT_EXTERNAL_ORIGIN;
1755+
switch (Type) {
17731756
case AggregatedLBREntry::BRANCH:
1774-
doBranch(AggrEntry.From.Offset, AggrEntry.To.Offset, AggrEntry.Count,
1775-
AggrEntry.Mispreds);
1757+
doBranch(From.Offset, To.Offset, Count, Mispreds);
17761758
break;
17771759
case AggregatedLBREntry::FT:
17781760
case AggregatedLBREntry::FT_EXTERNAL_ORIGIN: {
1779-
LBREntry First{AggrEntry.EntryType == AggregatedLBREntry::FT
1780-
? AggrEntry.From.Offset
1781-
: 0,
1782-
AggrEntry.From.Offset, false};
1783-
LBREntry Second{AggrEntry.To.Offset, AggrEntry.To.Offset, false};
1784-
doTrace(First, Second, AggrEntry.Count);
1785-
NumTraces += AggrEntry.Count;
1761+
doTrace(IsExternalOrigin ? 0 : From.Offset, To.Offset, Count);
1762+
NumTraces += Count;
17861763
break;
17871764
}
17881765
}

bolt/test/X86/callcont-fallthru.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@
66
# RUN: --print-cfg --print-only=main | FileCheck %s
77

88
# CHECK: callq foo
9-
# CHECK-NEXT: count: 0
9+
# CHECK-NEXT: count: 103204

0 commit comments

Comments
 (0)