eliminate internal length fields from record. Records already know their
[oota-llvm.git] / lib / Bitcode / Writer / BitcodeWriter.cpp
index 68f0a0d163709ade4ca4e88c636c98d31ca427f9..7fc82101a98c848ead74078741274c83bccec64b 100644 (file)
@@ -19,6 +19,7 @@
 #include "llvm/DerivedTypes.h"
 #include "llvm/Instructions.h"
 #include "llvm/Module.h"
+#include "llvm/ParameterAttributes.h"
 #include "llvm/TypeSymbolTable.h"
 #include "llvm/ValueSymbolTable.h"
 #include "llvm/Support/MathExtras.h"
@@ -71,8 +72,7 @@ static void WriteStringRecord(unsigned Code, const std::string &Str,
                               unsigned AbbrevToUse, BitstreamWriter &Stream) {
   SmallVector<unsigned, 64> Vals;
   
-  // Code: [strlen, strchar x N]
-  Vals.push_back(Str.size());
+  // Code: [strchar x N]
   for (unsigned i = 0, e = Str.size(); i != e; ++i)
     Vals.push_back(Str[i]);
     
@@ -80,6 +80,28 @@ static void WriteStringRecord(unsigned Code, const std::string &Str,
   Stream.EmitRecord(Code, Vals, AbbrevToUse);
 }
 
+// Emit information about parameter attributes.
+static void WriteParamAttrTable(const ValueEnumerator &VE, 
+                                BitstreamWriter &Stream) {
+  const std::vector<const ParamAttrsList*> &Attrs = VE.getParamAttrs();
+  if (Attrs.empty()) return;
+  
+  Stream.EnterSubblock(bitc::PARAMATTR_BLOCK_ID, 3);
+
+  SmallVector<uint64_t, 64> Record;
+  for (unsigned i = 0, e = Attrs.size(); i != e; ++i) {
+    const ParamAttrsList *A = Attrs[i];
+    for (unsigned op = 0, e = A->size(); op != e; ++op) {
+      Record.push_back(A->getParamIndex(op));
+      Record.push_back(A->getParamAttrsAtIndex(op));
+    }
+    
+    Stream.EmitRecord(bitc::PARAMATTR_CODE_ENTRY, Record);
+    Record.clear();
+  }
+  
+  Stream.ExitBlock();
+}
 
 /// WriteTypeTable - Write out the type table for a module.
 static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
@@ -122,12 +144,11 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
 
     case Type::FunctionTyID: {
       const FunctionType *FT = cast<FunctionType>(T);
-      // FUNCTION: [isvararg, #pararms, paramty x N]
+      // FUNCTION: [isvararg, attrid, #pararms, paramty x N]
       Code = bitc::TYPE_CODE_FUNCTION;
       TypeVals.push_back(FT->isVarArg());
+      TypeVals.push_back(VE.getParamAttrID(FT->getParamAttrs()));
       TypeVals.push_back(VE.getTypeID(FT->getReturnType()));
-      // FIXME: PARAM ATTR ID!
-      TypeVals.push_back(FT->getNumParams());
       for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i)
         TypeVals.push_back(VE.getTypeID(FT->getParamType(i)));
       break;
@@ -137,8 +158,7 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
       // STRUCT: [ispacked, #elts, eltty x N]
       Code = bitc::TYPE_CODE_STRUCT;
       TypeVals.push_back(ST->isPacked());
-      TypeVals.push_back(ST->getNumElements());
-      // Output all of the element types...
+      // Output all of the element types.
       for (StructType::element_iterator I = ST->element_begin(),
            E = ST->element_end(); I != E; ++I)
         TypeVals.push_back(VE.getTypeID(*I));
@@ -376,7 +396,6 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
         // So, we only write the number of active words.
         unsigned NWords = IV->getValue().getActiveWords(); 
         const uint64_t *RawWords = IV->getValue().getRawData();
-        Record.push_back(NWords);
         for (unsigned i = 0; i != NWords; ++i) {
           int64_t V = RawWords[i];
           if (V >= 0)
@@ -397,7 +416,6 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
     } else if (isa<ConstantArray>(C) || isa<ConstantStruct>(V) ||
                isa<ConstantVector>(V)) {
       Code = bitc::CST_CODE_AGGREGATE;
-      Record.push_back(C->getNumOperands());
       for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i)
         Record.push_back(VE.getValueID(C->getOperand(i)));
     } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
@@ -418,7 +436,6 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
         break;
       case Instruction::GetElementPtr:
         Code = bitc::CST_CODE_CE_GEP;
