r203085 - PGO: add instrumentation for Objective-C methods.
Bob Wilson
bob.wilson at apple.com
Wed Mar 5 22:10:02 PST 2014
Author: bwilson
Date: Thu Mar 6 00:10:02 2014
New Revision: 203085
URL: http://llvm.org/viewvc/llvm-project?rev=203085&view=rev
Log:
PGO: add instrumentation for Objective-C methods.
Modified:
cfe/trunk/lib/CodeGen/CGObjC.cpp
cfe/trunk/lib/CodeGen/CodeGenPGO.cpp
cfe/trunk/test/CodeGenObjC/Inputs/instr-profile.profdata
cfe/trunk/test/CodeGenObjC/instr-profile.m
Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=203085&r1=203084&r2=203085&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Thu Mar 6 00:10:02 2014
@@ -502,9 +502,14 @@ static llvm::Value *emitARCRetainLoadOfS
/// its pointer, name, and types registered in the class struture.
void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
StartObjCMethod(OMD, OMD->getClassInterface(), OMD->getLocStart());
+ PGO.assignRegionCounters(OMD, CurFn);
assert(isa<CompoundStmt>(OMD->getBody()));
+ RegionCounter Cnt = getPGORegionCounter(OMD->getBody());
+ Cnt.beginRegion(Builder);
EmitCompoundStmtWithoutScope(*cast<CompoundStmt>(OMD->getBody()));
FinishFunction(OMD->getBodyRBrace());
+ PGO.emitWriteoutFunction();
+ PGO.destroyRegionCounters();
}
/// emitStructGetterCall - Call the runtime function to load a property
Modified: cfe/trunk/lib/CodeGen/CodeGenPGO.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenPGO.cpp?rev=203085&r1=203084&r2=203085&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenPGO.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenPGO.cpp Thu Mar 6 00:10:02 2014
@@ -49,11 +49,17 @@ PGOProfileData::PGOProfileData(CodeGenMo
while (CurPtr < BufferEnd) {
// Read the function name.
const char *FuncStart = CurPtr;
- CurPtr = strchr(CurPtr, ' ');
+ // For Objective-C methods, the name may include whitespace, so search
+ // backward from the end of the line to find the space that separates the
+ // name from the number of counters. (This is a temporary hack since we are
+ // going to completely replace this file format in the near future.)
+ CurPtr = strchr(CurPtr, '\n');
if (!CurPtr) {
ReportBadPGOData(CGM, "pgo data file has malformed function entry");
return;
}
+ while (*--CurPtr != ' ')
+ ;
StringRef FuncName(FuncStart, CurPtr - FuncStart);
// Read the number of counters.
@@ -129,8 +135,10 @@ bool PGOProfileData::getFunctionCounts(S
const char *CurPtr = DataBuffer->getBufferStart() + OffsetIter->getValue();
// Skip over the function name.
- CurPtr = strchr(CurPtr, ' ');
+ CurPtr = strchr(CurPtr, '\n');
assert(CurPtr && "pgo-data has corrupted function entry");
+ while (*--CurPtr != ' ')
+ ;
// Read the number of counters.
char *EndPtr;
@@ -303,6 +311,10 @@ namespace {
(*CounterMap)[S->getBody()] = NextCounter++;
Visit(S->getBody());
}
+ void VisitObjCMethodDecl(const ObjCMethodDecl *S) {
+ (*CounterMap)[S->getBody()] = NextCounter++;
+ Visit(S->getBody());
+ }
/// Assign a counter to track the block following a label.
void VisitLabelStmt(const LabelStmt *S) {
(*CounterMap)[S] = NextCounter++;
@@ -462,6 +474,13 @@ namespace {
Visit(S->getBody());
}
+ void VisitObjCMethodDecl(const ObjCMethodDecl *S) {
+ RegionCounter Cnt(PGO, S->getBody());
+ Cnt.beginRegion();
+ (*CountMap)[S->getBody()] = PGO.getCurrentRegionCount();
+ Visit(S->getBody());
+ }
+
void VisitReturnStmt(const ReturnStmt *S) {
RecordStmtCount(S);
if (S->getRetValue())
@@ -781,6 +800,8 @@ void CodeGenPGO::mapRegionCounters(const
MapRegionCounters Walker(RegionCounterMap);
if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
Walker.VisitFunctionDecl(FD);
+ else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
+ Walker.VisitObjCMethodDecl(MD);
NumRegionCounters = Walker.NextCounter;
}
@@ -789,6 +810,8 @@ void CodeGenPGO::computeRegionCounts(con
ComputeRegionCounts Walker(StmtCountMap, *this);
if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
Walker.VisitFunctionDecl(FD);
+ else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
+ Walker.VisitObjCMethodDecl(MD);
}
void CodeGenPGO::emitCounterVariables() {
Modified: cfe/trunk/test/CodeGenObjC/Inputs/instr-profile.profdata
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/Inputs/instr-profile.profdata?rev=203085&r1=203084&r2=203085&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/Inputs/instr-profile.profdata (original)
+++ cfe/trunk/test/CodeGenObjC/Inputs/instr-profile.profdata Thu Mar 6 00:10:02 2014
@@ -1,4 +1,4 @@
-foreach 2
+instr-profile.m:+[A foreach:] 2
1
2
Modified: cfe/trunk/test/CodeGenObjC/instr-profile.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/instr-profile.m?rev=203085&r1=203084&r2=203085&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/instr-profile.m (original)
+++ cfe/trunk/test/CodeGenObjC/instr-profile.m Thu Mar 6 00:10:02 2014
@@ -8,11 +8,24 @@
// RUN: %clang %s -o - -emit-llvm -S -fprofile-instr-use=%S/Inputs/instr-profile.profdata | FileCheck -check-prefix=PGOUSE %s
#ifdef HAVE_FOUNDATION
+
// Use this to build an instrumented version to regenerate the input file.
#import <Foundation/Foundation.h>
+
#else
+
+// Minimal definitions to get this to compile without Foundation.h.
+
+ at protocol NSObject
+ at end
+
+ at interface NSObject <NSObject>
+- (id)init;
++ (id)alloc;
+ at end
+
struct NSFastEnumerationState;
- at interface NSArray
+ at interface NSArray : NSObject
- (unsigned long) countByEnumeratingWithState: (struct NSFastEnumerationState*) state
objects: (id*) buffer
count: (unsigned long) bufferSize;
@@ -22,17 +35,26 @@ struct NSFastEnumerationState;
// PGOGEN: @[[FOR:__llvm_pgo_ctr[0-9]*]] = private global [2 x i64] zeroinitializer
-// PGOGEN-LABEL: @foreach
-// PGOUSE-LABEL: @foreach
+ at interface A : NSObject
++ (void)foreach: (NSArray *)array;
+ at end
+
+ at implementation A
+// PGOGEN-LABEL: define {{.*}}+[A foreach:]
+// PGOUSE-LABEL: define {{.*}}+[A foreach:]
// PGOGEN: store {{.*}} @[[FOR]], i64 0, i64 0
-void foreach(NSArray *array) {
++ (void)foreach: (NSArray *)array
+{
// PGOGEN: store {{.*}} @[[FOR]], i64 0, i64 1
// FIXME: We don't emit branch weights for this yet.
for (id x in array) {
}
}
+ at end
int main(int argc, const char *argv[]) {
+ A *a = [[A alloc] init];
NSArray *array = [NSArray arrayWithObjects: @"0", @"1", (void*)0];
- foreach(array);
+ [A foreach: array];
+ return 0;
}
More information about the cfe-commits
mailing list