Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit f73c9c1

Browse files
author
Hal Finkel
committed
Add a counter-function insertion pass
As discussed in https://reviews.llvm.org/D22666, our current mechanism to support -pg profiling, where we insert calls to mcount(), or some similar function, is fundamentally broken. We insert these calls in the frontend, which means they get duplicated when inlining, and so the accumulated execution counts for the inlined-into functions are wrong. Because we don't want the presence of these functions to affect optimizaton, they should be inserted in the backend. Here's a pass which would do just that. The knowledge of the name of the counting function lives in the frontend, so we're passing it here as a function attribute. Clang will be updated to use this mechanism. Differential Revision: https://reviews.llvm.org/D22825 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@280347 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent e1ceee0 commit f73c9c1

File tree

11 files changed

+117
-0
lines changed

11 files changed

+117
-0
lines changed

include/llvm/CodeGen/Passes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ namespace llvm {
4343
/// the entry block.
4444
FunctionPass *createUnreachableBlockEliminationPass();
4545

46+
/// Insert mcount-like function calls.
47+
FunctionPass *createCountingFunctionInserterPass();
48+
4649
/// MachineFunctionPrinter pass - This pass prints out the machine function to
4750
/// the given stream as a debugging tool.
4851
MachineFunctionPass *

include/llvm/InitializePasses.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ void initializeCallGraphPrinterLegacyPassPass(PassRegistry&);
9292
void initializeCallGraphViewerPass(PassRegistry&);
9393
void initializeCallGraphWrapperPassPass(PassRegistry &);
9494
void initializeCodeGenPreparePass(PassRegistry&);
95+
void initializeCountingFunctionInserterPass(PassRegistry&);
9596
void initializeConstantHoistingLegacyPassPass(PassRegistry&);
9697
void initializeConstantMergeLegacyPassPass(PassRegistry &);
9798
void initializeConstantPropagationPass(PassRegistry&);

include/llvm/LinkAllPasses.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ namespace {
160160
(void) llvm::createInstCountPass();
161161
(void) llvm::createConstantHoistingPass();
162162
(void) llvm::createCodeGenPreparePass();
163+
(void) llvm::createCountingFunctionInserterPass();
163164
(void) llvm::createEarlyCSEPass();
164165
(void) llvm::createGVNHoistPass();
165166
(void) llvm::createMergedLoadStoreMotionPass();

lib/CodeGen/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ add_llvm_library(LLVMCodeGen
1010
CallingConvLower.cpp
1111
CodeGen.cpp
1212
CodeGenPrepare.cpp
13+
CountingFunctionInserter.cpp
1314
CriticalAntiDepBreaker.cpp
1415
DeadMachineInstructionElim.cpp
1516
DetectDeadLanes.cpp

lib/CodeGen/CodeGen.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
2323
initializeAtomicExpandPass(Registry);
2424
initializeBranchFolderPassPass(Registry);
2525
initializeCodeGenPreparePass(Registry);
26+
initializeCountingFunctionInserterPass(Registry);
2627
initializeDeadMachineInstructionElimPass(Registry);
2728
initializeDetectDeadLanesPass(Registry);
2829
initializeDwarfEHPreparePass(Registry);
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
//===- CountingFunctionInserter.cpp - Insert mcount-like function calls ---===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// Insert calls to counter functions, such as mcount, intended to be called
11+
// once per function, at the beginning of each function.
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
#include "llvm/Analysis/GlobalsModRef.h"
16+
#include "llvm/CodeGen/Passes.h"
17+
#include "llvm/IR/Function.h"
18+
#include "llvm/IR/Instructions.h"
19+
#include "llvm/IR/Module.h"
20+
#include "llvm/IR/Type.h"
21+
#include "llvm/Pass.h"
22+
using namespace llvm;
23+
24+
namespace {
25+
struct CountingFunctionInserter : public FunctionPass {
26+
static char ID; // Pass identification, replacement for typeid
27+
CountingFunctionInserter() : FunctionPass(ID) {
28+
initializeCountingFunctionInserterPass(*PassRegistry::getPassRegistry());
29+
}
30+
31+
void getAnalysisUsage(AnalysisUsage &AU) const override {
32+
AU.addPreserved<GlobalsAAWrapperPass>();
33+
}
34+
35+
bool runOnFunction(Function &F) override {
36+
std::string CountingFunctionName =
37+
F.getFnAttribute("counting-function").getValueAsString();
38+
if (CountingFunctionName.empty())
39+
return false;
40+
41+
Type *VoidTy = Type::getVoidTy(F.getContext());
42+
Constant *CountingFn =
43+
F.getParent()->getOrInsertFunction(CountingFunctionName,
44+
VoidTy, nullptr);
45+
CallInst::Create(CountingFn, "", &*F.begin()->getFirstInsertionPt());
46+
return true;
47+
}
48+
};
49+
50+
char CountingFunctionInserter::ID = 0;
51+
}
52+
53+
INITIALIZE_PASS(CountingFunctionInserter, "cfinserter",
54+
"Inserts calls to mcount-like functions", false, false)
55+
56+
//===----------------------------------------------------------------------===//
57+
//
58+
// CountingFunctionInserter - Give any unnamed non-void instructions "tmp" names.
59+
//
60+
FunctionPass *llvm::createCountingFunctionInserterPass() {
61+
return new CountingFunctionInserter();
62+
}

lib/CodeGen/TargetPassConfig.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,9 @@ void TargetPassConfig::addIRPasses() {
477477

478478
if (getOptLevel() != CodeGenOpt::None && !DisablePartialLibcallInlining)
479479
addPass(createPartiallyInlineLibCallsPass());
480+
481+
// Insert calls to mcount-like functions.
482+
addPass(createCountingFunctionInserterPass());
480483
}
481484

482485
/// Turn exception handling constructs into something the code generators can
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
; RUN: llc < %s | FileCheck %s
2+
target datalayout = "E-m:e-i64:64-n32:64"
3+
target triple = "powerpc64-bgq-linux"
4+
5+
define void @test1() #0 {
6+
entry:
7+
ret void
8+
9+
; CHECK-LABEL: @test1
10+
; CHECK: bl mcount
11+
; CHECK-NOT: mcount
12+
; CHECK: blr
13+
}
14+
15+
attributes #0 = { "counting-function"="mcount" }
16+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
; RUN: opt -S -cfinserter < %s | FileCheck %s
2+
target datalayout = "E-m:e-i64:64-n32:64"
3+
target triple = "powerpc64-bgq-linux"
4+
5+
define void @test1() #0 {
6+
entry:
7+
ret void
8+
9+
; CHECK-LABEL: define void @test1()
10+
; CHECK: entry:
11+
; CHECK-NEXT: call void @mcount()
12+
; CHECK: ret void
13+
}
14+
15+
define void @test2() #1 {
16+
entry:
17+
ret void
18+
19+
; CHECK-LABEL: define void @test2()
20+
; CHECK: entry:
21+
; CHECK-NEXT: call void @.mcount()
22+
; CHECK: ret void
23+
}
24+
25+
attributes #0 = { "counting-function"="mcount" }
26+
attributes #1 = { "counting-function"=".mcount" }
27+

tools/llc/llc.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ int main(int argc, char **argv) {
254254
initializeCodeGen(*Registry);
255255
initializeLoopStrengthReducePass(*Registry);
256256
initializeLowerIntrinsicsPass(*Registry);
257+
initializeCountingFunctionInserterPass(*Registry);
257258
initializeUnreachableBlockElimLegacyPassPass(*Registry);
258259

259260
// Register the target printer for --version.

tools/opt/opt.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,7 @@ int main(int argc, char **argv) {
384384
initializePreISelIntrinsicLoweringLegacyPassPass(Registry);
385385
initializeGlobalMergePass(Registry);
386386
initializeInterleavedAccessPass(Registry);
387+
initializeCountingFunctionInserterPass(Registry);
387388
initializeUnreachableBlockElimLegacyPassPass(Registry);
388389

389390
#ifdef LINK_POLLY_INTO_TOOLS

0 commit comments

Comments
 (0)