@@ -602,6 +602,36 @@ 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 () {
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
+
605
635
namespace {
606
636
// / Marking values in the host program need to either be moved, copied, or have
607
637
// / their results sent over to the accelerator.
@@ -689,6 +719,11 @@ class TFFunctionPartition {
689
719
// / Set of all of the __tf_send calls that silence copy-in warnings.
690
720
SmallPtrSet<SILInstruction*, 8 > explicitCopyMarkers;
691
721
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
+
692
727
struct PartitionedTensorProgram {
693
728
// Initialize all members to NULL.
694
729
PartitionedTensorProgram () {}
@@ -938,7 +973,10 @@ diagnoseCopyToAccelerator(SILValue value, SILInstruction *user,
938
973
939
974
auto &ctx = hostFn.getModule ().getASTContext ();
940
975
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
+
942
980
diagnose (ctx, loc.getSourceLoc (), diagID, description)
943
981
.highlight (loc.getSourceRange ());
944
982
auto userLoc = getUserSourceLocation (user);
@@ -973,7 +1011,6 @@ diagnoseCopyToAccelerator(SILValue value, SILInstruction *user,
973
1011
// / otherwise emit a warning to tell the programmer that they are doing
974
1012
// / something that induces an implicit data transfer into their code.
975
1013
void TFFunctionPartition::diagnoseUsesFromHost (SILValue value, SILLocation loc){
976
- bool diagnosed = false ;
977
1014
for (auto *use : value->getUses ()) {
978
1015
auto *user = use->getUser ();
979
1016
@@ -995,8 +1032,8 @@ void TFFunctionPartition::diagnoseUsesFromHost(SILValue value, SILLocation loc){
995
1032
if (hostFn.getName () == SWIFT_ENTRY_POINT_FUNCTION)
996
1033
continue ;
997
1034
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 )
1000
1037
diagnoseCopyToHost (value, user, loc);
1001
1038
}
1002
1039
}
0 commit comments