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