diff --git a/llvm/include/llvm/IR/Statepoint.h b/llvm/include/llvm/IR/Statepoint.h index 34eb1126b373f..ce3d5a655df82 100644 --- a/llvm/include/llvm/IR/Statepoint.h +++ b/llvm/include/llvm/IR/Statepoint.h @@ -115,6 +115,25 @@ class GCStatepointInst : public CallBase { uint64_t getFlags() const { return cast(getArgOperand(FlagsPos))->getZExtValue(); } + + /// Return the value actually being called or invoked. + Value *getActualCalledOperand() const { + return getArgOperand(CalledFunctionPos); + } + + /// Returns the function called if this is a wrapping a direct call, and null + /// otherwise. + Function *getActualCalledFunction() const { + return dyn_cast_or_null(getActualCalledOperand()); + } + + /// Return the type of the value returned by the call underlying the + /// statepoint. + Type *getActualReturnType() const { + auto *CalleeTy = + cast(getActualCalledOperand()->getType())->getElementType(); + return cast(CalleeTy)->getReturnType(); + } }; /// A wrapper around a GC intrinsic call, this provides most of the actual @@ -139,7 +158,6 @@ class StatepointBase { using arg_iterator = typename CallTy::const_op_iterator; enum { - CalledFunctionPos = GCStatepointInst::CalledFunctionPos, CallArgsBeginPos = GCStatepointInst::CallArgsBeginPos, }; @@ -162,22 +180,18 @@ class StatepointBase { uint64_t getID() const { return getCall()->getID(); } uint32_t getNumPatchBytes() const { return getCall()->getNumPatchBytes(); } int getNumCallArgs() const { return getCall()->getNumCallArgs(); } - - - /// Return the value actually being called or invoked. ValueTy *getCalledValue() const { - return getCall()->getArgOperand(CalledFunctionPos); + return getCall()->getActualCalledOperand(); + } + Type *getActualReturnType() const { return getCall()->getActualReturnType(); } + FunTy *getCalledFunction() const { + return getCall()->getActualCalledFunction(); } + // FIXME: Migrate users of this to `getCall` and remove it. InstructionTy *getInstruction() const { return getCall(); } - /// Return the function being called if this is a direct call, otherwise - /// return null (if it's an indirect call). - FunTy *getCalledFunction() const { - return dyn_cast(getCalledValue()); - } - /// Return the caller function for this statepoint. FunTy *getCaller() const { return getCall()->getCaller(); } @@ -187,13 +201,6 @@ class StatepointBase { return getCall()->doesNotThrow() || (F ? F->doesNotThrow() : false); } - /// Return the type of the value returned by the call underlying the - /// statepoint. - Type *getActualReturnType() const { - auto *FTy = cast( - cast(getCalledValue()->getType())->getElementType()); - return FTy->getReturnType(); - } size_t arg_size() const { return getNumCallArgs(); } arg_iterator arg_begin() const { diff --git a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp index acb68405470ca..664f56523d9b1 100644 --- a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp @@ -822,7 +822,7 @@ SelectionDAGBuilder::LowerStatepoint(const GCStatepointInst &I, #endif SDValue ActualCallee; - SDValue Callee = getValue(ISP.getCalledValue()); + SDValue Callee = getValue(I.getActualCalledOperand()); if (I.getNumPatchBytes() > 0) { // If we've been asked to emit a nop sequence instead of a call instruction @@ -838,7 +838,7 @@ SelectionDAGBuilder::LowerStatepoint(const GCStatepointInst &I, StatepointLoweringInfo SI(DAG); populateCallLoweringInfo(SI.CLI, &I, GCStatepointInst::CallArgsBeginPos, I.getNumCallArgs(), ActualCallee, - ISP.getActualReturnType(), false /* IsPatchPoint */); + I.getActualReturnType(), false /* IsPatchPoint */); // There may be duplication in the gc.relocate list; such as two copies of // each relocation on normal and exceptional path for an invoke. We only @@ -894,7 +894,7 @@ SelectionDAGBuilder::LowerStatepoint(const GCStatepointInst &I, // Export the result value if needed const GCResultInst *GCResult = ISP.getGCResult(); - Type *RetTy = ISP.getActualReturnType(); + Type *RetTy = I.getActualReturnType(); if (!RetTy->isVoidTy() && GCResult) { if (GCResult->getParent() != I.getParent()) { // Result value will be used in a different basic block so we need to @@ -979,10 +979,7 @@ void SelectionDAGBuilder::visitGCResult(const GCResultInst &CI) { // register because statepoint and actual call return types can be // different, and getValue() will use CopyFromReg of the wrong type, // which is always i32 in our case. - PointerType *CalleeType = cast( - ImmutableStatepoint(I).getCalledValue()->getType()); - Type *RetTy = - cast(CalleeType->getElementType())->getReturnType(); + Type *RetTy = cast(I)->getActualReturnType(); SDValue CopyFromReg = getCopyFromRegs(I, RetTy); assert(CopyFromReg.getNode());