Index: llvm/lib/CodeGen/RegAllocGreedy.cpp =================================================================== --- llvm/lib/CodeGen/RegAllocGreedy.cpp +++ llvm/lib/CodeGen/RegAllocGreedy.cpp @@ -550,16 +550,19 @@ struct RAGreedyStats { unsigned Reloads = 0; unsigned FoldedReloads = 0; + unsigned ZeroCostFoldedReloads = 0; unsigned Spills = 0; unsigned FoldedSpills = 0; bool isEmpty() { - return !(Reloads || FoldedReloads || Spills || FoldedSpills); + return !(Reloads || FoldedReloads || Spills || FoldedSpills || + ZeroCostFoldedReloads); } void add(RAGreedyStats other) { Reloads += other.Reloads; FoldedReloads += other.FoldedReloads; + ZeroCostFoldedReloads += other.ZeroCostFoldedReloads; Spills += other.Spills; FoldedSpills += other.FoldedSpills; } @@ -3138,6 +3141,9 @@ R << NV("NumReloads", Reloads) << " reloads "; if (FoldedReloads) R << NV("NumFoldedReloads", FoldedReloads) << " folded reloads "; + if (ZeroCostFoldedReloads) + R << NV("NumZeroCostFoldedReloads", ZeroCostFoldedReloads) + << " zero cost folded reloads "; } RAGreedy::RAGreedyStats @@ -3146,6 +3152,11 @@ const MachineFrameInfo &MFI = MF->getFrameInfo(); int FI; + auto isPatchpointInstr = [](const MachineInstr &MI) { + return MI.getOpcode() == TargetOpcode::PATCHPOINT || + MI.getOpcode() == TargetOpcode::STACKMAP || + MI.getOpcode() == TargetOpcode::STATEPOINT; + }; for (MachineInstr &MI : MBB) { SmallVector Accesses; auto isSpillSlotAccess = [&MFI](const MachineMemOperand *A) { @@ -3156,9 +3167,22 @@ if (TII->isLoadFromStackSlot(MI, FI) && MFI.isSpillSlotObjectIndex(FI)) ++Stats.Reloads; else if (TII->hasLoadFromStackSlot(MI, Accesses) && - llvm::any_of(Accesses, isSpillSlotAccess)) - ++Stats.FoldedReloads; - else if (TII->isStoreToStackSlot(MI, FI) && MFI.isSpillSlotObjectIndex(FI)) + llvm::any_of(Accesses, isSpillSlotAccess)) { + if (isPatchpointInstr(MI)) { + std::pair NonZeroCostRange = + TII->getPatchpointUnfoldableRange(MI); + if (any_of(MI.operands(), [&](MachineOperand &MO) { + return MO.isFI() && MFI.isSpillSlotObjectIndex(MO.getIndex()) && + MI.getOperandNo(&MO) >= NonZeroCostRange.first && + MI.getOperandNo(&MO) < NonZeroCostRange.second; + })) + ++Stats.FoldedReloads; + else + ++Stats.ZeroCostFoldedReloads; + } else + ++Stats.FoldedReloads; + } else if (TII->isStoreToStackSlot(MI, FI) && + MFI.isSpillSlotObjectIndex(FI)) ++Stats.Spills; else if (TII->hasStoreToStackSlot(MI, Accesses) && llvm::any_of(Accesses, isSpillSlotAccess)) Index: llvm/test/CodeGen/X86/statepoint-ra.ll =================================================================== --- llvm/test/CodeGen/X86/statepoint-ra.ll +++ llvm/test/CodeGen/X86/statepoint-ra.ll @@ -1,9 +1,23 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -; RUN: llc -verify-machineinstrs -O3 -use-registers-for-deopt-values -restrict-statepoint-remat=true < %s 2>&1 | FileCheck %s +; RUN: llc -verify-machineinstrs -O3 -use-registers-for-deopt-values -restrict-statepoint-remat=true -pass-remarks-filter=regalloc -pass-remarks-output=%t.yaml < %s 2>&1 | FileCheck %s +; RUN: cat %t.yaml | FileCheck -check-prefix=YAML %s target triple = "x86_64-unknown-linux-gnu" -; CHECK-NOT: error: ran out of registers during register allocation +;CHECK-NOT: error: ran out of registers during register allocation + +;YAML: --- !Missed +;YAML: Pass: regalloc +;YAML: Name: SpillReload +;YAML: Function: barney +;YAML: Args: +;YAML: - NumSpills: '10' +;YAML: - String: ' spills ' +;YAML: - NumReloads: '7' +;YAML: - String: ' reloads ' +;YAML: - NumZeroCostFoldedReloads: '1' +;YAML: - String: ' zero cost folded reloads ' +;YAML: - String: generated in function define void @barney(i8 addrspace(1)* %arg, double %arg1, double %arg2, double %arg3, double %arg4, double %arg5, double %arg6, double %arg7, double %arg8, double %arg9, double %arg10, double %arg11, double %arg12) gc "statepoint-example" personality i32* ()* @widget { bb: