Make sure to set stdout to binary when writing bitcode files via
[oota-llvm.git] / lib / Bitcode / Writer / BitcodeWriter.cpp
index 2c585b1370779a34e03d2a31a1535e062ac99a48..279e447873cab76fc90b4097f95d852e64366816 100644 (file)
@@ -23,6 +23,8 @@
 #include "llvm/TypeSymbolTable.h"
 #include "llvm/ValueSymbolTable.h"
 #include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Streams.h"
+#include "llvm/Support/raw_ostream.h"
 #include "llvm/System/Program.h"
 using namespace llvm;
 
@@ -107,18 +109,18 @@ static void WriteStringRecord(unsigned Code, const std::string &Str,
 }
 
 // Emit information about parameter attributes.
-static void WriteParamAttrTable(const ValueEnumerator &VE, 
+static void WriteAttributeTable(const ValueEnumerator &VE, 
                                 BitstreamWriter &Stream) {
-  const std::vector<PAListPtr> &Attrs = VE.getParamAttrs();
+  const std::vector<AttrListPtr> &Attrs = VE.getAttributes();
   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 PAListPtr &A = Attrs[i];
+    const AttrListPtr &A = Attrs[i];
     for (unsigned i = 0, e = A.getNumSlots(); i != e; ++i) {
-      const ParamAttrsWithIndex &PAWI = A.getSlot(i);
+      const AttributeWithIndex &PAWI = A.getSlot(i);
       Record.push_back(PAWI.Index);
       Record.push_back(PAWI.Attrs);
     }
@@ -303,10 +305,10 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
     WriteStringRecord(bitc::MODULE_CODE_ASM, M->getModuleInlineAsm(),
                       0/*TODO*/, Stream);
 
-  // Emit information about sections and collectors, computing how many there
-  // are.  Also compute the maximum alignment value.
+  // Emit information about sections and GC, computing how many there are. Also
+  // compute the maximum alignment value.
   std::map<std::string, unsigned> SectionMap;
-  std::map<std::string, unsigned> CollectorMap;
+  std::map<std::string, unsigned> GCMap;
   unsigned MaxAlignment = 0;
   unsigned MaxGlobalType = 0;
   for (Module::const_global_iterator GV = M->global_begin(),E = M->global_end();
@@ -333,13 +335,13 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
         Entry = SectionMap.size();
       }
     }
-    if (F->hasCollector()) {
-      // Same for collector names.
-      unsigned &Entry = CollectorMap[F->getCollector()];
+    if (F->hasGC()) {
+      // Same for GC names.
+      unsigned &Entry = GCMap[F->getGC()];
       if (!Entry) {
-        WriteStringRecord(bitc::MODULE_CODE_COLLECTORNAME, F->getCollector(),
+        WriteStringRecord(bitc::MODULE_CODE_GCNAME, F->getGC(),
                           0/*TODO*/, Stream);
-        Entry = CollectorMap.size();
+        Entry = GCMap.size();
       }
     }
   }
@@ -401,16 +403,16 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
   // Emit the function proto information.
   for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) {
     // FUNCTION:  [type, callingconv, isproto, paramattr,
-    //             linkage, alignment, section, visibility, collector]
+    //             linkage, alignment, section, visibility, gc]
     Vals.push_back(VE.getTypeID(F->getType()));
     Vals.push_back(F->getCallingConv());
     Vals.push_back(F->isDeclaration());
     Vals.push_back(getEncodedLinkage(F));
-    Vals.push_back(VE.getParamAttrID(F->getParamAttrs()));
+    Vals.push_back(VE.getAttributeID(F->getAttributes()));
     Vals.push_back(Log2_32(F->getAlignment())+1);
     Vals.push_back(F->hasSection() ? SectionMap[F->getSection()] : 0);
     Vals.push_back(getEncodedVisibility(F));
-    Vals.push_back(F->hasCollector() ? CollectorMap[F->getCollector()] : 0);
+    Vals.push_back(F->hasGC() ? GCMap[F->getGC()] : 0);
     
     unsigned AbbrevToUse = 0;
     Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse);
@@ -541,15 +543,15 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
       Code = bitc::CST_CODE_FLOAT;
       const Type *Ty = CFP->getType();
       if (Ty == Type::FloatTy || Ty == Type::DoubleTy) {
-        Record.push_back(CFP->getValueAPF().convertToAPInt().getZExtValue());
+        Record.push_back(CFP->getValueAPF().bitcastToAPInt().getZExtValue());
       } else if (Ty == Type::X86_FP80Ty) {
         // api needed to prevent premature destruction
-        APInt api = CFP->getValueAPF().convertToAPInt();
+        APInt api = CFP->getValueAPF().bitcastToAPInt();
         const uint64_t *p = api.getRawData();
         Record.push_back(p[0]);
         Record.push_back((uint16_t)p[1]);
       } else if (Ty == Type::FP128Ty || Ty == Type::PPC_FP128Ty) {
-        APInt api = CFP->getValueAPF().convertToAPInt();
+        APInt api = CFP->getValueAPF().bitcastToAPInt();
         const uint64_t *p = api.getRawData();
         Record.push_back(p[0]);
         Record.push_back(p[1]);
@@ -639,7 +641,14 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
       case Instruction::FCmp:
       case Instruction::VICmp:
       case Instruction::VFCmp:
-        Code = bitc::CST_CODE_CE_CMP;
+        if (isa<VectorType>(C->getOperand(0)->getType())
+            && (CE->getOpcode() == Instruction::ICmp
+                || CE->getOpcode() == Instruction::FCmp)) {
+          // compare returning vector of Int1Ty
+          assert(0 && "Unsupported constant!");
+        } else {
+          Code = bitc::CST_CODE_CE_CMP;
+        }
         Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
         Record.push_back(VE.getValueID(C->getOperand(0)));
         Record.push_back(VE.getValueID(C->getOperand(1)));
@@ -737,10 +746,10 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
     break;
   }
   case Instruction::Select:
-    Code = bitc::FUNC_CODE_INST_SELECT;
+    Code = bitc::FUNC_CODE_INST_VSELECT;
     PushValueAndType(I.getOperand(1), InstID, Vals, VE);
     Vals.push_back(VE.getValueID(I.getOperand(2)));
-    Vals.push_back(VE.getValueID(I.getOperand(0)));
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);
     break;
   case Instruction::ExtractElement:
     Code = bitc::FUNC_CODE_INST_EXTRACTELT;
