Index: lib/CodeGen/CodeGenPrepare.cpp =================================================================== --- lib/CodeGen/CodeGenPrepare.cpp +++ lib/CodeGen/CodeGenPrepare.cpp @@ -4276,10 +4276,6 @@ return true; } -// Max number of memory uses to look at before aborting the search to conserve -// compile time. -static constexpr int MaxMemoryUsesToScan = 20; - /// Recursively walk all the uses of I until we find a memory use. /// If we find an obviously non-foldable instruction, return true. /// Add the ultimately found memory instructions to MemoryUses. @@ -4287,7 +4283,7 @@ Instruction *I, SmallVectorImpl> &MemoryUses, SmallPtrSetImpl &ConsideredInsts, const TargetLowering &TLI, - const TargetRegisterInfo &TRI, int SeenInsts = 0) { + const TargetRegisterInfo &TRI) { // If we already considered this instruction, we're done. if (!ConsideredInsts.insert(I).second) return false; @@ -4300,11 +4296,6 @@ // Loop over all the uses, recursively processing them. for (Use &U : I->uses()) { - // Conservatively return true if we're seeing a large number or a deep chain - // of users. This avoids excessive compilation times in pathological cases. - if (SeenInsts++ >= MaxMemoryUsesToScan) - return true; - Instruction *UserI = cast(U.getUser()); if (LoadInst *LI = dyn_cast(UserI)) { MemoryUses.push_back(std::make_pair(LI, U.getOperandNo())); @@ -4313,24 +4304,30 @@ if (StoreInst *SI = dyn_cast(UserI)) { unsigned opNo = U.getOperandNo(); - if (opNo != StoreInst::getPointerOperandIndex()) + if (opNo != StoreInst::getPointerOperandIndex()) { + U.moveToFrontOfUseList(); return true; // Storing addr, not into addr. + } MemoryUses.push_back(std::make_pair(SI, opNo)); continue; } if (AtomicRMWInst *RMW = dyn_cast(UserI)) { unsigned opNo = U.getOperandNo(); - if (opNo != AtomicRMWInst::getPointerOperandIndex()) + if (opNo != AtomicRMWInst::getPointerOperandIndex()) { + U.moveToFrontOfUseList(); return true; // Storing addr, not into addr. + } MemoryUses.push_back(std::make_pair(RMW, opNo)); continue; } if (AtomicCmpXchgInst *CmpX = dyn_cast(UserI)) { unsigned opNo = U.getOperandNo(); - if (opNo != AtomicCmpXchgInst::getPointerOperandIndex()) + if (opNo != AtomicCmpXchgInst::getPointerOperandIndex()) { + U.moveToFrontOfUseList(); return true; // Storing addr, not into addr. + } MemoryUses.push_back(std::make_pair(CmpX, opNo)); continue; } @@ -4342,17 +4339,23 @@ continue; InlineAsm *IA = dyn_cast(CI->getCalledValue()); - if (!IA) return true; + if (!IA) { + U.moveToFrontOfUseList(); + return true; + } // If this is a memory operand, we're cool, otherwise bail out. - if (!IsOperandAMemoryOperand(CI, IA, I, TLI, TRI)) + if (!IsOperandAMemoryOperand(CI, IA, I, TLI, TRI)) { + U.moveToFrontOfUseList(); return true; + } continue; } - if (FindAllMemoryUses(UserI, MemoryUses, ConsideredInsts, TLI, TRI, - SeenInsts)) + if (FindAllMemoryUses(UserI, MemoryUses, ConsideredInsts, TLI, TRI)) { + U.moveToFrontOfUseList(); return true; + } } return false;