forked from OSchip/llvm-project
OpaquePtr: Add helpers for sret to mirror byval
Sret should really have a type parameter like byval does.
This commit is contained in:
parent
8f72717ebe
commit
d65a7003c4
|
@ -83,8 +83,8 @@ public:
|
|||
/// in-memory ABI size copied to the stack for the call. Otherwise, return 0.
|
||||
uint64_t getPassPointeeByValueCopySize(const DataLayout &DL) const;
|
||||
|
||||
/// Return true if this argument has the byval, inalloca, preallocated, or
|
||||
/// byref attribute. These attributes represent arguments being passed by
|
||||
/// Return true if this argument has the byval, sret, inalloca, preallocated,
|
||||
/// or byref attribute. These attributes represent arguments being passed by
|
||||
/// value (which may or may not involve a stack copy)
|
||||
bool hasPointeeInMemoryValueAttr() const;
|
||||
|
||||
|
@ -103,6 +103,9 @@ public:
|
|||
/// If this is a byval argument, return its type.
|
||||
Type *getParamByValType() const;
|
||||
|
||||
/// If this is an sret argument, return its type.
|
||||
Type *getParamStructRetType() const;
|
||||
|
||||
/// If this is a byref argument, return its type.
|
||||
Type *getParamByRefType() const;
|
||||
|
||||
|
|
|
@ -472,6 +472,12 @@ public:
|
|||
return Ty ? Ty : (arg_begin() + ArgNo)->getType()->getPointerElementType();
|
||||
}
|
||||
|
||||
/// Extract the sret type for a parameter.
|
||||
Type *getParamStructRetType(unsigned ArgNo) const {
|
||||
// FIXME: Add type to attribute like byval
|
||||
return (arg_begin() + ArgNo)->getType()->getPointerElementType();
|
||||
}
|
||||
|
||||
/// Extract the byref type for a parameter.
|
||||
Type *getParamByRefType(unsigned ArgNo) const {
|
||||
return AttributeSets.getParamByRefType(ArgNo);
|
||||
|
|
|
@ -250,7 +250,7 @@ void Lint::visitCallBase(CallBase &I) {
|
|||
|
||||
// Check that an sret argument points to valid memory.
|
||||
if (Formal->hasStructRetAttr() && Actual->getType()->isPointerTy()) {
|
||||
Type *Ty = cast<PointerType>(Formal->getType())->getElementType();
|
||||
Type *Ty = Formal->getParamStructRetType();
|
||||
visitMemoryReference(I, Actual, DL->getTypeStoreSize(Ty),
|
||||
DL->getABITypeAlign(Ty), Ty,
|
||||
MemRef::Read | MemRef::Write);
|
||||
|
|
|
@ -140,12 +140,13 @@ bool Argument::hasPointeeInMemoryValueAttr() const {
|
|||
return false;
|
||||
AttributeList Attrs = getParent()->getAttributes();
|
||||
return Attrs.hasParamAttribute(getArgNo(), Attribute::ByVal) ||
|
||||
Attrs.hasParamAttribute(getArgNo(), Attribute::StructRet) ||
|
||||
Attrs.hasParamAttribute(getArgNo(), Attribute::InAlloca) ||
|
||||
Attrs.hasParamAttribute(getArgNo(), Attribute::Preallocated) ||
|
||||
Attrs.hasParamAttribute(getArgNo(), Attribute::ByRef);
|
||||
}
|
||||
|
||||
/// For a byval, inalloca, or preallocated parameter, get the in-memory
|
||||
/// For a byval, sret, inalloca, or preallocated parameter, get the in-memory
|
||||
/// parameter type.
|
||||
static Type *getMemoryParamAllocType(AttributeSet ParamAttrs, Type *ArgTy) {
|
||||
// FIXME: All the type carrying attributes are mutually exclusive, so there
|
||||
|
@ -157,10 +158,11 @@ static Type *getMemoryParamAllocType(AttributeSet ParamAttrs, Type *ArgTy) {
|
|||
if (Type *PreAllocTy = ParamAttrs.getPreallocatedType())
|
||||
return PreAllocTy;
|
||||
|
||||
// FIXME: inalloca always depends on pointee element type. It's also possible
|
||||
// for byval to miss it.
|
||||
// FIXME: sret and inalloca always depends on pointee element type. It's also
|
||||
// possible for byval to miss it.
|
||||
if (ParamAttrs.hasAttribute(Attribute::InAlloca) ||
|
||||
ParamAttrs.hasAttribute(Attribute::ByVal) ||
|
||||
ParamAttrs.hasAttribute(Attribute::StructRet) ||
|
||||
ParamAttrs.hasAttribute(Attribute::Preallocated))
|
||||
return cast<PointerType>(ArgTy)->getElementType();
|
||||
|
||||
|
@ -196,6 +198,11 @@ Type *Argument::getParamByValType() const {
|
|||
return getParent()->getParamByValType(getArgNo());
|
||||
}
|
||||
|
||||
Type *Argument::getParamStructRetType() const {
|
||||
assert(getType()->isPointerTy() && "Only pointers have sret types");
|
||||
return getParent()->getParamStructRetType(getArgNo());
|
||||
}
|
||||
|
||||
Type *Argument::getParamByRefType() const {
|
||||
assert(getType()->isPointerTy() && "Only pointers have byval types");
|
||||
return getParent()->getParamByRefType(getArgNo());
|
||||
|
|
|
@ -804,7 +804,7 @@ Align Value::getPointerAlignment(const DataLayout &DL) const {
|
|||
const MaybeAlign Alignment = A->getParamAlign();
|
||||
if (!Alignment && A->hasStructRetAttr()) {
|
||||
// An sret parameter has at least the ABI alignment of the return type.
|
||||
Type *EltTy = cast<PointerType>(A->getType())->getElementType();
|
||||
Type *EltTy = A->getParamStructRetType();
|
||||
if (EltTy->isSized())
|
||||
return DL.getABITypeAlign(EltTy);
|
||||
}
|
||||
|
|
|
@ -813,7 +813,7 @@ bool MemCpyOptPass::performCallSlotOptzn(Instruction *cpy, Value *cpyDest,
|
|||
if (!A->hasStructRetAttr())
|
||||
return false;
|
||||
|
||||
Type *StructTy = cast<PointerType>(A->getType())->getElementType();
|
||||
Type *StructTy = A->getParamStructRetType();
|
||||
if (!StructTy->isSized()) {
|
||||
// The call may never return and hence the copy-instruction may never
|
||||
// be executed, and therefore it's not safe to say "the destination
|
||||
|
|
|
@ -172,7 +172,8 @@ declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture r
|
|||
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture writeonly, i8* nocapture readonly, i32, i1)
|
||||
|
||||
define x86_vectorcallcc void @test_mixed_7(%struct.HVA5* noalias sret %agg.result) {
|
||||
; CHECK-LABEL: test_mixed_7
|
||||
; X86-LABEL: test_mixed_7@@4
|
||||
; X64-LABEL: test_mixed_7@@8
|
||||
; X64: mov{{[ql]}} %rcx, %rax
|
||||
; CHECK: movaps %xmm{{[0-9]}}, 64(%{{rcx|eax}})
|
||||
; CHECK: movaps %xmm{{[0-9]}}, 48(%{{rcx|eax}})
|
||||
|
|
Loading…
Reference in New Issue