Skip to content

[AddressLowering] Don't end_borrow trivial args. #62198

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions lib/SILOptimizer/Mandatory/AddressLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -515,12 +515,14 @@ static void convertDirectToIndirectFunctionArgs(AddressLoweringState &pass) {
auto loc = SILValue(arg).getLoc();
SILValue undefAddress = SILUndef::get(addrType, *pass.function);
SingleValueInstruction *load;
if (param.isConsumed()) {
load = argBuilder.createTrivialLoadOr(loc, undefAddress,
LoadOwnershipQualifier::Take);
if (addrType.isTrivial(*pass.function)) {
load = argBuilder.createLoad(loc, undefAddress,
LoadOwnershipQualifier::Trivial);
} else if (param.isConsumed()) {
load = argBuilder.createLoad(loc, undefAddress,
LoadOwnershipQualifier::Take);
} else {
load = cast<SingleValueInstruction>(
argBuilder.emitLoadBorrowOperation(loc, undefAddress));
load = argBuilder.createLoadBorrow(loc, undefAddress);
for (SILInstruction *termInst : pass.exitingInsts) {
pass.getBuilder(termInst->getIterator())
.createEndBorrow(pass.genLoc(), load);
Expand Down
31 changes: 31 additions & 0 deletions lib/SILOptimizer/Mandatory/MandatoryInlining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,27 @@ STATISTIC(NumMandatoryInlines,
"Number of function application sites inlined by the mandatory "
"inlining pass");

//===----------------------------------------------------------------------===//
// Printing Helpers
//===----------------------------------------------------------------------===//

extern llvm::cl::opt<bool> SILPrintInliningCallee;

extern llvm::cl::opt<bool> SILPrintInliningCallerBefore;

extern llvm::cl::opt<bool> SILPrintInliningCallerAfter;

extern void printInliningDetailsCallee(StringRef passName, SILFunction *caller,
SILFunction *callee);

extern void printInliningDetailsCallerBefore(StringRef passName,
SILFunction *caller,
SILFunction *callee);

extern void printInliningDetailsCallerAfter(StringRef passName,
SILFunction *caller,
SILFunction *callee);

template<typename...T, typename...U>
static void diagnose(ASTContext &Context, SourceLoc loc, Diag<T...> diag,
U &&...args) {
Expand Down Expand Up @@ -923,11 +944,21 @@ runOnFunctionRecursively(SILOptFunctionBuilder &FuncBuilder, SILFunction *F,

invalidatedStackNesting |= Inliner.invalidatesStackNesting(InnerAI);

if (SILPrintInliningCallee) {
printInliningDetailsCallee("MandatoryInlining", F, CalleeFunction);
}
if (SILPrintInliningCallerBefore) {
printInliningDetailsCallerBefore("MandatoryInlining", F,
CalleeFunction);
}
// Inlining deletes the apply, and can introduce multiple new basic
// blocks. After this, CalleeValue and other instructions may be invalid.
// nextBB will point to the last inlined block
SILBasicBlock *lastBB =
Inliner.inlineFunction(CalleeFunction, InnerAI, FullArgs);
if (SILPrintInliningCallerAfter) {
printInliningDetailsCallerAfter("MandatoryInlining", F, CalleeFunction);
}
nextBB = lastBB->getReverseIterator();
++NumMandatoryInlines;

Expand Down
31 changes: 31 additions & 0 deletions lib/SILOptimizer/PassManager/PassManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,37 @@ bool isFunctionSelectedForPrinting(SILFunction *F) {
return true;
}

void printInliningDetails(StringRef passName, SILFunction *caller,
SILFunction *callee, bool isCaller,
bool alreadyInlined) {
if (!isFunctionSelectedForPrinting(caller))
return;
llvm::dbgs() << " " << passName
<< (alreadyInlined ? " has inlined " : " will inline ")
<< callee->getName() << " into " << caller->getName() << ".\n";
auto *printee = isCaller ? caller : callee;
printee->dump(caller->getModule().getOptions().EmitVerboseSIL);
llvm::dbgs() << '\n';
}

void printInliningDetailsCallee(StringRef passName, SILFunction *caller,
SILFunction *callee) {
printInliningDetails(passName, caller, callee, /*isCaller=*/false,
/*alreadyInlined=*/false);
}

void printInliningDetailsCallerBefore(StringRef passName, SILFunction *caller,
SILFunction *callee) {
printInliningDetails(passName, caller, callee, /*isCaller=*/true,
/*alreadyInlined=*/false);
}

void printInliningDetailsCallerAfter(StringRef passName, SILFunction *caller,
SILFunction *callee) {
printInliningDetails(passName, caller, callee, /*isCaller=*/true,
/*alreadyInlined=*/true);
}

static bool functionSelectionEmpty() {
return SILPrintFunction.empty() && SILPrintFunctions.empty();
}
Expand Down
36 changes: 6 additions & 30 deletions lib/SILOptimizer/Transforms/PerformanceInliner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,40 +67,16 @@ llvm::cl::opt<bool> SILPrintInliningCallerAfter(
// Printing Helpers
//===----------------------------------------------------------------------===//

extern bool isFunctionSelectedForPrinting(SILFunction *F);
extern void printInliningDetailsCallee(StringRef passName, SILFunction *caller,
SILFunction *callee);

static void printInliningDetails(StringRef passName, SILFunction *caller,
SILFunction *callee, bool isCaller,
bool alreadyInlined) {
if (!isFunctionSelectedForPrinting(caller))
return;
llvm::dbgs() << " " << passName
<< (alreadyInlined ? " has inlined " : " will inline ")
<< callee->getName() << " into " << caller->getName() << ".\n";
auto *printee = isCaller ? caller : callee;
printee->dump(caller->getModule().getOptions().EmitVerboseSIL);
llvm::dbgs() << '\n';
}

static void printInliningDetailsCallee(StringRef passName, SILFunction *caller,
SILFunction *callee) {
printInliningDetails(passName, caller, callee, /*isCaller=*/false,
/*alreadyInlined=*/false);
}

static void printInliningDetailsCallerBefore(StringRef passName,
extern void printInliningDetailsCallerBefore(StringRef passName,
SILFunction *caller,
SILFunction *callee) {
printInliningDetails(passName, caller, callee, /*isCaller=*/true,
/*alreadyInlined=*/false);
}
SILFunction *callee);

static void printInliningDetailsCallerAfter(StringRef passName,
extern void printInliningDetailsCallerAfter(StringRef passName,
SILFunction *caller,
SILFunction *callee) {
printInliningDetails(passName, caller, callee, /*isCaller=*/true,
/*alreadyInlined=*/true);
}
SILFunction *callee);

//===----------------------------------------------------------------------===//
// Performance Inliner
Expand Down
22 changes: 22 additions & 0 deletions test/SILOptimizer/address_lowering.sil
Original file line number Diff line number Diff line change
Expand Up @@ -1068,6 +1068,28 @@ bb3(%15 : @owned $T):
return %15 : $T
}

// Verify that trivial arguments are loaded trivially and for which no
// end_borrows were created.
// CHECK-LABEL: sil [ossa] @f171_subtract_overflow : {{.*}} {
// CHECK: {{bb[0-9]+}}([[RETVAL:%[^,]+]] : $*Builtin.Int64, [[LHS_ADDR:%[^,]+]] : $*Builtin.Int64, [[RHS_ADDR:%[^,]+]] :
// CHECK: [[LHS:%[^,]+]] = load [trivial] [[LHS_ADDR]]
// CHECK: [[RHS:%[^,]+]] = load [trivial] [[RHS_ADDR]]
// CHECK: [[SUM_AND:%[^,]+]] = apply {{%[^,]+}}([[LHS]], [[RHS]])
// CHECK-NOT: end_borrow
// CHECK: ([[SUM:%[^,]+]], [[OVERFLOWED:%[^,]+]]) = destructure_tuple [[SUM_AND]]
// CHECK: store [[SUM]] to [trivial] [[RETVAL]]
// CHECK: return [[OVERFLOWED]]
// CHECK-LABEL: } // end sil function 'f171_subtract_overflow'
sil [ossa] @f171_subtract_overflow : $@convention(thin) (@in_guaranteed Int, @in_guaranteed Int) -> (@out Int, Bool) {
bb0(%0 : $Int, %1 : $Int):
%2 = function_ref @f171_subtract_overflow_callee : $@convention(method) (Int, Int) -> (Int, Bool)
%3 = apply %2(%0, %1) : $@convention(method) (Int, Int) -> (Int, Bool)
(%4, %5) = destructure_tuple %3 : $(Int, Bool)
%6 = tuple (%4 : $Int, %5 : $Bool)
return %6 : $(Int, Bool)
}
sil [ossa] @f171_subtract_overflow_callee : $@convention(method) (Int, Int) -> (Int, Bool)

// Test switching on a single opaque value.
// CHECK-LABEL: sil [ossa] @f210_testSwitchEnum : $@convention(method) <T> (@in Optional<T>, @inout T) -> () {
// CHECK: bb0(%0 : $*Optional<T>, %1 : $*T):
Expand Down