diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c178703cc9..3e8b7007822 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ #### Big news - Frontend, druntime and Phobos are at version [2.106.0](https://dlang.org/changelog/2.106.0.html). (#4522) - New command-line options `-fno-{exceptions,moduleinfo,rtti}` to selectively enable some `-betterC` effects. (#4522) +- New command-line option `-fprofile-sample-use` for using sample-based profile data for optimization. Functionality and usage is identical to Clang's option with same name. (#4531). #### Platform support diff --git a/driver/cl_options_instrumentation.cpp b/driver/cl_options_instrumentation.cpp index ea00e7d130c..33e6ba6e49c 100644 --- a/driver/cl_options_instrumentation.cpp +++ b/driver/cl_options_instrumentation.cpp @@ -31,7 +31,7 @@ cl::opt IRPGOInstrGenFile( "'=' or LLVM_PROFILE_FILE env var)"), cl::ZeroOrMore, cl::ValueOptional); -/// Option for generating IR-based PGO instrumentation (LLVM pass) +/// Option for using IR-based PGO instrumentation (LLVM pass) cl::opt IRPGOInstrUseFile( "fprofile-use", cl::ZeroOrMore, cl::value_desc("filename"), cl::desc("Use instrumentation data for profile-guided optimization"), @@ -45,12 +45,20 @@ cl::opt ASTPGOInstrGenFile( "'=' or LLVM_PROFILE_FILE env var)"), cl::ZeroOrMore, cl::ValueOptional); -/// Option for generating frontend-based PGO instrumentation +/// Option for using frontend-based PGO instrumentation cl::opt ASTPGOInstrUseFile( "fprofile-instr-use", cl::ZeroOrMore, cl::value_desc("filename"), cl::desc("Use instrumentation data for profile-guided optimization"), cl::ValueRequired); +/// Option for using sample-based PGO instrumentation +cl::opt + SamplePGOInstrUseFile("fprofile-sample-use", cl::Optional, + cl::value_desc("filename"), + cl::desc("Use instrumentation data for sample-based " + "profile guided optimizations"), + cl::ValueRequired); + cl::opt fXRayInstructionThreshold( "fxray-instruction-threshold", cl::value_desc("value"), cl::desc("Sets the minimum function size to instrument with XRay"), @@ -119,6 +127,9 @@ void initializeInstrumentationOptionsFromCmdline(const llvm::Triple &triple) { } else if (!IRPGOInstrUseFile.empty()) { pgoMode = PGO_IRBasedUse; global.params.datafileInstrProf = fromPathString(IRPGOInstrUseFile).ptr; + } else if (!SamplePGOInstrUseFile.empty()) { + pgoMode = PGO_SampleBasedUse; + global.params.datafileInstrProf = fromPathString(SamplePGOInstrUseFile).ptr; } if (dmdFunctionTrace) diff --git a/driver/cl_options_instrumentation.h b/driver/cl_options_instrumentation.h index 9b06789b341..6159e07d2ee 100644 --- a/driver/cl_options_instrumentation.h +++ b/driver/cl_options_instrumentation.h @@ -43,6 +43,7 @@ enum PGOKind { PGO_ASTBasedUse, PGO_IRBasedInstr, PGO_IRBasedUse, + PGO_SampleBasedUse, }; extern PGOKind pgoMode; inline bool isInstrumentingForPGO() { @@ -59,5 +60,8 @@ inline bool isInstrumentingForIRBasedPGO() { return pgoMode == PGO_IRBasedInstr; } inline bool isUsingIRBasedPGOProfile() { return pgoMode == PGO_IRBasedUse; } +inline bool isUsingSampleBasedPGOProfile() { + return pgoMode == PGO_SampleBasedUse; +} } // namespace opts diff --git a/gen/functions.cpp b/gen/functions.cpp index f1f83a81f4c..6cfaae24293 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -1233,6 +1233,9 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) { if (opts::fSplitStack && !hasNoSplitStackUDA(fd)) { func->addFnAttr("split-stack"); } + if (opts::isUsingSampleBasedPGOProfile()) { + func->addFnAttr("use-sample-profile"); + } llvm::BasicBlock *beginbb = llvm::BasicBlock::Create(gIR->context(), "", func); diff --git a/gen/optimizer.cpp b/gen/optimizer.cpp index 9f831c61139..4f345e843a2 100644 --- a/gen/optimizer.cpp +++ b/gen/optimizer.cpp @@ -557,6 +557,11 @@ static llvm::Optional getPGOOptions() { PGOOptions::PGOAction::IRUse, PGOOptions::CSPGOAction::NoCSAction, debugInfoForProfiling, pseudoProbeForProfiling); + } else if (opts::isUsingSampleBasedPGOProfile()) { + return PGOOptions(global.params.datafileInstrProf, "", "", + PGOOptions::PGOAction::SampleUse, + PGOOptions::CSPGOAction::NoCSAction, + debugInfoForProfiling, pseudoProbeForProfiling); } #if LDC_LLVM_VER < 1600 return None; diff --git a/tests/PGO/sample_based.d b/tests/PGO/sample_based.d new file mode 100644 index 00000000000..599a8c4df78 --- /dev/null +++ b/tests/PGO/sample_based.d @@ -0,0 +1,21 @@ +// Test basic use of sample-based PGO profile + +// REQUIRES: atleast_llvm1500 + +// RUN: split-file %s %t +// RUN: %ldc -O2 -c -gline-tables-only -output-ll -of=%t.ll -fprofile-sample-use=%t/pgo-sample.prof %t/testcase.d && FileCheck %s < %t.ll + +//--- pgo-sample.prof +foo:100:100 + 1: 100 + +//--- testcase.d +// CHECK: define{{.*}} @foo{{.*}} #[[ATTRID:[0-9]+]]{{.*}} !prof ![[PROFID:[0-9]+]] +// CHECK: attributes #[[ATTRID]] = {{.*}} "use-sample-profile" +// CHECK-DAG: "ProfileFormat", !"SampleProfile" +// CHECK-DAG: "TotalCount", i64 100 +// CHECK-DAG: ![[PROFID]] = !{!"function_entry_count", i64 101} + +extern (C) int foo () { + return 1; +}