1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00

DAG: propagate whether an arg is a pointer for CallingConv decisions.

The arm64_32 ABI specifies that pointers (despite being 32-bits) should be
zero-extended to 64-bits when passed in registers for efficiency reasons. This
means that the SelectionDAG needs to be able to tell the backend that an
argument was originally a pointer, which is implmented here.

Additionally, some memory intrinsics need to be declared as taking an i8*
instead of an iPTR.

There should be no CodeGen change yet, but it will be triggered when AArch64
backend support for ILP32 is added.

llvm-svn: 358398
This commit is contained in:
Tim Northover 2019-04-15 12:03:54 +00:00
parent ddef9d89d4
commit 606d5bbe91
4 changed files with 52 additions and 8 deletions

View File

@ -45,9 +45,12 @@ namespace ISD {
unsigned IsInConsecutiveRegsLast : 1; unsigned IsInConsecutiveRegsLast : 1;
unsigned IsInConsecutiveRegs : 1; unsigned IsInConsecutiveRegs : 1;
unsigned IsCopyElisionCandidate : 1; ///< Argument copy elision candidate unsigned IsCopyElisionCandidate : 1; ///< Argument copy elision candidate
unsigned IsPointer : 1;
unsigned ByValSize; ///< Byval struct size unsigned ByValSize; ///< Byval struct size
unsigned PointerAddrSpace; ///< Address space of pointer argument
public: public:
ArgFlagsTy() ArgFlagsTy()
: IsZExt(0), IsSExt(0), IsInReg(0), IsSRet(0), IsByVal(0), IsNest(0), : IsZExt(0), IsSExt(0), IsInReg(0), IsSRet(0), IsByVal(0), IsNest(0),
@ -55,8 +58,9 @@ namespace ISD {
IsSwiftSelf(0), IsSwiftError(0), IsHva(0), IsHvaStart(0), IsSwiftSelf(0), IsSwiftError(0), IsHva(0), IsHvaStart(0),
IsSecArgPass(0), ByValAlign(0), OrigAlign(0), IsSecArgPass(0), ByValAlign(0), OrigAlign(0),
IsInConsecutiveRegsLast(0), IsInConsecutiveRegs(0), IsInConsecutiveRegsLast(0), IsInConsecutiveRegs(0),
IsCopyElisionCandidate(0), ByValSize(0) { IsCopyElisionCandidate(0), IsPointer(0), ByValSize(0),
static_assert(sizeof(*this) == 2 * sizeof(unsigned), "flags are too big"); PointerAddrSpace(0) {
static_assert(sizeof(*this) == 3 * sizeof(unsigned), "flags are too big");
} }
bool isZExt() const { return IsZExt; } bool isZExt() const { return IsZExt; }
@ -113,6 +117,9 @@ namespace ISD {
bool isCopyElisionCandidate() const { return IsCopyElisionCandidate; } bool isCopyElisionCandidate() const { return IsCopyElisionCandidate; }
void setCopyElisionCandidate() { IsCopyElisionCandidate = 1; } void setCopyElisionCandidate() { IsCopyElisionCandidate = 1; }
bool isPointer() const { return IsPointer; }
void setPointer() { IsPointer = 1; }
unsigned getByValAlign() const { return (1U << ByValAlign) / 2; } unsigned getByValAlign() const { return (1U << ByValAlign) / 2; }
void setByValAlign(unsigned A) { void setByValAlign(unsigned A) {
ByValAlign = Log2_32(A) + 1; ByValAlign = Log2_32(A) + 1;
@ -127,7 +134,10 @@ namespace ISD {
unsigned getByValSize() const { return ByValSize; } unsigned getByValSize() const { return ByValSize; }
void setByValSize(unsigned S) { ByValSize = S; } void setByValSize(unsigned S) { ByValSize = S; }
};
unsigned getPointerAddrSpace() const { return PointerAddrSpace; }
void setPointerAddrSpace(unsigned AS) { PointerAddrSpace = AS; }
};
/// InputArg - This struct carries flags and type information about a /// InputArg - This struct carries flags and type information about a
/// single incoming (formal) argument or incoming (from the perspective /// single incoming (formal) argument or incoming (from the perspective

View File

@ -82,6 +82,15 @@ class CCIfVarArg<CCAction A> : CCIf<"State.isVarArg()", A> {}
/// CCIfNotVarArg - If the current function is not vararg - apply the action /// CCIfNotVarArg - If the current function is not vararg - apply the action
class CCIfNotVarArg<CCAction A> : CCIf<"!State.isVarArg()", A> {} class CCIfNotVarArg<CCAction A> : CCIf<"!State.isVarArg()", A> {}
/// CCIfPtrAddrSpace - If the top-level parent of the current argument has
/// pointer type in the specified address-space.
class CCIfPtrAddrSpace<int AS, CCAction A>
: CCIf<"(ArgFlags.isPointer() && ArgFlags.getPointerAddrSpace() == " # AS # ")", A> {}
/// CCIfPtr - If the top-level parent of the current argument had
/// pointer type in some address-space.
class CCIfPtr<CCAction A> : CCIf<"ArgFlags.isPointer()", A> {}
/// CCAssignToReg - This action matches if there is a register in the specified /// CCAssignToReg - This action matches if there is a register in the specified
/// list that is still available. If so, it assigns the value to the first /// list that is still available. If so, it assigns the value to the first
/// available register and succeeds. /// available register and succeeds.

View File

@ -6093,9 +6093,11 @@ SDValue SelectionDAG::getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst,
// Emit a library call. // Emit a library call.
TargetLowering::ArgListTy Args; TargetLowering::ArgListTy Args;
TargetLowering::ArgListEntry Entry; TargetLowering::ArgListEntry Entry;
Entry.Ty = getDataLayout().getIntPtrType(*getContext()); Entry.Ty = Type::getInt8PtrTy(*getContext());
Entry.Node = Dst; Args.push_back(Entry); Entry.Node = Dst; Args.push_back(Entry);
Entry.Node = Src; Args.push_back(Entry); Entry.Node = Src; Args.push_back(Entry);
Entry.Ty = getDataLayout().getIntPtrType(*getContext());
Entry.Node = Size; Args.push_back(Entry); Entry.Node = Size; Args.push_back(Entry);
// FIXME: pass in SDLoc // FIXME: pass in SDLoc
TargetLowering::CallLoweringInfo CLI(*this); TargetLowering::CallLoweringInfo CLI(*this);
@ -6195,9 +6197,11 @@ SDValue SelectionDAG::getMemmove(SDValue Chain, const SDLoc &dl, SDValue Dst,
// Emit a library call. // Emit a library call.
TargetLowering::ArgListTy Args; TargetLowering::ArgListTy Args;
TargetLowering::ArgListEntry Entry; TargetLowering::ArgListEntry Entry;
Entry.Ty = getDataLayout().getIntPtrType(*getContext()); Entry.Ty = Type::getInt8PtrTy(*getContext());
Entry.Node = Dst; Args.push_back(Entry); Entry.Node = Dst; Args.push_back(Entry);
Entry.Node = Src; Args.push_back(Entry); Entry.Node = Src; Args.push_back(Entry);
Entry.Ty = getDataLayout().getIntPtrType(*getContext());
Entry.Node = Size; Args.push_back(Entry); Entry.Node = Size; Args.push_back(Entry);
// FIXME: pass in SDLoc // FIXME: pass in SDLoc
TargetLowering::CallLoweringInfo CLI(*this); TargetLowering::CallLoweringInfo CLI(*this);
@ -6290,16 +6294,15 @@ SDValue SelectionDAG::getMemset(SDValue Chain, const SDLoc &dl, SDValue Dst,
checkAddrSpaceIsValidForLibcall(TLI, DstPtrInfo.getAddrSpace()); checkAddrSpaceIsValidForLibcall(TLI, DstPtrInfo.getAddrSpace());
// Emit a library call. // Emit a library call.
Type *IntPtrTy = getDataLayout().getIntPtrType(*getContext());
TargetLowering::ArgListTy Args; TargetLowering::ArgListTy Args;
TargetLowering::ArgListEntry Entry; TargetLowering::ArgListEntry Entry;
Entry.Node = Dst; Entry.Ty = IntPtrTy; Entry.Node = Dst; Entry.Ty = Type::getInt8PtrTy(*getContext());
Args.push_back(Entry); Args.push_back(Entry);
Entry.Node = Src; Entry.Node = Src;
Entry.Ty = Src.getValueType().getTypeForEVT(*getContext()); Entry.Ty = Src.getValueType().getTypeForEVT(*getContext());
Args.push_back(Entry); Args.push_back(Entry);
Entry.Node = Size; Entry.Node = Size;
Entry.Ty = IntPtrTy; Entry.Ty = getDataLayout().getIntPtrType(*getContext());
Args.push_back(Entry); Args.push_back(Entry);
// FIXME: pass in SDLoc // FIXME: pass in SDLoc

View File

@ -1846,6 +1846,12 @@ void SelectionDAGBuilder::visitRet(const ReturnInst &I) {
if (RetInReg) if (RetInReg)
Flags.setInReg(); Flags.setInReg();
if (I.getOperand(0)->getType()->isPointerTy()) {
Flags.setPointer();
Flags.setPointerAddrSpace(
cast<PointerType>(I.getOperand(0)->getType())->getAddressSpace());
}
// Propagate extension type if any // Propagate extension type if any
if (ExtendKind == ISD::SIGN_EXTEND) if (ExtendKind == ISD::SIGN_EXTEND)
Flags.setSExt(); Flags.setSExt();
@ -8834,9 +8840,15 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
CLI.CallConv, VT); CLI.CallConv, VT);
for (unsigned i = 0; i != NumRegs; ++i) { for (unsigned i = 0; i != NumRegs; ++i) {
ISD::InputArg MyFlags; ISD::InputArg MyFlags;
MyFlags.Flags = Flags;
MyFlags.VT = RegisterVT; MyFlags.VT = RegisterVT;
MyFlags.ArgVT = VT; MyFlags.ArgVT = VT;
MyFlags.Used = CLI.IsReturnValueUsed; MyFlags.Used = CLI.IsReturnValueUsed;
if (CLI.RetTy->isPointerTy()) {
MyFlags.Flags.setPointer();
MyFlags.Flags.setPointerAddrSpace(
cast<PointerType>(CLI.RetTy)->getAddressSpace());
}
if (CLI.RetSExt) if (CLI.RetSExt)
MyFlags.Flags.setSExt(); MyFlags.Flags.setSExt();
if (CLI.RetZExt) if (CLI.RetZExt)
@ -8887,6 +8899,11 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
// specify the alignment it wants. // specify the alignment it wants.
unsigned OriginalAlignment = getABIAlignmentForCallingConv(ArgTy, DL); unsigned OriginalAlignment = getABIAlignmentForCallingConv(ArgTy, DL);
if (Args[i].Ty->isPointerTy()) {
Flags.setPointer();
Flags.setPointerAddrSpace(
cast<PointerType>(Args[i].Ty)->getAddressSpace());
}
if (Args[i].IsZExt) if (Args[i].IsZExt)
Flags.setZExt(); Flags.setZExt();
if (Args[i].IsSExt) if (Args[i].IsSExt)
@ -9375,6 +9392,11 @@ void SelectionDAGISel::LowerArguments(const Function &F) {
unsigned OriginalAlignment = unsigned OriginalAlignment =
TLI->getABIAlignmentForCallingConv(ArgTy, DL); TLI->getABIAlignmentForCallingConv(ArgTy, DL);
if (Arg.getType()->isPointerTy()) {
Flags.setPointer();
Flags.setPointerAddrSpace(
cast<PointerType>(Arg.getType())->getAddressSpace());
}
if (Arg.hasAttribute(Attribute::ZExt)) if (Arg.hasAttribute(Attribute::ZExt))
Flags.setZExt(); Flags.setZExt();
if (Arg.hasAttribute(Attribute::SExt)) if (Arg.hasAttribute(Attribute::SExt))