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

Hal Finkel hfinkel at anl.gov
Thu Jan 15 20:42:57 PST 2015


----- Original Message -----
> From: "Hal Finkel" <hfinkel at anl.gov>
> To: "Bill Schmidt" <wschmidt at linux.vnet.ibm.com>
> Cc: llvm-commits at cs.uiuc.edu
> Sent: Thursday, January 15, 2015 11:42:36 AM
> Subject: Re: [llvm] r225909 - Revert "r225811 - Revert "r225808 - [PowerPC]	Add StackMap/PatchPoint support""
> 
> ----- 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.

r226247.

 -Hal

> 
>  -Hal
> 
> > 
> > > +
> > >  bool
> > >  PPCTargetLowering::shouldExpandBuildVectorWithShuffles(
> > >                       EVT VT , unsigned DefinedValues) const {
> > > 
> > 
> > 
> > 
> 
> --
> Hal Finkel
> Assistant Computational Scientist
> Leadership Computing Facility
> Argonne National Laboratory
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> 

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



More information about the llvm-commits mailing list