diff --git a/include/swift/SIL/SILProfiler.h b/include/swift/SIL/SILProfiler.h index 4007493ca1ac1..45b2aa99ede8b 100644 --- a/include/swift/SIL/SILProfiler.h +++ b/include/swift/SIL/SILProfiler.h @@ -94,9 +94,6 @@ class SILProfiler : public SILAllocated { return RegionCounterMap; } - /// Increment the number of counter updates associated with this profiler. - void recordCounterUpdate(); - private: /// Map counters to ASTNodes and set them up for profiling the function. void assignRegionCounters(); diff --git a/lib/IRGen/GenBuiltin.cpp b/lib/IRGen/GenBuiltin.cpp index cb79a0a6154a9..12cc8c1128aa6 100644 --- a/lib/IRGen/GenBuiltin.cpp +++ b/lib/IRGen/GenBuiltin.cpp @@ -206,7 +206,9 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin, if (IID == llvm::Intrinsic::instrprof_increment) { // If we import profiling intrinsics from a swift module but profiling is // not enabled, ignore the increment. - if (!IGF.getSILModule().getOptions().GenerateProfile) { + SILModule &SILMod = IGF.getSILModule(); + const auto &Opts = SILMod.getOptions(); + if (!Opts.GenerateProfile) { (void)args.claimAll(); return; } @@ -246,6 +248,15 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin, replacement.add(NameGEP); replacement.add(args.claimAll()); args = std::move(replacement); + + if (Opts.EmitProfileCoverageMapping) { + // Update the associated coverage mapping: it's now safe to emit, because + // a symtab entry for this function is guaranteed (r://39146527). + auto &coverageMaps = SILMod.getCoverageMaps(); + auto CovMapIt = coverageMaps.find(PGOFuncName); + if (CovMapIt != coverageMaps.end()) + CovMapIt->second->setSymtabEntryGuaranteed(); + } } if (IID != llvm::Intrinsic::not_intrinsic) { diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp index 81c674f79f44b..125ab71248db7 100644 --- a/lib/IRGen/GenDecl.cpp +++ b/lib/IRGen/GenDecl.cpp @@ -1065,7 +1065,6 @@ void IRGenerator::emitGlobalTopLevel(bool emitForParallelEmission) { CurrentIGMPtr IGM = getGenModule(decl ? decl->getDeclContext() : nullptr); IGM->emitSILGlobalVariable(&v); } - PrimaryIGM->emitCoverageMapping(); // Emit SIL functions. for (SILFunction &f : PrimaryIGM->getSILModule()) { @@ -1099,6 +1098,9 @@ void IRGenerator::emitGlobalTopLevel(bool emitForParallelEmission) { IGM->emitSILProperty(&prop); } + // Emit code coverage mapping data. + PrimaryIGM->emitCoverageMapping(); + for (auto Iter : *this) { IRGenModule *IGM = Iter.second; IGM->finishEmitAfterTopLevel(); diff --git a/lib/ParseSIL/ParseSIL.cpp b/lib/ParseSIL/ParseSIL.cpp index 9500bf91540ec..a6103417033a3 100644 --- a/lib/ParseSIL/ParseSIL.cpp +++ b/lib/ParseSIL/ParseSIL.cpp @@ -6208,11 +6208,12 @@ bool SILParserTUState::parseSILCoverageMap(Parser &P) { return true; // Parse the covered name. - Identifier FuncName; - SourceLoc FuncLoc; - if (State.parseSILIdentifier(FuncName, FuncLoc, - diag::expected_sil_value_name)) + if (!P.Tok.is(tok::string_literal)) { + P.diagnose(P.Tok, diag::sil_coverage_expected_quote); return true; + } + StringRef FuncName = P.Tok.getText().drop_front().drop_back(); + P.consumeToken(); // Parse the PGO func name. if (!P.Tok.is(tok::string_literal)) { @@ -6222,12 +6223,6 @@ bool SILParserTUState::parseSILCoverageMap(Parser &P) { StringRef PGOFuncName = P.Tok.getText().drop_front().drop_back(); P.consumeToken(); - SILFunction *Func = M.lookUpFunction(FuncName.str()); - if (!Func) { - P.diagnose(FuncLoc, diag::sil_coverage_func_not_found, FuncName); - return true; - } - uint64_t Hash; if (State.parseInteger(Hash, diag::sil_coverage_invalid_hash)) return true; diff --git a/lib/SIL/SILPrinter.cpp b/lib/SIL/SILPrinter.cpp index 95b5e05448afb..14192c91cc25e 100644 --- a/lib/SIL/SILPrinter.cpp +++ b/lib/SIL/SILPrinter.cpp @@ -2941,9 +2941,9 @@ void SILDefaultWitnessTable::dump() const { void SILCoverageMap::print(SILPrintContext &PrintCtx) const { llvm::raw_ostream &OS = PrintCtx.OS(); - OS << "sil_coverage_map " << QuotedString(getFile()) << " " << getName() - << " " << QuotedString(getPGOFuncName()) << " " << getHash() << " {\t// " - << demangleSymbol(getName()) << "\n"; + OS << "sil_coverage_map " << QuotedString(getFile()) << " " + << QuotedString(getName()) << " " << QuotedString(getPGOFuncName()) << " " + << getHash() << " {\t// " << demangleSymbol(getName()) << "\n"; if (PrintCtx.sortSIL()) std::sort(MappedRegions.begin(), MappedRegions.end(), [](const MappedRegion &LHS, const MappedRegion &RHS) { diff --git a/lib/SIL/SILProfiler.cpp b/lib/SIL/SILProfiler.cpp index 91557c4741987..7cb0ba231b0cc 100644 --- a/lib/SIL/SILProfiler.cpp +++ b/lib/SIL/SILProfiler.cpp @@ -1078,10 +1078,3 @@ Optional SILProfiler::getPGOParent(ASTNode Node) { } return it->getSecond(); } - -void SILProfiler::recordCounterUpdate() { - // If a counter update is recorded, the profile symbol table is guaranteed - // to have name data needed by the coverage mapping. - if (CovMap) - CovMap->setSymtabEntryGuaranteed(); -} diff --git a/lib/SILGen/SILGenFunction.cpp b/lib/SILGen/SILGenFunction.cpp index 6f065aa586e06..b94a0895fe7f8 100644 --- a/lib/SILGen/SILGenFunction.cpp +++ b/lib/SILGen/SILGenFunction.cpp @@ -657,7 +657,6 @@ void SILGenFunction::emitProfilerIncrement(ASTNode N) { B.createIntegerLiteral(Loc, Int32Ty, CounterIt->second)}; B.createBuiltin(Loc, C.getIdentifier("int_instrprof_increment"), SGM.Types.getEmptyTupleType(), {}, Args); - SP->recordCounterUpdate(); } ProfileCounter SILGenFunction::loadProfilerCount(ASTNode Node) const { diff --git a/test/Profiler/instrprof_symtab_valid.sil b/test/Profiler/instrprof_symtab_valid.sil new file mode 100644 index 0000000000000..fce17c0332a5c --- /dev/null +++ b/test/Profiler/instrprof_symtab_valid.sil @@ -0,0 +1,30 @@ +// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil %s -profile-generate -profile-coverage-mapping -emit-ir -o - -module-name=irgen | %FileCheck %s + +// CHECK-NOT: @__llvm_coverage_mapping + +sil_stage canonical + +import Builtin +import Swift +import SwiftShims + +// main +sil @main : $@convention(c) (Int32, UnsafeMutablePointer>>) -> Int32 { +bb0(%0 : $Int32, %1 : $UnsafeMutablePointer>>): + %2 = string_literal utf8 ":__tlcd_line:1:1" // user: %6 + %3 = integer_literal $Builtin.Int64, 0 // user: %6 + %4 = integer_literal $Builtin.Int32, 2 // user: %6 + %5 = integer_literal $Builtin.Int32, 0 // user: %6 + + // Pass an invalid SIL value to the int_instrprof_increment intrinsic + // to force IRGen to drop it. + %6 = builtin "int_instrprof_increment"(%3 : $Builtin.Int64, %3 : $Builtin.Int64, %4 : $Builtin.Int32, %5 : $Builtin.Int32) : $() + + return %0 : $Int32 // id: %33 +} // end sil function 'main' + +sil_coverage_map "" "__tlcd_line:1:1" ":__tlcd_line:1:1" 0 { // __tlcd_line:1:1 + 1:19 -> 1:20 : 1 + 1:23 -> 1:24 : (0 - 1) + 1:1 -> 1:24 : 0 +} diff --git a/test/SIL/Parser/coverage_maps.sil b/test/SIL/Parser/coverage_maps.sil index d4d0acacc4634..0e4778f6ffd34 100644 --- a/test/SIL/Parser/coverage_maps.sil +++ b/test/SIL/Parser/coverage_maps.sil @@ -6,12 +6,12 @@ bb0: return %0 : $() } -// CHECK-LABEL: sil_coverage_map "coverage_maps.sil" someFunction "coverage_maps.sil:someFunction" 0 { +// CHECK-LABEL: sil_coverage_map "coverage_maps.sil" "someFunction" "coverage_maps.sil:someFunction" 0 { // CHECK: } -sil_coverage_map "coverage_maps.sil" someFunction "coverage_maps.sil:someFunction" 0 { +sil_coverage_map "coverage_maps.sil" "someFunction" "coverage_maps.sil:someFunction" 0 { } -// CHECK-LABEL: sil_coverage_map "/some/other/file.sil" someFunction "/some/other/file.sil:someFunction" 0 { +// CHECK-LABEL: sil_coverage_map "/some/other/file.sil" "someFunction" "/some/other/file.sil:someFunction" 0 { // CHECK: 4:19 -> 31:1 : 0 // CHECK: 7:9 -> 7:16 : (0 + 1) // CHECK: 7:18 -> 9:3 : zero diff --git a/test/SILGen/coverage_deinit.swift b/test/SILGen/coverage_deinit.swift index 39ebdcf17a740..86183baa89281 100644 --- a/test/SILGen/coverage_deinit.swift +++ b/test/SILGen/coverage_deinit.swift @@ -11,5 +11,5 @@ public class Derived: NSString { } } -// CHECK-LABEL: sil_coverage_map "{{.*}}coverage_deinit.swift" $S15coverage_deinit7DerivedCfD +// CHECK-LABEL: sil_coverage_map "{{.*}}coverage_deinit.swift" "$S15coverage_deinit7DerivedCfD" // CHECK-NEXT: [[@LINE-5]]:10 -> [[@LINE-4]]:4 : 0 diff --git a/test/SILGen/coverage_force_emission.swift b/test/SILGen/coverage_force_emission.swift index 702ba8e654a37..3ee3f827de0bb 100644 --- a/test/SILGen/coverage_force_emission.swift +++ b/test/SILGen/coverage_force_emission.swift @@ -1,22 +1,22 @@ -// RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sorted-sil -emit-sil -module-name coverage_force_emission %s | %FileCheck %s -check-prefix=COVERAGE -// RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -emit-sorted-sil -emit-sil -module-name coverage_force_emission %s | %FileCheck %s -check-prefix=PGO +// RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sil -module-name coverage_force_emission %s | %FileCheck %s -check-prefix=COVERAGE +// RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -emit-sil -module-name coverage_force_emission %s | %FileCheck %s -check-prefix=PGO final class VarInit { - // COVERAGE: sil_coverage_map {{.*}} $S23coverage_force_emission7VarInitC04lazydE033_7D375D72BA8B0C53C9AD7E4DBC7FF493LLSSvg + // COVERAGE: sil_coverage_map {{.*}} "$S23coverage_force_emission7VarInitC04lazydE033_7D375D72BA8B0C53C9AD7E4DBC7FF493LLSSvgSSyXEfU_" // PGO-LABEL: coverage_force_emission.VarInit.(lazyVarInit in _7D375D72BA8B0C53C9AD7E4DBC7FF493).getter : Swift.String // PGO: int_instrprof_increment private lazy var lazyVarInit: String = { return "Hello" }() - // CHECK: sil_coverage_map {{.*}} $S23coverage_force_emission7VarInitC05basicdE033_7D375D72BA8B0C53C9AD7E4DBC7FF493LLSSvpfiSSyXEfU_ + // CHECK: sil_coverage_map {{.*}} "$S23coverage_force_emission7VarInitC05basicdE033_7D375D72BA8B0C53C9AD7E4DBC7FF493LLSSvpfiSSyXEfU_" // PGO-LABEL: closure #1 () -> Swift.String in variable initialization expression of coverage_force_emission.VarInit.(basicVarInit in _7D375D72BA8B0C53C9AD7E4DBC7FF493) : Swift.String // PGO: int_instrprof_increment private var basicVarInit: String = { return "Hello" }() - // CHECK: sil_coverage_map {{.*}} $S23coverage_force_emission7VarInitC06simpleD033_7D375D72BA8B0C53C9AD7E4DBC7FF493LLSSvg + // CHECK: sil_coverage_map {{.*}} "$S23coverage_force_emission7VarInitC06simpleD033_7D375D72BA8B0C53C9AD7E4DBC7FF493LLSSvg" // PGO-LABEL: coverage_force_emission.VarInit.(simpleVar in _7D375D72BA8B0C53C9AD7E4DBC7FF493).getter : Swift.String // PGO: int_instrprof_increment private var simpleVar: String { diff --git a/test/SILGen/coverage_member_closure.swift b/test/SILGen/coverage_member_closure.swift index 4e2b0228f7777..78a72542215be 100644 --- a/test/SILGen/coverage_member_closure.swift +++ b/test/SILGen/coverage_member_closure.swift @@ -2,7 +2,7 @@ class C { // Closures in members receive their own coverage mapping. - // CHECK: sil_coverage_map {{.*}} $S23coverage_member_closure1CC17completionHandleryySS_SaySSGtcvpfiySS_AEtcfU_ + // CHECK: sil_coverage_map {{.*}} "$S23coverage_member_closure1CC17completionHandleryySS_SaySSGtcvpfiySS_AEtcfU_" // CHECK: [[@LINE+1]]:55 -> [[@LINE+1]]:79 : 0 var completionHandler: (String, [String]) -> Void = { (foo, bar) in return } } diff --git a/test/SILGen/coverage_var_init.swift b/test/SILGen/coverage_var_init.swift index fca436a962fcb..49dd0c397432e 100644 --- a/test/SILGen/coverage_var_init.swift +++ b/test/SILGen/coverage_var_init.swift @@ -1,19 +1,19 @@ // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sorted-sil -emit-sil -module-name coverage_var_init %s | %FileCheck %s final class VarInit { - // CHECK: sil_coverage_map {{.*}} $S17coverage_var_init7VarInitC04lazydE033_49373CB2DFB47C8DC62FA963604688DFLLSSvgSSyXEfU_ + // CHECK: sil_coverage_map {{.*}} "$S17coverage_var_init7VarInitC04lazydE033_49373CB2DFB47C8DC62FA963604688DFLLSSvgSSyXEfU_" // CHECK-NEXT: [[@LINE+1]]:42 -> [[@LINE+3]]:4 : 0 private lazy var lazyVarInit: String = { return "lazyVarInit" }() - // CHECK: sil_coverage_map {{.*}} $S17coverage_var_init7VarInitC05basicdE033_49373CB2DFB47C8DC62FA963604688DFLLSSvpfiSSyXEfU_ + // CHECK: sil_coverage_map {{.*}} "$S17coverage_var_init7VarInitC05basicdE033_49373CB2DFB47C8DC62FA963604688DFLLSSvpfiSSyXEfU_" // CHECK-NEXT: [[@LINE+1]]:38 -> [[@LINE+3]]:4 : 0 private var basicVarInit: String = { return "Hello" }() - // CHECK: sil_coverage_map {{.*}} $S17coverage_var_init7VarInitC06simpleD033_49373CB2DFB47C8DC62FA963604688DFLLSSvg + // CHECK: sil_coverage_map {{.*}} "$S17coverage_var_init7VarInitC06simpleD033_49373CB2DFB47C8DC62FA963604688DFLLSSvg" // CHECK-NEXT: [[@LINE+1]]:33 -> [[@LINE+3]]:4 : 0 private var simpleVar: String { return "Hello"