Skip to content

Commit 2fe531c

Browse files
committedMar 17, 2014
PGO: Statically generate data structures
In instrumentation-based profiling, we need a set of data structures to represent the counters. Previously, these were built up during static initialization. Now, they're shoved into a specially-named section so that they show up as an array. As a consequence of the reorganizing symbols, instrumentation data structures for linkonce functions are now correctly coalesced. This is the first step in a larger project to minimize runtime overhead and dependencies in instrumentation-based profilng. The larger picture includes removing all initialization overhead and making the dependency on libc optional. <rdar://problem/15943240> llvm-svn: 204080
1 parent 77a88e3 commit 2fe531c

12 files changed

+244
-115
lines changed
 

‎clang/lib/CodeGen/CGBlocks.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1199,7 +1199,7 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD,
11991199
RegionCounter Cnt = getPGORegionCounter(blockDecl->getBody());
12001200
Cnt.beginRegion(Builder);
12011201
EmitStmt(blockDecl->getBody());
1202-
PGO.emitWriteoutFunction();
1202+
PGO.emitInstrumentationData();
12031203
PGO.destroyRegionCounters();
12041204
}
12051205

‎clang/lib/CodeGen/CGObjC.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
507507
Cnt.beginRegion(Builder);
508508
EmitCompoundStmtWithoutScope(*cast<CompoundStmt>(OMD->getBody()));
509509
FinishFunction(OMD->getBodyRBrace());
510-
PGO.emitWriteoutFunction();
510+
PGO.emitInstrumentationData();
511511
PGO.destroyRegionCounters();
512512
}
513513

‎clang/lib/CodeGen/CodeGenFunction.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,7 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
821821
if (!CurFn->doesNotThrow())
822822
TryMarkNoThrow(CurFn);
823823

824-
PGO.emitWriteoutFunction();
824+
PGO.emitInstrumentationData();
825825
PGO.destroyRegionCounters();
826826
}
827827

‎clang/lib/CodeGen/CodeGenPGO.cpp

+148-84
Original file line numberDiff line numberDiff line change
@@ -144,119 +144,181 @@ bool PGOProfileData::getFunctionCounts(StringRef FuncName,
144144
}
145145

146146
void CodeGenPGO::setFuncName(llvm::Function *Fn) {
147-
StringRef Func = Fn->getName();
147+
RawFuncName = Fn->getName();
148148

149149
// Function names may be prefixed with a binary '1' to indicate
150150
// that the backend should not modify the symbols due to any platform
151151
// naming convention. Do not include that '1' in the PGO profile name.
152-
if (Func[0] == '\1')
153-
Func = Func.substr(1);
152+
if (RawFuncName[0] == '\1')
153+
RawFuncName = RawFuncName.substr(1);
154154

155155
if (!Fn->hasLocalLinkage()) {
156-
FuncName = new std::string(Func);
156+
PrefixedFuncName = new std::string(RawFuncName);
157157
return;
158158
}
159159

160160
// For local symbols, prepend the main file name to distinguish them.
161161
// Do not include the full path in the file name since there's no guarantee
162162
// that it will stay the same, e.g., if the files are checked out from
163163
// version control in different locations.
164-
FuncName = new std::string(CGM.getCodeGenOpts().MainFileName);
165-
if (FuncName->empty())
166-
FuncName->assign("<unknown>");
167-
FuncName->append(":");
168-
FuncName->append(Func);
164+
PrefixedFuncName = new std::string(CGM.getCodeGenOpts().MainFileName);
165+
if (PrefixedFuncName->empty())
166+
PrefixedFuncName->assign("<unknown>");
167+
PrefixedFuncName->append(":");
168+
PrefixedFuncName->append(RawFuncName);
169169
}
170170

