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:
parent
ddef9d89d4
commit
606d5bbe91
@ -45,9 +45,12 @@ namespace ISD {
|
||||
unsigned IsInConsecutiveRegsLast : 1;
|
||||
unsigned IsInConsecutiveRegs : 1;
|
||||
unsigned IsCopyElisionCandidate : 1; ///< Argument copy elision candidate
|
||||
unsigned IsPointer : 1;
|
||||
|
||||
unsigned ByValSize; ///< Byval struct size
|
||||
|
||||
unsigned PointerAddrSpace; ///< Address space of pointer argument
|
||||
|
||||
public:
|
||||
ArgFlagsTy()
|
||||
: 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),
|
||||
IsSecArgPass(0), ByValAlign(0), OrigAlign(0),
|
||||
IsInConsecutiveRegsLast(0), IsInConsecutiveRegs(0),
|
||||
IsCopyElisionCandidate(0), ByValSize(0) {
|
||||
static_assert(sizeof(*this) == 2 * sizeof(unsigned), "flags are too big");
|
||||
IsCopyElisionCandidate(0), IsPointer(0), ByValSize(0),
|
||||
PointerAddrSpace(0) {
|
||||
static_assert(sizeof(*this) == 3 * sizeof(unsigned), "flags are too big");
|
||||
}
|
||||
|
||||
bool isZExt() const { return IsZExt; }
|
||||
@ -113,6 +117,9 @@ namespace ISD {
|
||||
bool isCopyElisionCandidate() const { return IsCopyElisionCandidate; }
|
||||
void setCopyElisionCandidate() { IsCopyElisionCandidate = 1; }
|
||||
|
||||
bool isPointer() const { return IsPointer; }
|
||||
void setPointer() { IsPointer = 1; }
|
||||
|
||||
unsigned getByValAlign() const { return (1U << ByValAlign) / 2; }
|
||||
void setByValAlign(unsigned A) {
|
||||
ByValAlign = Log2_32(A) + 1;
|
||||
@ -127,7 +134,10 @@ namespace ISD {
|
||||
|
||||
unsigned getByValSize() const { return ByValSize; }
|
||||
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
|
||||
/// single incoming (formal) argument or incoming (from the perspective
|
||||
|
@ -82,6 +82,15 @@ class CCIfVarArg<CCAction A> : CCIf<"State.isVarArg()", A> {}
|
||||
/// CCIfNotVarArg - If the current function is not vararg - apply the action
|
||||
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
|
||||
/// list that is still available. If so, it assigns the value to the first
|
||||
/// available register and succeeds.
|
||||
|
@ -6093,9 +6093,11 @@ SDValue SelectionDAG::getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst,
|
||||
// Emit a library call.
|
||||
TargetLowering::ArgListTy Args;
|
||||
TargetLowering::ArgListEntry Entry;
|
||||
Entry.Ty = getDataLayout().getIntPtrType(*getContext());
|
||||
Entry.Ty = Type::getInt8PtrTy(*getContext());
|
||||
Entry.Node = Dst; Args.push_back(Entry);
|
||||
Entry.Node = Src; Args.push_back(Entry);
|
||||
|
||||
Entry.Ty = getDataLayout().getIntPtrType(*getContext());
|
||||
Entry.Node = Size; Args.push_back(Entry);
|
||||
// FIXME: pass in SDLoc
|
||||
TargetLowering::CallLoweringInfo CLI(*this);
|
||||
@ -6195,9 +6197,11 @@ SDValue SelectionDAG::getMemmove(SDValue Chain, const SDLoc &dl, SDValue Dst,
|
||||
// Emit a library call.
|
||||
TargetLowering::ArgListTy Args;
|
||||
TargetLowering::ArgListEntry Entry;
|
||||
Entry.Ty = getDataLayout().getIntPtrType(*getContext());
|
||||
Entry.Ty = Type::getInt8PtrTy(*getContext());
|
||||
Entry.Node = Dst; Args.push_back(Entry);
|
||||
Entry.Node = Src; Args.push_back(Entry);
|
||||
|
||||
Entry.Ty = getDataLayout().getIntPtrType(*getContext());
|
||||
Entry.Node = Size; Args.push_back(Entry);
|
||||
// FIXME: pass in SDLoc
|
||||
TargetLowering::CallLoweringInfo CLI(*this);
|
||||
@ -6290,16 +6294,15 @@ SDValue SelectionDAG::getMemset(SDValue Chain, const SDLoc &dl, SDValue Dst,
|
||||
checkAddrSpaceIsValidForLibcall(TLI, DstPtrInfo.getAddrSpace());
|
||||
|
||||
// Emit a library call.
|
||||
Type *IntPtrTy = getDataLayout().getIntPtrType(*getContext());
|
||||
TargetLowering::ArgListTy Args;
|
||||
TargetLowering::ArgListEntry Entry;
|
||||
Entry.Node = Dst; Entry.Ty = IntPtrTy;
|
||||
Entry.Node = Dst; Entry.Ty = Type::getInt8PtrTy(*getContext());
|
||||
Args.push_back(Entry);
|
||||
Entry.Node = Src;
|
||||
Entry.Ty = Src.getValueType().getTypeForEVT(*getContext());
|
||||
Args.push_back(Entry);
|
||||
Entry.Node = Size;
|
||||
Entry.Ty = IntPtrTy;
|
||||
Entry.Ty = getDataLayout().getIntPtrType(*getContext());
|
||||
Args.push_back(Entry);
|
||||
|
||||
// FIXME: pass in SDLoc
|
||||
|
@ -1846,6 +1846,12 @@ void SelectionDAGBuilder::visitRet(const ReturnInst &I) {
|
||||
if (RetInReg)
|
||||
Flags.setInReg();
|
||||
|
||||
if (I.getOperand(0)->getType()->isPointerTy()) {
|
||||
Flags.setPointer();
|
||||
Flags.setPointerAddrSpace(
|
||||
cast<PointerType>(I.getOperand(0)->getType())->getAddressSpace());
|
||||
}
|
||||
|
||||
// Propagate extension type if any
|
||||
if (ExtendKind == ISD::SIGN_EXTEND)
|
||||
Flags.setSExt();
|
||||
@ -8834,9 +8840,15 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
|
||||
CLI.CallConv, VT);
|
||||
for (unsigned i = 0; i != NumRegs; ++i) {
|
||||
ISD::InputArg MyFlags;
|
||||
MyFlags.Flags = Flags;
|
||||
MyFlags.VT = RegisterVT;
|
||||
MyFlags.ArgVT = VT;
|
||||
MyFlags.Used = CLI.IsReturnValueUsed;
|
||||
if (CLI.RetTy->isPointerTy()) {
|
||||
MyFlags.Flags.setPointer();
|
||||
MyFlags.Flags.setPointerAddrSpace(
|
||||
cast<PointerType>(CLI.RetTy)->getAddressSpace());
|
||||
}
|
||||
if (CLI.RetSExt)
|
||||
MyFlags.Flags.setSExt();
|
||||
if (CLI.RetZExt)
|
||||
@ -8887,6 +8899,11 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
|
||||
// specify the alignment it wants.
|
||||
unsigned OriginalAlignment = getABIAlignmentForCallingConv(ArgTy, DL);
|
||||
|
||||
if (Args[i].Ty->isPointerTy()) {
|
||||
Flags.setPointer();
|
||||
Flags.setPointerAddrSpace(
|
||||
cast<PointerType>(Args[i].Ty)->getAddressSpace());
|
||||
}
|
||||
if (Args[i].IsZExt)
|
||||
Flags.setZExt();
|
||||
if (Args[i].IsSExt)
|
||||
@ -9375,6 +9392,11 @@ void SelectionDAGISel::LowerArguments(const Function &F) {
|
||||
unsigned OriginalAlignment =
|
||||
TLI->getABIAlignmentForCallingConv(ArgTy, DL);
|
||||
|
||||
if (Arg.getType()->isPointerTy()) {
|
||||
Flags.setPointer();
|
||||
Flags.setPointerAddrSpace(
|
||||
cast<PointerType>(Arg.getType())->getAddressSpace());
|
||||
}
|
||||
if (Arg.hasAttribute(Attribute::ZExt))
|
||||
Flags.setZExt();
|
||||
if (Arg.hasAttribute(Attribute::SExt))
|
||||
|
Loading…
Reference in New Issue
Block a user