[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