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

Hal Finkel hfinkel at anl.gov
Thu Jan 15 09:42:36 PST 2015


----- Original Message -----
> From: "Bill Schmidt" <wschmidt at linux.vnet.ibm.com>
> To: "Hal Finkel" <hfinkel at anl.gov>
> Cc: llvm-commits at cs.uiuc.edu
> Sent: Thursday, January 15, 2015 9:46:05 AM
> Subject: Re: [llvm] r225909 - Revert "r225811 - Revert "r225808 - [PowerPC] Add StackMap/PatchPoint support""
> 
> Hi Hal,
> 
> A couple of comments below:

Thanks!

> 
> 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.

Good point.

> 
> > +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.

It will be an error either way, so I think it is fine.

> 
> >    // 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.

Because that's now handled by the common code that calls this function.

> 
> > +    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.

Okay, thanks. I'll update it.

 -Hal

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

-- 
Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory



More information about the llvm-commits mailing list