@@ -763,7 +772,13 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
   case Instruction::FCmp:
   case Instruction::VICmp:
   case Instruction::VFCmp:
-    Code = bitc::FUNC_CODE_INST_CMP;
+    if (I.getOpcode() == Instruction::ICmp
+        || I.getOpcode() == Instruction::FCmp) {
+      // compare returning Int1Ty or vector of Int1Ty
+      Code = bitc::FUNC_CODE_INST_CMP2;
+    } else {
+      Code = bitc::FUNC_CODE_INST_CMP;
+    }
     PushValueAndType(I.getOperand(0), InstID, Vals, VE);
     Vals.push_back(VE.getValueID(I.getOperand(1)));
     Vals.push_back(cast<CmpInst>(I).getPredicate());
@@ -804,7 +819,7 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
     Code = bitc::FUNC_CODE_INST_INVOKE;
     
     const InvokeInst *II = cast<InvokeInst>(&I);
-    Vals.push_back(VE.getParamAttrID(II->getParamAttrs()));
+    Vals.push_back(VE.getAttributeID(II->getAttributes()));
     Vals.push_back(II->getCallingConv());
     Vals.push_back(VE.getValueID(I.getOperand(1)));      // normal dest
     Vals.push_back(VE.getValueID(I.getOperand(2)));      // unwind dest
@@ -878,7 +893,7 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
     Code = bitc::FUNC_CODE_INST_CALL;
     
     const CallInst *CI = cast<CallInst>(&I);
-    Vals.push_back(VE.getParamAttrID(CI->getParamAttrs()));
+    Vals.push_back(VE.getAttributeID(CI->getAttributes()));
     Vals.push_back((CI->getCallingConv() << 1) | unsigned(CI->isTailCall()));
     PushValueAndType(CI->getOperand(0), InstID, Vals, VE);  // Callee
     
@@ -1212,7 +1227,7 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream) {
   WriteBlockInfo(VE, Stream);
   
   // Emit information about parameter attributes.
-  WriteParamAttrTable(VE, Stream);
+  WriteAttributeTable(VE, Stream);
   
   // Emit information describing all of the types in the module.
   WriteTypeTable(VE, Stream);
@@ -1316,6 +1331,16 @@ static void EmitDarwinBCTrailer(BitstreamWriter &Stream, unsigned BufferSize) {
 /// WriteBitcodeToFile - Write the specified module to the specified output
 /// stream.
 void llvm::WriteBitcodeToFile(const Module *M, std::ostream &Out) {
+  raw_os_ostream RawOut(Out);
+  // If writing to stdout, set binary mode.
+  if (llvm::cout == Out)
+    sys::Program::ChangeStdoutToBinary();
+  WriteBitcodeToFile(M, RawOut);
+}
+
+/// WriteBitcodeToFile - Write the specified module to the specified output
+/// stream.
+void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out) {
   std::vector<unsigned char> Buffer;
   BitstreamWriter Stream(Buffer);
   
@@ -1342,7 +1367,7 @@ void llvm::WriteBitcodeToFile(const Module *M, std::ostream &Out) {
 
   
   // If writing to stdout, set binary mode.
-  if (llvm::cout == Out)
+  if (&llvm::outs() == &Out)
     sys::Program::ChangeStdoutToBinary();
 
   // Write the generated bitstream to "Out".