Skip to content

Commit e777d37

Browse files
committed
[CodeGen] Limit mem operands checks count for reasonable compilation speed.
1 parent aec8883 commit e777d37

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

llvm/include/llvm/CodeGen/TargetInstrInfo.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2057,6 +2057,21 @@ class LLVM_ABI TargetInstrInfo : public MCInstrInfo {
20572057
/// overhead or too rigid restriction.
20582058
virtual unsigned getMemOperandAACheckLimit() const { return 16; }
20592059

2060+
/// Return the maximum number of memory operands to check instruction for
2061+
/// memory-related properties.
2062+
///
2063+
/// After MIR transformations like tail merging etc. memory operands are
2064+
/// united for the merged result instructions. Compiler might ends up with
2065+
/// thousands of memory operands for each instruction for tricky CFGs like
2066+
/// for switch construction.
2067+
///
2068+
/// Even linear algorithms on instructions with thousands of memory operands
2069+
/// leads to significant compilation slowdown.
2070+
///
2071+
/// Heuristic is designed to limit checks count for algorithms where
2072+
/// conservative answer like "I don't know" is possible.
2073+
virtual unsigned getMemOperandLinearCheckLimit() const { return 16; }
2074+
20602075
/// Return an array that contains the ids of the target indices (used for the
20612076
/// TargetIndex machine operand) and their names.
20622077
///

llvm/lib/CodeGen/MachineInstr.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1581,6 +1581,12 @@ bool MachineInstr::hasOrderedMemoryRef() const {
15811581
if (memoperands_empty())
15821582
return true;
15831583

1584+
// Conservatively skip analysis if there are too many memory operands. Keep
1585+
// compilation time reasonable.
1586+
const TargetInstrInfo *TII = getMF()->getSubtarget().getInstrInfo();
1587+
if (getNumMemOperands() > TII->getMemOperandLinearCheckLimit())
1588+
return true;
1589+
15841590
// Check if any of our memory operands are ordered.
15851591
return llvm::any_of(memoperands(), [](const MachineMemOperand *MMO) {
15861592
return !MMO->isUnordered();
@@ -1600,7 +1606,15 @@ bool MachineInstr::isDereferenceableInvariantLoad() const {
16001606
if (memoperands_empty())
16011607
return false;
16021608

1603-
const MachineFrameInfo &MFI = getParent()->getParent()->getFrameInfo();
1609+
const MachineFunction &MF = *getMF();
1610+
1611+
// Conservatively skip analysis if there are too many memory operands. Keep
1612+
// compilation time reasonable.
1613+
const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
1614+
if (getNumMemOperands() > TII->getMemOperandLinearCheckLimit())
1615+
return false;
1616+
1617+
const MachineFrameInfo &MFI = MF.getFrameInfo();
16041618

16051619
for (MachineMemOperand *MMO : memoperands()) {
16061620
if (!MMO->isUnordered())

0 commit comments

Comments
 (0)