Skip to content

Emit a DW_OP_deref for global variables in a fixed size buffer. #16342

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
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
25 changes: 14 additions & 11 deletions lib/IRGen/GenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1948,7 +1948,7 @@ bool LinkInfo::isUsed(llvm::GlobalValue::LinkageTypes Linkage,
llvm::GlobalVariable *swift::irgen::createVariable(
IRGenModule &IGM, LinkInfo &linkInfo, llvm::Type *storageType,
Alignment alignment, DebugTypeInfo DbgTy, Optional<SILLocation> DebugLoc,
StringRef DebugName) {
StringRef DebugName, bool inFixedBuffer) {
auto name = linkInfo.getName();
llvm::GlobalValue *existingValue = IGM.Module.getNamedGlobal(name);
if (existingValue) {
Expand Down Expand Up @@ -1980,7 +1980,7 @@ llvm::GlobalVariable *swift::irgen::createVariable(
if (IGM.DebugInfo && !DbgTy.isNull() && linkInfo.isForDefinition())
IGM.DebugInfo->emitGlobalVariableDeclaration(
var, DebugName.empty() ? name : DebugName, name, DbgTy,
var->hasInternalLinkage(), DebugLoc);
var->hasInternalLinkage(), inFixedBuffer, DebugLoc);

return var;
}
Expand Down Expand Up @@ -2116,6 +2116,7 @@ Address IRGenModule::getAddrOfSILGlobalVariable(SILGlobalVariable *var,
llvm::Type *storageType;
Size fixedSize;
Alignment fixedAlignment;
bool inFixedBuffer = false;

if (var->isInitializedObject()) {
assert(ti.isFixedSize(expansion));
Expand Down Expand Up @@ -2145,6 +2146,7 @@ Address IRGenModule::getAddrOfSILGlobalVariable(SILGlobalVariable *var,
} else {
// Allocate a fixed-size buffer and possibly heap-allocate a payload at
// runtime if the runtime size of the type does not fit in the buffer.
inFixedBuffer = true;
storageType = getFixedBufferTy();
fixedSize = Size(DataLayout.getTypeAllocSize(storageType));
fixedAlignment = Alignment(DataLayout.getABITypeAlignment(storageType));
Expand Down Expand Up @@ -2175,20 +2177,21 @@ Address IRGenModule::getAddrOfSILGlobalVariable(SILGlobalVariable *var,
gvar = createVariable(*this, link, storageTypeWithContainer,
fixedAlignment);
} else {
auto DbgTy = DebugTypeInfo::getGlobal(var, storageTypeWithContainer,
fixedSize, fixedAlignment);
StringRef name;
Optional<SILLocation> loc;
if (var->getDecl()) {
// If we have the VarDecl, use it for more accurate debugging information.
gvar = createVariable(*this, link, storageTypeWithContainer,
fixedAlignment, DbgTy, SILLocation(var->getDecl()),
var->getDecl()->getName().str());
// Use the VarDecl for more accurate debugging information.
loc = var->getDecl();
name = var->getDecl()->getName().str();
} else {
Optional<SILLocation> loc;
if (var->hasLocation())
loc = var->getLocation();
gvar = createVariable(*this, link, storageTypeWithContainer,
fixedAlignment, DbgTy, loc, var->getName());
name = var->getName();
}
auto DbgTy = DebugTypeInfo::getGlobal(var, storageTypeWithContainer,
fixedSize, fixedAlignment);
gvar = createVariable(*this, link, storageTypeWithContainer,
fixedAlignment, DbgTy, loc, name, inFixedBuffer);
}
/// Add a zero initializer.
if (forDefinition)
Expand Down
12 changes: 5 additions & 7 deletions lib/IRGen/GenDecl.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,11 @@ namespace irgen {
OptimizationMode FuncOptMode =
OptimizationMode::NotSet);

llvm::GlobalVariable *createVariable(IRGenModule &IGM,
LinkInfo &linkInfo,
llvm::Type *objectType,
Alignment alignment,
DebugTypeInfo DebugType=DebugTypeInfo(),
Optional<SILLocation> DebugLoc = None,
StringRef DebugName = StringRef());
llvm::GlobalVariable *
createVariable(IRGenModule &IGM, LinkInfo &linkInfo, llvm::Type *objectType,
Alignment alignment, DebugTypeInfo DebugType = DebugTypeInfo(),
Optional<SILLocation> DebugLoc = None,
StringRef DebugName = StringRef(), bool heapAllocated = false);

void disableAddressSanitizer(IRGenModule &IGM, llvm::GlobalVariable *var);
}
Expand Down
3 changes: 2 additions & 1 deletion lib/IRGen/GenInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ void IRGenModule::emitSILGlobalVariable(SILGlobalVariable *var) {
auto DbgTy = DebugTypeInfo::getGlobal(var, Int8Ty, Size(0), Alignment(1));
DebugInfo->emitGlobalVariableDeclaration(
nullptr, var->getDecl()->getName().str(), "", DbgTy,
var->getLinkage() != SILLinkage::Public, SILLocation(var->getDecl()));
var->getLinkage() != SILLinkage::Public,
IRGenDebugInfo::NotHeapAllocated, SILLocation(var->getDecl()));
}
return;
}
Expand Down
21 changes: 16 additions & 5 deletions lib/IRGen/IRGenDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
void emitGlobalVariableDeclaration(llvm::GlobalVariable *Storage,
StringRef Name, StringRef LinkageName,
DebugTypeInfo DebugType,
bool IsLocalToUnit,
bool IsLocalToUnit, bool InFixedBuffer,
Optional<SILLocation> Loc);
void emitTypeMetadata(IRGenFunction &IGF, llvm::Value *Metadata,
StringRef Name);
Expand Down Expand Up @@ -1989,7 +1989,8 @@ void IRGenDebugInfoImpl::emitDbgIntrinsic(

void IRGenDebugInfoImpl::emitGlobalVariableDeclaration(
llvm::GlobalVariable *Var, StringRef Name, StringRef LinkageName,
DebugTypeInfo DbgTy, bool IsLocalToUnit, Optional<SILLocation> Loc) {
DebugTypeInfo DbgTy, bool IsLocalToUnit, bool InFixedBuffer,
Optional<SILLocation> Loc) {
if (Opts.DebugInfoKind <= IRGenDebugInfoKind::LineTables)
return;

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

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

void IRGenDebugInfo::emitGlobalVariableDeclaration(
llvm::GlobalVariable *Storage, StringRef Name, StringRef LinkageName,
DebugTypeInfo DebugType, bool IsLocalToUnit, Optional<SILLocation> Loc) {
DebugTypeInfo DebugType, bool IsLocalToUnit, bool InFixedBuffer,
Optional<SILLocation> Loc) {
static_cast<IRGenDebugInfoImpl *>(this)->emitGlobalVariableDeclaration(
Storage, Name, LinkageName, DebugType, IsLocalToUnit, Loc);
Storage, Name, LinkageName, DebugType, IsLocalToUnit, InFixedBuffer, Loc);
}

void IRGenDebugInfo::emitTypeMetadata(IRGenFunction &IGF, llvm::Value *Metadata,
Expand Down
4 changes: 3 additions & 1 deletion lib/IRGen/IRGenDebugInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,13 @@ class IRGenDebugInfo {
unsigned Line, unsigned Col, llvm::DILocalScope *Scope,
const SILDebugScope *DS);

enum { NotHeapAllocated = false };

/// Create debug metadata for a global variable.
void emitGlobalVariableDeclaration(llvm::GlobalVariable *Storage,
StringRef Name, StringRef LinkageName,
DebugTypeInfo DebugType,
bool IsLocalToUnit,
bool IsLocalToUnit, bool InFixedBuffer,
Optional<SILLocation> Loc);

/// Emit debug metadata for type metadata (for generic types). So meta.
Expand Down
44 changes: 33 additions & 11 deletions test/DebugInfo/resilience.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,25 @@
// RUN: -enable-resilience-bypass | %FileCheck %s --check-prefix=CHECK-LLDB
import resilient_struct

// CHECK-LABEL: define{{( protected)?}} swiftcc void @"$S10resilience1fyyF"()
// CHECK-LLDB-LABEL: define{{( protected)?}} swiftcc void @"$S10resilience1fyyF"()
public func f() {
let fixed = Point(x: 1, y: 2)
let non_fixed = Size(w: 1, h: 2)
let int = ResilientInt(i: 1)
// CHECK: @"$S10resilience5fixed16resilient_struct5PointVvp" =
// CHECK-SAME: !dbg ![[FIXED:[0-9]+]]
// CHECK: @"$S10resilience9non_fixed16resilient_struct4SizeVvp" =
// CHECK-SAME: !dbg ![[NON_FIXED:[0-9]+]]
// CHECK: @"$S10resilience3int16resilient_struct12ResilientIntVvp" =
// CHECK-SAME: !dbg ![[INT:[0-9]+]]
// CHECK-LABEL: define{{.*}}main

// CHECK-LABEL: define{{.*}} swiftcc void @"$S10resilience9takesSizeyy16resilient_struct0C0VF"(%swift.opaque* noalias nocapture)
// CHECK-LLDB-LABEL: define{{.*}} swiftcc void @"$S10resilience9takesSizeyy16resilient_struct0C0VF"(%T16resilient_struct4SizeV* noalias nocapture dereferenceable({{8|16}}))
public func takesSize(_ s: Size) {}


// CHECK-LABEL: define{{.*}} swiftcc void @"$S10resilience1fyyF"()
// CHECK-LLDB-LABEL: define{{.*}} swiftcc void @"$S10resilience1fyyF"()
func f() {
let s1 = Size(w: 1, h: 2)
takesSize(s1)
// CHECK: %[[ADDR:.*]] = alloca i8*
Expand All @@ -30,15 +46,21 @@ public func f() {
// CHECK-LLDB-SAME: metadata ![[V1:[0-9]+]],
// CHECK-LLDB-SAME: metadata !DIExpression())
}
f()

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

// CHECK-LABEL: define{{( protected)?}} swiftcc void @"$S10resilience9takesSizeyy16resilient_struct0C0VF"(%swift.opaque* noalias nocapture)
// CHECK-LLDB-LABEL: define{{( protected)?}} swiftcc void @"$S10resilience9takesSizeyy16resilient_struct0C0VF"(%T16resilient_struct4SizeV* noalias nocapture dereferenceable({{8|16}}))
public func takesSize(_ s: Size) {}

// CHECK: ![[V1]] = !DILocalVariable(name: "s1", {{.*}}type: ![[TY]])

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

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