Remove Resilience workarounds and describe fixed-size global resilient

variables in DWARF.

rdar://problem/48409386
This commit is contained in:
Adrian Prantl
2019-03-19 11:41:04 -07:00
parent c7a6f8a5ef
commit 0b8fc3d405
7 changed files with 50 additions and 60 deletions

View File

@@ -27,4 +27,7 @@ FAILURE(TypeHasNoSuchMember,
FAILURE(CouldNotResolveTypeDecl, FAILURE(CouldNotResolveTypeDecl,
"could not resolve a type with mangled name '%0'", (String)) "could not resolve a type with mangled name '%0'", (String))
FAILURE(NotFixedLayout,
"query cannot be determined for a type with no fixed layout", ())
#undef FAILURE #undef FAILURE

View File

@@ -1637,7 +1637,7 @@ bool LinkInfo::isUsed(IRLinkage IRL) {
llvm::GlobalVariable *swift::irgen::createVariable( llvm::GlobalVariable *swift::irgen::createVariable(
IRGenModule &IGM, LinkInfo &linkInfo, llvm::Type *storageType, IRGenModule &IGM, LinkInfo &linkInfo, llvm::Type *storageType,
Alignment alignment, DebugTypeInfo DbgTy, Optional<SILLocation> DebugLoc, Alignment alignment, DebugTypeInfo DbgTy, Optional<SILLocation> DebugLoc,
StringRef DebugName, bool inFixedBuffer, bool indirectForDebugInfo) { StringRef DebugName, bool inFixedBuffer) {
auto name = linkInfo.getName(); auto name = linkInfo.getName();
llvm::GlobalValue *existingValue = IGM.Module.getNamedGlobal(name); llvm::GlobalValue *existingValue = IGM.Module.getNamedGlobal(name);
if (existingValue) { if (existingValue) {
@@ -1671,7 +1671,7 @@ llvm::GlobalVariable *swift::irgen::createVariable(
if (IGM.DebugInfo && !DbgTy.isNull() && linkInfo.isForDefinition()) if (IGM.DebugInfo && !DbgTy.isNull() && linkInfo.isForDefinition())
IGM.DebugInfo->emitGlobalVariableDeclaration( IGM.DebugInfo->emitGlobalVariableDeclaration(
var, DebugName.empty() ? name : DebugName, name, DbgTy, var, DebugName.empty() ? name : DebugName, name, DbgTy,
var->hasInternalLinkage(), indirectForDebugInfo, DebugLoc); var->hasInternalLinkage(), inFixedBuffer, DebugLoc);
return var; return var;
} }
@@ -1809,13 +1809,6 @@ Address IRGenModule::getAddrOfSILGlobalVariable(SILGlobalVariable *var,
Size fixedSize; Size fixedSize;
Alignment fixedAlignment; Alignment fixedAlignment;
bool inFixedBuffer = false; bool inFixedBuffer = false;
bool indirectForDebugInfo = false;
// FIXME: Remove this once LLDB has proper support for resilience.
bool isREPLVar = false;
if (auto *decl = var->getDecl())
if (decl->isREPLVar())
isREPLVar = true;
if (var->isInitializedObject()) { if (var->isInitializedObject()) {
assert(ti.isFixedSize(expansion)); assert(ti.isFixedSize(expansion));
@@ -1837,7 +1830,7 @@ Address IRGenModule::getAddrOfSILGlobalVariable(SILGlobalVariable *var,
fixedAlignment = Layout->getAlignment(); fixedAlignment = Layout->getAlignment();
castStorageToType = cast<FixedTypeInfo>(ti).getStorageType(); castStorageToType = cast<FixedTypeInfo>(ti).getStorageType();
assert(fixedAlignment >= TargetInfo.HeapObjectAlignment); assert(fixedAlignment >= TargetInfo.HeapObjectAlignment);
} else if (isREPLVar || ti.isFixedSize(expansion)) { } else if (ti.isFixedSize(expansion)) {
// Allocate static storage. // Allocate static storage.
auto &fixedTI = cast<FixedTypeInfo>(ti); auto &fixedTI = cast<FixedTypeInfo>(ti);
storageType = fixedTI.getStorageType(); storageType = fixedTI.getStorageType();
@@ -1850,28 +1843,6 @@ Address IRGenModule::getAddrOfSILGlobalVariable(SILGlobalVariable *var,
storageType = getFixedBufferTy(); storageType = getFixedBufferTy();
fixedSize = Size(DataLayout.getTypeAllocSize(storageType)); fixedSize = Size(DataLayout.getTypeAllocSize(storageType));
fixedAlignment = Alignment(DataLayout.getABITypeAlignment(storageType)); fixedAlignment = Alignment(DataLayout.getABITypeAlignment(storageType));
// DebugInfo is not resilient for now, so disable resilience to figure out
// if lldb needs to dereference the global variable or not.
//
// FIXME: Once lldb can make use of remote mirrors to calculate layouts
// at runtime, this should be removed.
{
LoweringModeScope Scope(*this, TypeConverter::Mode::CompletelyFragile);
SILType loweredTy = var->getLoweredType();
auto &nonResilientTI = cast<FixedTypeInfo>(getTypeInfo(loweredTy));
auto packing = nonResilientTI.getFixedPacking(*this);
switch (packing) {
case FixedPacking::OffsetZero:
break;
case FixedPacking::Allocate:
indirectForDebugInfo = true;
break;
default:
llvm_unreachable("Bad packing");
}
}
} }
// Check whether we've created the global variable already. // Check whether we've created the global variable already.
@@ -1913,8 +1884,7 @@ Address IRGenModule::getAddrOfSILGlobalVariable(SILGlobalVariable *var,
auto DbgTy = DebugTypeInfo::getGlobal(var, storageTypeWithContainer, auto DbgTy = DebugTypeInfo::getGlobal(var, storageTypeWithContainer,
fixedSize, fixedAlignment); fixedSize, fixedAlignment);
gvar = createVariable(*this, link, storageTypeWithContainer, gvar = createVariable(*this, link, storageTypeWithContainer,
fixedAlignment, DbgTy, loc, name, inFixedBuffer, fixedAlignment, DbgTy, loc, name, inFixedBuffer);
indirectForDebugInfo);
} }
/// Add a zero initializer. /// Add a zero initializer.
if (forDefinition) if (forDefinition)

View File

@@ -50,8 +50,7 @@ namespace irgen {
createVariable(IRGenModule &IGM, LinkInfo &linkInfo, llvm::Type *objectType, createVariable(IRGenModule &IGM, LinkInfo &linkInfo, llvm::Type *objectType,
Alignment alignment, DebugTypeInfo DebugType = DebugTypeInfo(), Alignment alignment, DebugTypeInfo DebugType = DebugTypeInfo(),
Optional<SILLocation> DebugLoc = None, Optional<SILLocation> DebugLoc = None,
StringRef DebugName = StringRef(), bool heapAllocated = false, StringRef DebugName = StringRef(), bool heapAllocated = false);
bool indirectForDebugInfo = false);
void disableAddressSanitizer(IRGenModule &IGM, llvm::GlobalVariable *var); void disableAddressSanitizer(IRGenModule &IGM, llvm::GlobalVariable *var);
} }

View File

@@ -1066,6 +1066,20 @@ private:
llvm::dwarf::DW_LANG_Swift, nullptr, MangledName); llvm::dwarf::DW_LANG_Swift, nullptr, MangledName);
} }
llvm::DIType *createFixedValueBufferStruct(llvm::DIType *PointeeTy) {
unsigned Line = 0;
unsigned PtrSize = CI.getTargetInfo().getPointerWidth(0);
llvm::DINode::DIFlags Flags = llvm::DINode::FlagArtificial;
llvm::DIFile *File = MainFile;
llvm::DIScope *Scope = TheCU;
llvm::Metadata *Elements[] = {DBuilder.createMemberType(
Scope, "contents", File, 0, PtrSize, 0, 0, Flags, PointeeTy)};
return DBuilder.createStructType(
Scope, "$swift.fixedbuffer", File, Line, 3 * PtrSize, 0, Flags,
/* DerivedFrom */ nullptr, DBuilder.getOrCreateArray(Elements),
llvm::dwarf::DW_LANG_Swift, nullptr);
}
llvm::DIType *createFunctionPointer(DebugTypeInfo DbgTy, llvm::DIScope *Scope, llvm::DIType *createFunctionPointer(DebugTypeInfo DbgTy, llvm::DIScope *Scope,
unsigned SizeInBits, unsigned AlignInBits, unsigned SizeInBits, unsigned AlignInBits,
llvm::DINode::DIFlags Flags, llvm::DINode::DIFlags Flags,
@@ -2227,7 +2241,7 @@ void IRGenDebugInfoImpl::emitDbgIntrinsic(
void IRGenDebugInfoImpl::emitGlobalVariableDeclaration( void IRGenDebugInfoImpl::emitGlobalVariableDeclaration(
llvm::GlobalVariable *Var, StringRef Name, StringRef LinkageName, llvm::GlobalVariable *Var, StringRef Name, StringRef LinkageName,
DebugTypeInfo DbgTy, bool IsLocalToUnit, bool Indirect, DebugTypeInfo DbgTy, bool IsLocalToUnit, bool InFixedBuffer,
Optional<SILLocation> Loc) { Optional<SILLocation> Loc) {
if (Opts.DebugInfoLevel <= IRGenDebugInfoLevel::LineTables) if (Opts.DebugInfoLevel <= IRGenDebugInfoLevel::LineTables)
return; return;
@@ -2240,6 +2254,9 @@ void IRGenDebugInfoImpl::emitGlobalVariableDeclaration(
// would confuse both the user and LLDB. // would confuse both the user and LLDB.
return; return;
if (InFixedBuffer)
Ty = createFixedValueBufferStruct(Ty);
auto L = getStartLocation(Loc); auto L = getStartLocation(Loc);
auto File = getOrCreateFile(L.Filename); auto File = getOrCreateFile(L.Filename);
@@ -2247,9 +2264,6 @@ void IRGenDebugInfoImpl::emitGlobalVariableDeclaration(
llvm::DIExpression *Expr = nullptr; llvm::DIExpression *Expr = nullptr;
if (!Var) if (!Var)
Expr = DBuilder.createConstantValueExpression(0); Expr = DBuilder.createConstantValueExpression(0);
else if (Indirect)
Expr =
DBuilder.createExpression(ArrayRef<uint64_t>(llvm::dwarf::DW_OP_deref));
auto *GV = DBuilder.createGlobalVariableExpression( auto *GV = DBuilder.createGlobalVariableExpression(
MainModule, Name, LinkageName, File, L.Line, Ty, IsLocalToUnit, Expr); MainModule, Name, LinkageName, File, L.Line, Ty, IsLocalToUnit, Expr);
if (Var) if (Var)
@@ -2388,10 +2402,10 @@ void IRGenDebugInfo::emitDbgIntrinsic(IRBuilder &Builder, llvm::Value *Storage,
void IRGenDebugInfo::emitGlobalVariableDeclaration( void IRGenDebugInfo::emitGlobalVariableDeclaration(
llvm::GlobalVariable *Storage, StringRef Name, StringRef LinkageName, llvm::GlobalVariable *Storage, StringRef Name, StringRef LinkageName,
DebugTypeInfo DebugType, bool IsLocalToUnit, bool Indirect, DebugTypeInfo DebugType, bool IsLocalToUnit, bool InFixedBuffer,
Optional<SILLocation> Loc) { Optional<SILLocation> Loc) {
static_cast<IRGenDebugInfoImpl *>(this)->emitGlobalVariableDeclaration( static_cast<IRGenDebugInfoImpl *>(this)->emitGlobalVariableDeclaration(
Storage, Name, LinkageName, DebugType, IsLocalToUnit, Indirect, Loc); Storage, Name, LinkageName, DebugType, IsLocalToUnit, InFixedBuffer, Loc);
} }
void IRGenDebugInfo::emitTypeMetadata(IRGenFunction &IGF, llvm::Value *Metadata, void IRGenDebugInfo::emitTypeMetadata(IRGenFunction &IGF, llvm::Value *Metadata,

View File

@@ -1884,15 +1884,9 @@ void IRGenSILFunction::visitAllocGlobalInst(AllocGlobalInst *i) {
auto expansion = IGM.getResilienceExpansionForLayout(var); auto expansion = IGM.getResilienceExpansionForLayout(var);
// FIXME: Remove this once LLDB has proper support for resilience.
bool isREPLVar = false;
if (auto *decl = var->getDecl())
if (decl->isREPLVar())
isREPLVar = true;
// If the global is fixed-size in all resilience domains that can see it, // If the global is fixed-size in all resilience domains that can see it,
// we allocated storage for it statically, and there's nothing to do. // we allocated storage for it statically, and there's nothing to do.
if (isREPLVar || ti.isFixedSize(expansion)) if (ti.isFixedSize(expansion))
return; return;
// Otherwise, the static storage for the global consists of a fixed-size // Otherwise, the static storage for the global consists of a fixed-size
@@ -1920,15 +1914,9 @@ void IRGenSILFunction::visitGlobalAddrInst(GlobalAddrInst *i) {
Address addr = IGM.getAddrOfSILGlobalVariable(var, ti, Address addr = IGM.getAddrOfSILGlobalVariable(var, ti,
NotForDefinition); NotForDefinition);
// FIXME: Remove this once LLDB has proper support for resilience.
bool isREPLVar = false;
if (auto *decl = var->getDecl())
if (decl->isREPLVar())
isREPLVar = true;
// If the global is fixed-size in all resilience domains that can see it, // If the global is fixed-size in all resilience domains that can see it,
// we allocated storage for it statically, and there's nothing to do. // we allocated storage for it statically, and there's nothing to do.
if (isREPLVar || ti.isFixedSize(expansion)) { if (ti.isFixedSize(expansion)) {
setLoweredAddress(i, addr); setLoweredAddress(i, addr);
return; return;
} }

View File

@@ -327,15 +327,21 @@ private:
return fail<uint64_t>(Failure::TypeHasNoSuchMember, memberName); return fail<uint64_t>(Failure::TypeHasNoSuchMember, memberName);
// Fast path: element 0 is always at offset 0. // Fast path: element 0 is always at offset 0.
if (targetIndex == 0) return uint64_t(0); if (targetIndex == 0)
return uint64_t(0);
// Create an IRGen instance. // Create an IRGen instance.
auto irgen = getIRGen(); auto irgen = getIRGen();
if (!irgen) return Result<uint64_t>::emplaceFailure(Failure::Unknown); if (!irgen)
return Result<uint64_t>::emplaceFailure(Failure::Unknown);
auto &IGM = irgen->IGM; auto &IGM = irgen->IGM;
SILType loweredTy = IGM.getLoweredType(type); SILType loweredTy = IGM.getLoweredType(type);
// Only the runtime metadata knows the offsets of resilient members.
auto &typeInfo = IGM.getTypeInfo(loweredTy);
if (!isa<irgen::FixedTypeInfo>(&typeInfo))
return Result<uint64_t>::emplaceFailure(Failure::NotFixedLayout);
// If the type has a statically fixed offset, return that. // If the type has a statically fixed offset, return that.
if (auto offset = if (auto offset =
irgen::getFixedTupleElementOffset(IGM, loweredTy, targetIndex)) irgen::getFixedTupleElementOffset(IGM, loweredTy, targetIndex))

View File

@@ -22,6 +22,16 @@ let large = Rectangle(p: Point(x: 1, y: 2), s: Size(w: 3, h: 4), color: 5)
// CHECK-SAME: !dbg ![[LARGE:[0-9]+]] // CHECK-SAME: !dbg ![[LARGE:[0-9]+]]
// CHECK: ![[SMALL]] = !DIGlobalVariableExpression( // CHECK: ![[SMALL]] = !DIGlobalVariableExpression(
// CHECK-SAME: var: ![[VAR_SMALL:[0-9]+]]
// CHECK-SAME: expr: !DIExpression()) // CHECK-SAME: expr: !DIExpression())
// CHECK: ![[VAR_SMALL]] = distinct !DIGlobalVariable(
// CHECK-SAME: type: ![[SMALL_TY:[0-9]+]]
// CHECK: ![[SMALL_TY]] = !DICompositeType(tag: DW_TAG_structure_type,
// CHECK-SAME: name: "$swift.fixedbuffer",
// CHECK: ![[LARGE]] = !DIGlobalVariableExpression( // CHECK: ![[LARGE]] = !DIGlobalVariableExpression(
// CHECK-SAME: expr: !DIExpression(DW_OP_deref)) // CHECK-SAME: var: ![[VAR_LARGE:[0-9]+]]
// CHECK-SAME: expr: !DIExpression())
// CHECK: ![[VAR_LARGE]] = distinct !DIGlobalVariable(
// CHECK-SAME: type: ![[LARGE_TY:[0-9]+]]
// CHECK: ![[LARGE_TY]] = !DICompositeType(tag: DW_TAG_structure_type,
// CHECK-SAME: name: "$swift.fixedbuffer",