[llvm] [EarlyIfConversion] Extend data dependent analysis across multiple blocks (PR #180623)
Jonathan Cohen via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 4 12:53:50 PDT 2026
================
@@ -923,15 +932,62 @@ static bool isConstantPoolLoad(const MachineInstr *MI) {
});
}
-/// Check if there are any calls in the range (From, To].
-static bool callInRange(const MachineInstr *From, const MachineInstr *To) {
- constexpr int MaxInstructionsToCheck = 64;
- int Count = 0;
- auto InstrRange =
- make_range(std::next(From->getIterator()), To->getIterator());
- return any_of(InstrRange, [&](const MachineInstr &MI) {
- return ++Count > MaxInstructionsToCheck || MI.isCall();
- });
+/// Check if there are any calls in the path from From to To, potentially
+/// spanning multiple basic blocks. The IntermediateBlocks set contains
+/// blocks that are between From's block and To's block in the control flow.
+///
+/// Checks:
+/// - If same block: (From, To)
+/// - If different blocks:
+/// - (From, end of From's block]
+/// - All instructions in IntermediateBlocks
+/// - [start of To's block, To)
+///
+/// Returns true if a call is found or if the path exceeds MaxInstructions.
+/// Uses NoCallBlocksCache to skip blocks already verified to have no calls.
+bool EarlyIfConverter::callInPath(
+ const MachineInstr *From, const MachineInstr *To,
+ const SmallPtrSetImpl<const MachineBasicBlock *> &IntermediateBlocks,
+ unsigned MaxInstructions /* = 64 */) {
+ if (From == To)
+ return false;
+
+ unsigned Count = 0;
+ const MachineBasicBlock *FromBB = From->getParent();
+ const MachineBasicBlock *ToBB = To->getParent();
+
+ // Helper to check if instruction limit exceeded or call found.
+ auto CheckInstrIsCall = [&](const MachineInstr &MI) {
+ return ++Count > MaxInstructions || MI.isCall();
+ };
+
+ // If From and To are in the same block, just check (From, To).
+ if (FromBB == ToBB)
+ return llvm::any_of(
+ llvm::make_range(std::next(From->getIterator()), To->getIterator()),
+ CheckInstrIsCall);
+
+ // Check (From, end of From's block].
+ if (any_of(
+ llvm::make_range(std::next(From->getIterator()), FromBB->instr_end()),
+ CheckInstrIsCall))
+ return true;
+
+ // Check all intermediate blocks entirely.
+ // Use cache to skip blocks already verified to have no calls.
+ for (const MachineBasicBlock *BB : IntermediateBlocks) {
+ if (BB == FromBB || BB == ToBB)
+ continue;
+ if (NoCallBlocksCache.contains(BB))
+ continue;
+ if (any_of(*BB, CheckInstrIsCall))
+ return true;
+ NoCallBlocksCache.insert(BB);
----------------
jcohen-apple wrote:
Fixed, thanks
https://github.com/llvm/llvm-project/pull/180623
More information about the llvm-commits
mailing list