diff --git a/clang/lib/DPCT/MigrationReport/Statics.cpp b/clang/lib/DPCT/MigrationReport/Statics.cpp index 804dd08124c8..321571a8810d 100644 --- a/clang/lib/DPCT/MigrationReport/Statics.cpp +++ b/clang/lib/DPCT/MigrationReport/Statics.cpp @@ -279,6 +279,7 @@ struct AnalysisModeSummary { class AnalysisModeStats { static const std::string LastMsg; static llvm::StringMap AnalysisModeStaticsMap; + static llvm::StringMap UnsupportedAPIsAndTypes; static struct { uint8_t Flag = 0; @@ -286,6 +287,7 @@ class AnalysisModeStats { } DependencyBits; struct EffortLevelWrap { + bool Unsupported = false; unsigned EL; EffortLevelWrap() : EL(NoEffort) {} EffortLevelWrap &operator=(EffortLevel Other) { @@ -311,7 +313,14 @@ class AnalysisModeStats { void recordEffort(unsigned Offset, EffortLevel Level) { FileEffortsMap[Offset] = Level; } - void recordApisOrTypes(unsigned Offset) { (void)FileEffortsMap[Offset]; } + void recordApisOrTypes(unsigned Offset, StringRef Name, + bool IsMigrated) { + auto &Value = FileEffortsMap[Offset]; + if (!IsMigrated && !Value.Unsupported){ + ++UnsupportedAPIsAndTypes[Name]; + Value.Unsupported = true; + } + } public: static void dump(llvm::raw_ostream &OS) { @@ -343,13 +352,24 @@ class AnalysisModeStats { LineStream(OS, EntryIndent) << "- The Intel " << Names.Strs[i]; } } + if (!UnsupportedAPIsAndTypes.empty()) { + LineStream(OS, Indent) + << llvm::raw_ostream::Colors::BLUE + << "Unsupported APIs and Types:" << llvm::raw_ostream::Colors::RESET; + auto EntryIndent = Indent + AnalysisModeSummary::IndentIncremental; + for (const auto &Entry : UnsupportedAPIsAndTypes) { + LineStream(OS, EntryIndent) << "- " << Entry.first() << " Occurrences " + << Entry.second << " times"; + } + } LineStream(OS, Indent) << LastMsg; } - static void recordApisOrTypes(SourceLocation SL) { + static void recordApisOrTypes(SourceLocation SL, StringRef Name, + bool IsMigrated) { auto LocInfo = DpctGlobalInfo::getLocInfo(SL); AnalysisModeStaticsMap[LocInfo.first.getPath()].recordApisOrTypes( - LocInfo.second); + LocInfo.second, Name, IsMigrated); } static void recordEffort(SourceLocation SL, EffortLevel EL) { auto LocInfo = DpctGlobalInfo::getLocInfo(SL); @@ -375,6 +395,7 @@ const std::string AnalysisModeStats::LastMsg = "https://www.intel.com/content/www/us/en/docs/dpcpp-compatibility-tool/" "developer-guide-reference/current/overview.html for more details."; llvm::StringMap AnalysisModeStats::AnalysisModeStaticsMap; +llvm::StringMap AnalysisModeStats::UnsupportedAPIsAndTypes; void dumpAnalysisModeStatics(llvm::raw_ostream &OS) { if (!DpctGlobalInfo::isAnalysisModeEnabled()) @@ -391,13 +412,13 @@ void recordAnalysisModeEffort(const clang::tooling::UnifiedPath &Filename, AnalysisModeStats::recordEffort(Filename, Offset, EL); } -void recordRecognizedAPI(const CallExpr *CE) { +void recordRecognizedAPI(const CallExpr *CE, StringRef Name, bool IsMigrated) { if (DpctGlobalInfo::isAnalysisModeEnabled()) - AnalysisModeStats::recordApisOrTypes(CE->getBeginLoc()); + AnalysisModeStats::recordApisOrTypes(CE->getBeginLoc(), Name, IsMigrated); } -void recordRecognizedType(TypeLoc TL) { +void recordRecognizedType(TypeLoc TL, StringRef Name, bool IsMigrated) { if (DpctGlobalInfo::isAnalysisModeEnabled()) - AnalysisModeStats::recordApisOrTypes(TL.getBeginLoc()); + AnalysisModeStats::recordApisOrTypes(TL.getBeginLoc(), Name, IsMigrated); } void setDependenciesInfo(const RuleGroups &Group) noexcept { AnalysisModeStats::setDependencies(Group); diff --git a/clang/lib/DPCT/MigrationReport/Statics.h b/clang/lib/DPCT/MigrationReport/Statics.h index f809daae00cb..a1a9707fd204 100644 --- a/clang/lib/DPCT/MigrationReport/Statics.h +++ b/clang/lib/DPCT/MigrationReport/Statics.h @@ -63,8 +63,8 @@ void recordAnalysisModeEffort(SourceLocation SL, EffortLevel EL); void recordAnalysisModeEffort(const clang::tooling::UnifiedPath &Filename, unsigned Offset, EffortLevel EL); -void recordRecognizedAPI(const CallExpr *CE); -void recordRecognizedType(TypeLoc TL); +void recordRecognizedAPI(const CallExpr *CE, StringRef Name, bool IsMigrated); +void recordRecognizedType(TypeLoc TL, StringRef Name, bool IsMigrated); class RuleGroups; void setDependenciesInfo(const RuleGroups &) noexcept; diff --git a/clang/lib/DPCT/RulesLang/RulesLang.cpp b/clang/lib/DPCT/RulesLang/RulesLang.cpp index d4d5238af442..3a8d40ae42c2 100644 --- a/clang/lib/DPCT/RulesLang/RulesLang.cpp +++ b/clang/lib/DPCT/RulesLang/RulesLang.cpp @@ -7904,7 +7904,6 @@ void RecognizeAPINameRule::processFuncCall(const CallExpr *CE) { return; } - recordRecognizedAPI(CE); auto *NSD = dyn_cast(ND->getDeclContext()); Namespace = getNameSpace(NSD); APIName = CE->getCalleeDecl()->getAsFunction()->getNameAsString(); @@ -7914,6 +7913,7 @@ void RecognizeAPINameRule::processFuncCall(const CallExpr *CE) { APIName = Namespace + "::" + APIName; SrcAPIStaticsMap[getFunctionSignature(CE->getCalleeDecl()->getAsFunction(), "")]++; + recordRecognizedAPI(CE, APIName, MigrationStatistics::IsMigrated(APIName)); if (!MigrationStatistics::IsMigrated(APIName)) { const SourceManager &SM = DpctGlobalInfo::getSourceManager(); @@ -7998,12 +7998,13 @@ void RecognizeTypeRule::runRule( PointeeTy + " *"); return; } + recordRecognizedType(*TL, TypeName, false); report(TL->getBeginLoc(), Diagnostics::KNOWN_UNSUPPORTED_TYPE, false, TypeName); return; } if (const TypeLoc *TL = getNodeAsType(Result, "alltypeloc")) { - recordRecognizedType(*TL); + recordRecognizedType(*TL, "", true); } } diff --git a/clang/test/dpct/analysis-mode/multi_files.check b/clang/test/dpct/analysis-mode/multi_files.check new file mode 100644 index 000000000000..48a614ee2097 --- /dev/null +++ b/clang/test/dpct/analysis-mode/multi_files.check @@ -0,0 +1,11 @@ +// CHECK: Total Project: +// CHECK-NEXT: + {{[0-9]+}} lines of code ( {{[0-9]+}}%) will be automatically migrated. +// CHECK-NEXT: - {{[0-9]+}} APIs/Types - No manual effort. +// CHECK-NEXT: - {{[0-9]+}} APIs/Types - Low manual effort for checking and code fixing. +// CHECK-NEXT: - {{[0-9]+}} APIs/Types - Medium manual effort for code fixing. +// CHECK-NEXT: + {{[0-9]+}} lines of code ( {{[0-9]+}}%) will not be automatically migrated. +// CHECK-NEXT: - {{[0-9]+}} APIs/Types - High manual effort for code fixing. +// CHECK: Library Dependencies of SYCL Project: +// CHECK-NEXT: - The Intel oneAPI Math Kernel Library (oneMKL) +// CHECK-NEXT: Unsupported APIs and Types: +// CHECK-NEXT: - cudaDeviceGetPCIBusId Occurrences 2 times \ No newline at end of file diff --git a/clang/test/dpct/analysis-mode/multi_files.cu b/clang/test/dpct/analysis-mode/multi_files.cu new file mode 100644 index 000000000000..6917d0b611c0 --- /dev/null +++ b/clang/test/dpct/analysis-mode/multi_files.cu @@ -0,0 +1,15 @@ +// RUN: dpct %S/multi_files.cu -in-root=%S -out-root=%T/multi -analysis-mode -analysis-mode-output-file=%T/multi_report.out + +// RUN: echo "// CHECK: %S/multi_files.cu:" > %T/multi_files.check +// RUN: echo "// CHECK: %S/multi_files.h:" >> %T/multi_files.check +// RUN: cat %S/multi_files.check >> %T/multi_files.check + +// RUN: FileCheck --match-full-lines --input-file %T/multi_report.out %T/multi_files.check + +#include "multi_files.h" + +void foo() { + int *a; + cudaDeviceGetPCIBusId(nullptr, 0, 0); + cudaMalloc(&a, sizeof(int) * 4); +} \ No newline at end of file diff --git a/clang/test/dpct/analysis-mode/multi_files.h b/clang/test/dpct/analysis-mode/multi_files.h new file mode 100644 index 000000000000..a0c0a65837a7 --- /dev/null +++ b/clang/test/dpct/analysis-mode/multi_files.h @@ -0,0 +1,7 @@ +#include "cublas.h" + +void foo_h() { + int *a; + cudaDeviceGetPCIBusId(nullptr, 0, 0); + cudaMalloc(&a, sizeof(int) * 4); +} \ No newline at end of file diff --git a/clang/test/dpct/analysis-mode/single_file.check b/clang/test/dpct/analysis-mode/single_file.check new file mode 100644 index 000000000000..2a8ab249c27f --- /dev/null +++ b/clang/test/dpct/analysis-mode/single_file.check @@ -0,0 +1,11 @@ +// CHECK-NEXT: + {{[0-9]+}} lines of code ( {{[0-9]+}}%) will be automatically migrated. +// CHECK-NEXT: - {{[0-9]+}} APIs/Types - No manual effort. +// CHECK-NEXT: - {{[0-9]+}} APIs/Types - Low manual effort for checking and code fixing. +// CHECK-NEXT: - {{[0-9]+}} APIs/Types - Medium manual effort for code fixing. +// CHECK-NEXT: + {{[0-9]+}} lines of code ( {{[0-9]+}}%) will not be automatically migrated. +// CHECK-NEXT: - {{[0-9]+}} APIs/Types - High manual effort for code fixing. +// CHECK-NEXT: Library Dependencies of SYCL Project: +// CHECK-NEXT: - The Intel oneAPI Deep Neural Network Library (oneDNN) +// CHECK-NEXT: Unsupported APIs and Types: +// CHECK-NEXT: - cudaDeviceGetPCIBusId Occurrences 2 times +// CHECK-NEXT: - cudnnReduceTensorIndices_t Occurrences 1 times \ No newline at end of file diff --git a/clang/test/dpct/analysis-mode/single_file.cu b/clang/test/dpct/analysis-mode/single_file.cu new file mode 100644 index 000000000000..8166d8b3230f --- /dev/null +++ b/clang/test/dpct/analysis-mode/single_file.cu @@ -0,0 +1,16 @@ +// RUN: dpct -in-root=%S -out-root=%T/single -analysis-mode -analysis-mode-output-file=%T/single_file.out %S/single_file.cu + +// RUN: echo "// CHECK: %S/single_file.cu:" > %T/single_file.check +// RUN: cat %S/single_file.check >> %T/single.check + +// RUN: FileCheck --match-full-lines --input-file %T/single_file.out %T/single_file.check + +#include "cudnn.h" + +void foo() { + int *a; + cudnnReduceTensorIndices_t m; + cudaDeviceGetPCIBusId(nullptr, 0, 0); + cudaDeviceGetPCIBusId(nullptr, 0, 0); + cudaMalloc(&a, sizeof(int) * 4); +} \ No newline at end of file