[llvm] r225909 - Revert "r225811 - Revert "r225808 - [PowerPC] Add StackMap/PatchPoint support""

Bill Schmidt wschmidt at linux.vnet.ibm.com
Thu Jan 15 07:46:05 PST 2015


Hi Hal,

A couple of comments below:

On Wed, 2015-01-14 at 01:07 +0000, Hal Finkel wrote:

> Modified: llvm/trunk/docs/StackMaps.rst
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/StackMaps.rst?rev=225909&r1=225908&r2=225909&view=diff
> ==============================================================================
> --- llvm/trunk/docs/StackMaps.rst (original)
> +++ llvm/trunk/docs/StackMaps.rst Tue Jan 13 19:07:51 2015
> @@ -221,6 +221,12 @@ lowered according to the calling convent
>  intrinsic's callsite. Variants of the intrinsic with non-void return
>  type also return a value according to calling convention.
> 
> +On PowerPC, note that the ``<target>`` must be the actual intended target of
> +the indirect call, not the function-descriptor address normally used as the
> +C/C++ function-pointer representation. As a result, the call target must be

                                        ^ under the ELFv1 ABI.

Also, "As a result":  Is this really a result of the foregoing?  It
looks to me like you wouldn't handle non-local calls regardless of the
use of function descriptors (i.e., isn't possible under ELFv2 either).
If it is possible under ELFv2, then you may want to consider expanding
the implementation.

> +local because no adjustment or restoration of the TOC pointer (in register r2)
> +will be performed.
> +
>  Requesting zero patch point arguments is valid. In this case, all
>  variable operands are handled just like
>  ``llvm.experimental.stackmap.*``. The difference is that space will
> 

<snip>

> Modified: llvm/trunk/lib/Target/PowerPC/PPCCallingConv.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCCallingConv.td?rev=225909&r1=225908&r2=225909&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/PowerPC/PPCCallingConv.td (original)
> +++ llvm/trunk/lib/Target/PowerPC/PPCCallingConv.td Tue Jan 13 19:07:51 2015
> @@ -28,8 +28,21 @@ class CCIfNotSubtarget<string F, CCActio
>  // Return Value Calling Convention
>  //===----------------------------------------------------------------------===//
> 
> +// PPC64 AnyReg return-value convention. No explicit register is specified for
> +// the return-value. The register allocator is allowed and expected to choose
> +// any free register.
> +//
> +// This calling convention is currently only supported by the stackmap and
> +// patchpoint intrinsics. All other uses will result in an assert on Debug
> +// builds. On Release builds we fallback to the PPC C calling convention.
> +def RetCC_PPC64_AnyReg : CallingConv<[
> +  CCCustom<"CC_PPC_AnyReg_Error">
> +]>;
> +
>  // Return-value convention for PowerPC
>  def RetCC_PPC : CallingConv<[
> +  CCIfCC<"CallingConv::AnyReg", CCDelegateTo<RetCC_PPC64_AnyReg>>,
> +

Is this ok to delegate if RetCC_PPC is being used for 32-bit?  I can't
tell for sure if there is a potential problem here or not.

>    // On PPC64, integer return values are always promoted to i64
>    CCIfType<[i32, i1], CCIfSubtarget<"isPPC64()", CCPromoteToType<i64>>>,
>    CCIfType<[i1], CCIfNotSubtarget<"isPPC64()", CCPromoteToType<i32>>>,
> @@ -51,6 +64,15 @@ def RetCC_PPC : CallingConv<[
>             CCAssignToReg<[VSH2, VSH3, VSH4, VSH5, VSH6, VSH7, VSH8, VSH9]>>
>  ]>;
> 
> +// No explicit register is specified for the AnyReg calling convention. The
> +// register allocator may assign the arguments to any free register.
> +//
> +// This calling convention is currently only supported by the stackmap and
> +// patchpoint intrinsics. All other uses will result in an assert on Debug
> +// builds. On Release builds we fallback to the PPC C calling convention.
> +def CC_PPC64_AnyReg : CallingConv<[
> +  CCCustom<"CC_PPC_AnyReg_Error">
> +]>;
> 
>  // Note that we don't currently have calling conventions for 64-bit
>  // PowerPC, but handle all the complexities of the ABI in the lowering
> @@ -61,6 +83,8 @@ def RetCC_PPC : CallingConv<[
>  // Only handle ints and floats.  All ints are promoted to i64.
>  // Vector types and quadword ints are not handled.
>  def CC_PPC64_ELF_FIS : CallingConv<[
> +  CCIfCC<"CallingConv::AnyReg", CCDelegateTo<CC_PPC64_AnyReg>>,
> +
>    CCIfType<[i1],  CCPromoteToType<i64>>,
>    CCIfType<[i8],  CCPromoteToType<i64>>,
>    CCIfType<[i16], CCPromoteToType<i64>>,
> @@ -74,6 +98,8 @@ def CC_PPC64_ELF_FIS : CallingConv<[
>  // and multiple register returns are "supported" to avoid compile
>  // errors, but none are handled by the fast selector.
>  def RetCC_PPC64_ELF_FIS : CallingConv<[
> +  CCIfCC<"CallingConv::AnyReg", CCDelegateTo<RetCC_PPC64_AnyReg>>,
> +
>    CCIfType<[i1],   CCPromoteToType<i64>>,
>    CCIfType<[i8],   CCPromoteToType<i64>>,
>    CCIfType<[i16],  CCPromoteToType<i64>>,
> @@ -203,3 +229,15 @@ def CSR_SVR464_Altivec : CalleeSavedRegs
> 
>  def CSR_NoRegs : CalleeSavedRegs<(add)>;
> 
> +def CSR_64_AllRegs: CalleeSavedRegs<(add X0, (sequence "X%u", 3, 10),
> +                                             (sequence "X%u", 14, 31),
> +                                             (sequence "F%u", 0, 31),
> +                                             (sequence "CR%u", 0, 7))>;
> +
> +def CSR_64_AllRegs_Altivec : CalleeSavedRegs<(add CSR_64_AllRegs,
> +                                             (sequence "V%u", 0, 31))>;
> +
> +def CSR_64_AllRegs_VSX : CalleeSavedRegs<(add CSR_64_AllRegs_Altivec,
> +                                         (sequence "VSL%u", 0, 31),
> +                                         (sequence "VSH%u", 0, 31))>;
> +
> 
> Modified: llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp?rev=225909&r1=225908&r2=225909&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp (original)
> +++ llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp Tue Jan 13 19:07:51 2015
> @@ -15,6 +15,7 @@
> 
>  #include "PPC.h"
>  #include "MCTargetDesc/PPCPredicates.h"
> +#include "PPCCallingConv.h"
>  #include "PPCISelLowering.h"
>  #include "PPCSubtarget.h"
>  #include "PPCTargetMachine.h"
> @@ -119,6 +120,8 @@ class PPCFastISel final : public FastISe
>                               unsigned Op0, bool Op0IsKill,
>                               unsigned Op1, bool Op1IsKill);
> 
> +    bool fastLowerCall(CallLoweringInfo &CLI) override;
> +
>    // Instruction selection routines.
>    private:
>      bool SelectLoad(const Instruction *I);
> @@ -130,7 +133,6 @@ class PPCFastISel final : public FastISe
>      bool SelectIToFP(const Instruction *I, bool IsSigned);
>      bool SelectFPToI(const Instruction *I, bool IsSigned);
>      bool SelectBinaryIntOp(const Instruction *I, unsigned ISDOpcode);
> -    bool SelectCall(const Instruction *I);
>      bool SelectRet(const Instruction *I);
>      bool SelectTrunc(const Instruction *I);
>      bool SelectIntExt(const Instruction *I);
> @@ -174,9 +176,7 @@ class PPCFastISel final : public FastISe
>                           CallingConv::ID CC,
>                           unsigned &NumBytes,
>                           bool IsVarArg);
> -    void finishCall(MVT RetVT, SmallVectorImpl<unsigned> &UsedRegs,
> -                    const Instruction *I, CallingConv::ID CC,
> -                    unsigned &NumBytes, bool IsVarArg);
> +    bool finishCall(MVT RetVT, CallLoweringInfo &CLI, unsigned &NumBytes);
>      CCAssignFn *usePPC32CCs(unsigned Flag);
> 
>    private:
> @@ -1339,9 +1339,9 @@ bool PPCFastISel::processCallArgs(SmallV
> 
>  // For a call that we've determined we can fast-select, finish the
>  // call sequence and generate a copy to obtain the return value (if any).
> -void PPCFastISel::finishCall(MVT RetVT, SmallVectorImpl<unsigned> &UsedRegs,
> -                             const Instruction *I, CallingConv::ID CC,
> -                             unsigned &NumBytes, bool IsVarArg) {
> +bool PPCFastISel::finishCall(MVT RetVT, CallLoweringInfo &CLI, unsigned &NumBytes) {
> +  CallingConv::ID CC = CLI.CallConv;
> +
>    // Issue CallSEQ_END.
>    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
>            TII.get(TII.getCallFrameDestroyOpcode()))
> @@ -1352,7 +1352,7 @@ void PPCFastISel::finishCall(MVT RetVT,
>    // any real difficulties there.
>    if (RetVT != MVT::isVoid) {
>      SmallVector<CCValAssign, 16> RVLocs;
> -    CCState CCInfo(CC, IsVarArg, *FuncInfo.MF, RVLocs, *Context);
> +    CCState CCInfo(CC, false, *FuncInfo.MF, RVLocs, *Context);
>      CCInfo.AnalyzeCallResult(RetVT, RetCC_PPC64_ELF_FIS);
>      CCValAssign &VA = RVLocs[0];
>      assert(RVLocs.size() == 1 && "No support for multi-reg return values!");
> @@ -1397,39 +1397,35 @@ void PPCFastISel::finishCall(MVT RetVT,
>      }
> 
>      assert(ResultReg && "ResultReg unset!");
> -    UsedRegs.push_back(SourcePhysReg);
> -    updateValueMap(I, ResultReg);

It's not clear to me why you deleted the call to updateValueMap(), which
associates ResultReg as the value of the call instruction within the
FastISel machinery.

> +    CLI.InRegs.push_back(SourcePhysReg);
> +    CLI.ResultReg = ResultReg;
> +    CLI.NumResultRegs = 1;
>    }
> +
> +  return true;
>  }
> 
> -// Attempt to fast-select a call instruction.
> -bool PPCFastISel::SelectCall(const Instruction *I) {
> -  const CallInst *CI = cast<CallInst>(I);
> -  const Value *Callee = CI->getCalledValue();
> +bool PPCFastISel::fastLowerCall(CallLoweringInfo &CLI) {
> +  CallingConv::ID CC  = CLI.CallConv;
> +  bool IsTailCall     = CLI.IsTailCall;
> +  bool IsVarArg       = CLI.IsVarArg;
> +  const Value *Callee = CLI.Callee;
> +  const char *SymName = CLI.SymName;
> 
> -  // Can't handle inline asm.
> -  if (isa<InlineAsm>(Callee))
> +  if (!Callee && !SymName)
>      return false;
> 
>    // Allow SelectionDAG isel to handle tail calls.
> -  if (CI->isTailCall())
> +  if (IsTailCall)
>      return false;
> 
> -  // Obtain calling convention.
> -  ImmutableCallSite CS(CI);
> -  CallingConv::ID CC = CS.getCallingConv();
> -
> -  PointerType *PT = cast<PointerType>(CS.getCalledValue()->getType());
> -  FunctionType *FTy = cast<FunctionType>(PT->getElementType());
> -  bool IsVarArg = FTy->isVarArg();
> -
> -  // Not ready for varargs yet.
> +  // Let SDISel handle vararg functions.
>    if (IsVarArg)
>      return false;
> 
>    // Handle simple calls for now, with legal return types and
>    // those that can be extended.
> -  Type *RetTy = I->getType();
> +  Type *RetTy = CLI.RetTy;
>    MVT RetVT;
>    if (RetTy->isVoidTy())
>      RetVT = MVT::isVoid;
> @@ -1450,7 +1446,7 @@ bool PPCFastISel::SelectCall(const Instr
> 
>    // Bail early if more than 8 arguments, as we only currently
>    // handle arguments passed in registers.
> -  unsigned NumArgs = CS.arg_size();
> +  unsigned NumArgs = CLI.OutVals.size();
>    if (NumArgs > 8)
>      return false;
> 
> @@ -1465,28 +1461,16 @@ bool PPCFastISel::SelectCall(const Instr
>    ArgVTs.reserve(NumArgs);
>    ArgFlags.reserve(NumArgs);
> 
> -  for (ImmutableCallSite::arg_iterator II = CS.arg_begin(), IE = CS.arg_end();
> -       II != IE; ++II) {
> -    // FIXME: ARM does something for intrinsic calls here, check into that.
> -
> -    unsigned AttrIdx = II - CS.arg_begin() + 1;
> -    
> +  for (unsigned i = 0, ie = NumArgs; i != ie; ++i) {
>      // Only handle easy calls for now.  It would be reasonably easy
>      // to handle <= 8-byte structures passed ByVal in registers, but we
>      // have to ensure they are right-justified in the register.
> -    if (CS.paramHasAttr(AttrIdx, Attribute::InReg) ||
> -        CS.paramHasAttr(AttrIdx, Attribute::StructRet) ||
> -        CS.paramHasAttr(AttrIdx, Attribute::Nest) ||
> -        CS.paramHasAttr(AttrIdx, Attribute::ByVal))
> +    ISD::ArgFlagsTy Flags = CLI.OutFlags[i];
> +    if (Flags.isInReg() || Flags.isSRet() || Flags.isNest() || Flags.isByVal())
>        return false;
> 
> -    ISD::ArgFlagsTy Flags;
> -    if (CS.paramHasAttr(AttrIdx, Attribute::SExt))
> -      Flags.setSExt();
> -    if (CS.paramHasAttr(AttrIdx, Attribute::ZExt))
> -      Flags.setZExt();
> -
> -    Type *ArgTy = (*II)->getType();
> +    Value *ArgValue = CLI.OutVals[i];
> +    Type *ArgTy = ArgValue->getType();
>      MVT ArgVT;
>      if (!isTypeLegal(ArgTy, ArgVT) && ArgVT != MVT::i16 && ArgVT != MVT::i8)
>        return false;
> @@ -1494,14 +1478,11 @@ bool PPCFastISel::SelectCall(const Instr
>      if (ArgVT.isVector())
>        return false;
> 
> -    unsigned Arg = getRegForValue(*II);
> +    unsigned Arg = getRegForValue(ArgValue);
>      if (Arg == 0)
>        return false;
> 
> -    unsigned OriginalAlignment = DL.getABITypeAlignment(ArgTy);
> -    Flags.setOrigAlign(OriginalAlignment);
> -
> -    Args.push_back(*II);
> +    Args.push_back(ArgValue);
>      ArgRegs.push_back(Arg);
>      ArgVTs.push_back(ArgVT);
>      ArgFlags.push_back(Flags);
> @@ -1515,18 +1496,28 @@ bool PPCFastISel::SelectCall(const Instr
>                         RegArgs, CC, NumBytes, IsVarArg))
>      return false;
> 
> +  MachineInstrBuilder MIB;
>    // FIXME: No handling for function pointers yet.  This requires
>    // implementing the function descriptor (OPD) setup.
>    const GlobalValue *GV = dyn_cast<GlobalValue>(Callee);
> -  if (!GV)
> -    return false;
> -
> -  // Build direct call with NOP for TOC restore.
> -  // FIXME: We can and should optimize away the NOP for local calls.
> -  MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
> -                                    TII.get(PPC::BL8_NOP));
> -  // Add callee.
> -  MIB.addGlobalAddress(GV);
> +  if (!GV) {
> +    // patchpoints are a special case; they always dispatch to a pointer value.
> +    // However, we don't actually want to generate the indirect call sequence
> +    // here (that will be generated, as necessary, during asm printing), and
> +    // the call we generate here will be erased by FastISel::selectPatchpoint,
> +    // so don't try very hard...
> +    if (CLI.IsPatchPoint)
> +      MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(PPC::NOP));
> +    else
> +      return false;
> +  } else {
> +    // Build direct call with NOP for TOC restore.
> +    // FIXME: We can and should optimize away the NOP for local calls.
> +    MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
> +                  TII.get(PPC::BL8_NOP));
> +    // Add callee.
> +    MIB.addGlobalAddress(GV);
> +  }
> 
>    // Add implicit physical register uses to the call.
>    for (unsigned II = 0, IE = RegArgs.size(); II != IE; ++II)
> @@ -1540,14 +1531,10 @@ bool PPCFastISel::SelectCall(const Instr
>    // defs for return values will be added by setPhysRegsDeadExcept().
>    MIB.addRegMask(TRI.getCallPreservedMask(CC));
> 
> -  // Finish off the call including any return values.
> -  SmallVector<unsigned, 4> UsedRegs;
> -  finishCall(RetVT, UsedRegs, I, CC, NumBytes, IsVarArg);
> -
> -  // Set all unused physregs defs as dead.
> -  static_cast<MachineInstr *>(MIB)->setPhysRegsDeadExcept(UsedRegs, TRI);
> +  CLI.Call = MIB;
> 
> -  return true;
> +  // Finish off the call including any return values.
> +  return finishCall(RetVT, CLI, NumBytes);
>  }
> 
>  // Attempt to fast-select a return instruction.
> @@ -1837,9 +1824,7 @@ bool PPCFastISel::fastSelectInstruction(
>      case Instruction::Sub:
>        return SelectBinaryIntOp(I, ISD::SUB);
>      case Instruction::Call:
> -      if (dyn_cast<IntrinsicInst>(I))
> -        return false;
> -      return SelectCall(I);
> +      return selectCall(I);
>      case Instruction::Ret:
>        return SelectRet(I);
>      case Instruction::Trunc:
> 
> Modified: llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp?rev=225909&r1=225908&r2=225909&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp (original)
> +++ llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp Tue Jan 13 19:07:51 2015
> @@ -450,6 +450,7 @@ bool PPCFrameLowering::needsFP(const Mac
> 
>    return MF.getTarget().Options.DisableFramePointerElim(MF) ||
>      MFI->hasVarSizedObjects() ||
> +    MFI->hasStackMap() || MFI->hasPatchPoint() ||
>      (MF.getTarget().Options.GuaranteedTailCallOpt &&
>       MF.getInfo<PPCFunctionInfo>()->hasFastCall());
>  }
> 
> Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=225909&r1=225908&r2=225909&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Tue Jan 13 19:07:51 2015
> @@ -13,6 +13,7 @@
> 
>  #include "PPCISelLowering.h"
>  #include "MCTargetDesc/PPCPredicates.h"
> +#include "PPCCallingConv.h"
>  #include "PPCMachineFunctionInfo.h"
>  #include "PPCPerfectShuffle.h"
>  #include "PPCTargetMachine.h"
> @@ -3590,6 +3591,7 @@ static bool isFunctionGlobalAddress(SDVa
>  static
>  unsigned PrepareCall(SelectionDAG &DAG, SDValue &Callee, SDValue &InFlag,
>                       SDValue &Chain, SDLoc dl, int SPDiff, bool isTailCall,
> +                     bool IsPatchPoint,
>                       SmallVectorImpl<std::pair<unsigned, SDValue> > &RegsToPass,
>                       SmallVectorImpl<SDValue> &Ops, std::vector<EVT> &NodeTys,
>                       const PPCSubtarget &Subtarget) {
> @@ -3658,6 +3660,16 @@ unsigned PrepareCall(SelectionDAG &DAG,
>      needIndirectCall = false;
>    }
> 
> +  if (IsPatchPoint) {
> +    // We'll form an invalid direct call when lowering a patchpoint; the full
> +    // sequence for an indirect call is complicated, and many of the
> +    // instructions introduced might have side effects (and, thus, can't be
> +    // removed later). The call itself will be removed as soon as the
> +    // argument/return lowering is complete, so the fact that it has the wrong
> +    // kind of operands should not really matter.
> +    needIndirectCall = false;
> +  }
> +
>    if (needIndirectCall) {
>      // Otherwise, this is an indirect call.  We have to use a MTCTR/BCTRL pair
>      // to do the call, we can't use PPCISD::CALL.
> @@ -3783,7 +3795,7 @@ unsigned PrepareCall(SelectionDAG &DAG,
>                                    RegsToPass[i].second.getValueType()));
> 
>    // Direct calls in the ELFv2 ABI need the TOC register live into the call.
> -  if (Callee.getNode() && isELFv2ABI)
> +  if (Callee.getNode() && isELFv2ABI && !IsPatchPoint)
>      Ops.push_back(DAG.getRegister(PPC::X2, PtrVT));
> 
>    return CallOpc;
> @@ -3846,7 +3858,7 @@ PPCTargetLowering::LowerCallResult(SDVal
> 
>  SDValue
>  PPCTargetLowering::FinishCall(CallingConv::ID CallConv, SDLoc dl,
> -                              bool isTailCall, bool isVarArg,
> +                              bool isTailCall, bool isVarArg, bool IsPatchPoint,
>                                SelectionDAG &DAG,
>                                SmallVector<std::pair<unsigned, SDValue>, 8>
>                                  &RegsToPass,
> @@ -3860,8 +3872,8 @@ PPCTargetLowering::FinishCall(CallingCon
>    std::vector<EVT> NodeTys;
>    SmallVector<SDValue, 8> Ops;
>    unsigned CallOpc = PrepareCall(DAG, Callee, InFlag, Chain, dl, SPDiff,
> -                                 isTailCall, RegsToPass, Ops, NodeTys,
> -                                 Subtarget);
> +                                 isTailCall, IsPatchPoint, RegsToPass, Ops,
> +                                 NodeTys, Subtarget);
> 
>    // Add implicit use of CR bit 6 for 32-bit SVR4 vararg calls
>    if (isVarArg && Subtarget.isSVR4ABI() && !Subtarget.isPPC64())
> @@ -3905,7 +3917,8 @@ PPCTargetLowering::FinishCall(CallingCon
>    // stack frame. If caller and callee belong to the same module (and have the
>    // same TOC), the NOP will remain unchanged.
> 
> -  if (!isTailCall && Subtarget.isSVR4ABI()&& Subtarget.isPPC64()) {
> +  if (!isTailCall && Subtarget.isSVR4ABI()&& Subtarget.isPPC64() &&
> +      !IsPatchPoint) {
>      if (CallOpc == PPCISD::BCTRL) {
>        // This is a call through a function pointer.
>        // Restore the caller TOC from the save area into R2.
> @@ -3963,6 +3976,7 @@ PPCTargetLowering::LowerCall(TargetLower
>    bool &isTailCall                      = CLI.IsTailCall;
>    CallingConv::ID CallConv              = CLI.CallConv;
>    bool isVarArg                         = CLI.IsVarArg;
> +  bool IsPatchPoint                     = CLI.IsPatchPoint;
> 
>    if (isTailCall)
>      isTailCall = IsEligibleForTailCallOptimization(Callee, CallConv, isVarArg,
> @@ -3975,23 +3989,23 @@ PPCTargetLowering::LowerCall(TargetLower
>    if (Subtarget.isSVR4ABI()) {
>      if (Subtarget.isPPC64())
>        return LowerCall_64SVR4(Chain, Callee, CallConv, isVarArg,
> -                              isTailCall, Outs, OutVals, Ins,
> +                              isTailCall, IsPatchPoint, Outs, OutVals, Ins,
>                                dl, DAG, InVals);
>      else
>        return LowerCall_32SVR4(Chain, Callee, CallConv, isVarArg,
> -                              isTailCall, Outs, OutVals, Ins,
> +                              isTailCall, IsPatchPoint, Outs, OutVals, Ins,
>                                dl, DAG, InVals);
>    }
> 
>    return LowerCall_Darwin(Chain, Callee, CallConv, isVarArg,
> -                          isTailCall, Outs, OutVals, Ins,
> +                          isTailCall, IsPatchPoint, Outs, OutVals, Ins,
>                            dl, DAG, InVals);
>  }
> 
>  SDValue
>  PPCTargetLowering::LowerCall_32SVR4(SDValue Chain, SDValue Callee,
>                                      CallingConv::ID CallConv, bool isVarArg,
> -                                    bool isTailCall,
> +                                    bool isTailCall, bool IsPatchPoint,
>                                      const SmallVectorImpl<ISD::OutputArg> &Outs,
>                                      const SmallVectorImpl<SDValue> &OutVals,
>                                      const SmallVectorImpl<ISD::InputArg> &Ins,
> @@ -4201,7 +4215,7 @@ PPCTargetLowering::LowerCall_32SVR4(SDVa
>      PrepareTailCall(DAG, InFlag, Chain, dl, false, SPDiff, NumBytes, LROp, FPOp,
>                      false, TailCallArguments);
> 
> -  return FinishCall(CallConv, dl, isTailCall, isVarArg, DAG,
> +  return FinishCall(CallConv, dl, isTailCall, isVarArg, IsPatchPoint, DAG,
>                      RegsToPass, InFlag, Chain, Callee, SPDiff, NumBytes,
>                      Ins, InVals);
>  }
> @@ -4229,7 +4243,7 @@ PPCTargetLowering::createMemcpyOutsideCa
>  SDValue
>  PPCTargetLowering::LowerCall_64SVR4(SDValue Chain, SDValue Callee,
>                                      CallingConv::ID CallConv, bool isVarArg,
> -                                    bool isTailCall,
> +                                    bool isTailCall, bool IsPatchPoint,
>                                      const SmallVectorImpl<ISD::OutputArg> &Outs,
>                                      const SmallVectorImpl<SDValue> &OutVals,
>                                      const SmallVectorImpl<ISD::InputArg> &Ins,
> @@ -4665,7 +4679,7 @@ PPCTargetLowering::LowerCall_64SVR4(SDVa
>    // Check if this is an indirect call (MTCTR/BCTRL).
>    // See PrepareCall() for more information about calls through function
>    // pointers in the 64-bit SVR4 ABI.
> -  if (!isTailCall &&
> +  if (!isTailCall && !IsPatchPoint &&
>        !isFunctionGlobalAddress(Callee) &&
>        !isa<ExternalSymbolSDNode>(Callee)) {
>      // Load r2 into a virtual register and store it to the TOC save area.
> @@ -4679,7 +4693,7 @@ PPCTargetLowering::LowerCall_64SVR4(SDVa
>      // In the ELFv2 ABI, R12 must contain the address of an indirect callee.
>      // This does not mean the MTCTR instruction must use R12; it's easier
>      // to model this as an extra parameter, so do that.
> -    if (isELFv2ABI)
> +    if (isELFv2ABI && !IsPatchPoint)
>        RegsToPass.push_back(std::make_pair((unsigned)PPC::X12, Callee));
>    }
> 
> @@ -4696,7 +4710,7 @@ PPCTargetLowering::LowerCall_64SVR4(SDVa
>      PrepareTailCall(DAG, InFlag, Chain, dl, true, SPDiff, NumBytes, LROp,
>                      FPOp, true, TailCallArguments);
> 
> -  return FinishCall(CallConv, dl, isTailCall, isVarArg, DAG,
> +  return FinishCall(CallConv, dl, isTailCall, isVarArg, IsPatchPoint, DAG,
>                      RegsToPass, InFlag, Chain, Callee, SPDiff, NumBytes,
>                      Ins, InVals);
>  }
> @@ -4704,7 +4718,7 @@ PPCTargetLowering::LowerCall_64SVR4(SDVa
>  SDValue
>  PPCTargetLowering::LowerCall_Darwin(SDValue Chain, SDValue Callee,
>                                      CallingConv::ID CallConv, bool isVarArg,
> -                                    bool isTailCall,
> +                                    bool isTailCall, bool IsPatchPoint,
>                                      const SmallVectorImpl<ISD::OutputArg> &Outs,
>                                      const SmallVectorImpl<SDValue> &OutVals,
>                                      const SmallVectorImpl<ISD::InputArg> &Ins,
> @@ -5089,7 +5103,7 @@ PPCTargetLowering::LowerCall_Darwin(SDVa
>      PrepareTailCall(DAG, InFlag, Chain, dl, isPPC64, SPDiff, NumBytes, LROp,
>                      FPOp, true, TailCallArguments);
> 
> -  return FinishCall(CallConv, dl, isTailCall, isVarArg, DAG,
> +  return FinishCall(CallConv, dl, isTailCall, isVarArg, IsPatchPoint, DAG,
>                      RegsToPass, InFlag, Chain, Callee, SPDiff, NumBytes,
>                      Ins, InVals);
>  }
> @@ -7246,6 +7260,10 @@ PPCTargetLowering::emitEHSjLjLongJmp(Mac
>  MachineBasicBlock *
>  PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
>                                                 MachineBasicBlock *BB) const {
> +  if (MI->getOpcode() == TargetOpcode::STACKMAP ||
> +      MI->getOpcode() == TargetOpcode::PATCHPOINT)
> +    return emitPatchPoint(MI, BB);
> +
>    if (MI->getOpcode() == PPC::EH_SjLj_SetJmp32 ||
>        MI->getOpcode() == PPC::EH_SjLj_SetJmp64) {
>      return emitEHSjLjSetJmp(MI, BB);
> @@ -9882,6 +9900,19 @@ bool PPCTargetLowering::isFMAFasterThanF
>    return false;
>  }
> 
> +const MCPhysReg *
> +PPCTargetLowering::getScratchRegisters(CallingConv::ID) const {
> +  // LR is a callee-save register, but we must treat it as clobbered by any call
> +  // site. Hence we include LR in the scratch registers, which are in turn added
> +  // as implicit-defs for stackmaps and patchpoints. The same reasoning applies
> +  // to CTR, which is used by any indirect call.
> +  static const MCPhysReg ScratchRegs[] = {
> +    PPC::X11, PPC::X12, PPC::LR8, PPC::CTR8, 0
> +  };
> +
> +  return ScratchRegs;
> +}

It isn't safe to assume PPC::X11 is clobbered at an indirect call site
under the ELFv2 ABI.  The rest of these are ok for both ABIs.

> +
>  bool
>  PPCTargetLowering::shouldExpandBuildVectorWithShuffles(
>                       EVT VT , unsigned DefinedValues) const {
> 





More information about the llvm-commits mailing list