@@ -602,6 +602,31 @@ void BlocksReachingTensorCode::dump() {
602
602
// FunctionPartitioner
603
603
// ===----------------------------------------------------------------------===//
604
604
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 () { return SourceRange (); }
616
+
617
+ static unsigned getHashValue (const SourceRange &Val) {
618
+ return hash_combine (
619
+ DenseMapInfo<const void *>::getHashValue (Val.Start .getOpaquePointerValue ()),
620
+ DenseMapInfo<const void *>::getHashValue (Val.End .getOpaquePointerValue ()));
621
+ }
622
+
623
+ static bool isEqual (const SourceRange &LHS,
624
+ const SourceRange &RHS) {
625
+ return LHS == RHS;
626
+ }
627
+ };
628
+ } // end llvm namespace
629
+
605
630
namespace {
606
631
// / Marking values in the host program need to either be moved, copied, or have
607
632
// / their results sent over to the accelerator.
@@ -689,6 +714,11 @@ class TFFunctionPartition {
689
714
// / Set of all of the __tf_send calls that silence copy-in warnings.
690
715
SmallPtrSet<SILInstruction*, 8 > explicitCopyMarkers;
691
716
717
+ // / Set of source locations where we have issued copy-to-host warnings.
718
+ llvm::DenseSet<SourceRange> copyToHostWarningLocs;
719
+ // / Set of source locations where we have issued copy-to-accelerator warnings.
720
+ llvm::DenseSet<SourceRange> copyToAccelWarningLocs;
721
+
692
722
struct PartitionedTensorProgram {
693
723
// Initialize all members to NULL.
694
724
PartitionedTensorProgram () {}
@@ -938,7 +968,10 @@ diagnoseCopyToAccelerator(SILValue value, SILInstruction *user,
938
968
939
969
auto &ctx = hostFn.getModule ().getASTContext ();
940
970
941
- // Emit the warning.
971
+ // Emit the warning on this value, if that has not been done before.
972
+ if (!copyToAccelWarningLocs.insert (loc.getSourceRange ()).second )
973
+ return ;
974
+
942
975
diagnose (ctx, loc.getSourceLoc (), diagID, description)
943
976
.highlight (loc.getSourceRange ());
944
977
auto userLoc = getUserSourceLocation (user);
@@ -973,7 +1006,6 @@ diagnoseCopyToAccelerator(SILValue value, SILInstruction *user,
973
1006
// / otherwise emit a warning to tell the programmer that they are doing
974
1007
// / something that induces an implicit data transfer into their code.
975
1008
void TFFunctionPartition::diagnoseUsesFromHost (SILValue value, SILLocation loc){
976
- bool diagnosed = false ;
977
1009
for (auto *use : value->getUses ()) {
978
1010
auto *user = use->getUser ();
979
1011
@@ -995,8 +1027,8 @@ void TFFunctionPartition::diagnoseUsesFromHost(SILValue value, SILLocation loc){
995
1027
if (hostFn.getName () == SWIFT_ENTRY_POINT_FUNCTION)
996
1028
continue ;
997
1029
998
- // Only emit one warning per use .
999
- if (!diagnosed )
1030
+ // Only emit one warning per value, even if it has multiple host uses .
1031
+ if (copyToHostWarningLocs. insert (loc. getSourceRange ()). second )
1000
1032
diagnoseCopyToHost (value, user, loc);
1001
1033
}
1002
1034
}
0 commit comments