171-
void CodeGenPGO::emitWriteoutFunction() {
172-
if (!CGM.getCodeGenOpts().ProfileInstrGenerate)
173-
return;
174-
175-
llvm::LLVMContext &Ctx = CGM.getLLVMContext();
171+
static llvm::Function *getRegisterFunc(CodeGenModule &CGM) {
172+
return CGM.getModule().getFunction("__llvm_pgo_register_functions");
173+
}
176174

177-
llvm::Type *Int32Ty = llvm::Type::getInt32Ty(Ctx);
178-
llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(Ctx);
179-
180-
llvm::Function *WriteoutF =
181-
CGM.getModule().getFunction("__llvm_pgo_writeout");
182-
if (!WriteoutF) {
183-
llvm::FunctionType *WriteoutFTy =
184-
llvm::FunctionType::get(llvm::Type::getVoidTy(Ctx), false);
185-
WriteoutF = llvm::Function::Create(WriteoutFTy,
186-
llvm::GlobalValue::InternalLinkage,
187-
"__llvm_pgo_writeout", &CGM.getModule());
188-
}
189-
WriteoutF->setUnnamedAddr(true);
190-
WriteoutF->addFnAttr(llvm::Attribute::NoInline);
175+
static llvm::BasicBlock *getOrInsertRegisterBB(CodeGenModule &CGM) {
176+
// Only need to insert this once per module.
177+
if (llvm::Function *RegisterF = getRegisterFunc(CGM))
178+
return &RegisterF->getEntryBlock();
179+
180+
// Construct the function.
181+
auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext());
182+
auto *RegisterFTy = llvm::FunctionType::get(VoidTy, false);
183+
auto *RegisterF = llvm::Function::Create(RegisterFTy,
184+
llvm::GlobalValue::InternalLinkage,
185+
"__llvm_pgo_register_functions",
186+
&CGM.getModule());
187+
RegisterF->setUnnamedAddr(true);
188+
RegisterF->addFnAttr(llvm::Attribute::NoInline);
191189
if (CGM.getCodeGenOpts().DisableRedZone)
192-
WriteoutF->addFnAttr(llvm::Attribute::NoRedZone);
190+
RegisterF->addFnAttr(llvm::Attribute::NoRedZone);
191+
192+
// Construct and return the entry block.
193+
auto *BB = llvm::BasicBlock::Create(CGM.getLLVMContext(), "", RegisterF);
194+
CGBuilderTy Builder(BB);
195+
Builder.CreateRetVoid();
196+
return BB;
197+
}
193198

194-
llvm::BasicBlock *BB = WriteoutF->empty() ?
195-
llvm::BasicBlock::Create(Ctx, "", WriteoutF) : &WriteoutF->getEntryBlock();
199+
static llvm::Constant *getOrInsertRuntimeRegister(CodeGenModule &CGM) {
200+
auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext());
201+
auto *VoidPtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
202+
auto *RuntimeRegisterTy = llvm::FunctionType::get(VoidTy, VoidPtrTy, false);
203+
return CGM.getModule().getOrInsertFunction("__llvm_pgo_register_function",
204+
RuntimeRegisterTy);
205+
}
206+
207+
static llvm::Constant *getOrInsertRuntimeWriteAtExit(CodeGenModule &CGM) {
208+
// TODO: make this depend on a command-line option.
209+
auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext());
210+
auto *WriteAtExitTy = llvm::FunctionType::get(VoidTy, false);
211+
return CGM.getModule().getOrInsertFunction("__llvm_pgo_register_write_atexit",
212+
WriteAtExitTy);
213+
}
214+
215+
static StringRef getCountersSection(const CodeGenModule &CGM) {
216+
if (CGM.getTarget().getTriple().getObjectFormat() == llvm::Triple::MachO)
217+
return "__DATA,__llvm_pgo_cnts";
218+
else
219+
return "__llvm_pgo_cnts";
220+
}
196221

197-
CGBuilderTy PGOBuilder(BB);
222+
static StringRef getNameSection(const CodeGenModule &CGM) {
223+
if (CGM.getTarget().getTriple().getObjectFormat() == llvm::Triple::MachO)
224+
return "__DATA,__llvm_pgo_names";
225+
else
226+
return "__llvm_pgo_names";
227+
}
198228

199-
llvm::Instruction *I = BB->getTerminator();
200-
if (!I)
201-
I = PGOBuilder.CreateRetVoid();
202-
PGOBuilder.SetInsertPoint(I);
229+
static StringRef getDataSection(const CodeGenModule &CGM) {
230+
if (CGM.getTarget().getTriple().getObjectFormat() == llvm::Triple::MachO)
231+
return "__DATA,__llvm_pgo_data";
232+
else
233+
return "__llvm_pgo_data";
234+
}
203235

