From 8ab169109129300e9cd7199b7b735ab3bd23760b Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Mon, 24 Feb 2014 01:13:09 +0000 Subject: [PATCH] Do not put instrumentation counters before phis in ObjC for-in loops. We still don't use the PGO to set branch weights for these loops, but at least this keeps the compiler from crashing. llvm-svn: 202002 --- clang/lib/CodeGen/CGObjC.cpp | 6 +-- .../CodeGenObjC/Inputs/instr-profile.profdata | 7 ++++ clang/test/CodeGenObjC/instr-profile.m | 38 +++++++++++++++++++ 3 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 clang/test/CodeGenObjC/Inputs/instr-profile.profdata create mode 100644 clang/test/CodeGenObjC/instr-profile.m diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index 7ca10575c12b..dcc1074b7d62 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -1525,13 +1525,10 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){ llvm::Value *initialMutations = Builder.CreateLoad(StateMutationsPtr, "forcoll.initial-mutations"); - RegionCounter Cnt = getPGORegionCounter(&S); - // Start looping. This is the point we return to whenever we have a // fresh, non-empty batch of objects. llvm::BasicBlock *LoopBodyBB = createBasicBlock("forcoll.loopbody"); EmitBlock(LoopBodyBB); - Cnt.beginRegion(Builder); // The current index into the buffer. llvm::PHINode *index = Builder.CreatePHI(UnsignedLongLTy, 3, "forcoll.index"); @@ -1541,6 +1538,9 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){ llvm::PHINode *count = Builder.CreatePHI(UnsignedLongLTy, 3, "forcoll.count"); count->addIncoming(initialBufferLimit, LoopInitBB); + RegionCounter Cnt = getPGORegionCounter(&S); + Cnt.beginRegion(Builder); + // Check whether the mutations value has changed from where it was // at start. StateMutationsPtr should actually be invariant between // refreshes. diff --git a/clang/test/CodeGenObjC/Inputs/instr-profile.profdata b/clang/test/CodeGenObjC/Inputs/instr-profile.profdata new file mode 100644 index 000000000000..f3c03cc7930e --- /dev/null +++ b/clang/test/CodeGenObjC/Inputs/instr-profile.profdata @@ -0,0 +1,7 @@ +foreach 2 +1 +2 + +main 1 +1 + diff --git a/clang/test/CodeGenObjC/instr-profile.m b/clang/test/CodeGenObjC/instr-profile.m new file mode 100644 index 000000000000..e1b13edf2154 --- /dev/null +++ b/clang/test/CodeGenObjC/instr-profile.m @@ -0,0 +1,38 @@ +// Test that instrumentation based profiling feeds branch prediction +// correctly. This tests both generation of profile data and use of the same, +// and the input file for the -fprofile-instr-use case is expected to be result +// of running the program generated by the -fprofile-instr-generate case. As +// such, main() should call every function in this test. + +// RUN: %clang %s -o - -emit-llvm -S -fprofile-instr-generate | FileCheck -check-prefix=PGOGEN %s +// 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 +#else +struct NSFastEnumerationState; +@interface NSArray +- (unsigned long) countByEnumeratingWithState: (struct NSFastEnumerationState*) state + objects: (id*) buffer + count: (unsigned long) bufferSize; ++(NSArray*) arrayWithObjects: (id) first, ...; +@end; +#endif + +// PGOGEN: @[[FOR:__llvm_pgo_ctr[0-9]*]] = private global [2 x i64] zeroinitializer + +// PGOGEN-LABEL: @foreach +// PGOUSE-LABEL: @foreach +// PGOGEN: store {{.*}} @[[FOR]], i64 0, i64 0 +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) { + } +} + +int main(int argc, const char *argv[]) { + NSArray *array = [NSArray arrayWithObjects: @"0", @"1", (void*)0]; + foreach(array); +}