Encoding calling conv info in call/invoke instrs, tree add now round trips completely
[oota-llvm.git] / lib / Bitcode / Writer / BitcodeWriter.cpp
index ad2534c75e2d4937298a442cdd025adb740fa880..6dcc37296c11ab5479cc75aeef988406013b8652 100644 (file)
@@ -497,7 +497,7 @@ static void WriteInstruction(const Instruction &I, ValueEnumerator &VE,
       Vals.push_back(VE.getValueID(I.getOperand(0)));
     } else {
       assert(isa<BinaryOperator>(I) && "Unknown instruction!");
-      Code = bitc::CST_CODE_CE_BINOP;
+      Code = bitc::FUNC_CODE_INST_BINOP;
       Vals.push_back(GetEncodedBinaryOpcode(I.getOpcode()));
       Vals.push_back(VE.getTypeID(I.getType()));
       Vals.push_back(VE.getValueID(I.getOperand(0)));
@@ -507,7 +507,6 @@ static void WriteInstruction(const Instruction &I, ValueEnumerator &VE,
 
   case Instruction::GetElementPtr:
     Code = bitc::FUNC_CODE_INST_GEP;
-    Vals.push_back(I.getNumOperands());
     for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
       Vals.push_back(VE.getTypeID(I.getOperand(i)->getType()));
       Vals.push_back(VE.getValueID(I.getOperand(i)));
@@ -567,13 +566,12 @@ static void WriteInstruction(const Instruction &I, ValueEnumerator &VE,
   case Instruction::Switch:
     Code = bitc::FUNC_CODE_INST_SWITCH;
     Vals.push_back(VE.getTypeID(I.getOperand(0)->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;
-  case Instruction::Invoke:
+  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
@@ -596,6 +594,7 @@ static void WriteInstruction(const Instruction &I, ValueEnumerator &VE,
       }
     }
     break;
+  }
   case Instruction::Unwind:
     Code = bitc::FUNC_CODE_INST_UNWIND;
     break;
@@ -648,7 +647,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
     
@@ -658,19 +658,17 @@ static void WriteInstruction(const Instruction &I, ValueEnumerator &VE,
     for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i)
       Vals.push_back(VE.getValueID(I.getOperand(i+1)));  // fixed param.
       
-      // 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()));
-          Vals.push_back(VE.getValueID(I.getOperand(i)));
-        }
+    // Emit type/value pairs for varargs params.
+    if (FTy->isVarArg()) {
+      unsigned NumVarargs = I.getNumOperands()-1-FTy->getNumParams();
+      for (unsigned i = I.getNumOperands()-NumVarargs, e = I.getNumOperands();
+           i != e; ++i) {
+        Vals.push_back(VE.getTypeID(I.getOperand(i)->getType()));
+        Vals.push_back(VE.getValueID(I.getOperand(i)));
       }
     }
     break;
-    
+  }
   case Instruction::VAArg:
     Code = bitc::FUNC_CODE_INST_VAARG;
     Vals.push_back(VE.getTypeID(I.getOperand(0)->getType()));   // valistty
@@ -683,6 +681,43 @@ static void WriteInstruction(const Instruction &I, ValueEnumerator &VE,
   Vals.clear();
 }
 
+// Emit names for globals/functions etc.
+static void WriteValueSymbolTable(const ValueSymbolTable &VST,
+                                  const ValueEnumerator &VE,
+                                  BitstreamWriter &Stream) {
+  if (VST.empty()) return;
+  Stream.EnterSubblock(bitc::VALUE_SYMTAB_BLOCK_ID, 3);
+  
+  // 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;
+  
+  for (ValueSymbolTable::const_iterator SI = VST.begin(), SE = VST.end();
+       SI != SE; ++SI) {
+    unsigned AbbrevToUse = 0;
+    
+    // VST_ENTRY:   [valueid, namelen, namechar x N]
+    // VST_BBENTRY: [bbid, namelen, namechar x N]
+    unsigned Code;
+    if (isa<BasicBlock>(SI->getValue())) {
+      Code = bitc::VST_CODE_BBENTRY;
+    } else {
+      Code = bitc::VST_CODE_ENTRY;
+    }
+    
+    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);
+    
+    // Emit the finished record.
+    Stream.EmitRecord(Code, NameVals, AbbrevToUse);
+    NameVals.clear();
+  }
+  Stream.ExitBlock();
+}
+
 /// WriteFunction - Emit a function body to the module stream.
 static void WriteFunction(const Function &F, ValueEnumerator &VE, 
                           BitstreamWriter &Stream) {
@@ -709,6 +744,9 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE,
     for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I)
       WriteInstruction(*I, VE, Stream, Vals);
   
+  // Emit names for all the instructions etc.
+  WriteValueSymbolTable(F.getValueSymbolTable(), VE, Stream);
+    
   VE.purgeFunction();
   Stream.ExitBlock();
 }
@@ -746,36 +784,6 @@ static void WriteTypeSymbolTable(const TypeSymbolTable &TST,
   Stream.ExitBlock();
 }
 
-// Emit names for globals/functions etc.
-static void WriteValueSymbolTable(const ValueSymbolTable &VST,
-                                  const ValueEnumerator &VE,
-                                  BitstreamWriter &Stream) {
-  if (VST.empty()) return;
-  Stream.EnterSubblock(bitc::VALUE_SYMTAB_BLOCK_ID, 3);
-  
-  // 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;
-  
-  for (ValueSymbolTable::const_iterator SI = VST.begin(), SE = VST.end();
-       SI != SE; ++SI) {
-    unsigned AbbrevToUse = 0;
-    
-    // VST_ENTRY: [valueid, namelen, namechar x N]
-    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);
-    
-    // Emit the finished record.
-    Stream.EmitRecord(bitc::VST_CODE_ENTRY, NameVals, AbbrevToUse);
-    NameVals.clear();
-  }
-  Stream.ExitBlock();
-}
-
 
 /// WriteModule - Emit the specified module to the bitstream.
 static void WriteModule(const Module *M, BitstreamWriter &Stream) {