mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Fix several incorrect uses of ApplySite::getArgumentConvention.
At least most of these were latent bugs since the code was unreachable in the PartialApply case. But that's no excuse to misuse the API. Also, whenever referring to an integer index, be explicit about whether it is an applied argument or callee argument.
This commit is contained in:
@@ -1936,11 +1936,6 @@ public:
|
||||
return OperandValueArrayRef(opsWithoutSelf);
|
||||
}
|
||||
|
||||
/// Return the SILArgumentConvention for the given applied argument index.
|
||||
SILArgumentConvention getArgumentConvention(unsigned index) const {
|
||||
return getSubstCalleeConv().getSILArgumentConvention(index);
|
||||
}
|
||||
|
||||
Optional<SILResultInfo> getSingleResult() const {
|
||||
auto SubstCallee = getSubstCalleeType();
|
||||
if (SubstCallee->getNumAllResults() != 1)
|
||||
@@ -7665,7 +7660,7 @@ public:
|
||||
}
|
||||
|
||||
/// Return the applied argument index for the given operand.
|
||||
unsigned getArgumentIndex(const Operand &oper) const {
|
||||
unsigned getAppliedArgIndex(const Operand &oper) const {
|
||||
assert(oper.getUser() == Inst);
|
||||
assert(isArgumentOperand(oper));
|
||||
|
||||
@@ -7704,21 +7699,16 @@ public:
|
||||
/// Note: Passing an applied argument index into SILFunctionConvention, as
|
||||
/// opposed to a function argument index, is incorrect.
|
||||
unsigned getCalleeArgIndex(const Operand &oper) const {
|
||||
return getCalleeArgIndexOfFirstAppliedArg() + getArgumentIndex(oper);
|
||||
return getCalleeArgIndexOfFirstAppliedArg() + getAppliedArgIndex(oper);
|
||||
}
|
||||
|
||||
/// Return the SILArgumentConvention for the given applied argument operand.
|
||||
SILArgumentConvention getArgumentConvention(Operand &oper) const {
|
||||
unsigned calleeArgIdx =
|
||||
getCalleeArgIndexOfFirstAppliedArg() + getArgumentIndex(oper);
|
||||
getCalleeArgIndexOfFirstAppliedArg() + getAppliedArgIndex(oper);
|
||||
return getSubstCalleeConv().getSILArgumentConvention(calleeArgIdx);
|
||||
}
|
||||
|
||||
// FIXME: This is incorrect. It will be removed in the next commit.
|
||||
SILArgumentConvention getArgumentConvention(unsigned index) const {
|
||||
return getSubstCalleeConv().getSILArgumentConvention(index);
|
||||
}
|
||||
|
||||
/// Return true if 'self' is an applied argument.
|
||||
bool hasSelfArgument() const {
|
||||
switch (Inst->getKind()) {
|
||||
|
||||
@@ -2713,7 +2713,7 @@ public:
|
||||
auto isConsumingOrMutatingApplyUse = [](Operand *use) -> bool {
|
||||
ApplySite apply(use->getUser());
|
||||
assert(apply && "Not an apply instruction kind");
|
||||
auto conv = apply.getArgumentConvention(use->getOperandNumber() - 1);
|
||||
auto conv = apply.getArgumentConvention(*use);
|
||||
switch (conv) {
|
||||
case SILArgumentConvention::Indirect_In_Guaranteed:
|
||||
return false;
|
||||
|
||||
@@ -339,8 +339,7 @@ static SILInstruction *getOnlyDestroy(CopyBlockWithoutEscapingInst *CB) {
|
||||
|
||||
// If this an apply use, only handle unowned parameters.
|
||||
if (auto Apply = FullApplySite::isa(Inst)) {
|
||||
SILArgumentConvention Conv =
|
||||
Apply.getArgumentConvention(Apply.getCalleeArgIndex(*Use));
|
||||
SILArgumentConvention Conv = Apply.getArgumentConvention(*Use);
|
||||
if (Conv != SILArgumentConvention::Direct_Unowned)
|
||||
return nullptr;
|
||||
continue;
|
||||
|
||||
@@ -877,11 +877,8 @@ static void checkForViolationsAtInstruction(SILInstruction &I,
|
||||
// SILVerifier to better pinpoint the offending pass.
|
||||
if (auto *PAI = dyn_cast<PartialApplyInst>(&I)) {
|
||||
ApplySite apply(PAI);
|
||||
if (llvm::any_of(range(apply.getNumArguments()),
|
||||
[apply](unsigned argIdx) {
|
||||
unsigned calleeIdx =
|
||||
apply.getCalleeArgIndexOfFirstAppliedArg() + argIdx;
|
||||
return apply.getArgumentConvention(calleeIdx)
|
||||
if (llvm::any_of(apply.getArgumentOperands(), [apply](Operand &oper) {
|
||||
return apply.getArgumentConvention(oper)
|
||||
== SILArgumentConvention::Indirect_InoutAliasable;
|
||||
})) {
|
||||
checkNoEscapePartialApply(PAI);
|
||||
@@ -1071,8 +1068,7 @@ static void checkAccessedAddress(Operand *memOper, StorageMap &Accesses) {
|
||||
return;
|
||||
|
||||
if (auto apply = ApplySite::isa(memInst)) {
|
||||
SILArgumentConvention conv =
|
||||
apply.getArgumentConvention(apply.getCalleeArgIndex(*memOper));
|
||||
SILArgumentConvention conv = apply.getArgumentConvention(*memOper);
|
||||
// Captured addresses currently use the @inout_aliasable convention. They
|
||||
// are considered an access at any call site that uses the closure. However,
|
||||
// those accesses are never explictly protected by access markers. Instead,
|
||||
|
||||
@@ -284,7 +284,7 @@ static bool partialApplyEscapes(SILValue V, bool examineApply) {
|
||||
SILModuleConventions ModConv(*V->getModule());
|
||||
llvm::SmallVector<Operand *, 32> Worklist(V->use_begin(), V->use_end());
|
||||
while (!Worklist.empty()) {
|
||||
auto *Op = Worklist.pop_back_val();
|
||||
Operand *Op = Worklist.pop_back_val();
|
||||
|
||||
// These instructions do not cause the address to escape.
|
||||
if (!useCaptured(Op))
|
||||
@@ -300,15 +300,14 @@ static bool partialApplyEscapes(SILValue V, bool examineApply) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (auto *Apply = dyn_cast<ApplyInst>(User)) {
|
||||
if (auto Apply = FullApplySite::isa(User)) {
|
||||
// Applying a function does not cause the function to escape.
|
||||
if (Op->getOperandNumber() == 0)
|
||||
if (!Apply.isArgumentOperand(*Op))
|
||||
continue;
|
||||
|
||||
// apply instructions do not capture the pointer when it is passed
|
||||
// indirectly
|
||||
if (Apply->getArgumentConvention(Op->getOperandNumber() - 1)
|
||||
.isIndirectConvention())
|
||||
if (Apply.getArgumentConvention(*Op).isIndirectConvention())
|
||||
continue;
|
||||
|
||||
// Optionally drill down into an apply to see if the operand is
|
||||
|
||||
@@ -152,12 +152,10 @@ static SILArgumentConvention getAddressArgConvention(ApplyInst *Apply,
|
||||
Operand *&Oper) {
|
||||
Oper = nullptr;
|
||||
auto Args = Apply->getArgumentOperands();
|
||||
llvm::Optional<unsigned> FoundArgIdx;
|
||||
for (auto ArgIdx : indices(Args)) {
|
||||
if (Args[ArgIdx].get() != Address)
|
||||
continue;
|
||||
|
||||
FoundArgIdx = ArgIdx;
|
||||
assert(!Oper && "Address can only be passed once as an indirection.");
|
||||
Oper = &Args[ArgIdx];
|
||||
#ifdef NDEBUG
|
||||
@@ -165,7 +163,7 @@ static SILArgumentConvention getAddressArgConvention(ApplyInst *Apply,
|
||||
#endif
|
||||
}
|
||||
assert(Oper && "Address value not passed as an argument to this call.");
|
||||
return Apply->getArgumentConvention(FoundArgIdx.getValue());
|
||||
return ApplySite(Apply).getArgumentConvention(*Oper);
|
||||
}
|
||||
|
||||
/// If the given instruction is a store, return the stored value.
|
||||
@@ -1633,10 +1631,10 @@ bool TempRValueOptPass::collectLoads(
|
||||
return false;
|
||||
|
||||
case SILInstructionKind::ApplyInst: {
|
||||
auto *AI = cast<ApplyInst>(user);
|
||||
auto Convention = AI->getArgumentConvention(userOp->getOperandNumber() - 1);
|
||||
ApplySite apply(user);
|
||||
auto Convention = apply.getArgumentConvention(*userOp);
|
||||
if (Convention.isGuaranteedConvention()) {
|
||||
loadInsts.insert(AI);
|
||||
loadInsts.insert(user);
|
||||
return true;
|
||||
}
|
||||
LLVM_DEBUG(llvm::dbgs() << " Temp consuming use may write/destroy "
|
||||
|
||||
@@ -152,9 +152,7 @@ SILValue swift::getAddressOfStackInit(AllocStackInst *ASI,
|
||||
}
|
||||
if (isa<ApplyInst>(User) || isa<TryApplyInst>(User)) {
|
||||
// Ignore function calls which do not write to the stack location.
|
||||
auto Idx =
|
||||
Use->getOperandNumber() - ApplyInst::getArgumentOperandNumber();
|
||||
auto Conv = FullApplySite(User).getArgumentConvention(Idx);
|
||||
auto Conv = FullApplySite(User).getArgumentConvention(*Use);
|
||||
if (Conv != SILArgumentConvention::Indirect_In &&
|
||||
Conv != SILArgumentConvention::Indirect_In_Guaranteed)
|
||||
return SILValue();
|
||||
|
||||
Reference in New Issue
Block a user