diff --git a/bolt/include/bolt/Core/BinaryFunction.h b/bolt/include/bolt/Core/BinaryFunction.h --- a/bolt/include/bolt/Core/BinaryFunction.h +++ b/bolt/include/bolt/Core/BinaryFunction.h @@ -1757,6 +1757,16 @@ return ParentFragments.contains(&Other); } + /// Returns if this function is a parent of \p Other function. + bool isParentOf(const BinaryFunction &Other) const { + return llvm::is_contained(Fragments, &Other); + } + + /// Returns if this function is a parent or child of \p Other function. + bool isParentOrChildOf(const BinaryFunction &Other) const { + return isChildOf(Other) || isParentOf(Other); + } + /// Set the profile data for the number of times the function was called. BinaryFunction &setExecutionCount(uint64_t Count) { ExecutionCount = Count; diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp --- a/bolt/lib/Core/BinaryContext.cpp +++ b/bolt/lib/Core/BinaryContext.cpp @@ -506,17 +506,6 @@ EntriesAsAddress->emplace_back(EntryAddress); }; - auto doesBelongToFunction = [&](const uint64_t Addr, - const BinaryFunction *TargetBF) -> bool { - if (BF.containsAddress(Addr)) - return true; - // Nothing to do if we failed to identify the containing function. - if (!TargetBF) - return false; - // Check if BF is a fragment of TargetBF or vice versa. - return BF.isChildOf(*TargetBF) || TargetBF->isChildOf(BF); - }; - ErrorOr Section = getSectionForAddress(Address); if (!Section) return false; @@ -576,8 +565,11 @@ // Function or one of its fragments. const BinaryFunction *TargetBF = getBinaryFunctionContainingAddress(Value); + bool DoesBelongToFunction = BF.containsAddress(Value) || + (TargetBF && TargetBF->isParentOrChildOf(BF)); + // We assume that a jump table cannot have function start as an entry. - if (!doesBelongToFunction(Value, TargetBF) || Value == BF.getAddress()) { + if (!DoesBelongToFunction || Value == BF.getAddress()) { LLVM_DEBUG({ if (!BF.containsAddress(Value)) { dbgs() << "FAIL: function doesn't contain this address\n"; @@ -766,8 +758,7 @@ // Prevent associating a jump table to a specific fragment twice. // This simple check arises from the assumption: no more than 2 fragments. if (JT->Parents.size() == 1 && JT->Parents[0] != &Function) { - assert((JT->Parents[0]->isChildOf(Function) || - Function.isChildOf(*JT->Parents[0])) && + assert(JT->Parents[0]->isParentOrChildOf(Function) && "cannot re-use jump table of a different function"); // Duplicate the entry for the parent function for easy access JT->Parents.push_back(&Function); diff --git a/bolt/lib/Core/Exceptions.cpp b/bolt/lib/Core/Exceptions.cpp --- a/bolt/lib/Core/Exceptions.cpp +++ b/bolt/lib/Core/Exceptions.cpp @@ -188,9 +188,8 @@ "BOLT-ERROR: cannot find landing pad fragment"); BC.addInterproceduralReference(this, Fragment->getAddress()); BC.processInterproceduralReferences(); - assert((isChildOf(*Fragment) || Fragment->isChildOf(*this)) && - "BOLT-ERROR: cannot have landing pads in different " - "functions"); + assert(isParentOrChildOf(*Fragment) && + "BOLT-ERROR: cannot have landing pads in different functions"); setHasIndirectTargetToSplitFragment(true); BC.addFragmentsToSkip(this); return;