r203712 - Revert "CodeGen: Use a binary format for instrumentation based profiling"

Justin Bogner mail at justinbogner.com
Wed Mar 12 14:06:32 PDT 2014


Author: bogner
Date: Wed Mar 12 16:06:31 2014
New Revision: 203712

URL: http://llvm.org/viewvc/llvm-project?rev=203712&view=rev
Log:
Revert "CodeGen: Use a binary format for instrumentation based profiling"

I've clearly done something wrong with how to get this to link
correctly. Reverting for now.

This reverts commit r203711.

Modified:
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h
    cfe/trunk/lib/CodeGen/CodeGenPGO.cpp
    cfe/trunk/lib/CodeGen/CodeGenPGO.h
    cfe/trunk/test/Profile/Inputs/c-attributes.profdata
    cfe/trunk/test/Profile/Inputs/c-counter-overflows.profdata
    cfe/trunk/test/Profile/Inputs/c-general.profdata
    cfe/trunk/test/Profile/Inputs/c-outdated-data.profdata
    cfe/trunk/test/Profile/Inputs/cxx-class.profdata
    cfe/trunk/test/Profile/Inputs/cxx-throws.profdata
    cfe/trunk/test/Profile/Inputs/objc-general.profdata
    cfe/trunk/tools/driver/CMakeLists.txt

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=203712&r1=203711&r2=203712&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Wed Mar 12 16:06:31 2014
@@ -47,7 +47,6 @@
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
-#include "llvm/Profile/ProfileDataReader.h"
 #include "llvm/Support/ConvertUTF.h"
 #include "llvm/Support/ErrorHandling.h"
 
