add an abbreviation for common PARM_VAR_DECL.  All but 9 of the 
parm var decls in leopard cocoa.h end up using this abbreviation,
which shrinks the bitcode file by about 50K: 7217736->7167120.

Before:
  Block ID #12 (DECLS_BLOCK):
      Num Instances: 1
         Total Size: 2.23595e+07b/2.79494e+06B/698736W
          % of file: 38.7233
      Num SubBlocks: 0
        Num Abbrevs: 0
        Num Records: 139387
      % Abbrev Recs: 0

After:
  Block ID #12 (DECLS_BLOCK):
      Num Instances: 1
         Total Size: 2.02405e+07b/2.53006e+06B/632516W
          % of file: 35.301
      Num SubBlocks: 0
        Num Abbrevs: 1
        Num Records: 139387
      % Abbrev Recs: 19.2902



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70199 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp
index e2cf3d8..799c77b 100644
--- a/lib/Frontend/PCHWriterDecl.cpp
+++ b/lib/Frontend/PCHWriterDecl.cpp
@@ -30,10 +30,12 @@
 
   public:
     pch::DeclCode Code;
+    unsigned AbbrevToUse;
 
     PCHDeclWriter(PCHWriter &Writer, ASTContext &Context, 
                   PCHWriter::RecordData &Record) 
-      : Writer(Writer), Context(Context), Record(Record) { }
+      : Writer(Writer), Context(Context), Record(Record) {
+    }
 
     void VisitDecl(Decl *D);
     void VisitTranslationUnitDecl(TranslationUnitDecl *D);
@@ -349,12 +351,34 @@
   // FIXME: why isn't the "default argument" just stored as the initializer
   // in VarDecl?
   Code = pch::DECL_PARM_VAR;
+  
+  
+  // If the assumptions about the DECL_PARM_VAR abbrev are true, use it.  Here
+  // we dynamically check for the properties that we optimize for, but don't
+  // know are true of all PARM_VAR_DECLs.
+  if (!D->hasAttrs() &&
+      !D->isImplicit() &&
+      D->getAccess() == AS_none &&
+      D->getStorageClass() == 0 &&
+      !D->hasCXXDirectInitializer() && // Can params have this ever?
+      D->getObjCDeclQualifier() == 0)
+    AbbrevToUse = Writer.getParmVarDeclAbbrev();
+
+  // Check things we know are true of *every* PARM_VAR_DECL, which is more than
+  // just us assuming it.
+  assert(!D->isInvalidDecl() && "Shouldn't emit invalid decls");
+  assert(!D->isThreadSpecified() && "PARM_VAR_DECL can't be __thread");
+  assert(D->getAccess() == AS_none && "PARM_VAR_DECL can't be public/private");
+  assert(!D->isDeclaredInCondition() && "PARM_VAR_DECL can't be in condition");
+  assert(D->getPreviousDeclaration() == 0 && "PARM_VAR_DECL can't be redecl");
+  assert(D->getInit() == 0 && "PARM_VAR_DECL never has init");
 }
 
 void PCHDeclWriter::VisitOriginalParmVarDecl(OriginalParmVarDecl *D) {
   VisitParmVarDecl(D);
   Writer.AddTypeRef(D->getOriginalType(), Record);
   Code = pch::DECL_ORIGINAL_PARM_VAR;
+  AbbrevToUse = 0;
 }
 
 void PCHDeclWriter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
@@ -395,11 +419,48 @@
 // PCHWriter Implementation
 //===----------------------------------------------------------------------===//
 
+void PCHWriter::WriteDeclsBlockAbbrevs() {
+  using namespace llvm;
+  // Abbreviation for DECL_PARM_VAR.
+  BitCodeAbbrev *Abv = new BitCodeAbbrev();
+  Abv->Add(BitCodeAbbrevOp(pch::DECL_PARM_VAR));
+
+  // Decl
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
+  Abv->Add(BitCodeAbbrevOp(0));                       // isInvalidDecl (!?)
+  Abv->Add(BitCodeAbbrevOp(0));                       // HasAttrs
+  Abv->Add(BitCodeAbbrevOp(0));                       // isImplicit
+  Abv->Add(BitCodeAbbrevOp(AS_none));                 // C++ AccessSpecifier
+  
+  // NamedDecl
+  Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
+  // ValueDecl
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
+  // VarDecl
+  Abv->Add(BitCodeAbbrevOp(0));                       // StorageClass
+  Abv->Add(BitCodeAbbrevOp(0));                       // isThreadSpecified
+  Abv->Add(BitCodeAbbrevOp(0));                       // hasCXXDirectInitializer
+  Abv->Add(BitCodeAbbrevOp(0));                       // isDeclaredInCondition
+  Abv->Add(BitCodeAbbrevOp(0));                       // PrevDecl
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeSpecStartLoc
+  Abv->Add(BitCodeAbbrevOp(0));                       // HasInit
+  // ParmVarDecl
+  Abv->Add(BitCodeAbbrevOp(0));                       // ObjCDeclQualifier
+  
+  ParmVarDeclAbbrev = Stream.EmitAbbrev(Abv);
+}
+
 /// \brief Write a block containing all of the declarations.
 void PCHWriter::WriteDeclsBlock(ASTContext &Context) {
   // Enter the declarations block.
-  Stream.EnterSubblock(pch::DECLS_BLOCK_ID, 2);
+  Stream.EnterSubblock(pch::DECLS_BLOCK_ID, 3);
 
+  // Output the abbreviations that we will use in this block.
+  WriteDeclsBlockAbbrevs();
+  
   // Emit all of the declarations.
   RecordData Record;
   PCHDeclWriter W(*this, Context, Record);
@@ -439,6 +500,7 @@
     // Build and emit a record for this declaration
     Record.clear();
     W.Code = (pch::DeclCode)0;
+    W.AbbrevToUse = 0;
     W.Visit(D);
     if (DC) W.VisitDeclContext(DC, LexicalOffset, VisibleOffset);
 
@@ -448,8 +510,8 @@
       assert(false && "Unhandled declaration kind while generating PCH");
       exit(-1);
     }
-    Stream.EmitRecord(W.Code, Record);
-
+    Stream.EmitRecord(W.Code, Record, W.AbbrevToUse);
+    
     // If the declaration had any attributes, write them now.
     if (D->hasAttrs())
       WriteAttributeRecord(D->getAttrs());