-        Record.push_back(CE->getNumOperands());
         for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) {
           Record.push_back(VE.getTypeID(C->getOperand(i)->getType()));
           Record.push_back(VE.getValueID(C->getOperand(i)));
@@ -571,7 +588,7 @@ static void WriteInstruction(const Instruction &I, ValueEnumerator &VE,
     break;
   case Instruction::Invoke: {
     Code = bitc::FUNC_CODE_INST_INVOKE;
-    // FIXME: param attrs
+    Vals.push_back(cast<InvokeInst>(I).getCallingConv());
     Vals.push_back(VE.getTypeID(I.getOperand(0)->getType()));
     Vals.push_back(VE.getValueID(I.getOperand(0)));  // callee
     Vals.push_back(VE.getValueID(I.getOperand(1)));  // normal
@@ -586,7 +603,6 @@ static void WriteInstruction(const Instruction &I, ValueEnumerator &VE,
     // Emit type/value pairs for varargs params.
     if (FTy->isVarArg()) {
       unsigned NumVarargs = I.getNumOperands()-3-FTy->getNumParams();
-      Vals.push_back(NumVarargs);
       for (unsigned i = I.getNumOperands()-NumVarargs, e = I.getNumOperands();
            i != e; ++i) {
         Vals.push_back(VE.getTypeID(I.getOperand(i)->getType()));
@@ -605,7 +621,6 @@ static void WriteInstruction(const Instruction &I, ValueEnumerator &VE,
   case Instruction::PHI:
     Code = bitc::FUNC_CODE_INST_PHI;
     Vals.push_back(VE.getTypeID(I.getType()));
-    Vals.push_back(I.getNumOperands());
     for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
       Vals.push_back(VE.getValueID(I.getOperand(i)));
     break;
@@ -647,7 +662,8 @@ static void WriteInstruction(const Instruction &I, ValueEnumerator &VE,
     break;
   case Instruction::Call: {
     Code = bitc::FUNC_CODE_INST_CALL;
-    // FIXME: param attrs
+    Vals.push_back((cast<CallInst>(I).getCallingConv() << 1) |
+                   cast<CallInst>(I).isTailCall());
     Vals.push_back(VE.getTypeID(I.getOperand(0)->getType()));
     Vals.push_back(VE.getValueID(I.getOperand(0)));  // callee
     
@@ -660,7 +676,6 @@ static void WriteInstruction(const Instruction &I, ValueEnumerator &VE,
     // Emit type/value pairs for varargs params.
     if (FTy->isVarArg()) {
       unsigned NumVarargs = I.getNumOperands()-1-FTy->getNumParams();
-      Vals.push_back(NumVarargs);
       for (unsigned i = I.getNumOperands()-NumVarargs, e = I.getNumOperands();
            i != e; ++i) {
         Vals.push_back(VE.getTypeID(I.getOperand(i)->getType()));
@@ -688,6 +703,16 @@ static void WriteValueSymbolTable(const ValueSymbolTable &VST,
   if (VST.empty()) return;
   Stream.EnterSubblock(bitc::VALUE_SYMTAB_BLOCK_ID, 3);
   
+#if 0
+  BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+  Abbv->Add(BitCodeAbbrevOp(bitc::VST_ENTRY));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::FixedWidth,
+                            Log2_32_Ceil(MaxGlobalType+1)));
+  // Don't bother emitting vis + thread local.
+  SimpleGVarAbbrev = Stream.EmitAbbrev(Abbv);
+#endif
+  
+  
   // FIXME: Set up the abbrev, we know how many values there are!
   // FIXME: We know if the type names can use 7-bit ascii.
   SmallVector<unsigned, 64> NameVals;
@@ -706,7 +731,6 @@ static void WriteValueSymbolTable(const ValueSymbolTable &VST,
     }
     
     NameVals.push_back(VE.getValueID(SI->getValue()));
-    NameVals.push_back(SI->getKeyLength());
     for (const char *P = SI->getKeyData(),
          *E = SI->getKeyData()+SI->getKeyLength(); P != E; ++P)
       NameVals.push_back((unsigned char)*P);
@@ -772,7 +796,6 @@ static void WriteTypeSymbolTable(const TypeSymbolTable &TST,
     NameVals.push_back(VE.getTypeID(TI->second));
     
     const std::string &Str = TI->first;
-    NameVals.push_back(Str.size());
     for (unsigned i = 0, e = Str.size(); i != e; ++i)
       NameVals.push_back(Str[i]);
     
@@ -799,6 +822,9 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream) {
   // Analyze the module, enumerating globals, functions, etc.
   ValueEnumerator VE(M);
   
+  // Emit information about parameter attributes.
+  WriteParamAttrTable(VE, Stream);
+  
   // Emit information describing all of the types in the module.
   WriteTypeTable(VE, Stream);
   
@@ -833,6 +859,28 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream) {
   Stream.ExitBlock();
 }
 
+// Emit blockinfo, which defines the standard abbreviations etc.
+static void WriteBlockInfo(BitstreamWriter &Stream) {
+  // We only want to emit block info records for blocks that have multiple
+  // instances: CONSTANTS_BLOCK, FUNCTION_BLOCK and VALUE_SYMTAB_BLOCK.  Other
+  // blocks can defined their abbrevs inline.
+  Stream.EnterSubblock(bitc::BLOCKINFO_BLOCK_ID, 2);
+
+#if 0
+  // Configure TYPE_SYMTAB_BLOCK's.
+
+  // Add an abbrev for VST_ENTRY where the characters each fit in 7 bits.
+  BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+  Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_ENTRY));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8); // Value ID
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::FixedWidth, 3)); // Linkage.
+  
+  xxx = Stream.EmitAbbrev(Abbv);
+#endif
+  Stream.ExitBlock();
+}
+
+
 /// WriteBitcodeToFile - Write the specified module to the specified output
 /// stream.
 void llvm::WriteBitcodeToFile(const Module *M, std::ostream &Out) {
@@ -849,6 +897,9 @@ void llvm::WriteBitcodeToFile(const Module *M, std::ostream &Out) {
   Stream.Emit(0xE, 4);
   Stream.Emit(0xD, 4);
 
+  // Emit blockinfo, which defines the standard abbreviations etc.
+  WriteBlockInfo(Stream);
+  
   // Emit the module.
   WriteModule(M, Stream);