IR: Rename Argument::hasPassPointeeByValueAttr to prepare for byref

When the byref attribute is added, there will need to be two similar
functions for the existing cases which have an associate value copy,
and byref which does not. Most, but not all of the existing uses will
use the existing version.

The associated size function added by D82679 also needs to
contextually differ, and will help eliminate a few places still
relying on pointee element types.
This commit is contained in:
Matt Arsenault 2020-06-29 15:13:32 -04:00
parent 0347039a6e
commit 023883a834
11 changed files with 14 additions and 13 deletions

View File

@ -146,7 +146,7 @@ inline bool IsPotentialRetainableObjPtr(const Value *Op) {
return false;
// Special arguments can not be a valid retainable object pointer.
if (const Argument *Arg = dyn_cast<Argument>(Op))
if (Arg->hasPassPointeeByValueAttr() || Arg->hasNestAttr() ||
if (Arg->hasPassPointeeByValueCopyAttr() || Arg->hasNestAttr() ||
Arg->hasStructRetAttr())
return false;
// Only consider values with pointer types.

View File

@ -72,8 +72,9 @@ public:
bool hasSwiftErrorAttr() const;
/// Return true if this argument has the byval, inalloca, or preallocated
/// attribute. These attributes represent arguments being passed by value.
bool hasPassPointeeByValueAttr() const;
/// attribute. These attributes represent arguments being passed by value,
/// with an associated copy between the caller and callee
bool hasPassPointeeByValueCopyAttr() const;
/// If this argument satisfies has hasPassPointeeByValueAttr, return the
/// in-memory ABI size copied to the stack for the call. Otherwise, return 0.

View File

@ -677,7 +677,7 @@ SizeOffsetType ObjectSizeOffsetVisitor::visitAllocaInst(AllocaInst &I) {
SizeOffsetType ObjectSizeOffsetVisitor::visitArgument(Argument &A) {
// No interprocedural analysis is done at the moment.
if (!A.hasPassPointeeByValueAttr()) {
if (!A.hasPassPointeeByValueCopyAttr()) {
++ObjectVisitorArgument;
return unknown();
}

View File

@ -2362,7 +2362,7 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth,
// A byval, inalloca may not be null in a non-default addres space. A
// nonnull argument is assumed never 0.
if (const Argument *A = dyn_cast<Argument>(V)) {
if (((A->hasPassPointeeByValueAttr() &&
if (((A->hasPassPointeeByValueCopyAttr() &&
!NullPointerIsDefined(A->getParent(), PtrTy->getAddressSpace())) ||
A->hasNonNullAttr()))
return true;

View File

@ -9571,7 +9571,7 @@ findArgumentCopyElisionCandidates(const DataLayout &DL,
// initializes the alloca. Don't elide copies from the same argument twice.
const Value *Val = SI->getValueOperand()->stripPointerCasts();
const auto *Arg = dyn_cast<Argument>(Val);
if (!Arg || Arg->hasPassPointeeByValueAttr() ||
if (!Arg || Arg->hasPassPointeeByValueCopyAttr() ||
Arg->getType()->isEmptyTy() ||
DL.getTypeStoreSize(Arg->getType()) !=
DL.getTypeAllocSize(AI->getAllocatedType()) ||

View File

@ -121,7 +121,7 @@ bool Argument::hasPreallocatedAttr() const {
return hasAttribute(Attribute::Preallocated);
}
bool Argument::hasPassPointeeByValueAttr() const {
bool Argument::hasPassPointeeByValueCopyAttr() const {
if (!getType()->isPointerTy()) return false;
AttributeList Attrs = getParent()->getAttributes();
return Attrs.hasParamAttribute(getArgNo(), Attribute::ByVal) ||

View File

@ -100,7 +100,7 @@ static void addByteCountSuffix(raw_ostream &OS, const Function *F,
for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
AI != AE; ++AI) {
// 'Dereference' type in case of byval or inalloca parameter attribute.
uint64_t AllocSize = AI->hasPassPointeeByValueAttr() ?
uint64_t AllocSize = AI->hasPassPointeeByValueCopyAttr() ?
AI->getPassPointeeByValueCopySize(DL) :
DL.getTypeAllocSize(AI->getType());

View File

@ -435,7 +435,7 @@ bool ARMCallLowering::lowerFormalArguments(
for (auto &Arg : F.args()) {
if (!isSupportedType(DL, TLI, Arg.getType()))
return false;
if (Arg.hasPassPointeeByValueAttr())
if (Arg.hasPassPointeeByValueCopyAttr())
return false;
}

View File

@ -289,7 +289,7 @@ bool DeadArgumentEliminationPass::RemoveDeadArgumentsFromCallers(Function &Fn) {
for (Argument &Arg : Fn.args()) {
if (!Arg.hasSwiftErrorAttr() && Arg.use_empty() &&
!Arg.hasPassPointeeByValueAttr()) {
!Arg.hasPassPointeeByValueCopyAttr()) {
if (Arg.isUsedByMetadata()) {
Arg.replaceAllUsesWith(UndefValue::get(Arg.getType()));
Changed = true;

View File

@ -848,7 +848,7 @@ static bool handleEndBlock(BasicBlock &BB, AliasAnalysis *AA,
// Treat byval or inalloca arguments the same, stores to them are dead at the
// end of the function.
for (Argument &AI : BB.getParent()->args())
if (AI.hasPassPointeeByValueAttr())
if (AI.hasPassPointeeByValueCopyAttr())
DeadStackObjects.insert(&AI);
const DataLayout &DL = BB.getModule()->getDataLayout();
@ -1563,7 +1563,7 @@ struct DSEState {
// Treat byval or inalloca arguments the same as Allocas, stores to them are
// dead at the end of the function.
for (Argument &AI : F.args())
if (AI.hasPassPointeeByValueAttr()) {
if (AI.hasPassPointeeByValueCopyAttr()) {
// For byval, the caller doesn't know the address of the allocation.
if (AI.hasByValAttr())
State.InvisibleToCallerBeforeRet.insert(&AI);

View File

@ -1245,7 +1245,7 @@ static void AddAlignmentAssumptions(CallBase &CB, InlineFunctionInfo &IFI) {
Function *CalledFunc = CB.getCalledFunction();
for (Argument &Arg : CalledFunc->args()) {
unsigned Align = Arg.getType()->isPointerTy() ? Arg.getParamAlignment() : 0;
if (Align && !Arg.hasPassPointeeByValueAttr() && !Arg.hasNUses(0)) {
if (Align && !Arg.hasPassPointeeByValueCopyAttr() && !Arg.hasNUses(0)) {
if (!DTCalculated) {
DT.recalculate(*CB.getCaller());
DTCalculated = true;