diff --git a/llvm/include/llvm/CodeGen/TargetInstrInfo.h b/llvm/include/llvm/CodeGen/TargetInstrInfo.h --- a/llvm/include/llvm/CodeGen/TargetInstrInfo.h +++ b/llvm/include/llvm/CodeGen/TargetInstrInfo.h @@ -1064,6 +1064,16 @@ /// has the potential of causing nasty silent breakage in out-of-tree targets. virtual bool isSubregFoldable() const { return false; } + /// For a patchpoint, stackmap, or statepoint intrinsic, return the range of + /// operands which can't be folded into stack references. Operands outside + /// of the range are most likely foldable but it is not guaranteed. + /// These instructions are unique in that stack references for some operands + /// have the same execution cost (e.g. none) as the unfolded register forms. + /// The ranged return is guaranteed to include all operands which can't be + /// folded at zero cost. + virtual std::pair + getPatchpointUnfoldableRange(const MachineInstr &MI) const; + /// Attempt to fold a load or store of the specified stack /// slot into the specified machine instruction for the specified operand(s). /// If this is possible, a new instruction is returned with the specified diff --git a/llvm/lib/CodeGen/TargetInstrInfo.cpp b/llvm/lib/CodeGen/TargetInstrInfo.cpp --- a/llvm/lib/CodeGen/TargetInstrInfo.cpp +++ b/llvm/lib/CodeGen/TargetInstrInfo.cpp @@ -474,32 +474,31 @@ MCInst TargetInstrInfo::getNop() const { llvm_unreachable("Not implemented"); } -static MachineInstr *foldPatchpoint(MachineFunction &MF, MachineInstr &MI, - ArrayRef Ops, int FrameIndex, - const TargetInstrInfo &TII) { - unsigned StartIdx = 0; - unsigned NumDefs = 0; +std::pair +TargetInstrInfo::getPatchpointUnfoldableRange(const MachineInstr &MI) const { switch (MI.getOpcode()) { - case TargetOpcode::STACKMAP: { + case TargetOpcode::STACKMAP: // StackMapLiveValues are foldable - StartIdx = StackMapOpers(&MI).getVarIdx(); - break; - } - case TargetOpcode::PATCHPOINT: { + return std::make_pair(0, StackMapOpers(&MI).getVarIdx()); + case TargetOpcode::PATCHPOINT: // For PatchPoint, the call args are not foldable (even if reported in the // stackmap e.g. via anyregcc). - StartIdx = PatchPointOpers(&MI).getVarIdx(); - break; - } - case TargetOpcode::STATEPOINT: { + return std::make_pair(0, PatchPointOpers(&MI).getVarIdx()); + case TargetOpcode::STATEPOINT: // For statepoints, fold deopt and gc arguments, but not call arguments. - StartIdx = StatepointOpers(&MI).getVarIdx(); - NumDefs = MI.getNumDefs(); - break; - } + return std::make_pair(MI.getNumDefs(), StatepointOpers(&MI).getVarIdx()); default: llvm_unreachable("unexpected stackmap opcode"); } +} + +static MachineInstr *foldPatchpoint(MachineFunction &MF, MachineInstr &MI, + ArrayRef Ops, int FrameIndex, + const TargetInstrInfo &TII) { + unsigned StartIdx = 0; + unsigned NumDefs = 0; + // getPatchpointUnfoldableRange throws guarantee if MI is not a patchpoint. + std::tie(NumDefs, StartIdx) = TII.getPatchpointUnfoldableRange(MI); unsigned DefToFoldIdx = MI.getNumOperands();