Skip to content

Commit ebf12c3

Browse files
Merge pull request #16318 from adrian-prantl/39722386
Emits a DW_OP_deref for global variables in a fixed size buffer.
2 parents 4099e85 + 2c7a698 commit ebf12c3

File tree

6 files changed

+73
-36
lines changed

6 files changed

+73
-36
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1943,7 +1943,7 @@ bool LinkInfo::isUsed(llvm::GlobalValue::LinkageTypes Linkage,
19431943
llvm::GlobalVariable *swift::irgen::createVariable(
19441944
IRGenModule &IGM, LinkInfo &linkInfo, llvm::Type *storageType,
19451945
Alignment alignment, DebugTypeInfo DbgTy, Optional<SILLocation> DebugLoc,
1946-
StringRef DebugName) {
1946+
StringRef DebugName, bool inFixedBuffer) {
19471947
auto name = linkInfo.getName();
19481948
llvm::GlobalValue *existingValue = IGM.Module.getNamedGlobal(name);
19491949
if (existingValue) {
@@ -1975,7 +1975,7 @@ llvm::GlobalVariable *swift::irgen::createVariable(
19751975
if (IGM.DebugInfo && !DbgTy.isNull() && linkInfo.isForDefinition())
19761976
IGM.DebugInfo->emitGlobalVariableDeclaration(
19771977
var, DebugName.empty() ? name : DebugName, name, DbgTy,
1978-
var->hasInternalLinkage(), DebugLoc);
1978+
var->hasInternalLinkage(), inFixedBuffer, DebugLoc);
19791979

19801980
return var;
19811981
}
@@ -2111,6 +2111,7 @@ Address IRGenModule::getAddrOfSILGlobalVariable(SILGlobalVariable *var,
21112111
llvm::Type *storageType;
21122112
Size fixedSize;
21132113
Alignment fixedAlignment;
2114+
bool inFixedBuffer = false;
21142115

21152116
if (var->isInitializedObject()) {
21162117
assert(ti.isFixedSize(expansion));
@@ -2140,6 +2141,7 @@ Address IRGenModule::getAddrOfSILGlobalVariable(SILGlobalVariable *var,
21402141
} else {
21412142
// Allocate a fixed-size buffer and possibly heap-allocate a payload at
21422143
// runtime if the runtime size of the type does not fit in the buffer.
2144+
inFixedBuffer = true;
21432145
storageType = getFixedBufferTy();
21442146
fixedSize = Size(DataLayout.getTypeAllocSize(storageType));
21452147
fixedAlignment = Alignment(DataLayout.getABITypeAlignment(storageType));
@@ -2170,20 +2172,21 @@ Address IRGenModule::getAddrOfSILGlobalVariable(SILGlobalVariable *var,
21702172
gvar = createVariable(*this, link, storageTypeWithContainer,
21712173
fixedAlignment);
21722174
} else {
2173-
auto DbgTy = DebugTypeInfo::getGlobal(var, storageTypeWithContainer,
2174-
fixedSize, fixedAlignment);
2175+
StringRef name;
2176+
Optional<SILLocation> loc;
21752177
if (var->getDecl()) {
2176-
// If we have the VarDecl, use it for more accurate debugging information.
2177-
gvar = createVariable(*this, link, storageTypeWithContainer,
2178-
fixedAlignment, DbgTy, SILLocation(var->getDecl()),
2179-
var->getDecl()->getName().str());
2178+
// Use the VarDecl for more accurate debugging information.
2179+
loc = var->getDecl();
2180+
name = var->getDecl()->getName().str();
21802181
} else {
2181-
Optional<SILLocation> loc;
21822182
if (var->hasLocation())
21832183
loc = var->getLocation();
2184-
gvar = createVariable(*this, link, storageTypeWithContainer,
2185-
fixedAlignment, DbgTy, loc, var->getName());
2184+
name = var->getName();
21862185
}
2186+
auto DbgTy = DebugTypeInfo::getGlobal(var, storageTypeWithContainer,
2187+
fixedSize, fixedAlignment);
2188+
gvar = createVariable(*this, link, storageTypeWithContainer,
2189+
fixedAlignment, DbgTy, loc, name, inFixedBuffer);
21872190
}
21882191
/// Add a zero initializer.
21892192
if (forDefinition)

lib/IRGen/GenDecl.h

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,11 @@ namespace irgen {
4646
OptimizationMode FuncOptMode =
4747
OptimizationMode::NotSet);
4848

49-
llvm::GlobalVariable *createVariable(IRGenModule &IGM,
50-
LinkInfo &linkInfo,
51-
llvm::Type *objectType,
52-
Alignment alignment,
53-
DebugTypeInfo DebugType=DebugTypeInfo(),
54-
Optional<SILLocation> DebugLoc = None,
55-
StringRef DebugName = StringRef());
49+
llvm::GlobalVariable *
50+
createVariable(IRGenModule &IGM, LinkInfo &linkInfo, llvm::Type *objectType,
51+
Alignment alignment, DebugTypeInfo DebugType = DebugTypeInfo(),
52+
Optional<SILLocation> DebugLoc = None,
53+
StringRef DebugName = StringRef(), bool heapAllocated = false);
5654

5755
void disableAddressSanitizer(IRGenModule &IGM, llvm::GlobalVariable *var);
5856
}

lib/IRGen/GenInit.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ void IRGenModule::emitSILGlobalVariable(SILGlobalVariable *var) {
4545
auto DbgTy = DebugTypeInfo::getGlobal(var, Int8Ty, Size(0), Alignment(1));
4646
DebugInfo->emitGlobalVariableDeclaration(
4747
nullptr, var->getDecl()->getName().str(), "", DbgTy,
48-
var->getLinkage() != SILLinkage::Public, SILLocation(var->getDecl()));
48+
var->getLinkage() != SILLinkage::Public,
49+
IRGenDebugInfo::NotHeapAllocated, SILLocation(var->getDecl()));
4950
}
5051
return;
5152
}

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
154154
void emitGlobalVariableDeclaration(llvm::GlobalVariable *Storage,
155155
StringRef Name, StringRef LinkageName,
156156
DebugTypeInfo DebugType,
157-
bool IsLocalToUnit,
157+
bool IsLocalToUnit, bool InFixedBuffer,
158158
Optional<SILLocation> Loc);
159159
void emitTypeMetadata(IRGenFunction &IGF, llvm::Value *Metadata,
160160
StringRef Name);
@@ -1989,7 +1989,8 @@ void IRGenDebugInfoImpl::emitDbgIntrinsic(
19891989

19901990
void IRGenDebugInfoImpl::emitGlobalVariableDeclaration(
19911991
llvm::GlobalVariable *Var, StringRef Name, StringRef LinkageName,
1992-
DebugTypeInfo DbgTy, bool IsLocalToUnit, Optional<SILLocation> Loc) {
1992+
DebugTypeInfo DbgTy, bool IsLocalToUnit, bool InFixedBuffer,
1993+
Optional<SILLocation> Loc) {
19931994
if (Opts.DebugInfoKind <= IRGenDebugInfoKind::LineTables)
19941995
return;
19951996

@@ -2005,7 +2006,16 @@ void IRGenDebugInfoImpl::emitGlobalVariableDeclaration(
20052006
auto File = getOrCreateFile(L.Filename);
20062007

20072008
// Emit it as global variable of the current module.
2008-
auto *Expr = Var ? nullptr : DBuilder.createConstantValueExpression(0);
2009+
llvm::DIExpression *Expr = nullptr;
2010+
if (!Var)
2011+
Expr = DBuilder.createConstantValueExpression(0);
2012+
else if (InFixedBuffer)
2013+
// FIXME: This is *not* generally correct, but LLDB at the moment cannot
2014+
// poke to runtime to figure out whether a resilient value has inline
2015+
// storage, so this is assuming that it doesn't to get the majority of
2016+
// resilient Foundation types.
2017+
Expr =
2018+
DBuilder.createExpression(ArrayRef<uint64_t>(llvm::dwarf::DW_OP_deref));
20092019
auto *GV = DBuilder.createGlobalVariableExpression(
20102020
MainModule, Name, LinkageName, File, L.Line, Ty, IsLocalToUnit, Expr);
20112021
if (Var)
@@ -2129,9 +2139,10 @@ void IRGenDebugInfo::emitDbgIntrinsic(IRBuilder &Builder, llvm::Value *Storage,
21292139

21302140
void IRGenDebugInfo::emitGlobalVariableDeclaration(
21312141
llvm::GlobalVariable *Storage, StringRef Name, StringRef LinkageName,
2132-
DebugTypeInfo DebugType, bool IsLocalToUnit, Optional<SILLocation> Loc) {
2142+
DebugTypeInfo DebugType, bool IsLocalToUnit, bool InFixedBuffer,
2143+
Optional<SILLocation> Loc) {
21332144
static_cast<IRGenDebugInfoImpl *>(this)->emitGlobalVariableDeclaration(
2134-
Storage, Name, LinkageName, DebugType, IsLocalToUnit, Loc);
2145+
Storage, Name, LinkageName, DebugType, IsLocalToUnit, InFixedBuffer, Loc);
21352146
}
21362147

21372148
void IRGenDebugInfo::emitTypeMetadata(IRGenFunction &IGF, llvm::Value *Metadata,

lib/IRGen/IRGenDebugInfo.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,13 @@ class IRGenDebugInfo {
136136
unsigned Line, unsigned Col, llvm::DILocalScope *Scope,
137137
const SILDebugScope *DS);
138138

139+
enum { NotHeapAllocated = false };
140+
139141
/// Create debug metadata for a global variable.
140142
void emitGlobalVariableDeclaration(llvm::GlobalVariable *Storage,
141143
StringRef Name, StringRef LinkageName,
142144
DebugTypeInfo DebugType,
143-
bool IsLocalToUnit,
145+
bool IsLocalToUnit, bool InFixedBuffer,
144146
Optional<SILLocation> Loc);
145147

146148
/// Emit debug metadata for type metadata (for generic types). So meta.

test/DebugInfo/resilience.swift

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,25 @@
1313
// RUN: -enable-resilience-bypass | %FileCheck %s --check-prefix=CHECK-LLDB
1414
import resilient_struct
1515

16-
// CHECK-LABEL: define{{( protected)?}} swiftcc void @"$S10resilience1fyyF"()
17-
// CHECK-LLDB-LABEL: define{{( protected)?}} swiftcc void @"$S10resilience1fyyF"()
18-
public func f() {
16+
let fixed = Point(x: 1, y: 2)
17+
let non_fixed = Size(w: 1, h: 2)
18+
let int = ResilientInt(i: 1)
19+
// CHECK: @"$S10resilience5fixed16resilient_struct5PointVvp" =
20+
// CHECK-SAME: !dbg ![[FIXED:[0-9]+]]
21+
// CHECK: @"$S10resilience9non_fixed16resilient_struct4SizeVvp" =
22+
// CHECK-SAME: !dbg ![[NON_FIXED:[0-9]+]]
23+
// CHECK: @"$S10resilience3int16resilient_struct12ResilientIntVvp" =
24+
// CHECK-SAME: !dbg ![[INT:[0-9]+]]
25+
// CHECK-LABEL: define{{.*}}main
26+
27+
// CHECK-LABEL: define{{.*}} swiftcc void @"$S10resilience9takesSizeyy16resilient_struct0C0VF"(%swift.opaque* noalias nocapture)
28+
// CHECK-LLDB-LABEL: define{{.*}} swiftcc void @"$S10resilience9takesSizeyy16resilient_struct0C0VF"(%T16resilient_struct4SizeV* noalias nocapture dereferenceable({{8|16}}))
29+
public func takesSize(_ s: Size) {}
30+
31+
32+
// CHECK-LABEL: define{{.*}} swiftcc void @"$S10resilience1fyyF"()
33+
// CHECK-LLDB-LABEL: define{{.*}} swiftcc void @"$S10resilience1fyyF"()
34+
func f() {
1935
let s1 = Size(w: 1, h: 2)
2036
takesSize(s1)
2137
// CHECK: %[[ADDR:.*]] = alloca i8*
@@ -30,15 +46,21 @@ public func f() {
3046
// CHECK-LLDB-SAME: metadata ![[V1:[0-9]+]],
3147
// CHECK-LLDB-SAME: metadata !DIExpression())
3248
}
49+
f()
3350

51+
// Note that these DW_OP_deref are not necessarily correct, but it's the best
52+
// approxmiation we have until LLDB can query the runtime for whether a relient
53+
// type's storage is inline or not.
54+
// CHECK: ![[FIXED]] = !DIGlobalVariableExpression(
55+
// CHECK-SAME: expr: !DIExpression())
56+
// CHECK: ![[NON_FIXED]] = !DIGlobalVariableExpression(
57+
// CHECK-SAME: expr: !DIExpression(DW_OP_deref))
58+
// CHECK: ![[TY:[0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Size",
59+
// CHECK: ![[INT]] = !DIGlobalVariableExpression(
60+
// CHECK-SAME: expr: !DIExpression(DW_OP_deref))
3461

35-
// CHECK-LABEL: define{{( protected)?}} swiftcc void @"$S10resilience9takesSizeyy16resilient_struct0C0VF"(%swift.opaque* noalias nocapture)
36-
// CHECK-LLDB-LABEL: define{{( protected)?}} swiftcc void @"$S10resilience9takesSizeyy16resilient_struct0C0VF"(%T16resilient_struct4SizeV* noalias nocapture dereferenceable({{8|16}}))
37-
public func takesSize(_ s: Size) {}
38-
62+
// CHECK: ![[V1]] = !DILocalVariable(name: "s1", {{.*}}type: ![[TY]])
3963

40-
// CHECK: ![[V1]] = !DILocalVariable(name: "s1", {{.*}}type: ![[TY:[0-9]+]])
41-
// CHECK: ![[TY]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Size",
64+
// CHECK-LLDB: ![[TY:[0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Size",
65+
// CHECK-LLDB: ![[V1]] = !DILocalVariable(name: "s1", {{.*}}type: ![[TY]])
4266

43-
// CHECK-LLDB: ![[V1]] = !DILocalVariable(name: "s1", {{.*}}type: ![[TY:[0-9]+]])
44-
// CHECK-LLDB: ![[TY]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Size",

0 commit comments

Comments
 (0)