[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