Skip to content

Commit

Permalink
PGO: Add IR-based PGO.
Browse files Browse the repository at this point in the history
  • Loading branch information
JohanEngelen committed Dec 28, 2017
1 parent 7cf6565 commit 7b80a26
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 3 deletions.
13 changes: 13 additions & 0 deletions driver/cl_options_instrumentation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,20 @@ void initializeInstrumentationOptionsFromCmdline() {
pgoMode = PGO_ASTBasedUse;
initFromPathString(global.params.datafileInstrProf, ASTPGOInstrUseFile);
}
#if LDC_LLVM_VER >= 309
else if (IRPGOInstrGenFile.getNumOccurrences() > 0) {
pgoMode = PGO_IRBasedInstr;
if (IRPGOInstrGenFile.empty()) {
global.params.datafileInstrProf = "default_%m.profraw";
} else {
initFromPathString(global.params.datafileInstrProf, IRPGOInstrGenFile);
}
} else if (!IRPGOInstrUseFile.empty()) {
pgoMode = PGO_IRBasedUse;
initFromPathString(global.params.datafileInstrProf, IRPGOInstrUseFile);
}
#endif
#endif // LDC_WITH_PGO
}

} // namespace opts
14 changes: 11 additions & 3 deletions gen/optimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,8 @@ static void addSanitizerCoveragePass(const PassManagerBuilder &Builder,
}

// Adds PGO instrumentation generation and use passes.
static void addPGOPasses(legacy::PassManagerBase &mpm, unsigned optLevel) {
static void addPGOPasses(PassManagerBuilder &builder,
legacy::PassManagerBase &mpm, unsigned optLevel) {
#if LDC_WITH_PGO
if (opts::isInstrumentingForASTBasedPGO()) {
InstrProfOptions options;
Expand All @@ -221,8 +222,15 @@ static void addPGOPasses(legacy::PassManagerBase &mpm, unsigned optLevel) {
mpm.add(createPGOIndirectCallPromotionLegacyPass());
}
#endif
}
} else if (opts::isInstrumentingForIRBasedPGO()) {
#if LDC_LLVM_VER >= 600
builder.EnablePGOInstrGen = true;
#endif
builder.PGOInstrGen = global.params.datafileInstrProf;
} else if (opts::isUsingIRBasedPGOProfile()) {
builder.PGOInstrUse = global.params.datafileInstrProf;
}
#endif // LDC_WITH_PGO
}

/**
Expand Down Expand Up @@ -324,7 +332,7 @@ static void addOptimizationPasses(legacy::PassManagerBase &mpm,
builder.addExtension(PassManagerBuilder::EP_OptimizerLast,
addStripExternalsPass);

addPGOPasses(mpm, optLevel);
addPGOPasses(builder, mpm, optLevel);

builder.populateFunctionPassManager(fpm);
builder.populateModulePassManager(mpm);
Expand Down
67 changes: 67 additions & 0 deletions tests/PGO/irbased_indirect_calls.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Test instrumentation of indirect calls

// REQUIRES: atleast_llvm309

// RUN: %ldc -c -output-ll -fprofile-generate -of=%t.ll %s && FileCheck %s --check-prefix=PROFGEN < %t.ll

// RUN: %ldc -O3 -fprofile-generate=%t.profraw -run %s \
// RUN: && %profdata merge %t.profraw -o %t.profdata \
// RUN: && %ldc -O3 -c -output-ll -of=%t.use.ll -fprofile-use=%t.profdata %s \
// RUN: && FileCheck %s -check-prefix=PROFUSE < %t.use.ll

import ldc.attributes : weak;

extern (C)
{ // simplify name mangling for simpler string matching

@weak // disable reasoning about this function
void hot()
{
}

void luke()
{
}

void cold()
{
}

void function() foo;

@weak // disable reasoning about this function
void select_func(int i)
{
if (i < 1700)
foo = &hot;
else if (i < 1990)
foo = &luke;
else
foo = &cold;
}

} // extern C

// PROFGEN-LABEL: @_Dmain(
// PROFUSE-LABEL: @_Dmain(
int main()
{
for (int i; i < 2000; ++i)
{
select_func(i);

// PROFGEN: [[REG1:%[0-9]+]] = load void ()*, void ()** @foo
// PROFGEN-NEXT: [[REG2:%[0-9]+]] = ptrtoint void ()* [[REG1]] to i64
// PROFGEN-NEXT: call void @__llvm_profile_instrument_target(i64 [[REG2]], i8* bitcast ({{.*}}_Dmain to i8*), i32 0)
// PROFGEN-NEXT: call void [[REG1]]()

// PROFUSE: [[REG1:%[0-9]+]] = load void ()*, void ()** @foo
// PROFUSE: [[REG2:%[0-9]+]] = icmp eq void ()* [[REG1]], @hot
// PROFUSE: call void @hot()
// PROFUSE: call void [[REG1]]()

foo();
}

return 0;
}

0 comments on commit 7b80a26

Please sign in to comment.