Skip to content

Commit 003820d

Browse files
Merge pull request #6624 from adrian-prantl/107687703
Implement a workaround to acrtificially extend the lifetime of async
2 parents e7c8cd8 + 0561df7 commit 003820d

File tree

10 files changed

+107
-18
lines changed

10 files changed

+107
-18
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
SWIFT_SOURCES := main.swift
2+
SWIFTFLAGS_EXTRAS := -parse-as-library
3+
include Makefile.rules
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import lldb
2+
from lldbsuite.test.decorators import *
3+
import lldbsuite.test.lldbtest as lldbtest
4+
import lldbsuite.test.lldbutil as lldbutil
5+
import unittest2
6+
7+
8+
class TestSwiftAsyncVariables(lldbtest.TestBase):
9+
10+
mydir = lldbtest.TestBase.compute_mydir(__file__)
11+
12+
@swiftTest
13+
@skipIf(oslist=['windows', 'linux'])
14+
def test(self):
15+
"""Test local variables in async functions"""
16+
self.build()
17+
src = lldb.SBFileSpec('main.swift')
18+
target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
19+
self, 'break here', src)
20+
21+
while process.selected_thread.stop_reason == lldb.eStopReasonBreakpoint:
22+
self.expect("frame variable x", substrs=["23"])
23+
process.Continue()
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import Swift
2+
func use<T>(_ t: T) {}
3+
func sink<T>(_ t: T) {}
4+
5+
func split() async {}
6+
7+
func f(_ xs: [Int?]) async {
8+
for x in xs {
9+
let x = x!
10+
sink(x) // break here
11+
}
12+
await split()
13+
for x in xs {
14+
let x = x!
15+
sink(x) // break here
16+
}
17+
}
18+
19+
@main struct Main {
20+
static func main() async {
21+
await f([23])
22+
}
23+
}

llvm/include/llvm/CodeGen/DebugHandlerBase.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ class DebugHandlerBase : public AsmPrinterHandler {
9898

9999
/// Ensure that a label will be emitted before MI.
100100
void requestLabelBeforeInsn(const MachineInstr *MI) {
101-
LabelsBeforeInsn.insert(std::make_pair(MI, nullptr));
101+
if (!LabelsBeforeInsn.count(MI))
102+
LabelsBeforeInsn.insert(std::make_pair(MI, nullptr));
102103
}
103104

104105
/// Ensure that a label will be emitted after MI.

llvm/include/llvm/CodeGen/MachineInstr.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1946,6 +1946,10 @@ struct MachineInstrExpressionTrait : DenseMapInfo<MachineInstr*> {
19461946
}
19471947
};
19481948

1949+
// BEGIN SWIFT
1950+
bool isSwiftAsyncContext(const MachineFunction &MF, Register Reg);
1951+
// END SWIFT
1952+
19491953
//===----------------------------------------------------------------------===//
19501954
// Debugging Support
19511955

llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "llvm/CodeGen/MachineFunction.h"
1717
#include "llvm/CodeGen/MachineInstr.h"
1818
#include "llvm/CodeGen/MachineOperand.h"
19+
#include "llvm/CodeGen/MachineRegisterInfo.h"
1920
#include "llvm/CodeGen/TargetLowering.h"
2021
#include "llvm/CodeGen/TargetRegisterInfo.h"
2122
#include "llvm/CodeGen/TargetSubtargetInfo.h"
@@ -182,6 +183,25 @@ void DbgValueHistoryMap::trimLocationRanges(
182183
if (!EI->isDbgValue())
183184
continue;
184185

186+
// BEGIN SWIFT
187+
// Swift async function handling.
188+
{
189+
bool skipAsyncEntryValue = false;
190+
auto &MI = *EI->getInstr();
191+
auto *Expr = MI.getDebugExpression();
192+
for (const MachineOperand &MO : MI.debug_operands()) {
193+
if (MO.isReg() && MO.getReg() != 0)
194+
if (Expr && Expr->isEntryValue() &&
195+
isSwiftAsyncContext(MF, MO.getReg())) {
196+
skipAsyncEntryValue = true;
197+
break;
198+
}
199+
}
200+
if (skipAsyncEntryValue)
201+
continue;
202+
}
203+
// END SWIFT
204+
185205
// Index of the entry which closes this range.
186206
EntryIndex EndIndex = EI->getEndIndex();
187207
// If this range is closed bump the reference count of the closing entry.

llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
300300
Entries.front().getInstr()->getDebugVariable();
301301
if (DIVar->isParameter() &&
302302
getDISubprogram(DIVar->getScope())->describes(&MF->getFunction())) {
303+
303304
if (!IsDescribedByReg(Entries.front().getInstr()))
304305
LabelsBeforeInsn[Entries.front().getInstr()] = Asm->getFunctionBegin();
305306
if (Entries.front().getInstr()->getDebugExpression()->isFragment()) {

llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1562,6 +1562,20 @@ static bool validThroughout(LexicalScopes &LScopes,
15621562
if (LSRange.size() == 0)
15631563
return false;
15641564

1565+
// BEGIN SWIFT
1566+
// Swift async function handling.
1567+
{
1568+
auto &MI = *DbgValue;
1569+
auto MF = MBB->getParent();
1570+
auto *Expr = MI.getDebugExpression();
1571+
if (Expr && Expr->isEntryValue())
1572+
for (const MachineOperand &MO : MI.debug_operands())
1573+
if (MO.isReg() && MO.getReg() != 0)
1574+
if (isSwiftAsyncContext(*MF, MO.getReg()))
1575+
return true;
1576+
}
1577+
// END SWIFT
1578+
15651579
const MachineInstr *LScopeBegin = LSRange.front().first;
15661580
// If the scope starts before the DBG_VALUE then we may have a negative
15671581
// result. Otherwise the location is live coming into the scope and we

llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -155,23 +155,6 @@ static cl::opt<unsigned>
155155
cl::desc("livedebugvalues-stack-ws-limit"),
156156
cl::init(250));
157157

158-
// BEGIN SWIFT
159-
static bool isSwiftAsyncContext(const MachineFunction &MF, Register Reg) {
160-
const llvm::Function &F = MF.getFunction();
161-
if (!MF.getProperties().hasProperty(
162-
MachineFunctionProperties::Property::TracksLiveness))
163-
return false;
164-
unsigned I = 0;
165-
for (auto R : MF.getRegInfo().liveins()) {
166-
if (R.first == (unsigned)Reg &&
167-
F.hasParamAttribute(I, Attribute::SwiftAsync))
168-
return true;
169-
++I;
170-
}
171-
return false;
172-
}
173-
// END SWIFT
174-
175158
DbgOpID DbgOpID::UndefID = DbgOpID(0xffffffff);
176159

177160
/// Tracker for converting machine value locations and variable values into

llvm/lib/CodeGen/MachineRegisterInfo.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,3 +671,20 @@ bool MachineRegisterInfo::isGeneralPurposeRegister(const MachineFunction &MF,
671671
MCRegister Reg) const {
672672
return getTargetRegisterInfo()->isGeneralPurposeRegister(MF, Reg);
673673
}
674+
675+
// BEGIN SWIFT
676+
bool llvm::isSwiftAsyncContext(const MachineFunction &MF, Register Reg) {
677+
const llvm::Function &F = MF.getFunction();
678+
if (!MF.getProperties().hasProperty(
679+
MachineFunctionProperties::Property::TracksLiveness))
680+
return false;
681+
unsigned I = 0;
682+
for (auto R : MF.getRegInfo().liveins()) {
683+
if (R.first == (unsigned)Reg &&
684+
F.hasParamAttribute(I, Attribute::SwiftAsync))
685+
return true;
686+
++I;
687+
}
688+
return false;
689+
}
690+
// END SWIFT

0 commit comments

Comments
 (0)