Skip to content

[CodeGen] Limit mem ops checks count for reasonable compilation speed #147151

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions llvm/include/llvm/CodeGen/TargetInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -2057,6 +2057,21 @@ class LLVM_ABI TargetInstrInfo : public MCInstrInfo {
/// overhead or too rigid restriction.
virtual unsigned getMemOperandAACheckLimit() const { return 16; }

/// Return the maximum number of memory operands to check instruction for
/// memory-related properties.
///
/// After MIR transformations like tail merging etc. memory operands are
/// united for the merged result instructions. Compiler might ends up with
/// thousands of memory operands for each instruction for tricky CFGs like
/// for switch construction.
///
/// Even linear algorithms on instructions with thousands of memory operands
/// leads to significant compilation slowdown.
///
/// Heuristic is designed to limit checks count for algorithms where
/// conservative answer like "I don't know" is possible.
virtual unsigned getMemOperandLinearCheckLimit() const { return 16; }

/// Return an array that contains the ids of the target indices (used for the
/// TargetIndex machine operand) and their names.
///
Expand Down
16 changes: 15 additions & 1 deletion llvm/lib/CodeGen/MachineInstr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1581,6 +1581,12 @@ bool MachineInstr::hasOrderedMemoryRef() const {
if (memoperands_empty())
return true;

// Conservatively skip analysis if there are too many memory operands. Keep
// compilation time reasonable.
const TargetInstrInfo *TII = getMF()->getSubtarget().getInstrInfo();
if (getNumMemOperands() > TII->getMemOperandLinearCheckLimit())
return true;

// Check if any of our memory operands are ordered.
return llvm::any_of(memoperands(), [](const MachineMemOperand *MMO) {
return !MMO->isUnordered();
Expand All @@ -1600,7 +1606,15 @@ bool MachineInstr::isDereferenceableInvariantLoad() const {
if (memoperands_empty())
return false;

const MachineFrameInfo &MFI = getParent()->getParent()->getFrameInfo();
const MachineFunction &MF = *getMF();

// Conservatively skip analysis if there are too many memory operands. Keep
// compilation time reasonable.
const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
if (getNumMemOperands() > TII->getMemOperandLinearCheckLimit())
return false;

const MachineFrameInfo &MFI = MF.getFrameInfo();

for (MachineMemOperand *MMO : memoperands()) {
if (!MMO->isUnordered())
Expand Down
Loading