mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Don't emit shadow copies for anonymous variables.
Switch statements generate at least one anonymous match variable per case, which consumes both a lot of stack space and an explosion of range extension depencies due to the way case statements are scoped. rdar://problem/34326355
This commit is contained in:
@@ -1994,19 +1994,7 @@ void IRGenDebugInfoImpl::emitDbgIntrinsic(
|
||||
return;
|
||||
}
|
||||
|
||||
// If the storage is an instruction, insert the dbg.value directly after it.
|
||||
if (auto *I = dyn_cast<llvm::Instruction>(Storage)) {
|
||||
auto InsPt = std::next(I->getIterator());
|
||||
auto E = I->getParent()->end();
|
||||
while (InsPt != E && isa<llvm::PHINode>(&*InsPt))
|
||||
++InsPt;
|
||||
if (InsPt != E) {
|
||||
DBuilder.insertDbgValueIntrinsic(Storage, Var, Expr, DL, &*InsPt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise just insert it at the current insertion point.
|
||||
// Insert a dbg.value at the current insertion point.
|
||||
DBuilder.insertDbgValueIntrinsic(Storage, Var, Expr, DL, BB);
|
||||
}
|
||||
|
||||
|
||||
@@ -578,13 +578,15 @@ public:
|
||||
}
|
||||
|
||||
template <class DebugVarCarryingInst>
|
||||
StringRef getVarName(DebugVarCarryingInst *i) {
|
||||
StringRef getVarName(DebugVarCarryingInst *i, bool &IsAnonymous) {
|
||||
StringRef Name = i->getVarInfo().Name;
|
||||
// The $match variables generated by the type checker are not
|
||||
// guaranteed to be unique within their scope, but they have
|
||||
// unique VarDecls.
|
||||
if ((Name.empty() || Name == "$match") && i->getDecl())
|
||||
if ((Name.empty() || Name == "$match") && i->getDecl()) {
|
||||
IsAnonymous = true;
|
||||
return getOrCreateAnonymousVarName(i->getDecl());
|
||||
}
|
||||
return Name;
|
||||
}
|
||||
|
||||
@@ -665,15 +667,13 @@ public:
|
||||
/// register allocator doesn't elide the dbg.value intrinsic when
|
||||
/// register pressure is high. There is a trade-off to this: With
|
||||
/// shadow copies, we lose the precise lifetime.
|
||||
llvm::Value *emitShadowCopy(llvm::Value *Storage,
|
||||
const SILDebugScope *Scope,
|
||||
StringRef Name, unsigned ArgNo,
|
||||
llvm::Value *emitShadowCopy(llvm::Value *Storage, const SILDebugScope *Scope,
|
||||
StringRef Name, unsigned ArgNo, bool IsAnonymous,
|
||||
Alignment Align = Alignment(0)) {
|
||||
auto Ty = Storage->getType();
|
||||
// Never emit shadow copies when optimizing, or if already on the stack.
|
||||
if (IGM.IRGen.Opts.shouldOptimize() ||
|
||||
isa<llvm::AllocaInst>(Storage) ||
|
||||
isa<llvm::UndefValue>(Storage) ||
|
||||
if (IGM.IRGen.Opts.shouldOptimize() || IsAnonymous ||
|
||||
isa<llvm::AllocaInst>(Storage) || isa<llvm::UndefValue>(Storage) ||
|
||||
Ty == IGM.RefCountedPtrTy) // No debug info is emitted for refcounts.
|
||||
return Storage;
|
||||
|
||||
@@ -701,16 +701,17 @@ public:
|
||||
}
|
||||
|
||||
llvm::Value *emitShadowCopy(Address Storage, const SILDebugScope *Scope,
|
||||
StringRef Name, unsigned ArgNo) {
|
||||
return emitShadowCopy(Storage.getAddress(), Scope, Name, ArgNo,
|
||||
StringRef Name, unsigned ArgNo,
|
||||
bool IsAnonymous) {
|
||||
return emitShadowCopy(Storage.getAddress(), Scope, Name, ArgNo, IsAnonymous,
|
||||
Storage.getAlignment());
|
||||
}
|
||||
|
||||
void emitShadowCopy(ArrayRef<llvm::Value *> vals, const SILDebugScope *Scope,
|
||||
StringRef Name, unsigned ArgNo,
|
||||
StringRef Name, unsigned ArgNo, bool IsAnonymous,
|
||||
llvm::SmallVectorImpl<llvm::Value *> ©) {
|
||||
// Only do this at -O0.
|
||||
if (IGM.IRGen.Opts.shouldOptimize()) {
|
||||
if (IGM.IRGen.Opts.shouldOptimize() || IsAnonymous) {
|
||||
copy.append(vals.begin(), vals.end());
|
||||
return;
|
||||
}
|
||||
@@ -718,7 +719,7 @@ public:
|
||||
// Single or empty values.
|
||||
if (vals.size() <= 1) {
|
||||
for (auto val : vals)
|
||||
copy.push_back(emitShadowCopy(val, Scope, Name, ArgNo));
|
||||
copy.push_back(emitShadowCopy(val, Scope, Name, ArgNo, IsAnonymous));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3435,7 +3436,7 @@ void IRGenSILFunction::emitErrorResultVar(SILResultInfo ErrorInfo,
|
||||
auto ErrorResultSlot = getErrorResultSlot(IGM.silConv.getSILType(ErrorInfo));
|
||||
SILDebugVariable Var = DbgValue->getVarInfo();
|
||||
auto Storage = emitShadowCopy(ErrorResultSlot.getAddress(), getDebugScope(),
|
||||
Var.Name, Var.ArgNo);
|
||||
Var.Name, Var.ArgNo, false);
|
||||
DebugTypeInfo DTI(nullptr, nullptr, ErrorInfo.getType(),
|
||||
ErrorResultSlot->getType(), IGM.getPointerSize(),
|
||||
IGM.getPointerAlignment(), true);
|
||||
@@ -3460,7 +3461,8 @@ void IRGenSILFunction::visitDebugValueInst(DebugValueInst *i) {
|
||||
return;
|
||||
}
|
||||
|
||||
StringRef Name = getVarName(i);
|
||||
bool IsAnonymous = false;
|
||||
StringRef Name = getVarName(i, IsAnonymous);
|
||||
DebugTypeInfo DbgTy;
|
||||
SILType SILTy = SILVal->getType();
|
||||
auto RealTy = SILVal->getType().getSwiftRValueType();
|
||||
@@ -3481,7 +3483,8 @@ void IRGenSILFunction::visitDebugValueInst(DebugValueInst *i) {
|
||||
llvm::SmallVector<llvm::Value *, 8> Copy;
|
||||
Explosion e = getLoweredExplosion(SILVal);
|
||||
unsigned ArgNo = i->getVarInfo().ArgNo;
|
||||
emitShadowCopy(e.claimAll(), i->getDebugScope(), Name, ArgNo, Copy);
|
||||
emitShadowCopy(e.claimAll(), i->getDebugScope(), Name, ArgNo, IsAnonymous,
|
||||
Copy);
|
||||
emitDebugVariableDeclaration(Copy, DbgTy, SILTy, i->getDebugScope(),
|
||||
i->getDecl(), Name, ArgNo);
|
||||
}
|
||||
@@ -3497,7 +3500,8 @@ void IRGenSILFunction::visitDebugValueAddrInst(DebugValueAddrInst *i) {
|
||||
if (isa<SILUndef>(SILVal))
|
||||
return;
|
||||
|
||||
StringRef Name = getVarName(i);
|
||||
bool IsAnonymous = false;
|
||||
StringRef Name = getVarName(i, IsAnonymous);
|
||||
auto Addr = getLoweredAddress(SILVal).getAddress();
|
||||
SILType SILTy = SILVal->getType();
|
||||
auto RealType = SILTy.getSwiftRValueType();
|
||||
@@ -3519,7 +3523,7 @@ void IRGenSILFunction::visitDebugValueAddrInst(DebugValueAddrInst *i) {
|
||||
// intrinsic.
|
||||
unsigned ArgNo = i->getVarInfo().ArgNo;
|
||||
emitDebugVariableDeclaration(
|
||||
emitShadowCopy(Addr, i->getDebugScope(), Name, ArgNo), DbgTy,
|
||||
emitShadowCopy(Addr, i->getDebugScope(), Name, ArgNo, IsAnonymous), DbgTy,
|
||||
SILType(), i->getDebugScope(), Decl, Name, ArgNo,
|
||||
DbgTy.isImplicitlyIndirect() ? DirectValue : IndirectValue);
|
||||
}
|
||||
@@ -3736,7 +3740,8 @@ void IRGenSILFunction::emitDebugInfoForAllocStack(AllocStackInst *i,
|
||||
auto DbgTy = DebugTypeInfo::getLocalVariable(
|
||||
CurSILFn->getDeclContext(), CurSILFn->getGenericEnvironment(), Decl,
|
||||
RealType, type, false);
|
||||
StringRef Name = getVarName(i);
|
||||
bool IsAnonymous = false;
|
||||
StringRef Name = getVarName(i, IsAnonymous);
|
||||
if (auto DS = i->getDebugScope())
|
||||
emitDebugVariableDeclaration(addr, DbgTy, SILTy, DS, Decl, Name,
|
||||
i->getVarInfo().ArgNo);
|
||||
@@ -3751,7 +3756,8 @@ void IRGenSILFunction::visitAllocStackInst(swift::AllocStackInst *i) {
|
||||
StringRef dbgname;
|
||||
# ifndef NDEBUG
|
||||
// If this is a DEBUG build, use pretty names for the LLVM IR.
|
||||
dbgname = getVarName(i);
|
||||
bool IsAnonymous = false;
|
||||
dbgname = getVarName(i, IsAnonymous);
|
||||
# endif
|
||||
|
||||
(void) Decl;
|
||||
@@ -3888,8 +3894,9 @@ void IRGenSILFunction::visitAllocBoxInst(swift::AllocBoxInst *i) {
|
||||
->getFieldType(IGM.getSILModule(), 0));
|
||||
|
||||
// Derive name from SIL location.
|
||||
bool IsAnonymous = false;
|
||||
VarDecl *Decl = i->getDecl();
|
||||
StringRef Name = getVarName(i);
|
||||
StringRef Name = getVarName(i, IsAnonymous);
|
||||
StringRef DbgName =
|
||||
# ifndef NDEBUG
|
||||
// If this is a DEBUG build, use pretty names for the LLVM IR.
|
||||
@@ -3928,7 +3935,8 @@ void IRGenSILFunction::visitAllocBoxInst(swift::AllocBoxInst *i) {
|
||||
|
||||
IGM.DebugInfo->emitVariableDeclaration(
|
||||
Builder,
|
||||
emitShadowCopy(boxWithAddr.getAddress(), i->getDebugScope(), Name, 0),
|
||||
emitShadowCopy(boxWithAddr.getAddress(), i->getDebugScope(), Name, 0,
|
||||
IsAnonymous),
|
||||
DbgTy, i->getDebugScope(), Decl, Name, 0,
|
||||
DbgTy.isImplicitlyIndirect() ? DirectValue : IndirectValue);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// RUN: %target-swift-frontend -primary-file %s -emit-ir -g -o - | %FileCheck %s
|
||||
|
||||
// CHECK: !DILocalVariable(name: "x4", arg: 4
|
||||
// CHECK: !DILocalVariable(name: "_0", arg: 1
|
||||
// CHECK: !DILocalVariable(name: "_1", arg: 2
|
||||
// CHECK: !DILocalVariable(name: "_2", arg: 3
|
||||
// CHECK: !DILocalVariable(name: "x4", arg: 4
|
||||
|
||||
public func fourth<T>(_: T, _: T, _: T, x4 : T) -> T {
|
||||
return x4
|
||||
|
||||
@@ -31,27 +31,28 @@ public func mangle(s: [UnicodeScalar]) -> [UnicodeScalar] {
|
||||
|
||||
// The patterns in the first case statement each define an anonymous variable,
|
||||
// which shares the storage with the expression in the switch statement. Make
|
||||
// sure we only emit live range extensions for the storage once per basic block.
|
||||
// sure we emit a dbg.value once per basic block.
|
||||
|
||||
// CHECK: define {{.*}}@_T011patternvars6mangleSayAA13UnicodeScalarVGAE1s_tFA2DcfU_
|
||||
// CHECK: call void asm sideeffect "", "r"
|
||||
// CHECK-NOT: call void asm sideeffect "", "r"
|
||||
// CHECK: br {{.*}}label
|
||||
// CHECK: call void asm sideeffect "", "r"
|
||||
// CHECK-NOT: call void asm sideeffect "", "r"
|
||||
// CHECK: br {{.*}}label
|
||||
// CHECK: call void asm sideeffect "", "r"
|
||||
// CHECK-NOT: call void asm sideeffect "", "r"
|
||||
// CHECK: br {{.*}}label
|
||||
// CHECK: call void asm sideeffect "", "r"
|
||||
// CHECK-NOT: call void asm sideeffect "", "r"
|
||||
// CHECK: br {{.*}}label
|
||||
// CHECK: call void asm sideeffect "", "r"
|
||||
// CHECK-NOT: call void asm sideeffect "", "r"
|
||||
// CHECK: br {{.*}}label
|
||||
// CHECK: call void asm sideeffect "", "r"
|
||||
// CHECK-NOT: call void asm sideeffect "", "r"
|
||||
// CHECK: br {{.*}}label
|
||||
// CHECK: call void asm sideeffect "", "r"
|
||||
// CHECK-NOT: call void asm sideeffect "", "r"
|
||||
// CHECK: br {{.*}}label
|
||||
// CHECK: %[[VAL:[0-9]+]] = call swiftcc i32 @_T011patternvars13UnicodeScalarV5values6UInt32Vvg(i32 %0)
|
||||
// CHECK-NEXT: call void @llvm.dbg.value(metadata i32 %[[VAL]]
|
||||
// CHECK: ; <label>
|
||||
// CHECK: call void @llvm.dbg.value(metadata i32 %[[VAL]]
|
||||
// CHECK-NOT: call void @llvm.dbg.value
|
||||
// CHECK-NOT: call void asm sideeffect "", "r"
|
||||
|
||||
// CHECK: ; <label>
|
||||
// CHECK: call void @llvm.dbg.value(metadata i32 %[[VAL]]
|
||||
// CHECK-NOT: call void @llvm.dbg.value
|
||||
// CHECK-NOT: call void asm sideeffect "", "r"
|
||||
|
||||
// CHECK: ; <label>
|
||||
// CHECK: call void @llvm.dbg.value(metadata i32 %[[VAL]]
|
||||
// CHECK-NOT: call void @llvm.dbg.value
|
||||
// CHECK-NOT: call void asm sideeffect "", "r"
|
||||
|
||||
// CHECK: ; <label>
|
||||
// CHECK: call void @llvm.dbg.value(metadata i32 %[[VAL]]
|
||||
// CHECK-NOT: call void @llvm.dbg.value
|
||||
// CHECK-NOT: call void asm sideeffect "", "r"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user