@@ -78,7 +77,7 @@ CodeGenModule::CodeGenModule(ASTContext
       ABI(createCXXABI(*this)), VMContext(M.getContext()), TBAA(0),
       TheTargetCodeGenInfo(0), Types(*this), VTables(*this), ObjCRuntime(0),
       OpenCLRuntime(0), CUDARuntime(0), DebugInfo(0), ARCData(0),
-      NoObjCARCExceptionsMetadata(0), RRData(0), PGOReader(nullptr),
+      NoObjCARCExceptionsMetadata(0), RRData(0), PGOData(0),
       CFConstantStringClassRef(0),
       ConstantStringClassRef(0), NSConstantStringType(0),
       NSConcreteGlobalBlock(0), NSConcreteStackBlock(0), BlockObjectAssign(0),
@@ -134,14 +133,8 @@ CodeGenModule::CodeGenModule(ASTContext
     ARCData = new ARCEntrypoints();
   RRData = new RREntrypoints();
 
-  if (!CodeGenOpts.InstrProfileInput.empty()) {
-    if (llvm::error_code EC = llvm::ProfileDataReader::create(
-            CodeGenOpts.InstrProfileInput, PGOReader)) {
-      unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-                                              "Could not read profile: %0");
-      getDiags().Report(DiagID) << EC.message();
-    }
-  }
+  if (!CodeGenOpts.InstrProfileInput.empty())
+    PGOData = new PGOProfileData(*this, CodeGenOpts.InstrProfileInput);
 }
 
 CodeGenModule::~CodeGenModule() {

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=203712&r1=203711&r2=203712&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Wed Mar 12 16:06:31 2014
@@ -42,7 +42,6 @@ namespace llvm {
   class DataLayout;
   class FunctionType;
   class LLVMContext;
-  class ProfileDataReader;
 }
 
 namespace clang {
@@ -86,6 +85,7 @@ namespace CodeGen {
   class CGCUDARuntime;
   class BlockFieldFlags;
   class FunctionArgList;
+  class PGOProfileData;
 
   struct OrderGlobalInits {
     unsigned int priority;
@@ -257,7 +257,7 @@ class CodeGenModule : public CodeGenType
   ARCEntrypoints *ARCData;
   llvm::MDNode *NoObjCARCExceptionsMetadata;
   RREntrypoints *RRData;
-  std::unique_ptr<llvm::ProfileDataReader> PGOReader;
+  PGOProfileData *PGOData;
 
   // WeakRefReferences - A set of references that have only been seen via
   // a weakref so far. This is used to remove the weak of the reference if we
@@ -480,8 +480,8 @@ public:
     return *RRData;
   }
 
-  llvm::ProfileDataReader *getPGOReader() const {
-    return PGOReader.get();
+  PGOProfileData *getPGOData() const {
+    return PGOData;
   }
 
   llvm::Constant *getStaticLocalDeclAddress(const VarDecl *D) {

Modified: cfe/trunk/lib/CodeGen/CodeGenPGO.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenPGO.cpp?rev=203712&r1=203711&r2=203712&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenPGO.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenPGO.cpp Wed Mar 12 16:06:31 2014
@@ -17,12 +17,132 @@
 #include "clang/AST/StmtVisitor.h"
 #include "llvm/Config/config.h" // for strtoull()/strtoll() define
 #include "llvm/IR/MDBuilder.h"
-#include "llvm/Profile/ProfileDataReader.h"
 #include "llvm/Support/FileSystem.h"
 
 using namespace clang;
 using namespace CodeGen;
 
+static void ReportBadPGOData(CodeGenModule &CGM, const char *Message) {
+  DiagnosticsEngine &Diags = CGM.getDiags();
+  unsigned diagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, "%0");
+  Diags.Report(diagID) << Message;
+}
+
+PGOProfileData::PGOProfileData(CodeGenModule &CGM, std::string Path)
+  : CGM(CGM) {
+  if (llvm::MemoryBuffer::getFile(Path, DataBuffer)) {
+    ReportBadPGOData(CGM, "failed to open pgo data file");
+    return;
+  }
+
+  if (DataBuffer->getBufferSize() > std::numeric_limits<unsigned>::max()) {
+    ReportBadPGOData(CGM, "pgo data file too big");
+    return;
+  }
+
+  // Scan through the data file and map each function to the corresponding
+  // file offset where its counts are stored.
+  const char *BufferStart = DataBuffer->getBufferStart();
+  const char *BufferEnd = DataBuffer->getBufferEnd();
+  const char *CurPtr = BufferStart;
+  uint64_t MaxCount = 0;
+  while (CurPtr < BufferEnd) {
+    // Read the function name.
+    const char *FuncStart = 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.
+    char *EndPtr;
+    unsigned NumCounters = strtol(++CurPtr, &EndPtr, 10);
+    if (EndPtr == CurPtr || *EndPtr != '\n' || NumCounters <= 0) {
+      ReportBadPGOData(CGM, "pgo data file has unexpected number of counters");
+      return;
+    }
+    CurPtr = EndPtr;
+
+    // Read function count.
+    uint64_t Count = strtoll(CurPtr, &EndPtr, 10);
+    if (EndPtr == CurPtr || *EndPtr != '\n') {
+      ReportBadPGOData(CGM, "pgo-data file has bad count value");
+      return;
+    }
+    CurPtr = EndPtr; // Point to '\n'.
+    FunctionCounts[FuncName] = Count;
+    MaxCount = Count > MaxCount ? Count : MaxCount;
+
+    // There is one line for each counter; skip over those lines.
+    // Since function count is already read, we start the loop from 1.
+    for (unsigned N = 1; N < NumCounters; ++N) {
+      CurPtr = strchr(++CurPtr, '\n');
+      if (!CurPtr) {
+        ReportBadPGOData(CGM, "pgo data file is missing some counter info");
+        return;
+      }
+    }
+
+    // Skip over the blank line separating functions.
+    CurPtr += 2;
+
+    DataOffsets[FuncName] = FuncStart - BufferStart;
+  }
+  MaxFunctionCount = MaxCount;
+}
+
+bool PGOProfileData::getFunctionCounts(StringRef FuncName,
+                                       std::vector<uint64_t> &Counts) {
+  // Find the relevant section of the pgo-data file.
+  llvm::StringMap<unsigned>::const_iterator OffsetIter =
+    DataOffsets.find(FuncName);
+  if (OffsetIter == DataOffsets.end())
+    return true;
+  const char *CurPtr = DataBuffer->getBufferStart() + OffsetIter->getValue();
+
+  // Skip over the function name.
+  CurPtr = strchr(CurPtr, '\n');
+  assert(CurPtr && "pgo-data has corrupted function entry");
+  while (*--CurPtr != ' ')
+    ;
+
+  // Read the number of counters.
+  char *EndPtr;
+  unsigned NumCounters = strtol(++CurPtr, &EndPtr, 10);
+  assert(EndPtr != CurPtr && *EndPtr == '\n' && NumCounters > 0 &&
+         "pgo-data file has corrupted number of counters");
+  CurPtr = EndPtr;
+
+  Counts.reserve(NumCounters);
+
+  for (unsigned N = 0; N < NumCounters; ++N) {
+    // Read the count value.
+    uint64_t Count = strtoll(CurPtr, &EndPtr, 10);
+    if (EndPtr == CurPtr || *EndPtr != '\n') {
+      ReportBadPGOData(CGM, "pgo-data file has bad count value");
+      return true;
+    }
+    Counts.push_back(Count);
+    CurPtr = EndPtr + 1;
+  }
+
+  // Make sure the number of counters matches up.
+  if (Counts.size() != NumCounters) {
+    ReportBadPGOData(CGM, "pgo-data file has inconsistent counters");
+    return true;
+  }
+
+  return false;
+}
+
 void CodeGenPGO::setFuncName(llvm::Function *Fn) {
   StringRef Func = Fn->getName();
 
@@ -57,23 +177,22 @@ void CodeGenPGO::emitWriteoutFunction()
   llvm::Type *Int32Ty = llvm::Type::getInt32Ty(Ctx);
   llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(Ctx);
 
-  llvm::Function *AddFuncsF =
-    CGM.getModule().getFunction("__llvm_pgo_add_functions");
-  if (!AddFuncsF) {
-    llvm::FunctionType *AddFuncsFTy =
+  llvm::Function *WriteoutF =
+    CGM.getModule().getFunction("__llvm_pgo_writeout");
+  if (!WriteoutF) {
+    llvm::FunctionType *WriteoutFTy =
       llvm::FunctionType::get(llvm::Type::getVoidTy(Ctx), false);
-    AddFuncsF = llvm::Function::Create(AddFuncsFTy,
+    WriteoutF = llvm::Function::Create(WriteoutFTy,
                                        llvm::GlobalValue::InternalLinkage,
-                                       "__llvm_pgo_add_functions",
-                                       &CGM.getModule());
+                                       "__llvm_pgo_writeout", &CGM.getModule());
   }
-  AddFuncsF->setUnnamedAddr(true);
-  AddFuncsF->addFnAttr(llvm::Attribute::NoInline);
+  WriteoutF->setUnnamedAddr(true);
+  WriteoutF->addFnAttr(llvm::Attribute::NoInline);
   if (CGM.getCodeGenOpts().DisableRedZone)
-    AddFuncsF->addFnAttr(llvm::Attribute::NoRedZone);
+    WriteoutF->addFnAttr(llvm::Attribute::NoRedZone);
 
-  llvm::BasicBlock *BB = AddFuncsF->empty() ?
-    llvm::BasicBlock::Create(Ctx, "", AddFuncsF) : &AddFuncsF->getEntryBlock();
+  llvm::BasicBlock *BB = WriteoutF->empty() ?
+    llvm::BasicBlock::Create(Ctx, "", WriteoutF) : &WriteoutF->getEntryBlock();
 
   CGBuilderTy PGOBuilder(BB);
 
@@ -83,35 +202,32 @@ void CodeGenPGO::emitWriteoutFunction()
   PGOBuilder.SetInsertPoint(I);
 
   llvm::Type *Int64PtrTy = llvm::Type::getInt64PtrTy(Ctx);
-  llvm::Type *Int64Ty = llvm::Type::getInt64Ty(Ctx);
   llvm::Type *Args[] = {
     Int8PtrTy,                       // const char *FuncName
-    Int64Ty,                         // uint64_t FunctionHash
     Int32Ty,                         // uint32_t NumCounters
     Int64PtrTy                       // uint64_t *Counters
   };
   llvm::FunctionType *FTy =
     llvm::FunctionType::get(PGOBuilder.getVoidTy(), Args, false);
   llvm::Constant *EmitFunc =
-    CGM.getModule().getOrInsertFunction("llvm_pgo_add_function", FTy);
+    CGM.getModule().getOrInsertFunction("llvm_pgo_emit", FTy);
 
   llvm::Constant *NameString =
     CGM.GetAddrOfConstantCString(getFuncName(), "__llvm_pgo_name");
   NameString = llvm::ConstantExpr::getBitCast(NameString, Int8PtrTy);
-  PGOBuilder.CreateCall4(EmitFunc, NameString,
-                         // TODO: This should be a hash, not just the count!
-                         PGOBuilder.getInt64(NumRegionCounters),
+  PGOBuilder.CreateCall3(EmitFunc, NameString,
                          PGOBuilder.getInt32(NumRegionCounters),
                          PGOBuilder.CreateBitCast(RegionCounters, Int64PtrTy));
 }
 
 llvm::Function *CodeGenPGO::emitInitialization(CodeGenModule &CGM) {
-  llvm::Function *AddFuncsF =
-    CGM.getModule().getFunction("__llvm_pgo_add_functions");
-  if (!AddFuncsF)
+  llvm::Function *WriteoutF =
+    CGM.getModule().getFunction("__llvm_pgo_writeout");
+  if (!WriteoutF)
     return NULL;
 
-  // Create a small bit of code that initializes PGO at startup
+  // Create a small bit of code that registers the "__llvm_pgo_writeout" to
+  // be executed at exit.
   llvm::Function *F = CGM.getModule().getFunction("__llvm_pgo_init");
   if (F)
     return NULL;
@@ -139,7 +255,7 @@ llvm::Function *CodeGenPGO::emitInitiali
   // Inialize the environment and register the local writeout function.
   llvm::Constant *PGOInit =
     CGM.getModule().getOrInsertFunction("llvm_pgo_init", FTy);
-  PGOBuilder.CreateCall(PGOInit, AddFuncsF);
+  PGOBuilder.CreateCall(PGOInit, WriteoutF);
   PGOBuilder.CreateRetVoid();
 
   return F;
@@ -642,8 +758,8 @@ namespace {
 
 void CodeGenPGO::assignRegionCounters(const Decl *D, llvm::Function *Fn) {
   bool InstrumentRegions = CGM.getCodeGenOpts().ProfileInstrGenerate;
-  llvm::ProfileDataReader *PGOReader = CGM.getPGOReader();
-  if (!InstrumentRegions && !PGOReader)
+  PGOProfileData *PGOData = CGM.getPGOData();
+  if (!InstrumentRegions && !PGOData)
     return;
   if (!D)
     return;
@@ -651,10 +767,10 @@ void CodeGenPGO::assignRegionCounters(co
   mapRegionCounters(D);
   if (InstrumentRegions)
     emitCounterVariables();
-  if (PGOReader) {
-    loadRegionCounts(PGOReader);
+  if (PGOData) {
+    loadRegionCounts(PGOData);
     computeRegionCounts(D);
-    applyFunctionAttributes(PGOReader, Fn);
+    applyFunctionAttributes(PGOData, Fn);
   }
 }
 
@@ -681,12 +797,12 @@ void CodeGenPGO::computeRegionCounts(con
     Walker.VisitBlockDecl(BD);
 }
 
-void CodeGenPGO::applyFunctionAttributes(llvm::ProfileDataReader *PGOReader,
+void CodeGenPGO::applyFunctionAttributes(PGOProfileData *PGOData,
                                          llvm::Function *Fn) {
   if (!haveRegionCounts())
     return;
 
-  uint64_t MaxFunctionCount = PGOReader->getMaximumFunctionCount();
+  uint64_t MaxFunctionCount = PGOData->getMaximumFunctionCount();
   uint64_t FunctionCount = getRegionCount(0);
   if (FunctionCount >= (uint64_t)(0.3 * (double)MaxFunctionCount))
     // Turn on InlineHint attribute for hot functions.
@@ -719,15 +835,13 @@ void CodeGenPGO::emitCounterIncrement(CG
   Builder.CreateStore(Count, Addr);
 }
 
-void CodeGenPGO::loadRegionCounts(llvm::ProfileDataReader *PGOReader) {
+void CodeGenPGO::loadRegionCounts(PGOProfileData *PGOData) {
   // For now, ignore the counts from the PGO data file only if the number of
   // counters does not match. This could be tightened down in the future to
   // ignore counts when the input changes in various ways, e.g., by comparing a
   // hash value based on some characteristics of the input.
   RegionCounts = new std::vector<uint64_t>();
-  uint64_t Hash;
-  // TODO: Check for hash mismatch
-  if (PGOReader->getFunctionCounts(getFuncName(), Hash, *RegionCounts) ||
+  if (PGOData->getFunctionCounts(getFuncName(), *RegionCounts) ||
       RegionCounts->size() != NumRegionCounters) {
     delete RegionCounts;
     RegionCounts = 0;

Modified: cfe/trunk/lib/CodeGen/CodeGenPGO.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenPGO.h?rev=203712&r1=203711&r2=203712&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenPGO.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenPGO.h Wed Mar 12 16:06:31 2014
@@ -26,6 +26,27 @@ namespace clang {
 namespace CodeGen {
 class RegionCounter;
 
+/// The raw counter data from an instrumented PGO binary
+class PGOProfileData {
+private:
+  /// The PGO data
+  std::unique_ptr<llvm::MemoryBuffer> DataBuffer;
+  /// Offsets into DataBuffer for each function's counters
+  llvm::StringMap<unsigned> DataOffsets;
+  /// Execution counts for each function.
+  llvm::StringMap<uint64_t> FunctionCounts;
+  /// The maximal execution count among all functions.
+  uint64_t MaxFunctionCount;
+  CodeGenModule &CGM;
+public:
+  PGOProfileData(CodeGenModule &CGM, std::string Path);
+  /// Fill Counts with the profile data for the given function name. Returns
+  /// false on success.
+  bool getFunctionCounts(StringRef FuncName, std::vector<uint64_t> &Counts);
+  /// Return the maximum of all known function counts.
+  uint64_t getMaximumFunctionCount() { return MaxFunctionCount; }
+};
+
 /// Per-function PGO state. This class should generally not be used directly,
 /// but instead through the CodeGenFunction and RegionCounter types.
 class CodeGenPGO {
@@ -115,9 +136,8 @@ private:
   void setFuncName(llvm::Function *Fn);
   void mapRegionCounters(const Decl *D);
   void computeRegionCounts(const Decl *D);
-  void applyFunctionAttributes(llvm::ProfileDataReader *PGOReader,
-                               llvm::Function *Fn);
-  void loadRegionCounts(llvm::ProfileDataReader *PGOReader);
+  void applyFunctionAttributes(PGOProfileData *PGOData, llvm::Function *Fn);
+  void loadRegionCounts(PGOProfileData *PGOData);
   void emitCounterVariables();
 
   /// Emit code to increment the counter at the given index

Modified: cfe/trunk/test/Profile/Inputs/c-attributes.profdata
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Profile/Inputs/c-attributes.profdata?rev=203712&r1=203711&r2=203712&view=diff
==============================================================================
Binary files cfe/trunk/test/Profile/Inputs/c-attributes.profdata (original) and cfe/trunk/test/Profile/Inputs/c-attributes.profdata Wed Mar 12 16:06:31 2014 differ

Modified: cfe/trunk/test/Profile/Inputs/c-counter-overflows.profdata
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Profile/Inputs/c-counter-overflows.profdata?rev=203712&r1=203711&r2=203712&view=diff
==============================================================================
Binary files cfe/trunk/test/Profile/Inputs/c-counter-overflows.profdata (original) and cfe/trunk/test/Profile/Inputs/c-counter-overflows.profdata Wed Mar 12 16:06:31 2014 differ

Modified: cfe/trunk/test/Profile/Inputs/c-general.profdata
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Profile/Inputs/c-general.profdata?rev=203712&r1=203711&r2=203712&view=diff
==============================================================================
Binary files cfe/trunk/test/Profile/Inputs/c-general.profdata (original) and cfe/trunk/test/Profile/Inputs/c-general.profdata Wed Mar 12 16:06:31 2014 differ

Modified: cfe/trunk/test/Profile/Inputs/c-outdated-data.profdata
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Profile/Inputs/c-outdated-data.profdata?rev=203712&r1=203711&r2=203712&view=diff
==============================================================================
Binary files cfe/trunk/test/Profile/Inputs/c-outdated-data.profdata (original) and cfe/trunk/test/Profile/Inputs/c-outdated-data.profdata Wed Mar 12 16:06:31 2014 differ

Modified: cfe/trunk/test/Profile/Inputs/cxx-class.profdata
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Profile/Inputs/cxx-class.profdata?rev=203712&r1=203711&r2=203712&view=diff
==============================================================================
Binary files cfe/trunk/test/Profile/Inputs/cxx-class.profdata (original) and cfe/trunk/test/Profile/Inputs/cxx-class.profdata Wed Mar 12 16:06:31 2014 differ

Modified: cfe/trunk/test/Profile/Inputs/cxx-throws.profdata
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Profile/Inputs/cxx-throws.profdata?rev=203712&r1=203711&r2=203712&view=diff
==============================================================================
Binary files cfe/trunk/test/Profile/Inputs/cxx-throws.profdata (original) and cfe/trunk/test/Profile/Inputs/cxx-throws.profdata Wed Mar 12 16:06:31 2014 differ

Modified: cfe/trunk/test/Profile/Inputs/objc-general.profdata
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Profile/Inputs/objc-general.profdata?rev=203712&r1=203711&r2=203712&view=diff
==============================================================================
Binary files cfe/trunk/test/Profile/Inputs/objc-general.profdata (original) and cfe/trunk/test/Profile/Inputs/objc-general.profdata Wed Mar 12 16:06:31 2014 differ

Modified: cfe/trunk/tools/driver/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/driver/CMakeLists.txt?rev=203712&r1=203711&r2=203712&view=diff
==============================================================================
--- cfe/trunk/tools/driver/CMakeLists.txt (original)
+++ cfe/trunk/tools/driver/CMakeLists.txt Wed Mar 12 16:06:31 2014
@@ -10,7 +10,6 @@ set( LLVM_LINK_COMPONENTS
   MCParser
   ObjCARCOpts
   Option
-  Profile
   ScalarOpts
   Support
   TransformUtils





More information about the cfe-commits mailing list