@@ -646,7 +646,7 @@ bool BinaryContext::analyzeJumpTable(const uint64_t Address,
646646 const BinaryFunction *TargetBF = getBinaryFunctionContainingAddress (Value);
647647 const bool DoesBelongToFunction =
648648 BF.containsAddress (Value) ||
649- (TargetBF && TargetBF-> isParentOrChildOf ( BF));
649+ (TargetBF && areRelatedFragments (TargetBF, & BF));
650650 if (!DoesBelongToFunction) {
651651 LLVM_DEBUG ({
652652 if (!BF.containsAddress (Value)) {
@@ -839,9 +839,11 @@ BinaryContext::getOrCreateJumpTable(BinaryFunction &Function, uint64_t Address,
839839 assert (Address == JT->getAddress () && " unexpected non-empty jump table" );
840840
841841 // Prevent associating a jump table to a specific fragment twice.
842- // This simple check arises from the assumption: no more than 2 fragments.
843- if (JT->Parents .size () == 1 && JT->Parents [0 ] != &Function) {
844- assert (JT->Parents [0 ]->isParentOrChildOf (Function) &&
842+ if (!llvm::is_contained (JT->Parents , &Function)) {
843+ assert (llvm::all_of (JT->Parents ,
844+ [&](const BinaryFunction *BF) {
845+ return areRelatedFragments (&Function, BF);
846+ }) &&
845847 " cannot re-use jump table of a different function" );
846848 // Duplicate the entry for the parent function for easy access
847849 JT->Parents .push_back (&Function);
@@ -852,8 +854,8 @@ BinaryContext::getOrCreateJumpTable(BinaryFunction &Function, uint64_t Address,
852854 JT->print (this ->outs ());
853855 }
854856 Function.JumpTables .emplace (Address, JT);
855- JT->Parents [ 0 ]-> setHasIndirectTargetToSplitFragment ( true );
856- JT-> Parents [ 1 ] ->setHasIndirectTargetToSplitFragment (true );
857+ for (BinaryFunction *Parent : JT->Parents )
858+ Parent ->setHasIndirectTargetToSplitFragment (true );
857859 }
858860
859861 bool IsJumpTableParent = false ;
@@ -1209,12 +1211,13 @@ void BinaryContext::generateSymbolHashes() {
12091211}
12101212
12111213bool BinaryContext::registerFragment (BinaryFunction &TargetFunction,
1212- BinaryFunction &Function) const {
1214+ BinaryFunction &Function) {
12131215 assert (TargetFunction.isFragment () && " TargetFunction must be a fragment" );
12141216 if (TargetFunction.isChildOf (Function))
12151217 return true ;
12161218 TargetFunction.addParentFragment (Function);
12171219 Function.addFragment (TargetFunction);
1220+ FragmentClasses.unionSets (&TargetFunction, &Function);
12181221 if (!HasRelocations) {
12191222 TargetFunction.setSimple (false );
12201223 Function.setSimple (false );
@@ -1336,7 +1339,7 @@ void BinaryContext::processInterproceduralReferences() {
13361339
13371340 if (TargetFunction) {
13381341 if (TargetFunction->isFragment () &&
1339- !TargetFunction-> isChildOf ( Function)) {
1342+ !areRelatedFragments (TargetFunction, & Function)) {
13401343 this ->errs ()
13411344 << " BOLT-WARNING: interprocedural reference between unrelated "
13421345 " fragments: "
0 commit comments