204-
llvm::Type *Int64PtrTy = llvm::Type::getInt64PtrTy(Ctx);
205-
llvm::Type *Args[] = {
206-
Int8PtrTy, // const char *FuncName
207-
Int32Ty, // uint32_t NumCounters
208-
Int64PtrTy // uint64_t *Counters
236+
llvm::GlobalVariable *CodeGenPGO::buildDataVar() {
237+
// Create name variable.
238+
llvm::LLVMContext &Ctx = CGM.getLLVMContext();
239+
auto *VarName = llvm::ConstantDataArray::getString(Ctx, getFuncName(),
240+
false);
241+
auto *Name = new llvm::GlobalVariable(CGM.getModule(), VarName->getType(),
242+
true, FuncLinkage, VarName,
243+
getFuncVarName("name"));
244+
Name->setSection(getNameSection(CGM));
245+
Name->setAlignment(1);
246+
247+
// Create data variable.
248+
auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
249+
auto *Int8PtrTy = llvm::Type::getInt8PtrTy(Ctx);
250+
auto *Int64PtrTy = llvm::Type::getInt64PtrTy(Ctx);
251+
llvm::Type *DataTypes[] = {
252+
Int32Ty, Int32Ty, Int8PtrTy, Int64PtrTy
209253
};
210-
llvm::FunctionType *FTy =
211-
llvm::FunctionType::get(PGOBuilder.getVoidTy(), Args, false);
212-
llvm::Constant *EmitFunc =
213-
CGM.getModule().getOrInsertFunction("llvm_pgo_emit", FTy);
214-
215-
llvm::Constant *NameString =
216-
CGM.GetAddrOfConstantCString(getFuncName(), "__llvm_pgo_name");
217-
NameString = llvm::ConstantExpr::getBitCast(NameString, Int8PtrTy);
218-
PGOBuilder.CreateCall3(EmitFunc, NameString,
219-
PGOBuilder.getInt32(NumRegionCounters),
220-
PGOBuilder.CreateBitCast(RegionCounters, Int64PtrTy));
254+
auto *DataTy = llvm::StructType::get(Ctx, makeArrayRef(DataTypes));
255+
llvm::Constant *DataVals[] = {
256+
llvm::ConstantInt::get(Int32Ty, getFuncName().size()),
257+
llvm::ConstantInt::get(Int32Ty, NumRegionCounters),
258+
llvm::ConstantExpr::getBitCast(Name, Int8PtrTy),
259+
llvm::ConstantExpr::getBitCast(RegionCounters, Int64PtrTy)
260+
};
261+
auto *Data =
262+
new llvm::GlobalVariable(CGM.getModule(), DataTy, true, FuncLinkage,
263+
llvm::ConstantStruct::get(DataTy, DataVals),
264+
getFuncVarName("data"));
265+
266+
// All the data should be packed into an array in its own section.
267+
Data->setSection(getDataSection(CGM));
268+
Data->setAlignment(8);
269+
270+
// Make sure the data doesn't get deleted.
271+
CGM.addUsedGlobal(Data);
272+
return Data;
273+
}
274+
275+
void CodeGenPGO::emitInstrumentationData() {
276+
if (!CGM.getCodeGenOpts().ProfileInstrGenerate)
277+
return;
278+
279+
// Build the data.
280+
auto *Data = buildDataVar();
281+
282+
// Register the data.
283+
//
284+
// TODO: only register when static initialization is required.
285+
CGBuilderTy Builder(getOrInsertRegisterBB(CGM)->getTerminator());
286+
auto *VoidPtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
287+
Builder.CreateCall(getOrInsertRuntimeRegister(CGM),
288+
Builder.CreateBitCast(Data, VoidPtrTy));
221289
}
222290

223291
llvm::Function *CodeGenPGO::emitInitialization(CodeGenModule &CGM) {
224-
llvm::Function *WriteoutF =
225-
CGM.getModule().getFunction("__llvm_pgo_writeout");
226-
if (!WriteoutF)
227-
return NULL;
292+
if (!CGM.getCodeGenOpts().ProfileInstrGenerate)
293+
return 0;
228294

229-
// Create a small bit of code that registers the "__llvm_pgo_writeout" to
230-
// be executed at exit.
231-
llvm::Function *F = CGM.getModule().getFunction("__llvm_pgo_init");
232-
if (F)
233-
return NULL;
295+
// Only need to create this once per module.
296+
if (CGM.getModule().getFunction("__llvm_pgo_init"))
297+
return 0;
234298

235-
llvm::LLVMContext &Ctx = CGM.getLLVMContext();
236-
llvm::FunctionType *FTy = llvm::FunctionType::get(llvm::Type::getVoidTy(Ctx),
237-
false);
238-
F = llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage,
239-
"__llvm_pgo_init", &CGM.getModule());
299+
// Get the functions to call at initialization.
300+
llvm::Constant *RegisterF = getRegisterFunc(CGM);
301+
llvm::Constant *WriteAtExitF = getOrInsertRuntimeWriteAtExit(CGM);
302+
if (!RegisterF && !WriteAtExitF)
303+
return 0;
304+
305+
// Create the initialization function.
306+
auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext());
307+
auto *F = llvm::Function::Create(llvm::FunctionType::get(VoidTy, false),
308+
llvm::GlobalValue::InternalLinkage,
309+
"__llvm_pgo_init", &CGM.getModule());
240310
F->setUnnamedAddr(true);
241-
F->setLinkage(llvm::GlobalValue::InternalLinkage);
242311
F->addFnAttr(llvm::Attribute::NoInline);
243312
if (CGM.getCodeGenOpts().DisableRedZone)
244313
F->addFnAttr(llvm::Attribute::NoRedZone);
245314

