diff --git a/llvm/include/llvm/IR/Statepoint.h b/llvm/include/llvm/IR/Statepoint.h index 81679e2612da7..d31484207c10b 100644 --- a/llvm/include/llvm/IR/Statepoint.h +++ b/llvm/include/llvm/IR/Statepoint.h @@ -181,6 +181,23 @@ class GCStatepointInst : public CallBase { iterator_range gc_args() const { return make_range(gc_args_begin(), gc_args_end()); } + + + /// Get list of all gc reloactes linked to this statepoint + /// May contain several relocations for the same base/derived pair. + /// For example this could happen due to relocations on unwinding + /// path of invoke. + inline std::vector getGCRelocates() const; + + /// Get the experimental_gc_result call tied to this statepoint if there is + /// one, otherwise return nullptr. + const GCResultInst *getGCResult() const { + for (auto *U : users()) + if (auto *GRI = dyn_cast(U)) + return GRI; + return nullptr; + } + }; /// A wrapper around a GC intrinsic call, this provides most of the actual @@ -322,20 +339,11 @@ class StatepointBase { return getCall()->gc_args(); } - /// Get list of all gc reloactes linked to this statepoint - /// May contain several relocations for the same base/derived pair. - /// For example this could happen due to relocations on unwinding - /// path of invoke. - std::vector getRelocates() const; - - /// Get the experimental_gc_result call tied to this statepoint. Can be - /// nullptr if there isn't a gc_result tied to this statepoint. Guaranteed to - /// be a CallInst if non-null. + std::vector getRelocates() const { + return getCall()->getGCRelocates(); + } const GCResultInst *getGCResult() const { - for (auto *U : getInstruction()->users()) - if (auto *GRI = dyn_cast(U)) - return GRI; - return nullptr; + return getCall()->getGCResult(); } #ifndef NDEBUG @@ -470,21 +478,17 @@ class GCResultInst : public GCProjectionInst { } }; -template -std::vector -StatepointBase::getRelocates() - const { +std::vector GCStatepointInst::getGCRelocates() const { std::vector Result; // Search for relocated pointers. Note that working backwards from the // gc_relocates ensures that we only get pairs which are actually relocated // and used after the statepoint. - for (const User *U : StatepointCall->users()) + for (const User *U : users()) if (auto *Relocate = dyn_cast(U)) Result.push_back(Relocate); - auto *StatepointInvoke = dyn_cast(StatepointCall); + auto *StatepointInvoke = dyn_cast(this); if (!StatepointInvoke) return Result; diff --git a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp index 4f51efd094723..3e8911859e2de 100644 --- a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp @@ -854,7 +854,7 @@ SelectionDAGBuilder::LowerStatepoint(const GCStatepointInst &I, // separately with half the space. This would require a format rev and a // fairly major rework of the STATEPOINT node though. SmallSet Seen; - for (const GCRelocateInst *Relocate : ISP.getRelocates()) { + for (const GCRelocateInst *Relocate : I.getGCRelocates()) { SI.GCRelocates.push_back(Relocate); SDValue DerivedSD = getValue(Relocate->getDerivedPtr()); @@ -893,7 +893,7 @@ SelectionDAGBuilder::LowerStatepoint(const GCStatepointInst &I, SDValue ReturnValue = LowerAsSTATEPOINT(SI); // Export the result value if needed - const GCResultInst *GCResult = ISP.getGCResult(); + const GCResultInst *GCResult = I.getGCResult(); Type *RetTy = I.getActualReturnType(); if (!RetTy->isVoidTy() && GCResult) { if (GCResult->getParent() != I.getParent()) {