Skip to content

Commit 5bbe84b

Browse files
authored
[AutoDiff] Add mangling for @differentiable function types. (#26595)
Add mangling support for `@differentiable` and `@differentiable(linear)` function types. This fixes debug info builds. Previously, IRGenDebugInfo crashed because `@differentiable` function types did not have full mangling support. `IRGenDebugInfoImpl::getOrCreateType` computes `llvm::DIType` type debug info by demangling type names, leading to a type size inconsistency for `@differentiable` function types. Change `tensorflow_osx_base` build preset to use `--release-debuginfo`. macOS toolchains (with TensorFlow) now have debug info again. Resolves TF-597.
1 parent c189a7e commit 5bbe84b

File tree

12 files changed

+119
-5
lines changed

12 files changed

+119
-5
lines changed

docs/ABI/Mangling.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -583,12 +583,16 @@ mangled in to disambiguate.
583583
impl-function-type ::= type* 'I' FUNC-ATTRIBUTES '_'
584584
impl-function-type ::= type* generic-signature 'I' PSEUDO-GENERIC? FUNC-ATTRIBUTES '_'
585585

586-
FUNC-ATTRIBUTES ::= CALLEE-ESCAPE? CALLEE-CONVENTION FUNC-REPRESENTATION? PARAM-CONVENTION* RESULT-CONVENTION* ('z' RESULT-CONVENTION)
586+
FUNC-ATTRIBUTES ::= CALLEE-ESCAPE? DIFFERENTIABILITY-KIND? CALLEE-CONVENTION FUNC-REPRESENTATION? PARAM-CONVENTION* RESULT-CONVENTION* ('z' RESULT-CONVENTION)
587587

588588
PSEUDO-GENERIC ::= 'P'
589589

590590
CALLEE-ESCAPE ::= 'e' // @escaping (inverse of SIL @noescape)
591591

592+
DIFFERENTIABILITY-KIND ::= DIFFERENTIABLE | LINEAR
593+
DIFFERENTIABLE ::= 'd' // @differentiable
594+
LINEAR ::= 'l' // @differentiable(linear)
595+
592596
CALLEE-CONVENTION ::= 'y' // @callee_unowned
593597
CALLEE-CONVENTION ::= 'g' // @callee_guaranteed
594598
CALLEE-CONVENTION ::= 'x' // @callee_owned

include/swift/Demangling/DemangleNodes.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ NODE(Identifier)
115115
NODE(Index)
116116
CONTEXT_NODE(IVarInitializer)
117117
CONTEXT_NODE(IVarDestroyer)
118+
// SWIFT_ENABLE_TENSORFLOW
119+
NODE(ImplDifferentiable)
120+
NODE(ImplLinear)
121+
// SWIFT_ENABLE_TENSORFLOW END
118122
NODE(ImplEscaping)
119123
NODE(ImplConvention)
120124
NODE(ImplFunctionAttribute)

lib/AST/ASTMangler.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1445,6 +1445,18 @@ void ASTMangler::appendImplFunctionType(SILFunctionType *fn) {
14451445
if (!fn->isNoEscape())
14461446
OpArgs.push_back('e');
14471447

1448+
// SWIFT_ENABLE_TENSORFLOW
1449+
switch (fn->getExtInfo().getDifferentiabilityKind()) {
1450+
case DifferentiabilityKind::NonDifferentiable:
1451+
break;
1452+
case DifferentiabilityKind::Normal:
1453+
OpArgs.push_back('d');
1454+
break;
1455+
case DifferentiabilityKind::Linear:
1456+
OpArgs.push_back('l');
1457+
break;
1458+
}
1459+
14481460
// <impl-callee-convention>
14491461
if (fn->getExtInfo().hasContext()) {
14501462
OpArgs.push_back(getParamConvention(fn->getCalleeConvention()));

lib/Demangling/Demangler.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1729,6 +1729,12 @@ NodePointer Demangler::demangleImplFunctionType() {
17291729
if (nextIf('e'))
17301730
type->addChild(createNode(Node::Kind::ImplEscaping), *this);
17311731

1732+
// SWIFT_ENABLE_TENSORFLOW
1733+
if (nextIf('d'))
1734+
type->addChild(createNode(Node::Kind::ImplDifferentiable), *this);
1735+
if (nextIf('l'))
1736+
type->addChild(createNode(Node::Kind::ImplLinear), *this);
1737+
17321738
const char *CAttr = nullptr;
17331739
switch (nextChar()) {
17341740
case 'y': CAttr = "@callee_unowned"; break;

lib/Demangling/NodePrinter.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,10 @@ class NodePrinter {
393393
case Node::Kind::Index:
394394
case Node::Kind::IVarInitializer:
395395
case Node::Kind::IVarDestroyer:
396+
// SWIFT_ENABLE_TENSORFLOW
397+
case Node::Kind::ImplDifferentiable:
398+
case Node::Kind::ImplLinear:
399+
// SWIFT_ENABLE_TENSORFLOW END
396400
case Node::Kind::ImplEscaping:
397401
case Node::Kind::ImplConvention:
398402
case Node::Kind::ImplFunctionAttribute:
@@ -2019,6 +2023,14 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) {
20192023
return nullptr;
20202024
case Node::Kind::LabelList:
20212025
return nullptr;
2026+
// SWIFT_ENABLE_TENSORFLOW
2027+
case Node::Kind::ImplDifferentiable:
2028+
Printer << "@differentiable";
2029+
return nullptr;
2030+
case Node::Kind::ImplLinear:
2031+
Printer << "@differentiable(linear)";
2032+
return nullptr;
2033+
// SWIFT_ENABLE_TENSORFLOW END
20222034
case Node::Kind::ImplEscaping:
20232035
Printer << "@escaping";
20242036
return nullptr;

lib/Demangling/OldRemangler.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,6 +1267,18 @@ void Remangler::mangleImplResult(Node *node) {
12671267
mangleChildNodes(node); // impl convention, type
12681268
}
12691269

1270+
// SWIFT_ENABLE_TENSORFLOW
1271+
void Remangler::mangleImplDifferentiable(Node *node) {
1272+
// The old mangler does not encode `@differentiable` function types.
1273+
Buffer << 'd';
1274+
}
1275+
1276+
// SWIFT_ENABLE_TENSORFLOW
1277+
void Remangler::mangleImplLinear(Node *node) {
1278+
// The old mangler does not encode `@differentiable(linear)` function types.
1279+
Buffer << 'l';
1280+
}
1281+
12701282
void Remangler::mangleImplEscaping(Node *node) {
12711283
// The old mangler does not encode escaping.
12721284
}

lib/Demangling/Remangler.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,6 +1379,16 @@ void Remangler::mangleIVarDestroyer(Node *node) {
13791379
Buffer << "fE";
13801380
}
13811381

1382+
// SWIFT_ENABLE_TENSORFLOW
1383+
void Remangler::mangleImplDifferentiable(Node *node) {
1384+
Buffer << 'd';
1385+
}
1386+
1387+
// SWIFT_ENABLE_TENSORFLOW
1388+
void Remangler::mangleImplLinear(Node *node) {
1389+
Buffer << 'l';
1390+
}
1391+
13821392
void Remangler::mangleImplEscaping(Node *node) {
13831393
Buffer << 'e';
13841394
}
@@ -1423,6 +1433,14 @@ void Remangler::mangleImplFunctionType(Node *node) {
14231433
Buffer << 'I' << PseudoGeneric;
14241434
for (NodePointer Child : *node) {
14251435
switch (Child->getKind()) {
1436+
// SWIFT_ENABLE_TENSORFLOW
1437+
case Node::Kind::ImplDifferentiable:
1438+
Buffer << 'd';
1439+
break;
1440+
case Node::Kind::ImplLinear:
1441+
Buffer << 'l';
1442+
break;
1443+
// SWIFT_ENABLE_TENSORFLOW END
14261444
case Node::Kind::ImplEscaping:
14271445
Buffer << 'e';
14281446
break;

lib/IRGen/GenDiffFunc.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
using namespace swift;
3333
using namespace irgen;
3434

35+
/// A pair of `@differentiable` function extractee and differentiation order.
3536
using DiffFuncIndex =
3637
std::pair<AutoDiffFunctionExtractInst::Extractee, unsigned>;
3738

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// RUN: %target-swift-frontend -c %s -g -O -parse-stdlib -parse-as-library -module-name Swift
2+
3+
// TF-597: Exact minimal reproducer for IRGenDebugInfo crash.
4+
// Crash occurred only with `-g` and `-O`.
5+
//
6+
// ```
7+
// Assertion failed: (OffsetInBits + SizeInBits <= getSizeInBits(Var) && "pars > totum"),
8+
// function emitVariableDeclaration, file swift/lib/IRGen/IRGenDebugInfo.cpp, line 2216.
9+
// Stack dump:
10+
// 1. Swift version 5.1-dev (LLVM 200186e28b, Swift c09c14dec5)
11+
// 2. While emitting IR SIL function "@$ss8pullback2at2inyx_q_xXFts14DifferentiableRzsADR_r0_lF".
12+
// for 'pullback(at:in:)' (at swift/test/AutoDiff/differentiable_func_debuginfo.swift:21:8)
13+
// ```
14+
//
15+
// The crash was because `IRGenDebugInfoImpl::getOrCreateType` computes
16+
// `llvm::DIType` type debug info by demangling type names.
17+
//
18+
// Since `@differentiable` and `@differentiable(linear)` function types did
19+
// not have mangling support, `getOrCreateType` computed a regular `(A) -> B`
20+
// function type instead of a `@differentiable (A) -> B` function type, leading
21+
// to a type size inconsistency.
22+
//
23+
// Conclusion: mangling coverage is important.
24+
25+
// Minimal dummy compiler-known `Differentiable` protocol.
26+
public protocol Differentiable {
27+
associatedtype TangentVector
28+
}
29+
30+
// This declaration is necessary to reproduce the crash for some reason.
31+
public func blackHole<T, U>(_: (T) -> U) {}
32+
33+
public func pullback<T, R>(
34+
at x: T, in tf597ProblematicVarDecl: @differentiable (T) -> R
35+
) {
36+
let _ = Builtin.autodiffApply_vjp(tf597ProblematicVarDecl, x)
37+
}

test/Demangle/Inputs/manglings.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,3 +351,6 @@ $s18keypaths_inlinable13KeypathStructV8computedSSvpACTKq ---> key path getter f
351351
$s18resilient_protocol24ResilientDerivedProtocolPxAA0c4BaseE0Tn --> associated conformance descriptor for resilient_protocol.ResilientDerivedProtocol.A: resilient_protocol.ResilientBaseProtocol
352352
$s3red4testyAA3ResOyxSayq_GAEs5ErrorAAq_sAFHD1__HCg_GADyxq_GsAFR_r0_lF --> red.test<A, B where B: Swift.Error>(red.Res<A, B>) -> red.Res<A, [B]>
353353
$s3red4testyAA7OurTypeOy4them05TheirD0Vy5AssocQzGAjE0F8ProtocolAAxAA0c7DerivedH0HD1_AA0c4BaseH0HI1_AieKHA2__HCg_GxmAaLRzlF ---> red.test<A where A: red.OurDerivedProtocol>(A.Type) -> red.OurType<them.TheirType<A.Assoc>>
354+
// SWIFT_ENABLE_TENSORFLOW
355+
$sxq_Idgnr_D ---> @differentiable @callee_guaranteed (@in_guaranteed A) -> (@out B)
356+
$sxq_Ilgnr_D ---> @differentiable(linear) @callee_guaranteed (@in_guaranteed A) -> (@out B)

test/SILGen/mangling.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,3 +184,11 @@ func varargsVsArray(arr: [Int], n: String) { }
184184

185185
// CHECK-LABEL: sil hidden [ossa] @$s8mangling14varargsVsArray3arr1nySaySiGd_SStF : $@convention(thin) (@guaranteed Array<Array<Int>>, @guaranteed String) -> ()
186186
func varargsVsArray(arr: [Int]..., n: String) { }
187+
188+
// SWIFT_ENABLE_TENSORFLOW
189+
// CHECK-LABEL: sil hidden [ossa] @$s8mangling15funcVsDiffFunc12fnyS2fXE_tF : $@convention(thin) (@noescape @callee_guaranteed (Float) -> Float) -> ()
190+
func funcVsDiffFunc1(fn: (Float) -> Float) {}
191+
192+
// SWIFT_ENABLE_TENSORFLOW
193+
// CHECK-LABEL: sil hidden [ossa] @$s8mangling15funcVsDiffFunc22fnyS2fXF_tF : $@convention(thin) (@differentiable @noescape @callee_guaranteed (Float) -> Float) -> ()
194+
func funcVsDiffFunc2(fn: @differentiable (Float) -> Float) {}

utils/build-presets.ini

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2143,10 +2143,7 @@ libcxx
21432143
indexstore-db
21442144
sourcekit-lsp
21452145

2146-
# SWIFT_ENABLE_TENSORFLOW
2147-
# FIXME(TF-597): IRGenDebugInfo crash for `pullback(at:in:)`.
2148-
# release-debuginfo
2149-
release
2146+
release-debuginfo
21502147

21512148
lldb-no-debugserver
21522149
lldb-use-system-debugserver

0 commit comments

Comments
 (0)