246-
llvm::BasicBlock *BB = llvm::BasicBlock::Create(CGM.getLLVMContext(), "", F);
247-
CGBuilderTy PGOBuilder(BB);
248-
249-
FTy = llvm::FunctionType::get(PGOBuilder.getVoidTy(), false);
250-
llvm::Type *Params[] = {
251-
llvm::PointerType::get(FTy, 0)
252-
};
253-
FTy = llvm::FunctionType::get(PGOBuilder.getVoidTy(), Params, false);
254-
255-
// Inialize the environment and register the local writeout function.
256-
llvm::Constant *PGOInit =
257-
CGM.getModule().getOrInsertFunction("llvm_pgo_init", FTy);
258-
PGOBuilder.CreateCall(PGOInit, WriteoutF);
259-
PGOBuilder.CreateRetVoid();
315+
// Add the basic block and the necessary calls.
316+
CGBuilderTy Builder(llvm::BasicBlock::Create(CGM.getLLVMContext(), "", F));
317+
if (RegisterF)
318+
Builder.CreateCall(RegisterF);
319+
if (WriteAtExitF)
320+
Builder.CreateCall(WriteAtExitF);
321+
Builder.CreateRetVoid();
260322

261323
return F;
262324
}
@@ -764,6 +826,7 @@ void CodeGenPGO::assignRegionCounters(const Decl *D, llvm::Function *Fn) {
764826
if (!D)
765827
return;
766828
setFuncName(Fn);
829+
FuncLinkage = Fn->getLinkage();
767830
mapRegionCounters(D);
768831
if (InstrumentRegions)
769832
emitCounterVariables();
@@ -819,10 +882,11 @@ void CodeGenPGO::emitCounterVariables() {
819882
llvm::ArrayType *CounterTy = llvm::ArrayType::get(llvm::Type::getInt64Ty(Ctx),
820883
NumRegionCounters);
821884
RegionCounters =
822-
new llvm::GlobalVariable(CGM.getModule(), CounterTy, false,
823-
llvm::GlobalVariable::PrivateLinkage,
885+
new llvm::GlobalVariable(CGM.getModule(), CounterTy, false, FuncLinkage,
824886
llvm::Constant::getNullValue(CounterTy),
825-
"__llvm_pgo_ctr");
887+
getFuncVarName("counters"));
888+
RegionCounters->setAlignment(8);
889+
RegionCounters->setSection(getCountersSection(CGM));
826890
}
827891

828892
void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, unsigned Counter) {

‎clang/lib/CodeGen/CodeGenPGO.h

+13-8
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ class PGOProfileData {
5252
class CodeGenPGO {
5353
private:
5454
CodeGenModule &CGM;
55-
std::string *FuncName;
55+
std::string *PrefixedFuncName;
56+
StringRef RawFuncName;
57+
llvm::GlobalValue::LinkageTypes FuncLinkage;
5658

5759
unsigned NumRegionCounters;
5860
llvm::GlobalVariable *RegionCounters;
@@ -63,11 +65,11 @@ class CodeGenPGO {
6365

6466
public:
6567
CodeGenPGO(CodeGenModule &CGM)
66-
: CGM(CGM), FuncName(0), NumRegionCounters(0), RegionCounters(0),
68+
: CGM(CGM), PrefixedFuncName(0), NumRegionCounters(0), RegionCounters(0),
6769
RegionCounterMap(0), StmtCountMap(0), RegionCounts(0),
6870
CurrentRegionCount(0) {}
6971
~CodeGenPGO() {
70-
if (FuncName) delete FuncName;
72+
if (PrefixedFuncName) delete PrefixedFuncName;
7173
}
7274

7375
/// Whether or not we have PGO region data for the current function. This is
@@ -77,7 +79,10 @@ class CodeGenPGO {
7779

7880
/// Get the string used to identify this function in the profile data.
7981
/// For functions with local linkage, this includes the main file name.
80-
const StringRef getFuncName() const { return StringRef(*FuncName); }
82+
StringRef getFuncName() const { return StringRef(*PrefixedFuncName); }
83+
std::string getFuncVarName(StringRef VarName) const {
84+
return ("__llvm_pgo_" + VarName + "_" + RawFuncName).str();
85+
}
8186

8287
/// Return the counter value of the current region.
8388
uint64_t getCurrentRegionCount() const { return CurrentRegionCount; }
@@ -123,13 +128,12 @@ class CodeGenPGO {
123128
/// generates global variables or associates PGO data with each of the
124129
/// counters depending on whether we are generating or using instrumentation.
125130
void assignRegionCounters(const Decl *D, llvm::Function *Fn);
126-
/// Emit code to write counts for a given function to disk, if necessary.
127-
void emitWriteoutFunction();
131+
/// Emit static data structures for instrumentation data.
132+
void emitInstrumentationData();
128133
/// Clean up region counter state. Must be called if assignRegionCounters is
129134
/// used.
130135
void destroyRegionCounters();
131-
/// Emit the logic to register region counter write out functions. Returns a
132-
/// function that implements this logic.
136+
/// Emit static initialization code, if any.
133137
static llvm::Function *emitInitialization(CodeGenModule &CGM);
134138

135139
private:
@@ -139,6 +143,7 @@ class CodeGenPGO {
139143
void applyFunctionAttributes(PGOProfileData *PGOData, llvm::Function *Fn);
140144
void loadRegionCounts(PGOProfileData *PGOData);
141145
void emitCounterVariables();
146+
llvm::GlobalVariable *buildDataVar();
142147

143148
/// Emit code to increment the counter at the given index
144149
void emitCounterIncrement(CGBuilderTy &Builder, unsigned Counter);

‎clang/test/Profile/c-counter-overflows.c

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
typedef unsigned long long uint64_t;
77

8-
// PGOGEN: @[[MAIN:__llvm_pgo_ctr[0-9]*]] = private global [2 x i64] zeroinitializer
98
int main(int argc, const char *argv[]) {
109
// Need counts higher than 32-bits.
1110
// CHECK: br {{.*}} !prof ![[FOR:[0-9]+]]

‎clang/test/Profile/c-general.c

+10-10
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-general.c %s -o - -emit-llvm -fprofile-instr-generate | FileCheck -check-prefix=PGOGEN %s
44
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-general.c %s -o - -emit-llvm -fprofile-instr-use=%S/Inputs/c-general.profdata | FileCheck -check-prefix=PGOUSE %s
55

6-
// PGOGEN: @[[SLC:__llvm_pgo_ctr[0-9]*]] = private global [4 x i64] zeroinitializer
7-
// PGOGEN: @[[IFC:__llvm_pgo_ctr[0-9]*]] = private global [11 x i64] zeroinitializer
8-
// PGOGEN: @[[EEC:__llvm_pgo_ctr[0-9]*]] = private global [9 x i64] zeroinitializer
9-
// PGOGEN: @[[JMC:__llvm_pgo_ctr[0-9]*]] = private global [22 x i64] zeroinitializer
10-
// PGOGEN: @[[SWC:__llvm_pgo_ctr[0-9]*]] = private global [19 x i64] zeroinitializer
11-
// PGOGEN: @[[BSC:__llvm_pgo_ctr[0-9]*]] = private global [17 x i64] zeroinitializer
12-
// PGOGEN: @[[BOC:__llvm_pgo_ctr[0-9]*]] = private global [8 x i64] zeroinitializer
13-
// PGOGEN: @[[BLC:__llvm_pgo_ctr[0-9]*]] = private global [9 x i64] zeroinitializer
14-
// PGOGEN: @[[MAC:__llvm_pgo_ctr[0-9]*]] = private global [1 x i64] zeroinitializer
15-
// PGOGEN: @[[STC:__llvm_pgo_ctr[0-9]*]] = private global [2 x i64] zeroinitializer
6+
// PGOGEN: @[[SLC:__llvm_pgo_counters_simple_loops]] = global [4 x i64] zeroinitializer
7+
// PGOGEN: @[[IFC:__llvm_pgo_counters_conditionals]] = global [11 x i64] zeroinitializer
8+
// PGOGEN: @[[EEC:__llvm_pgo_counters_early_exits]] = global [9 x i64] zeroinitializer
9+
// PGOGEN: @[[JMC:__llvm_pgo_counters_jumps]] = global [22 x i64] zeroinitializer
10+
// PGOGEN: @[[SWC:__llvm_pgo_counters_switches]] = global [19 x i64] zeroinitializer
11+
// PGOGEN: @[[BSC:__llvm_pgo_counters_big_switch]] = global [17 x i64] zeroinitializer
12+
// PGOGEN: @[[BOC:__llvm_pgo_counters_boolean_operators]] = global [8 x i64] zeroinitializer
13+
// PGOGEN: @[[BLC:__llvm_pgo_counters_boolop_loops]] = global [9 x i64] zeroinitializer
14+
// PGOGEN: @[[MAC:__llvm_pgo_counters_main]] = global [1 x i64] zeroinitializer
15+
// PGOGEN: @[[STC:__llvm_pgo_counters_static_func]] = internal global [2 x i64] zeroinitializer
1616

1717
// PGOGEN-LABEL: @simple_loops()
1818
// PGOUSE-LABEL: @simple_loops()

‎clang/test/Profile/c-linkage.c

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Check the data structures emitted by instrumentation.
2+
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-linkage.c %s -o - -emit-llvm -fprofile-instr-generate | FileCheck %s
3+
4+
// CHECK: @__llvm_pgo_counters_foo = global [1 x i64] zeroinitializer, section "__DATA,__llvm_pgo_cnts", align 8
5+
// CHECK: @__llvm_pgo_name_foo = constant [3 x i8] c"foo", section "__DATA,__llvm_pgo_names", align 1
6+
// CHECK: @__llvm_pgo_data_foo = constant { i32, i32, i8*, i64* } { i32 3, i32 1, i8* getelementptr inbounds ([3 x i8]* @__llvm_pgo_name_foo, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64]* @__llvm_pgo_counters_foo, i32 0, i32 0) }, section "__DATA,__llvm_pgo_data", align 8
7+
void foo(void) { }
8+
9+
// CHECK: @__llvm_pgo_counters_foo_weak = weak global [5 x i64] zeroinitializer, section "__DATA,__llvm_pgo_cnts", align 8
10+
// CHECK: @__llvm_pgo_name_foo_weak = weak constant [8 x i8] c"foo_weak", section "__DATA,__llvm_pgo_names", align 1
11+
// CHECK: @__llvm_pgo_data_foo_weak = weak constant { i32, i32, i8*, i64* } { i32 8, i32 5, i8* getelementptr inbounds ([8 x i8]* @__llvm_pgo_name_foo_weak, i32 0, i32 0), i64* getelementptr inbounds ([5 x i64]* @__llvm_pgo_counters_foo_weak, i32 0, i32 0) }, section "__DATA,__llvm_pgo_data", align 8
12+
void foo_weak(void) __attribute__((weak));
13+
void foo_weak(void) { if (0){} if (0){} if (0){} if (0){} }
14+
15+
// CHECK: @__llvm_pgo_counters_main = global [1 x i64] zeroinitializer, section "__DATA,__llvm_pgo_cnts", align 8
16+
// CHECK: @__llvm_pgo_name_main = constant [4 x i8] c"main", section "__DATA,__llvm_pgo_names", align 1
17+
// CHECK: @__llvm_pgo_data_main = constant { i32, i32, i8*, i64* } { i32 4, i32 1, i8* getelementptr inbounds ([4 x i8]* @__llvm_pgo_name_main, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64]* @__llvm_pgo_counters_main, i32 0, i32 0) }, section "__DATA,__llvm_pgo_data", align 8
18+
static void foo_internal(void);
19+
int main(void) {
20+
foo();
21+
foo_internal();
22+
foo_weak();
23+
return 0;
24+
}
25+
26+
// CHECK: @__llvm_pgo_counters_foo_internal = internal global [3 x i64] zeroinitializer, section "__DATA,__llvm_pgo_cnts", align 8
27+
// CHECK: @__llvm_pgo_name_foo_internal = internal constant [24 x i8] c"c-linkage.c:foo_internal", section "__DATA,__llvm_pgo_names", align 1
28+
// CHECK: @__llvm_pgo_data_foo_internal = internal constant { i32, i32, i8*, i64* } { i32 24, i32 3, i8* getelementptr inbounds ([24 x i8]* @__llvm_pgo_name_foo_internal, i32 0, i32 0), i64* getelementptr inbounds ([3 x i64]* @__llvm_pgo_counters_foo_internal, i32 0, i32 0) }, section "__DATA,__llvm_pgo_data", align 8
29+
static void foo_internal(void) { if (0){} if (0){} }
30+
31+
// CHECK: @llvm.used = appending global [4 x i8*] [i8* bitcast ({ i32, i32, i8*, i64* }* @__llvm_pgo_data_foo to i8*), i8* bitcast ({ i32, i32, i8*, i64* }* @__llvm_pgo_data_foo_weak to i8*), i8* bitcast ({ i32, i32, i8*, i64* }* @__llvm_pgo_data_main to i8*), i8* bitcast ({ i32, i32, i8*, i64* }* @__llvm_pgo_data_foo_internal to i8*)], section "llvm.metadata"

‎clang/test/Profile/cxx-class.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class Simple {
1717
public:
1818
// CTRGEN-LABEL: define {{.*}} @_ZN6SimpleC2Ei(
1919
// CTRUSE-LABEL: define {{.*}} @_ZN6SimpleC2Ei(
20-
// CTRGEN: store {{.*}} @[[SCC:__llvm_pgo_ctr[0-9]*]], i64 0, i64 0
20+
// CTRGEN: store {{.*}} @[[SCC:__llvm_pgo_counters__ZN6SimpleC2Ei]], i64 0, i64 0
2121
explicit Simple(int Member) : Member(Member) {
2222
// CTRGEN: store {{.*}} @[[SCC]], i64 0, i64 1
2323
// CTRUSE: br {{.*}} !prof ![[SC1:[0-9]+]]
@@ -30,7 +30,7 @@ class Simple {
3030

3131
// DTRGEN-LABEL: define {{.*}} @_ZN6SimpleD2Ev(
3232
// DTRUSE-LABEL: define {{.*}} @_ZN6SimpleD2Ev(
33-
// DTRGEN: store {{.*}} @[[SDC:__llvm_pgo_ctr[0-9]*]], i64 0, i64 0
33+
// DTRGEN: store {{.*}} @[[SDC:__llvm_pgo_counters__ZN6SimpleD2Ev]], i64 0, i64 0
3434
~Simple() {
3535
// DTRGEN: store {{.*}} @[[SDC]], i64 0, i64 1
3636
// DTRUSE: br {{.*}} !prof ![[SD1:[0-9]+]]
@@ -43,7 +43,7 @@ class Simple {
4343

4444
// MTHGEN-LABEL: define {{.*}} @_ZN6Simple6methodEv(
4545
// MTHUSE-LABEL: define {{.*}} @_ZN6Simple6methodEv(
46-
// MTHGEN: store {{.*}} @[[SMC:__llvm_pgo_ctr[0-9]*]], i64 0, i64 0
46+
// MTHGEN: store {{.*}} @[[SMC:__llvm_pgo_counters__ZN6Simple6methodEv]], i64 0, i64 0
4747
void method() {
4848
// MTHGEN: store {{.*}} @[[SMC]], i64 0, i64 1
4949
// MTHUSE: br {{.*}} !prof ![[SM1:[0-9]+]]
@@ -57,7 +57,7 @@ class Simple {
5757

5858
// WRPGEN-LABEL: define {{.*}} @_Z14simple_wrapperv(
5959
// WRPUSE-LABEL: define {{.*}} @_Z14simple_wrapperv(
60-
// WRPGEN: store {{.*}} @[[SWC:__llvm_pgo_ctr[0-9]*]], i64 0, i64 0
60+
// WRPGEN: store {{.*}} @[[SWC:__llvm_pgo_counters__Z14simple_wrapperv]], i64 0, i64 0
6161
void simple_wrapper() {
6262
// WRPGEN: store {{.*}} @[[SWC]], i64 0, i64 1
6363
// WRPUSE: br {{.*}} !prof ![[SW1:[0-9]+]]

‎clang/test/Profile/cxx-linkage.cpp

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9.0 -emit-llvm -main-file-name cxx-linkage.cpp %s -o - -fprofile-instr-generate | FileCheck %s
2+
3+
// CHECK: @__llvm_pgo_counters__Z3foov = global [1 x i64] zeroinitializer, section "__DATA,__llvm_pgo_cnts", align 8
4+
// CHECK: @__llvm_pgo_name__Z3foov = constant [7 x i8] c"_Z3foov", section "__DATA,__llvm_pgo_names", align 1
5+
// CHECK: @__llvm_pgo_data__Z3foov = constant { i32, i32, i8*, i64* } { i32 7, i32 1, i8* getelementptr inbounds ([7 x i8]* @__llvm_pgo_name__Z3foov, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64]* @__llvm_pgo_counters__Z3foov, i32 0, i32 0) }, section "__DATA,__llvm_pgo_data", align 8
6+
void foo(void) { }
7+
8+
// CHECK: @__llvm_pgo_counters__Z8foo_weakv = weak global [5 x i64] zeroinitializer, section "__DATA,__llvm_pgo_cnts", align 8
9+
// CHECK: @__llvm_pgo_name__Z8foo_weakv = weak constant [12 x i8] c"_Z8foo_weakv", section "__DATA,__llvm_pgo_names", align 1
10+
// CHECK: @__llvm_pgo_data__Z8foo_weakv = weak constant { i32, i32, i8*, i64* } { i32 12, i32 5, i8* getelementptr inbounds ([12 x i8]* @__llvm_pgo_name__Z8foo_weakv, i32 0, i32 0), i64* getelementptr inbounds ([5 x i64]* @__llvm_pgo_counters__Z8foo_weakv, i32 0, i32 0) }, section "__DATA,__llvm_pgo_data", align 8
11+
void foo_weak(void) __attribute__((weak));
12+
void foo_weak(void) { if (0){} if (0){} if (0){} if (0){} }
13+
14+
// CHECK: @__llvm_pgo_counters_main = global [1 x i64] zeroinitializer, section "__DATA,__llvm_pgo_cnts", align 8
15+
// CHECK: @__llvm_pgo_name_main = constant [4 x i8] c"main", section "__DATA,__llvm_pgo_names", align 1
16+
// CHECK: @__llvm_pgo_data_main = constant { i32, i32, i8*, i64* } { i32 4, i32 1, i8* getelementptr inbounds ([4 x i8]* @__llvm_pgo_name_main, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64]* @__llvm_pgo_counters_main, i32 0, i32 0) }, section "__DATA,__llvm_pgo_data", align 8
17+
inline void foo_inline(void);
18+
int main(void) {
19+
foo();
20+
foo_inline();
21+
foo_weak();
22+
return 0;
23+
}
24+
25+
// CHECK: @__llvm_pgo_counters__Z10foo_inlinev = linkonce_odr global [7 x i64] zeroinitializer, section "__DATA,__llvm_pgo_cnts", align 8
26+
// CHECK: @__llvm_pgo_name__Z10foo_inlinev = linkonce_odr constant [15 x i8] c"_Z10foo_inlinev", section "__DATA,__llvm_pgo_names", align 1
27+
// CHECK: @__llvm_pgo_data__Z10foo_inlinev = linkonce_odr constant { i32, i32, i8*, i64* } { i32 15, i32 7, i8* getelementptr inbounds ([15 x i8]* @__llvm_pgo_name__Z10foo_inlinev, i32 0, i32 0), i64* getelementptr inbounds ([7 x i64]* @__llvm_pgo_counters__Z10foo_inlinev, i32 0, i32 0) }, section "__DATA,__llvm_pgo_data", align 8
28+
inline void foo_inline(void) { if (0){} if (0){} if (0){} if (0){} if (0){} if (0){}}
29+
30+
// CHECK: @llvm.used = appending global [4 x i8*] [i8* bitcast ({ i32, i32, i8*, i64* }* @__llvm_pgo_data__Z3foov to i8*), i8* bitcast ({ i32, i32, i8*, i64* }* @__llvm_pgo_data__Z8foo_weakv to i8*), i8* bitcast ({ i32, i32, i8*, i64* }* @__llvm_pgo_data_main to i8*), i8* bitcast ({ i32, i32, i8*, i64* }* @__llvm_pgo_data__Z10foo_inlinev to i8*)], section "llvm.metadata"

‎clang/test/Profile/cxx-throws.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
// RUN: %clang %s -o - -emit-llvm -S -fprofile-instr-use=%S/Inputs/cxx-throws.profdata -target %itanium_abi_triple | FileCheck -check-prefix=PGOUSE %s
1010
// RUN: %clang %s -o - -emit-llvm -S -fprofile-instr-use=%S/Inputs/cxx-throws.profdata -target %itanium_abi_triple | FileCheck -check-prefix=PGOUSE-EXC %s
1111

12-
// PGOGEN: @[[THC:__llvm_pgo_ctr[0-9]*]] = private global [9 x i64] zeroinitializer
13-
// PGOGEN-EXC: @[[THC:__llvm_pgo_ctr[0-9]*]] = private global [9 x i64] zeroinitializer
12+
// PGOGEN: @[[THC:__llvm_pgo_counters__Z6throwsv]] = global [9 x i64] zeroinitializer
13+
// PGOGEN-EXC: @[[THC:__llvm_pgo_counters__Z6throwsv]] = global [9 x i64] zeroinitializer
1414

1515
// PGOGEN-LABEL: @_Z6throwsv()
1616
// PGOUSE-LABEL: @_Z6throwsv()

‎clang/test/Profile/objc-general.m

+3-3
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ +(NSArray*) arrayWithObjects: (id) first, ...;
2929
@end;
3030
#endif
3131

32-
// PGOGEN: @[[FRC:__llvm_pgo_ctr[0-9]*]] = private global [2 x i64] zeroinitializer
33-
// PGOGEN: @[[BLC:__llvm_pgo_ctr[0-9]*]] = private global [2 x i64] zeroinitializer
34-
// PGOGEN: @[[MAC:__llvm_pgo_ctr[0-9]*]] = private global [1 x i64] zeroinitializer
32+
// PGOGEN: @[[FRC:"__llvm_pgo_counters_\+\[A foreach:\]"]] = internal global [2 x i64] zeroinitializer
33+
// PGOGEN: @[[BLC:"__llvm_pgo_counters___13\+\[A foreach:\]_block_invoke"]] = internal global [2 x i64] zeroinitializer
34+
// PGOGEN: @[[MAC:__llvm_pgo_counters_main]] = global [1 x i64] zeroinitializer
3535

3636
@interface A : NSObject
3737
+ (void)foreach: (NSArray *)array;

0 commit comments

Comments
 (0)
Please sign in to comment.