Skip to content

Commit 10fd132

Browse files
author
Mingsheng Hong
authored
Only emit one copy-to-host or copy-to-accelerator compiler warning per source location, even if it has multiple host uses. (#18402)
Only emit one copy-to-host or copy-to-accelerator compiler warning per source location, even if it has multiple host uses.
1 parent 44c18b2 commit 10fd132

File tree

4 files changed

+63
-7
lines changed

4 files changed

+63
-7
lines changed

lib/SILOptimizer/Mandatory/TFPartition.cpp

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,36 @@ void BlocksReachingTensorCode::dump() {
602602
// FunctionPartitioner
603603
//===----------------------------------------------------------------------===//
604604

605+
namespace llvm {
606+
template<typename T> struct DenseMapInfo;
607+
608+
// An alternative is to SourceManager::getLineAndColumn() as the
609+
// DenseMap/DenseSet key type instead of SourceRange. That would require that
610+
// the call-site translate a SILLocation / SourceRange to line and column
611+
// numbers first.
612+
template<> struct DenseMapInfo<SourceRange> {
613+
static SourceRange getEmptyKey() { return SourceRange(); }
614+
615+
static SourceRange getTombstoneKey() {
616+
// Make this different from empty key. See for context:
617+
// http://lists.llvm.org/pipermail/llvm-dev/2015-July/088744.html
618+
return SourceRange(SourceLoc(
619+
SMLoc::getFromPointer(DenseMapInfo<const char *>::getTombstoneKey())));
620+
}
621+
622+
static unsigned getHashValue(const SourceRange &Val) {
623+
return hash_combine(
624+
DenseMapInfo<const void *>::getHashValue(Val.Start.getOpaquePointerValue()),
625+
DenseMapInfo<const void *>::getHashValue(Val.End.getOpaquePointerValue()));
626+
}
627+
628+
static bool isEqual(const SourceRange &LHS,
629+
const SourceRange &RHS) {
630+
return LHS == RHS;
631+
}
632+
};
633+
} // end llvm namespace
634+
605635
namespace {
606636
/// Marking values in the host program need to either be moved, copied, or have
607637
/// their results sent over to the accelerator.
@@ -689,6 +719,11 @@ class TFFunctionPartition {
689719
/// Set of all of the __tf_send calls that silence copy-in warnings.
690720
SmallPtrSet<SILInstruction*, 8> explicitCopyMarkers;
691721

722+
/// Set of source locations where we have issued copy-to-host warnings.
723+
llvm::DenseSet<SourceRange> copyToHostWarningLocs;
724+
/// Set of source locations where we have issued copy-to-accelerator warnings.
725+
llvm::DenseSet<SourceRange> copyToAccelWarningLocs;
726+
692727
struct PartitionedTensorProgram {
693728
// Initialize all members to NULL.
694729
PartitionedTensorProgram() {}
@@ -938,7 +973,10 @@ diagnoseCopyToAccelerator(SILValue value, SILInstruction *user,
938973

939974
auto &ctx = hostFn.getModule().getASTContext();
940975

941-
// Emit the warning.
976+
// Emit the warning on this value, if that has not been done before.
977+
if (!copyToAccelWarningLocs.insert(loc.getSourceRange()).second)
978+
return;
979+
942980
diagnose(ctx, loc.getSourceLoc(), diagID, description)
943981
.highlight(loc.getSourceRange());
944982
auto userLoc = getUserSourceLocation(user);
@@ -973,7 +1011,6 @@ diagnoseCopyToAccelerator(SILValue value, SILInstruction *user,
9731011
/// otherwise emit a warning to tell the programmer that they are doing
9741012
/// something that induces an implicit data transfer into their code.
9751013
void TFFunctionPartition::diagnoseUsesFromHost(SILValue value, SILLocation loc){
976-
bool diagnosed = false;
9771014
for (auto *use : value->getUses()) {
9781015
auto *user = use->getUser();
9791016

@@ -995,8 +1032,8 @@ void TFFunctionPartition::diagnoseUsesFromHost(SILValue value, SILLocation loc){
9951032
if (hostFn.getName() == SWIFT_ENTRY_POINT_FUNCTION)
9961033
continue;
9971034

998-
// Only emit one warning per use.
999-
if (!diagnosed)
1035+
// Only emit one warning per value, even if it has multiple host uses.
1036+
if (copyToHostWarningLocs.insert(loc.getSourceRange()).second)
10001037
diagnoseCopyToHost(value, user, loc);
10011038
}
10021039
}

test/TensorFlow/crashers.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,6 @@ public func testMultiResultOp_send_recv() {
244244
// Accelerator -> Host
245245
_hostOp(x)
246246
x += [[2.0]]
247-
// expected-warning @+2{{implicitly copied to the host}}
248247
// expected-warning @+1{{implicitly copied to the host}}
249248
let results = TensorFlow.Raw.softmaxCrossEntropyWithLogits(features: x, labels: x)
250249
// Accelerator -> Host

test/TensorFlow/diagnostics.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,23 @@ public func testDevice() {
4646
_hostOp(extra)
4747
}
4848

49+
// This loop is unrolled, so we have multiple SIL values for `x`, but there
50+
// should be a single copy-to-host compiler warning.
51+
public func SR8412_CopyToHost() {
52+
for _ in 0...10 {
53+
let x = Tensor(1) // expected-warning {{value implicitly copied to the host}}
54+
_hostOp(x)
55+
}
56+
}
57+
58+
@inline(never)
59+
public func hostFunc() -> Tensor<Float> {
60+
return Tensor<Float>(1.0)
61+
}
62+
63+
public func SR8412_CopyToAccel(a: Int32) {
64+
let x = Tensor<Float>(1.0)
65+
for _ in 0...10 {
66+
let _ = hostFunc() + x // expected-warning {{value implicitly copied to the accelerator}}
67+
}
68+
}

test/TensorFlow/integration.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -458,8 +458,8 @@ public struct NonInlineMethodExample {
458458
var b = Tensor<Float>(2.0)
459459

460460
@inline(never)
461-
public mutating func mutatingMethod() { // expected-warning 2 {{value implicitly copied}}
462-
a += b // expected-note 2 {{value used here}}
461+
public mutating func mutatingMethod() { // expected-warning {{value implicitly copied}}
462+
a += b // expected-note {{value used here}}
463463
b += a
464464
}
465465
}

0 commit comments

Comments
 (0)