| Chris Lattner | 1a9df8e | 2007-04-29 05:31:57 +0000 | [diff] [blame] | 1 | //===--- Bitcode/Writer/BitcodeWriter.cpp - Bitcode Writer ----------------===// | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 2 | // | 
 | 3 | //                     The LLVM Compiler Infrastructure | 
 | 4 | // | 
| Chris Lattner | 4ee451d | 2007-12-29 20:36:04 +0000 | [diff] [blame] | 5 | // This file is distributed under the University of Illinois Open Source | 
 | 6 | // License. See LICENSE.TXT for details. | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 7 | // | 
 | 8 | //===----------------------------------------------------------------------===// | 
 | 9 | // | 
 | 10 | // Bitcode writer implementation. | 
 | 11 | // | 
 | 12 | //===----------------------------------------------------------------------===// | 
 | 13 |  | 
 | 14 | #include "llvm/Bitcode/ReaderWriter.h" | 
 | 15 | #include "llvm/Bitcode/BitstreamWriter.h" | 
| Chris Lattner | 47f96bf | 2007-04-23 01:01:37 +0000 | [diff] [blame] | 16 | #include "llvm/Bitcode/LLVMBitCodes.h" | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 17 | #include "ValueEnumerator.h" | 
| Chris Lattner | 2edd22b | 2007-04-24 00:16:04 +0000 | [diff] [blame] | 18 | #include "llvm/Constants.h" | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 19 | #include "llvm/DerivedTypes.h" | 
| Chris Lattner | 2bce93a | 2007-05-06 01:58:20 +0000 | [diff] [blame] | 20 | #include "llvm/InlineAsm.h" | 
| Chris Lattner | b9d0c2a | 2007-04-26 05:53:54 +0000 | [diff] [blame] | 21 | #include "llvm/Instructions.h" | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 22 | #include "llvm/Module.h" | 
| Chris Lattner | f0a6531 | 2007-05-04 02:59:04 +0000 | [diff] [blame] | 23 | #include "llvm/ParameterAttributes.h" | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 24 | #include "llvm/TypeSymbolTable.h" | 
| Chris Lattner | b992be1 | 2007-04-23 20:35:01 +0000 | [diff] [blame] | 25 | #include "llvm/ValueSymbolTable.h" | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 26 | #include "llvm/Support/MathExtras.h" | 
 | 27 | using namespace llvm; | 
 | 28 |  | 
| Chris Lattner | 5969830 | 2007-05-04 20:52:02 +0000 | [diff] [blame] | 29 | /// These are manifest constants used by the bitcode writer. They do not need to | 
 | 30 | /// be kept in sync with the reader, but need to be consistent within this file. | 
 | 31 | enum { | 
 | 32 |   CurVersion = 0, | 
 | 33 |    | 
 | 34 |   // VALUE_SYMTAB_BLOCK abbrev id's. | 
 | 35 |   VST_ENTRY_8_ABBREV = bitc::FIRST_APPLICATION_ABBREV, | 
| Chris Lattner | 2453f71 | 2007-05-04 20:58:35 +0000 | [diff] [blame] | 36 |   VST_ENTRY_7_ABBREV, | 
| Chris Lattner | ff294a4 | 2007-05-05 01:26:50 +0000 | [diff] [blame] | 37 |   VST_ENTRY_6_ABBREV, | 
| Chris Lattner | a0f1ecc | 2007-05-05 07:36:14 +0000 | [diff] [blame] | 38 |   VST_BBENTRY_6_ABBREV, | 
 | 39 |    | 
 | 40 |   // CONSTANTS_BLOCK abbrev id's. | 
 | 41 |   CONSTANTS_SETTYPE_ABBREV = bitc::FIRST_APPLICATION_ABBREV, | 
 | 42 |   CONSTANTS_INTEGER_ABBREV, | 
 | 43 |   CONSTANTS_CE_CAST_Abbrev, | 
| Chris Lattner | 440168b | 2007-05-05 07:44:49 +0000 | [diff] [blame] | 44 |   CONSTANTS_NULL_Abbrev, | 
 | 45 |    | 
 | 46 |   // FUNCTION_BLOCK abbrev id's. | 
| Chris Lattner | 94687ac | 2007-05-06 01:28:01 +0000 | [diff] [blame] | 47 |   FUNCTION_INST_LOAD_ABBREV = bitc::FIRST_APPLICATION_ABBREV, | 
| Chris Lattner | f9f2e83 | 2007-05-06 02:38:57 +0000 | [diff] [blame] | 48 |   FUNCTION_INST_BINOP_ABBREV, | 
 | 49 |   FUNCTION_INST_CAST_ABBREV, | 
| Chris Lattner | 94687ac | 2007-05-06 01:28:01 +0000 | [diff] [blame] | 50 |   FUNCTION_INST_RET_VOID_ABBREV, | 
 | 51 |   FUNCTION_INST_RET_VAL_ABBREV, | 
 | 52 |   FUNCTION_INST_UNREACHABLE_ABBREV | 
| Chris Lattner | 5969830 | 2007-05-04 20:52:02 +0000 | [diff] [blame] | 53 | }; | 
 | 54 |  | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 55 |  | 
| Chris Lattner | f581c3b | 2007-04-24 07:07:11 +0000 | [diff] [blame] | 56 | static unsigned GetEncodedCastOpcode(unsigned Opcode) { | 
 | 57 |   switch (Opcode) { | 
 | 58 |   default: assert(0 && "Unknown cast instruction!"); | 
 | 59 |   case Instruction::Trunc   : return bitc::CAST_TRUNC; | 
 | 60 |   case Instruction::ZExt    : return bitc::CAST_ZEXT; | 
 | 61 |   case Instruction::SExt    : return bitc::CAST_SEXT; | 
 | 62 |   case Instruction::FPToUI  : return bitc::CAST_FPTOUI; | 
 | 63 |   case Instruction::FPToSI  : return bitc::CAST_FPTOSI; | 
 | 64 |   case Instruction::UIToFP  : return bitc::CAST_UITOFP; | 
 | 65 |   case Instruction::SIToFP  : return bitc::CAST_SITOFP; | 
 | 66 |   case Instruction::FPTrunc : return bitc::CAST_FPTRUNC; | 
 | 67 |   case Instruction::FPExt   : return bitc::CAST_FPEXT; | 
 | 68 |   case Instruction::PtrToInt: return bitc::CAST_PTRTOINT; | 
 | 69 |   case Instruction::IntToPtr: return bitc::CAST_INTTOPTR; | 
 | 70 |   case Instruction::BitCast : return bitc::CAST_BITCAST; | 
 | 71 |   } | 
 | 72 | } | 
 | 73 |  | 
 | 74 | static unsigned GetEncodedBinaryOpcode(unsigned Opcode) { | 
 | 75 |   switch (Opcode) { | 
 | 76 |   default: assert(0 && "Unknown binary instruction!"); | 
 | 77 |   case Instruction::Add:  return bitc::BINOP_ADD; | 
 | 78 |   case Instruction::Sub:  return bitc::BINOP_SUB; | 
 | 79 |   case Instruction::Mul:  return bitc::BINOP_MUL; | 
 | 80 |   case Instruction::UDiv: return bitc::BINOP_UDIV; | 
 | 81 |   case Instruction::FDiv: | 
 | 82 |   case Instruction::SDiv: return bitc::BINOP_SDIV; | 
 | 83 |   case Instruction::URem: return bitc::BINOP_UREM; | 
 | 84 |   case Instruction::FRem: | 
 | 85 |   case Instruction::SRem: return bitc::BINOP_SREM; | 
 | 86 |   case Instruction::Shl:  return bitc::BINOP_SHL; | 
 | 87 |   case Instruction::LShr: return bitc::BINOP_LSHR; | 
 | 88 |   case Instruction::AShr: return bitc::BINOP_ASHR; | 
 | 89 |   case Instruction::And:  return bitc::BINOP_AND; | 
 | 90 |   case Instruction::Or:   return bitc::BINOP_OR; | 
 | 91 |   case Instruction::Xor:  return bitc::BINOP_XOR; | 
 | 92 |   } | 
 | 93 | } | 
 | 94 |  | 
 | 95 |  | 
 | 96 |  | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 97 | static void WriteStringRecord(unsigned Code, const std::string &Str,  | 
 | 98 |                               unsigned AbbrevToUse, BitstreamWriter &Stream) { | 
 | 99 |   SmallVector<unsigned, 64> Vals; | 
 | 100 |    | 
| Chris Lattner | 15e6d17 | 2007-05-04 19:11:41 +0000 | [diff] [blame] | 101 |   // Code: [strchar x N] | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 102 |   for (unsigned i = 0, e = Str.size(); i != e; ++i) | 
 | 103 |     Vals.push_back(Str[i]); | 
 | 104 |      | 
 | 105 |   // Emit the finished record. | 
 | 106 |   Stream.EmitRecord(Code, Vals, AbbrevToUse); | 
 | 107 | } | 
 | 108 |  | 
| Chris Lattner | 62bbeea | 2007-05-04 00:44:52 +0000 | [diff] [blame] | 109 | // Emit information about parameter attributes. | 
 | 110 | static void WriteParamAttrTable(const ValueEnumerator &VE,  | 
 | 111 |                                 BitstreamWriter &Stream) { | 
 | 112 |   const std::vector<const ParamAttrsList*> &Attrs = VE.getParamAttrs(); | 
 | 113 |   if (Attrs.empty()) return; | 
 | 114 |    | 
| Chris Lattner | f0a6531 | 2007-05-04 02:59:04 +0000 | [diff] [blame] | 115 |   Stream.EnterSubblock(bitc::PARAMATTR_BLOCK_ID, 3); | 
 | 116 |  | 
 | 117 |   SmallVector<uint64_t, 64> Record; | 
 | 118 |   for (unsigned i = 0, e = Attrs.size(); i != e; ++i) { | 
 | 119 |     const ParamAttrsList *A = Attrs[i]; | 
 | 120 |     for (unsigned op = 0, e = A->size(); op != e; ++op) { | 
 | 121 |       Record.push_back(A->getParamIndex(op)); | 
| Dale Johannesen | 8d1433c | 2008-02-20 21:15:19 +0000 | [diff] [blame] | 122 |       Record.push_back(A->getParamAttrsAtIndex(op)); | 
| Chris Lattner | f0a6531 | 2007-05-04 02:59:04 +0000 | [diff] [blame] | 123 |     } | 
 | 124 |      | 
 | 125 |     Stream.EmitRecord(bitc::PARAMATTR_CODE_ENTRY, Record); | 
 | 126 |     Record.clear(); | 
 | 127 |   } | 
| Chris Lattner | 62bbeea | 2007-05-04 00:44:52 +0000 | [diff] [blame] | 128 |    | 
| Chris Lattner | f0a6531 | 2007-05-04 02:59:04 +0000 | [diff] [blame] | 129 |   Stream.ExitBlock(); | 
| Chris Lattner | 62bbeea | 2007-05-04 00:44:52 +0000 | [diff] [blame] | 130 | } | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 131 |  | 
 | 132 | /// WriteTypeTable - Write out the type table for a module. | 
 | 133 | static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { | 
 | 134 |   const ValueEnumerator::TypeList &TypeList = VE.getTypes(); | 
 | 135 |    | 
 | 136 |   Stream.EnterSubblock(bitc::TYPE_BLOCK_ID, 4 /*count from # abbrevs */); | 
 | 137 |   SmallVector<uint64_t, 64> TypeVals; | 
 | 138 |    | 
| Chris Lattner | d092e0e | 2007-05-05 06:30:12 +0000 | [diff] [blame] | 139 |   // Abbrev for TYPE_CODE_POINTER. | 
 | 140 |   BitCodeAbbrev *Abbv = new BitCodeAbbrev(); | 
 | 141 |   Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_POINTER)); | 
 | 142 |   Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, | 
 | 143 |                             Log2_32_Ceil(VE.getTypes().size()+1))); | 
| Christopher Lamb | d49e18d | 2007-12-12 08:44:39 +0000 | [diff] [blame] | 144 |   Abbv->Add(BitCodeAbbrevOp(0));  // Addrspace = 0 | 
| Chris Lattner | d092e0e | 2007-05-05 06:30:12 +0000 | [diff] [blame] | 145 |   unsigned PtrAbbrev = Stream.EmitAbbrev(Abbv); | 
 | 146 |    | 
 | 147 |   // Abbrev for TYPE_CODE_FUNCTION. | 
 | 148 |   Abbv = new BitCodeAbbrev(); | 
 | 149 |   Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_FUNCTION)); | 
 | 150 |   Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));  // isvararg | 
| Chris Lattner | a1afde7 | 2007-11-27 17:48:06 +0000 | [diff] [blame] | 151 |   Abbv->Add(BitCodeAbbrevOp(0));  // FIXME: DEAD value, remove in LLVM 3.0 | 
| Chris Lattner | d092e0e | 2007-05-05 06:30:12 +0000 | [diff] [blame] | 152 |   Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); | 
 | 153 |   Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, | 
 | 154 |                             Log2_32_Ceil(VE.getTypes().size()+1))); | 
 | 155 |   unsigned FunctionAbbrev = Stream.EmitAbbrev(Abbv); | 
 | 156 |    | 
 | 157 |   // Abbrev for TYPE_CODE_STRUCT. | 
 | 158 |   Abbv = new BitCodeAbbrev(); | 
 | 159 |   Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT)); | 
 | 160 |   Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));  // ispacked | 
 | 161 |   Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); | 
 | 162 |   Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, | 
 | 163 |                             Log2_32_Ceil(VE.getTypes().size()+1))); | 
 | 164 |   unsigned StructAbbrev = Stream.EmitAbbrev(Abbv); | 
 | 165 |   | 
 | 166 |   // Abbrev for TYPE_CODE_ARRAY. | 
 | 167 |   Abbv = new BitCodeAbbrev(); | 
 | 168 |   Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_ARRAY)); | 
 | 169 |   Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));   // size | 
 | 170 |   Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, | 
 | 171 |                             Log2_32_Ceil(VE.getTypes().size()+1))); | 
 | 172 |   unsigned ArrayAbbrev = Stream.EmitAbbrev(Abbv); | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 173 |    | 
 | 174 |   // Emit an entry count so the reader can reserve space. | 
 | 175 |   TypeVals.push_back(TypeList.size()); | 
 | 176 |   Stream.EmitRecord(bitc::TYPE_CODE_NUMENTRY, TypeVals); | 
 | 177 |   TypeVals.clear(); | 
 | 178 |    | 
 | 179 |   // Loop over all of the types, emitting each in turn. | 
 | 180 |   for (unsigned i = 0, e = TypeList.size(); i != e; ++i) { | 
 | 181 |     const Type *T = TypeList[i].first; | 
 | 182 |     int AbbrevToUse = 0; | 
 | 183 |     unsigned Code = 0; | 
 | 184 |      | 
 | 185 |     switch (T->getTypeID()) { | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 186 |     default: assert(0 && "Unknown type!"); | 
 | 187 |     case Type::VoidTyID:   Code = bitc::TYPE_CODE_VOID;   break; | 
 | 188 |     case Type::FloatTyID:  Code = bitc::TYPE_CODE_FLOAT;  break; | 
 | 189 |     case Type::DoubleTyID: Code = bitc::TYPE_CODE_DOUBLE; break; | 
| Dale Johannesen | 320fc8a | 2007-08-03 01:03:46 +0000 | [diff] [blame] | 190 |     case Type::X86_FP80TyID: Code = bitc::TYPE_CODE_X86_FP80; break; | 
 | 191 |     case Type::FP128TyID: Code = bitc::TYPE_CODE_FP128; break; | 
 | 192 |     case Type::PPC_FP128TyID: Code = bitc::TYPE_CODE_PPC_FP128; break; | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 193 |     case Type::LabelTyID:  Code = bitc::TYPE_CODE_LABEL;  break; | 
 | 194 |     case Type::OpaqueTyID: Code = bitc::TYPE_CODE_OPAQUE; break; | 
 | 195 |     case Type::IntegerTyID: | 
 | 196 |       // INTEGER: [width] | 
 | 197 |       Code = bitc::TYPE_CODE_INTEGER; | 
 | 198 |       TypeVals.push_back(cast<IntegerType>(T)->getBitWidth()); | 
 | 199 |       break; | 
| Duncan Sands | 216b74c | 2007-12-11 12:20:47 +0000 | [diff] [blame] | 200 |     case Type::PointerTyID: { | 
| Christopher Lamb | fe63fb9 | 2007-12-11 08:59:05 +0000 | [diff] [blame] | 201 |       const PointerType *PTy = cast<PointerType>(T); | 
| Christopher Lamb | d49e18d | 2007-12-12 08:44:39 +0000 | [diff] [blame] | 202 |       // POINTER: [pointee type, address space] | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 203 |       Code = bitc::TYPE_CODE_POINTER; | 
| Christopher Lamb | fe63fb9 | 2007-12-11 08:59:05 +0000 | [diff] [blame] | 204 |       TypeVals.push_back(VE.getTypeID(PTy->getElementType())); | 
| Christopher Lamb | d49e18d | 2007-12-12 08:44:39 +0000 | [diff] [blame] | 205 |       unsigned AddressSpace = PTy->getAddressSpace(); | 
 | 206 |       TypeVals.push_back(AddressSpace); | 
 | 207 |       if (AddressSpace == 0) AbbrevToUse = PtrAbbrev; | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 208 |       break; | 
| Duncan Sands | 216b74c | 2007-12-11 12:20:47 +0000 | [diff] [blame] | 209 |     } | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 210 |     case Type::FunctionTyID: { | 
 | 211 |       const FunctionType *FT = cast<FunctionType>(T); | 
| Chris Lattner | a1afde7 | 2007-11-27 17:48:06 +0000 | [diff] [blame] | 212 |       // FUNCTION: [isvararg, attrid, retty, paramty x N] | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 213 |       Code = bitc::TYPE_CODE_FUNCTION; | 
 | 214 |       TypeVals.push_back(FT->isVarArg()); | 
| Chris Lattner | a1afde7 | 2007-11-27 17:48:06 +0000 | [diff] [blame] | 215 |       TypeVals.push_back(0);  // FIXME: DEAD: remove in llvm 3.0 | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 216 |       TypeVals.push_back(VE.getTypeID(FT->getReturnType())); | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 217 |       for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) | 
 | 218 |         TypeVals.push_back(VE.getTypeID(FT->getParamType(i))); | 
| Chris Lattner | d092e0e | 2007-05-05 06:30:12 +0000 | [diff] [blame] | 219 |       AbbrevToUse = FunctionAbbrev; | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 220 |       break; | 
 | 221 |     } | 
 | 222 |     case Type::StructTyID: { | 
 | 223 |       const StructType *ST = cast<StructType>(T); | 
| Chris Lattner | d092e0e | 2007-05-05 06:30:12 +0000 | [diff] [blame] | 224 |       // STRUCT: [ispacked, eltty x N] | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 225 |       Code = bitc::TYPE_CODE_STRUCT; | 
 | 226 |       TypeVals.push_back(ST->isPacked()); | 
| Chris Lattner | 15e6d17 | 2007-05-04 19:11:41 +0000 | [diff] [blame] | 227 |       // Output all of the element types. | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 228 |       for (StructType::element_iterator I = ST->element_begin(), | 
 | 229 |            E = ST->element_end(); I != E; ++I) | 
 | 230 |         TypeVals.push_back(VE.getTypeID(*I)); | 
| Chris Lattner | d092e0e | 2007-05-05 06:30:12 +0000 | [diff] [blame] | 231 |       AbbrevToUse = StructAbbrev; | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 232 |       break; | 
 | 233 |     } | 
 | 234 |     case Type::ArrayTyID: { | 
 | 235 |       const ArrayType *AT = cast<ArrayType>(T); | 
 | 236 |       // ARRAY: [numelts, eltty] | 
 | 237 |       Code = bitc::TYPE_CODE_ARRAY; | 
 | 238 |       TypeVals.push_back(AT->getNumElements()); | 
 | 239 |       TypeVals.push_back(VE.getTypeID(AT->getElementType())); | 
| Chris Lattner | d092e0e | 2007-05-05 06:30:12 +0000 | [diff] [blame] | 240 |       AbbrevToUse = ArrayAbbrev; | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 241 |       break; | 
 | 242 |     } | 
 | 243 |     case Type::VectorTyID: { | 
 | 244 |       const VectorType *VT = cast<VectorType>(T); | 
 | 245 |       // VECTOR [numelts, eltty] | 
 | 246 |       Code = bitc::TYPE_CODE_VECTOR; | 
 | 247 |       TypeVals.push_back(VT->getNumElements()); | 
 | 248 |       TypeVals.push_back(VE.getTypeID(VT->getElementType())); | 
 | 249 |       break; | 
 | 250 |     } | 
 | 251 |     } | 
 | 252 |  | 
 | 253 |     // Emit the finished record. | 
 | 254 |     Stream.EmitRecord(Code, TypeVals, AbbrevToUse); | 
 | 255 |     TypeVals.clear(); | 
 | 256 |   } | 
 | 257 |    | 
 | 258 |   Stream.ExitBlock(); | 
 | 259 | } | 
 | 260 |  | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 261 | static unsigned getEncodedLinkage(const GlobalValue *GV) { | 
 | 262 |   switch (GV->getLinkage()) { | 
 | 263 |   default: assert(0 && "Invalid linkage!"); | 
| Chris Lattner | 384003d | 2007-05-11 23:51:59 +0000 | [diff] [blame] | 264 |   case GlobalValue::GhostLinkage:  // Map ghost linkage onto external. | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 265 |   case GlobalValue::ExternalLinkage:     return 0; | 
 | 266 |   case GlobalValue::WeakLinkage:         return 1; | 
 | 267 |   case GlobalValue::AppendingLinkage:    return 2; | 
 | 268 |   case GlobalValue::InternalLinkage:     return 3; | 
 | 269 |   case GlobalValue::LinkOnceLinkage:     return 4; | 
 | 270 |   case GlobalValue::DLLImportLinkage:    return 5; | 
 | 271 |   case GlobalValue::DLLExportLinkage:    return 6; | 
 | 272 |   case GlobalValue::ExternalWeakLinkage: return 7; | 
 | 273 |   } | 
 | 274 | } | 
 | 275 |  | 
 | 276 | static unsigned getEncodedVisibility(const GlobalValue *GV) { | 
 | 277 |   switch (GV->getVisibility()) { | 
 | 278 |   default: assert(0 && "Invalid visibility!"); | 
| Anton Korobeynikov | 9cd3ccf | 2007-04-29 20:56:48 +0000 | [diff] [blame] | 279 |   case GlobalValue::DefaultVisibility:   return 0; | 
 | 280 |   case GlobalValue::HiddenVisibility:    return 1; | 
 | 281 |   case GlobalValue::ProtectedVisibility: return 2; | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 282 |   } | 
 | 283 | } | 
 | 284 |  | 
 | 285 | // Emit top-level description of module, including target triple, inline asm, | 
 | 286 | // descriptors for global variables, and function prototype info. | 
 | 287 | static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, | 
 | 288 |                             BitstreamWriter &Stream) { | 
 | 289 |   // Emit the list of dependent libraries for the Module. | 
 | 290 |   for (Module::lib_iterator I = M->lib_begin(), E = M->lib_end(); I != E; ++I) | 
 | 291 |     WriteStringRecord(bitc::MODULE_CODE_DEPLIB, *I, 0/*TODO*/, Stream); | 
 | 292 |  | 
 | 293 |   // Emit various pieces of data attached to a module. | 
 | 294 |   if (!M->getTargetTriple().empty()) | 
 | 295 |     WriteStringRecord(bitc::MODULE_CODE_TRIPLE, M->getTargetTriple(), | 
 | 296 |                       0/*TODO*/, Stream); | 
 | 297 |   if (!M->getDataLayout().empty()) | 
 | 298 |     WriteStringRecord(bitc::MODULE_CODE_DATALAYOUT, M->getDataLayout(), | 
 | 299 |                       0/*TODO*/, Stream); | 
 | 300 |   if (!M->getModuleInlineAsm().empty()) | 
 | 301 |     WriteStringRecord(bitc::MODULE_CODE_ASM, M->getModuleInlineAsm(), | 
 | 302 |                       0/*TODO*/, Stream); | 
 | 303 |  | 
| Gordon Henriksen | 80a75bf | 2007-12-10 03:18:06 +0000 | [diff] [blame] | 304 |   // Emit information about sections and collectors, computing how many there | 
 | 305 |   // are.  Also compute the maximum alignment value. | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 306 |   std::map<std::string, unsigned> SectionMap; | 
| Gordon Henriksen | 80a75bf | 2007-12-10 03:18:06 +0000 | [diff] [blame] | 307 |   std::map<std::string, unsigned> CollectorMap; | 
| Chris Lattner | 36d5e7d | 2007-04-23 16:04:05 +0000 | [diff] [blame] | 308 |   unsigned MaxAlignment = 0; | 
| Chris Lattner | d127c1b | 2007-04-23 18:58:34 +0000 | [diff] [blame] | 309 |   unsigned MaxGlobalType = 0; | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 310 |   for (Module::const_global_iterator GV = M->global_begin(),E = M->global_end(); | 
 | 311 |        GV != E; ++GV) { | 
| Chris Lattner | 36d5e7d | 2007-04-23 16:04:05 +0000 | [diff] [blame] | 312 |     MaxAlignment = std::max(MaxAlignment, GV->getAlignment()); | 
| Chris Lattner | d127c1b | 2007-04-23 18:58:34 +0000 | [diff] [blame] | 313 |     MaxGlobalType = std::max(MaxGlobalType, VE.getTypeID(GV->getType())); | 
| Chris Lattner | 36d5e7d | 2007-04-23 16:04:05 +0000 | [diff] [blame] | 314 |      | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 315 |     if (!GV->hasSection()) continue; | 
 | 316 |     // Give section names unique ID's. | 
 | 317 |     unsigned &Entry = SectionMap[GV->getSection()]; | 
 | 318 |     if (Entry != 0) continue; | 
 | 319 |     WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, GV->getSection(), | 
 | 320 |                       0/*TODO*/, Stream); | 
 | 321 |     Entry = SectionMap.size(); | 
 | 322 |   } | 
 | 323 |   for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) { | 
| Chris Lattner | 36d5e7d | 2007-04-23 16:04:05 +0000 | [diff] [blame] | 324 |     MaxAlignment = std::max(MaxAlignment, F->getAlignment()); | 
| Gordon Henriksen | 80a75bf | 2007-12-10 03:18:06 +0000 | [diff] [blame] | 325 |     if (F->hasSection()) { | 
 | 326 |       // Give section names unique ID's. | 
 | 327 |       unsigned &Entry = SectionMap[F->getSection()]; | 
 | 328 |       if (!Entry) { | 
 | 329 |         WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, F->getSection(), | 
 | 330 |                           0/*TODO*/, Stream); | 
 | 331 |         Entry = SectionMap.size(); | 
 | 332 |       } | 
 | 333 |     } | 
 | 334 |     if (F->hasCollector()) { | 
 | 335 |       // Same for collector names. | 
 | 336 |       unsigned &Entry = CollectorMap[F->getCollector()]; | 
 | 337 |       if (!Entry) { | 
 | 338 |         WriteStringRecord(bitc::MODULE_CODE_COLLECTORNAME, F->getCollector(), | 
 | 339 |                           0/*TODO*/, Stream); | 
 | 340 |         Entry = CollectorMap.size(); | 
 | 341 |       } | 
 | 342 |     } | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 343 |   } | 
 | 344 |    | 
| Chris Lattner | 36d5e7d | 2007-04-23 16:04:05 +0000 | [diff] [blame] | 345 |   // Emit abbrev for globals, now that we know # sections and max alignment. | 
 | 346 |   unsigned SimpleGVarAbbrev = 0; | 
| Chris Lattner | d127c1b | 2007-04-23 18:58:34 +0000 | [diff] [blame] | 347 |   if (!M->global_empty()) {  | 
| Chris Lattner | 36d5e7d | 2007-04-23 16:04:05 +0000 | [diff] [blame] | 348 |     // Add an abbrev for common globals with no visibility or thread localness. | 
 | 349 |     BitCodeAbbrev *Abbv = new BitCodeAbbrev(); | 
 | 350 |     Abbv->Add(BitCodeAbbrevOp(bitc::MODULE_CODE_GLOBALVAR)); | 
| Chris Lattner | 2e7899d | 2007-05-04 20:34:50 +0000 | [diff] [blame] | 351 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, | 
| Chris Lattner | d127c1b | 2007-04-23 18:58:34 +0000 | [diff] [blame] | 352 |                               Log2_32_Ceil(MaxGlobalType+1))); | 
| Chris Lattner | 2e7899d | 2007-05-04 20:34:50 +0000 | [diff] [blame] | 353 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));      // Constant. | 
| Chris Lattner | 36d5e7d | 2007-04-23 16:04:05 +0000 | [diff] [blame] | 354 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));        // Initializer. | 
| Chris Lattner | 2e7899d | 2007-05-04 20:34:50 +0000 | [diff] [blame] | 355 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3));      // Linkage. | 
 | 356 |     if (MaxAlignment == 0)                                      // Alignment. | 
| Chris Lattner | 36d5e7d | 2007-04-23 16:04:05 +0000 | [diff] [blame] | 357 |       Abbv->Add(BitCodeAbbrevOp(0)); | 
 | 358 |     else { | 
 | 359 |       unsigned MaxEncAlignment = Log2_32(MaxAlignment)+1; | 
| Chris Lattner | 2e7899d | 2007-05-04 20:34:50 +0000 | [diff] [blame] | 360 |       Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, | 
| Chris Lattner | d127c1b | 2007-04-23 18:58:34 +0000 | [diff] [blame] | 361 |                                Log2_32_Ceil(MaxEncAlignment+1))); | 
| Chris Lattner | 36d5e7d | 2007-04-23 16:04:05 +0000 | [diff] [blame] | 362 |     } | 
 | 363 |     if (SectionMap.empty())                                    // Section. | 
 | 364 |       Abbv->Add(BitCodeAbbrevOp(0)); | 
 | 365 |     else | 
| Chris Lattner | 2e7899d | 2007-05-04 20:34:50 +0000 | [diff] [blame] | 366 |       Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, | 
| Chris Lattner | 631a8ed | 2007-04-24 03:29:47 +0000 | [diff] [blame] | 367 |                                Log2_32_Ceil(SectionMap.size()+1))); | 
| Chris Lattner | 36d5e7d | 2007-04-23 16:04:05 +0000 | [diff] [blame] | 368 |     // Don't bother emitting vis + thread local. | 
 | 369 |     SimpleGVarAbbrev = Stream.EmitAbbrev(Abbv); | 
 | 370 |   } | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 371 |    | 
 | 372 |   // Emit the global variable information. | 
 | 373 |   SmallVector<unsigned, 64> Vals; | 
 | 374 |   for (Module::const_global_iterator GV = M->global_begin(),E = M->global_end(); | 
 | 375 |        GV != E; ++GV) { | 
| Chris Lattner | 36d5e7d | 2007-04-23 16:04:05 +0000 | [diff] [blame] | 376 |     unsigned AbbrevToUse = 0; | 
 | 377 |  | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 378 |     // GLOBALVAR: [type, isconst, initid,  | 
 | 379 |     //             linkage, alignment, section, visibility, threadlocal] | 
 | 380 |     Vals.push_back(VE.getTypeID(GV->getType())); | 
 | 381 |     Vals.push_back(GV->isConstant()); | 
 | 382 |     Vals.push_back(GV->isDeclaration() ? 0 : | 
 | 383 |                    (VE.getValueID(GV->getInitializer()) + 1)); | 
 | 384 |     Vals.push_back(getEncodedLinkage(GV)); | 
 | 385 |     Vals.push_back(Log2_32(GV->getAlignment())+1); | 
 | 386 |     Vals.push_back(GV->hasSection() ? SectionMap[GV->getSection()] : 0); | 
| Chris Lattner | 36d5e7d | 2007-04-23 16:04:05 +0000 | [diff] [blame] | 387 |     if (GV->isThreadLocal() ||  | 
 | 388 |         GV->getVisibility() != GlobalValue::DefaultVisibility) { | 
 | 389 |       Vals.push_back(getEncodedVisibility(GV)); | 
 | 390 |       Vals.push_back(GV->isThreadLocal()); | 
 | 391 |     } else { | 
 | 392 |       AbbrevToUse = SimpleGVarAbbrev; | 
 | 393 |     } | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 394 |      | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 395 |     Stream.EmitRecord(bitc::MODULE_CODE_GLOBALVAR, Vals, AbbrevToUse); | 
 | 396 |     Vals.clear(); | 
 | 397 |   } | 
 | 398 |  | 
 | 399 |   // Emit the function proto information. | 
 | 400 |   for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) { | 
| Duncan Sands | dc02467 | 2007-11-27 13:23:08 +0000 | [diff] [blame] | 401 |     // FUNCTION:  [type, callingconv, isproto, paramattr, | 
| Gordon Henriksen | 80a75bf | 2007-12-10 03:18:06 +0000 | [diff] [blame] | 402 |     //             linkage, alignment, section, visibility, collector] | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 403 |     Vals.push_back(VE.getTypeID(F->getType())); | 
 | 404 |     Vals.push_back(F->getCallingConv()); | 
 | 405 |     Vals.push_back(F->isDeclaration()); | 
 | 406 |     Vals.push_back(getEncodedLinkage(F)); | 
| Duncan Sands | dc02467 | 2007-11-27 13:23:08 +0000 | [diff] [blame] | 407 |     Vals.push_back(VE.getParamAttrID(F->getParamAttrs())); | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 408 |     Vals.push_back(Log2_32(F->getAlignment())+1); | 
 | 409 |     Vals.push_back(F->hasSection() ? SectionMap[F->getSection()] : 0); | 
 | 410 |     Vals.push_back(getEncodedVisibility(F)); | 
| Gordon Henriksen | 80a75bf | 2007-12-10 03:18:06 +0000 | [diff] [blame] | 411 |     Vals.push_back(F->hasCollector() ? CollectorMap[F->getCollector()] : 0); | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 412 |      | 
 | 413 |     unsigned AbbrevToUse = 0; | 
 | 414 |     Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse); | 
 | 415 |     Vals.clear(); | 
 | 416 |   } | 
| Chris Lattner | 07d98b4 | 2007-04-26 02:46:40 +0000 | [diff] [blame] | 417 |    | 
 | 418 |    | 
 | 419 |   // Emit the alias information. | 
 | 420 |   for (Module::const_alias_iterator AI = M->alias_begin(), E = M->alias_end(); | 
 | 421 |        AI != E; ++AI) { | 
 | 422 |     Vals.push_back(VE.getTypeID(AI->getType())); | 
 | 423 |     Vals.push_back(VE.getValueID(AI->getAliasee())); | 
 | 424 |     Vals.push_back(getEncodedLinkage(AI)); | 
 | 425 |     unsigned AbbrevToUse = 0; | 
 | 426 |     Stream.EmitRecord(bitc::MODULE_CODE_ALIAS, Vals, AbbrevToUse); | 
 | 427 |     Vals.clear(); | 
 | 428 |   } | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 429 | } | 
 | 430 |  | 
 | 431 |  | 
| Chris Lattner | 2edd22b | 2007-04-24 00:16:04 +0000 | [diff] [blame] | 432 | static void WriteConstants(unsigned FirstVal, unsigned LastVal, | 
 | 433 |                            const ValueEnumerator &VE, | 
| Chris Lattner | a0f1ecc | 2007-05-05 07:36:14 +0000 | [diff] [blame] | 434 |                            BitstreamWriter &Stream, bool isGlobal) { | 
| Chris Lattner | 2edd22b | 2007-04-24 00:16:04 +0000 | [diff] [blame] | 435 |   if (FirstVal == LastVal) return; | 
 | 436 |    | 
| Chris Lattner | a0f1ecc | 2007-05-05 07:36:14 +0000 | [diff] [blame] | 437 |   Stream.EnterSubblock(bitc::CONSTANTS_BLOCK_ID, 4); | 
| Chris Lattner | b992be1 | 2007-04-23 20:35:01 +0000 | [diff] [blame] | 438 |  | 
| Chris Lattner | a0f1ecc | 2007-05-05 07:36:14 +0000 | [diff] [blame] | 439 |   unsigned AggregateAbbrev = 0; | 
| Chris Lattner | cb3d91b | 2007-05-06 00:53:07 +0000 | [diff] [blame] | 440 |   unsigned String8Abbrev = 0; | 
 | 441 |   unsigned CString7Abbrev = 0; | 
 | 442 |   unsigned CString6Abbrev = 0; | 
| Chris Lattner | a0f1ecc | 2007-05-05 07:36:14 +0000 | [diff] [blame] | 443 |   // If this is a constant pool for the module, emit module-specific abbrevs. | 
 | 444 |   if (isGlobal) { | 
 | 445 |     // Abbrev for CST_CODE_AGGREGATE. | 
 | 446 |     BitCodeAbbrev *Abbv = new BitCodeAbbrev(); | 
 | 447 |     Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_AGGREGATE)); | 
 | 448 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); | 
 | 449 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, Log2_32_Ceil(LastVal+1))); | 
 | 450 |     AggregateAbbrev = Stream.EmitAbbrev(Abbv); | 
| Chris Lattner | 817f08a | 2007-05-06 00:42:18 +0000 | [diff] [blame] | 451 |  | 
 | 452 |     // Abbrev for CST_CODE_STRING. | 
 | 453 |     Abbv = new BitCodeAbbrev(); | 
 | 454 |     Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_STRING)); | 
 | 455 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); | 
| Chris Lattner | cb3d91b | 2007-05-06 00:53:07 +0000 | [diff] [blame] | 456 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8)); | 
 | 457 |     String8Abbrev = Stream.EmitAbbrev(Abbv); | 
 | 458 |     // Abbrev for CST_CODE_CSTRING. | 
 | 459 |     Abbv = new BitCodeAbbrev(); | 
 | 460 |     Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_CSTRING)); | 
 | 461 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); | 
| Chris Lattner | 817f08a | 2007-05-06 00:42:18 +0000 | [diff] [blame] | 462 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7)); | 
| Chris Lattner | cb3d91b | 2007-05-06 00:53:07 +0000 | [diff] [blame] | 463 |     CString7Abbrev = Stream.EmitAbbrev(Abbv); | 
 | 464 |     // Abbrev for CST_CODE_CSTRING. | 
 | 465 |     Abbv = new BitCodeAbbrev(); | 
 | 466 |     Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_CSTRING)); | 
 | 467 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); | 
 | 468 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6)); | 
 | 469 |     CString6Abbrev = Stream.EmitAbbrev(Abbv); | 
| Chris Lattner | a0f1ecc | 2007-05-05 07:36:14 +0000 | [diff] [blame] | 470 |   }   | 
 | 471 |    | 
| Chris Lattner | 2edd22b | 2007-04-24 00:16:04 +0000 | [diff] [blame] | 472 |   SmallVector<uint64_t, 64> Record; | 
 | 473 |  | 
 | 474 |   const ValueEnumerator::ValueList &Vals = VE.getValues(); | 
 | 475 |   const Type *LastTy = 0; | 
 | 476 |   for (unsigned i = FirstVal; i != LastVal; ++i) { | 
 | 477 |     const Value *V = Vals[i].first; | 
 | 478 |     // If we need to switch types, do so now. | 
 | 479 |     if (V->getType() != LastTy) { | 
 | 480 |       LastTy = V->getType(); | 
 | 481 |       Record.push_back(VE.getTypeID(LastTy)); | 
| Chris Lattner | a0f1ecc | 2007-05-05 07:36:14 +0000 | [diff] [blame] | 482 |       Stream.EmitRecord(bitc::CST_CODE_SETTYPE, Record, | 
 | 483 |                         CONSTANTS_SETTYPE_ABBREV); | 
| Chris Lattner | 2edd22b | 2007-04-24 00:16:04 +0000 | [diff] [blame] | 484 |       Record.clear(); | 
 | 485 |     } | 
 | 486 |      | 
 | 487 |     if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) { | 
| Chris Lattner | 2bce93a | 2007-05-06 01:58:20 +0000 | [diff] [blame] | 488 |       Record.push_back(unsigned(IA->hasSideEffects())); | 
 | 489 |        | 
 | 490 |       // Add the asm string. | 
 | 491 |       const std::string &AsmStr = IA->getAsmString(); | 
 | 492 |       Record.push_back(AsmStr.size()); | 
 | 493 |       for (unsigned i = 0, e = AsmStr.size(); i != e; ++i) | 
 | 494 |         Record.push_back(AsmStr[i]); | 
 | 495 |        | 
 | 496 |       // Add the constraint string. | 
 | 497 |       const std::string &ConstraintStr = IA->getConstraintString(); | 
 | 498 |       Record.push_back(ConstraintStr.size()); | 
 | 499 |       for (unsigned i = 0, e = ConstraintStr.size(); i != e; ++i) | 
 | 500 |         Record.push_back(ConstraintStr[i]); | 
 | 501 |       Stream.EmitRecord(bitc::CST_CODE_INLINEASM, Record); | 
 | 502 |       Record.clear(); | 
| Chris Lattner | 2edd22b | 2007-04-24 00:16:04 +0000 | [diff] [blame] | 503 |       continue; | 
 | 504 |     } | 
 | 505 |     const Constant *C = cast<Constant>(V); | 
 | 506 |     unsigned Code = -1U; | 
 | 507 |     unsigned AbbrevToUse = 0; | 
 | 508 |     if (C->isNullValue()) { | 
 | 509 |       Code = bitc::CST_CODE_NULL; | 
 | 510 |     } else if (isa<UndefValue>(C)) { | 
 | 511 |       Code = bitc::CST_CODE_UNDEF; | 
 | 512 |     } else if (const ConstantInt *IV = dyn_cast<ConstantInt>(C)) { | 
 | 513 |       if (IV->getBitWidth() <= 64) { | 
 | 514 |         int64_t V = IV->getSExtValue(); | 
 | 515 |         if (V >= 0) | 
 | 516 |           Record.push_back(V << 1); | 
 | 517 |         else | 
 | 518 |           Record.push_back((-V << 1) | 1); | 
 | 519 |         Code = bitc::CST_CODE_INTEGER; | 
| Chris Lattner | a0f1ecc | 2007-05-05 07:36:14 +0000 | [diff] [blame] | 520 |         AbbrevToUse = CONSTANTS_INTEGER_ABBREV; | 
| Chris Lattner | 2edd22b | 2007-04-24 00:16:04 +0000 | [diff] [blame] | 521 |       } else {                             // Wide integers, > 64 bits in size. | 
 | 522 |         // We have an arbitrary precision integer value to write whose  | 
 | 523 |         // bit width is > 64. However, in canonical unsigned integer  | 
 | 524 |         // format it is likely that the high bits are going to be zero. | 
 | 525 |         // So, we only write the number of active words. | 
 | 526 |         unsigned NWords = IV->getValue().getActiveWords();  | 
 | 527 |         const uint64_t *RawWords = IV->getValue().getRawData(); | 
| Chris Lattner | 2edd22b | 2007-04-24 00:16:04 +0000 | [diff] [blame] | 528 |         for (unsigned i = 0; i != NWords; ++i) { | 
 | 529 |           int64_t V = RawWords[i]; | 
 | 530 |           if (V >= 0) | 
 | 531 |             Record.push_back(V << 1); | 
 | 532 |           else | 
 | 533 |             Record.push_back((-V << 1) | 1); | 
 | 534 |         } | 
 | 535 |         Code = bitc::CST_CODE_WIDE_INTEGER; | 
 | 536 |       } | 
 | 537 |     } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C)) { | 
 | 538 |       Code = bitc::CST_CODE_FLOAT; | 
| Dale Johannesen | ebbc95d | 2007-08-09 22:51:36 +0000 | [diff] [blame] | 539 |       const Type *Ty = CFP->getType(); | 
| Dale Johannesen | 9d5f456 | 2007-09-12 03:30:33 +0000 | [diff] [blame] | 540 |       if (Ty == Type::FloatTy || Ty == Type::DoubleTy) { | 
 | 541 |         Record.push_back(CFP->getValueAPF().convertToAPInt().getZExtValue()); | 
| Dale Johannesen | 3f6eb74 | 2007-09-11 18:32:33 +0000 | [diff] [blame] | 542 |       } else if (Ty == Type::X86_FP80Ty) { | 
| Dale Johannesen | 693717f | 2007-09-26 23:20:33 +0000 | [diff] [blame] | 543 |         // api needed to prevent premature destruction | 
 | 544 |         APInt api = CFP->getValueAPF().convertToAPInt(); | 
 | 545 |         const uint64_t *p = api.getRawData(); | 
| Dale Johannesen | 3f6eb74 | 2007-09-11 18:32:33 +0000 | [diff] [blame] | 546 |         Record.push_back(p[0]); | 
 | 547 |         Record.push_back((uint16_t)p[1]); | 
| Dale Johannesen | a471c2e | 2007-10-11 18:07:22 +0000 | [diff] [blame] | 548 |       } else if (Ty == Type::FP128Ty || Ty == Type::PPC_FP128Ty) { | 
| Dale Johannesen | 693717f | 2007-09-26 23:20:33 +0000 | [diff] [blame] | 549 |         APInt api = CFP->getValueAPF().convertToAPInt(); | 
 | 550 |         const uint64_t *p = api.getRawData(); | 
| Dale Johannesen | 3f6eb74 | 2007-09-11 18:32:33 +0000 | [diff] [blame] | 551 |         Record.push_back(p[0]); | 
 | 552 |         Record.push_back(p[1]); | 
| Dale Johannesen | ebbc95d | 2007-08-09 22:51:36 +0000 | [diff] [blame] | 553 |       } else { | 
 | 554 |         assert (0 && "Unknown FP type!"); | 
| Chris Lattner | 2edd22b | 2007-04-24 00:16:04 +0000 | [diff] [blame] | 555 |       } | 
| Chris Lattner | ff7fc5d | 2007-05-06 00:35:24 +0000 | [diff] [blame] | 556 |     } else if (isa<ConstantArray>(C) && cast<ConstantArray>(C)->isString()) { | 
 | 557 |       // Emit constant strings specially. | 
| Chris Lattner | cb3d91b | 2007-05-06 00:53:07 +0000 | [diff] [blame] | 558 |       unsigned NumOps = C->getNumOperands(); | 
 | 559 |       // If this is a null-terminated string, use the denser CSTRING encoding. | 
 | 560 |       if (C->getOperand(NumOps-1)->isNullValue()) { | 
 | 561 |         Code = bitc::CST_CODE_CSTRING; | 
 | 562 |         --NumOps;  // Don't encode the null, which isn't allowed by char6. | 
 | 563 |       } else { | 
 | 564 |         Code = bitc::CST_CODE_STRING; | 
 | 565 |         AbbrevToUse = String8Abbrev; | 
 | 566 |       } | 
 | 567 |       bool isCStr7 = Code == bitc::CST_CODE_CSTRING; | 
 | 568 |       bool isCStrChar6 = Code == bitc::CST_CODE_CSTRING; | 
 | 569 |       for (unsigned i = 0; i != NumOps; ++i) { | 
| Chris Lattner | 817f08a | 2007-05-06 00:42:18 +0000 | [diff] [blame] | 570 |         unsigned char V = cast<ConstantInt>(C->getOperand(i))->getZExtValue(); | 
 | 571 |         Record.push_back(V); | 
| Chris Lattner | cb3d91b | 2007-05-06 00:53:07 +0000 | [diff] [blame] | 572 |         isCStr7 &= (V & 128) == 0; | 
 | 573 |         if (isCStrChar6)  | 
 | 574 |           isCStrChar6 = BitCodeAbbrevOp::isChar6(V); | 
| Chris Lattner | 817f08a | 2007-05-06 00:42:18 +0000 | [diff] [blame] | 575 |       } | 
| Chris Lattner | cb3d91b | 2007-05-06 00:53:07 +0000 | [diff] [blame] | 576 |        | 
 | 577 |       if (isCStrChar6) | 
 | 578 |         AbbrevToUse = CString6Abbrev; | 
 | 579 |       else if (isCStr7) | 
 | 580 |         AbbrevToUse = CString7Abbrev; | 
| Chris Lattner | 2edd22b | 2007-04-24 00:16:04 +0000 | [diff] [blame] | 581 |     } else if (isa<ConstantArray>(C) || isa<ConstantStruct>(V) || | 
 | 582 |                isa<ConstantVector>(V)) { | 
 | 583 |       Code = bitc::CST_CODE_AGGREGATE; | 
| Chris Lattner | 2edd22b | 2007-04-24 00:16:04 +0000 | [diff] [blame] | 584 |       for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) | 
 | 585 |         Record.push_back(VE.getValueID(C->getOperand(i))); | 
| Chris Lattner | a0f1ecc | 2007-05-05 07:36:14 +0000 | [diff] [blame] | 586 |       AbbrevToUse = AggregateAbbrev; | 
| Chris Lattner | 2edd22b | 2007-04-24 00:16:04 +0000 | [diff] [blame] | 587 |     } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) { | 
| Chris Lattner | f581c3b | 2007-04-24 07:07:11 +0000 | [diff] [blame] | 588 |       switch (CE->getOpcode()) { | 
 | 589 |       default: | 
 | 590 |         if (Instruction::isCast(CE->getOpcode())) { | 
 | 591 |           Code = bitc::CST_CODE_CE_CAST; | 
 | 592 |           Record.push_back(GetEncodedCastOpcode(CE->getOpcode())); | 
 | 593 |           Record.push_back(VE.getTypeID(C->getOperand(0)->getType())); | 
 | 594 |           Record.push_back(VE.getValueID(C->getOperand(0))); | 
| Chris Lattner | a0f1ecc | 2007-05-05 07:36:14 +0000 | [diff] [blame] | 595 |           AbbrevToUse = CONSTANTS_CE_CAST_Abbrev; | 
| Chris Lattner | f581c3b | 2007-04-24 07:07:11 +0000 | [diff] [blame] | 596 |         } else { | 
 | 597 |           assert(CE->getNumOperands() == 2 && "Unknown constant expr!"); | 
 | 598 |           Code = bitc::CST_CODE_CE_BINOP; | 
 | 599 |           Record.push_back(GetEncodedBinaryOpcode(CE->getOpcode())); | 
 | 600 |           Record.push_back(VE.getValueID(C->getOperand(0))); | 
 | 601 |           Record.push_back(VE.getValueID(C->getOperand(1))); | 
 | 602 |         } | 
 | 603 |         break; | 
 | 604 |       case Instruction::GetElementPtr: | 
 | 605 |         Code = bitc::CST_CODE_CE_GEP; | 
| Chris Lattner | f581c3b | 2007-04-24 07:07:11 +0000 | [diff] [blame] | 606 |         for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) { | 
 | 607 |           Record.push_back(VE.getTypeID(C->getOperand(i)->getType())); | 
 | 608 |           Record.push_back(VE.getValueID(C->getOperand(i))); | 
 | 609 |         } | 
 | 610 |         break; | 
 | 611 |       case Instruction::Select: | 
 | 612 |         Code = bitc::CST_CODE_CE_SELECT; | 
 | 613 |         Record.push_back(VE.getValueID(C->getOperand(0))); | 
 | 614 |         Record.push_back(VE.getValueID(C->getOperand(1))); | 
 | 615 |         Record.push_back(VE.getValueID(C->getOperand(2))); | 
 | 616 |         break; | 
 | 617 |       case Instruction::ExtractElement: | 
 | 618 |         Code = bitc::CST_CODE_CE_EXTRACTELT; | 
 | 619 |         Record.push_back(VE.getTypeID(C->getOperand(0)->getType())); | 
 | 620 |         Record.push_back(VE.getValueID(C->getOperand(0))); | 
 | 621 |         Record.push_back(VE.getValueID(C->getOperand(1))); | 
 | 622 |         break; | 
 | 623 |       case Instruction::InsertElement: | 
 | 624 |         Code = bitc::CST_CODE_CE_INSERTELT; | 
 | 625 |         Record.push_back(VE.getValueID(C->getOperand(0))); | 
 | 626 |         Record.push_back(VE.getValueID(C->getOperand(1))); | 
 | 627 |         Record.push_back(VE.getValueID(C->getOperand(2))); | 
 | 628 |         break; | 
 | 629 |       case Instruction::ShuffleVector: | 
 | 630 |         Code = bitc::CST_CODE_CE_SHUFFLEVEC; | 
 | 631 |         Record.push_back(VE.getValueID(C->getOperand(0))); | 
 | 632 |         Record.push_back(VE.getValueID(C->getOperand(1))); | 
 | 633 |         Record.push_back(VE.getValueID(C->getOperand(2))); | 
 | 634 |         break; | 
 | 635 |       case Instruction::ICmp: | 
 | 636 |       case Instruction::FCmp: | 
 | 637 |         Code = bitc::CST_CODE_CE_CMP; | 
 | 638 |         Record.push_back(VE.getTypeID(C->getOperand(0)->getType())); | 
 | 639 |         Record.push_back(VE.getValueID(C->getOperand(0))); | 
 | 640 |         Record.push_back(VE.getValueID(C->getOperand(1))); | 
 | 641 |         Record.push_back(CE->getPredicate()); | 
 | 642 |         break; | 
 | 643 |       } | 
| Chris Lattner | 2edd22b | 2007-04-24 00:16:04 +0000 | [diff] [blame] | 644 |     } else { | 
 | 645 |       assert(0 && "Unknown constant!"); | 
 | 646 |     } | 
 | 647 |     Stream.EmitRecord(Code, Record, AbbrevToUse); | 
 | 648 |     Record.clear(); | 
 | 649 |   } | 
 | 650 |  | 
 | 651 |   Stream.ExitBlock(); | 
 | 652 | } | 
 | 653 |  | 
 | 654 | static void WriteModuleConstants(const ValueEnumerator &VE, | 
 | 655 |                                  BitstreamWriter &Stream) { | 
 | 656 |   const ValueEnumerator::ValueList &Vals = VE.getValues(); | 
 | 657 |    | 
 | 658 |   // Find the first constant to emit, which is the first non-globalvalue value. | 
 | 659 |   // We know globalvalues have been emitted by WriteModuleInfo. | 
 | 660 |   for (unsigned i = 0, e = Vals.size(); i != e; ++i) { | 
 | 661 |     if (!isa<GlobalValue>(Vals[i].first)) { | 
| Chris Lattner | a0f1ecc | 2007-05-05 07:36:14 +0000 | [diff] [blame] | 662 |       WriteConstants(i, Vals.size(), VE, Stream, true); | 
| Chris Lattner | 2edd22b | 2007-04-24 00:16:04 +0000 | [diff] [blame] | 663 |       return; | 
 | 664 |     } | 
 | 665 |   } | 
 | 666 | } | 
| Chris Lattner | b992be1 | 2007-04-23 20:35:01 +0000 | [diff] [blame] | 667 |  | 
| Chris Lattner | 7337ab9 | 2007-05-06 00:00:00 +0000 | [diff] [blame] | 668 | /// PushValueAndType - The file has to encode both the value and type id for | 
 | 669 | /// many values, because we need to know what type to create for forward | 
 | 670 | /// references.  However, most operands are not forward references, so this type | 
 | 671 | /// field is not needed. | 
 | 672 | /// | 
 | 673 | /// This function adds V's value ID to Vals.  If the value ID is higher than the | 
 | 674 | /// instruction ID, then it is a forward reference, and it also includes the | 
 | 675 | /// type ID. | 
 | 676 | static bool PushValueAndType(Value *V, unsigned InstID, | 
 | 677 |                              SmallVector<unsigned, 64> &Vals,  | 
 | 678 |                              ValueEnumerator &VE) { | 
 | 679 |   unsigned ValID = VE.getValueID(V); | 
 | 680 |   Vals.push_back(ValID); | 
 | 681 |   if (ValID >= InstID) { | 
 | 682 |     Vals.push_back(VE.getTypeID(V->getType())); | 
 | 683 |     return true; | 
 | 684 |   } | 
 | 685 |   return false; | 
 | 686 | } | 
 | 687 |  | 
| Chris Lattner | b9d0c2a | 2007-04-26 05:53:54 +0000 | [diff] [blame] | 688 | /// WriteInstruction - Emit an instruction to the specified stream. | 
| Chris Lattner | 7337ab9 | 2007-05-06 00:00:00 +0000 | [diff] [blame] | 689 | static void WriteInstruction(const Instruction &I, unsigned InstID, | 
 | 690 |                              ValueEnumerator &VE, BitstreamWriter &Stream, | 
| Chris Lattner | b9d0c2a | 2007-04-26 05:53:54 +0000 | [diff] [blame] | 691 |                              SmallVector<unsigned, 64> &Vals) { | 
| Chris Lattner | b9d0c2a | 2007-04-26 05:53:54 +0000 | [diff] [blame] | 692 |   unsigned Code = 0; | 
 | 693 |   unsigned AbbrevToUse = 0; | 
 | 694 |   switch (I.getOpcode()) { | 
 | 695 |   default: | 
 | 696 |     if (Instruction::isCast(I.getOpcode())) { | 
| Chris Lattner | d309c75 | 2007-05-01 02:13:26 +0000 | [diff] [blame] | 697 |       Code = bitc::FUNC_CODE_INST_CAST; | 
| Chris Lattner | f9f2e83 | 2007-05-06 02:38:57 +0000 | [diff] [blame] | 698 |       if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE)) | 
 | 699 |         AbbrevToUse = FUNCTION_INST_CAST_ABBREV; | 
| Chris Lattner | b9d0c2a | 2007-04-26 05:53:54 +0000 | [diff] [blame] | 700 |       Vals.push_back(VE.getTypeID(I.getType())); | 
| Chris Lattner | abfbf85 | 2007-05-06 00:21:25 +0000 | [diff] [blame] | 701 |       Vals.push_back(GetEncodedCastOpcode(I.getOpcode())); | 
| Chris Lattner | b9d0c2a | 2007-04-26 05:53:54 +0000 | [diff] [blame] | 702 |     } else { | 
 | 703 |       assert(isa<BinaryOperator>(I) && "Unknown instruction!"); | 
| Chris Lattner | f639875 | 2007-05-02 04:26:36 +0000 | [diff] [blame] | 704 |       Code = bitc::FUNC_CODE_INST_BINOP; | 
| Chris Lattner | f9f2e83 | 2007-05-06 02:38:57 +0000 | [diff] [blame] | 705 |       if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE)) | 
 | 706 |         AbbrevToUse = FUNCTION_INST_BINOP_ABBREV; | 
| Chris Lattner | b9d0c2a | 2007-04-26 05:53:54 +0000 | [diff] [blame] | 707 |       Vals.push_back(VE.getValueID(I.getOperand(1))); | 
| Chris Lattner | abfbf85 | 2007-05-06 00:21:25 +0000 | [diff] [blame] | 708 |       Vals.push_back(GetEncodedBinaryOpcode(I.getOpcode())); | 
| Chris Lattner | b9d0c2a | 2007-04-26 05:53:54 +0000 | [diff] [blame] | 709 |     } | 
 | 710 |     break; | 
| Chris Lattner | d309c75 | 2007-05-01 02:13:26 +0000 | [diff] [blame] | 711 |  | 
 | 712 |   case Instruction::GetElementPtr: | 
 | 713 |     Code = bitc::FUNC_CODE_INST_GEP; | 
| Chris Lattner | 7337ab9 | 2007-05-06 00:00:00 +0000 | [diff] [blame] | 714 |     for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) | 
 | 715 |       PushValueAndType(I.getOperand(i), InstID, Vals, VE); | 
| Chris Lattner | d309c75 | 2007-05-01 02:13:26 +0000 | [diff] [blame] | 716 |     break; | 
 | 717 |   case Instruction::Select: | 
 | 718 |     Code = bitc::FUNC_CODE_INST_SELECT; | 
| Chris Lattner | abfbf85 | 2007-05-06 00:21:25 +0000 | [diff] [blame] | 719 |     PushValueAndType(I.getOperand(1), InstID, Vals, VE); | 
| Chris Lattner | d309c75 | 2007-05-01 02:13:26 +0000 | [diff] [blame] | 720 |     Vals.push_back(VE.getValueID(I.getOperand(2))); | 
| Chris Lattner | abfbf85 | 2007-05-06 00:21:25 +0000 | [diff] [blame] | 721 |     Vals.push_back(VE.getValueID(I.getOperand(0))); | 
| Chris Lattner | d309c75 | 2007-05-01 02:13:26 +0000 | [diff] [blame] | 722 |     break; | 
 | 723 |   case Instruction::ExtractElement: | 
 | 724 |     Code = bitc::FUNC_CODE_INST_EXTRACTELT; | 
| Chris Lattner | abfbf85 | 2007-05-06 00:21:25 +0000 | [diff] [blame] | 725 |     PushValueAndType(I.getOperand(0), InstID, Vals, VE); | 
| Chris Lattner | d309c75 | 2007-05-01 02:13:26 +0000 | [diff] [blame] | 726 |     Vals.push_back(VE.getValueID(I.getOperand(1))); | 
 | 727 |     break; | 
 | 728 |   case Instruction::InsertElement: | 
 | 729 |     Code = bitc::FUNC_CODE_INST_INSERTELT; | 
| Chris Lattner | abfbf85 | 2007-05-06 00:21:25 +0000 | [diff] [blame] | 730 |     PushValueAndType(I.getOperand(0), InstID, Vals, VE); | 
| Chris Lattner | d309c75 | 2007-05-01 02:13:26 +0000 | [diff] [blame] | 731 |     Vals.push_back(VE.getValueID(I.getOperand(1))); | 
 | 732 |     Vals.push_back(VE.getValueID(I.getOperand(2))); | 
 | 733 |     break; | 
 | 734 |   case Instruction::ShuffleVector: | 
 | 735 |     Code = bitc::FUNC_CODE_INST_SHUFFLEVEC; | 
| Chris Lattner | abfbf85 | 2007-05-06 00:21:25 +0000 | [diff] [blame] | 736 |     PushValueAndType(I.getOperand(0), InstID, Vals, VE); | 
| Chris Lattner | d309c75 | 2007-05-01 02:13:26 +0000 | [diff] [blame] | 737 |     Vals.push_back(VE.getValueID(I.getOperand(1))); | 
 | 738 |     Vals.push_back(VE.getValueID(I.getOperand(2))); | 
 | 739 |     break; | 
 | 740 |   case Instruction::ICmp: | 
 | 741 |   case Instruction::FCmp: | 
 | 742 |     Code = bitc::FUNC_CODE_INST_CMP; | 
| Chris Lattner | 7337ab9 | 2007-05-06 00:00:00 +0000 | [diff] [blame] | 743 |     PushValueAndType(I.getOperand(0), InstID, Vals, VE); | 
| Chris Lattner | d309c75 | 2007-05-01 02:13:26 +0000 | [diff] [blame] | 744 |     Vals.push_back(VE.getValueID(I.getOperand(1))); | 
 | 745 |     Vals.push_back(cast<CmpInst>(I).getPredicate()); | 
 | 746 |     break; | 
| Devang Patel | 197be3d | 2008-02-22 02:49:49 +0000 | [diff] [blame^] | 747 |   case Instruction::GetResult: | 
 | 748 |     Code = bitc::FUNC_CODE_INST_GETRESULT; | 
 | 749 |     PushValueAndType(I.getOperand(0), InstID, Vals, VE); | 
 | 750 |     Vals.push_back(Log2_32(cast<GetResultInst>(I).getIndex())+1); | 
 | 751 |     break; | 
| Chris Lattner | d309c75 | 2007-05-01 02:13:26 +0000 | [diff] [blame] | 752 |  | 
 | 753 |   case Instruction::Ret: | 
 | 754 |     Code = bitc::FUNC_CODE_INST_RET; | 
| Chris Lattner | 94687ac | 2007-05-06 01:28:01 +0000 | [diff] [blame] | 755 |     if (!I.getNumOperands()) | 
 | 756 |       AbbrevToUse = FUNCTION_INST_RET_VOID_ABBREV; | 
 | 757 |     else if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE)) | 
 | 758 |       AbbrevToUse = FUNCTION_INST_RET_VAL_ABBREV; | 
| Chris Lattner | d309c75 | 2007-05-01 02:13:26 +0000 | [diff] [blame] | 759 |     break; | 
 | 760 |   case Instruction::Br: | 
 | 761 |     Code = bitc::FUNC_CODE_INST_BR; | 
 | 762 |     Vals.push_back(VE.getValueID(I.getOperand(0))); | 
 | 763 |     if (cast<BranchInst>(I).isConditional()) { | 
 | 764 |       Vals.push_back(VE.getValueID(I.getOperand(1))); | 
 | 765 |       Vals.push_back(VE.getValueID(I.getOperand(2))); | 
 | 766 |     } | 
 | 767 |     break; | 
 | 768 |   case Instruction::Switch: | 
 | 769 |     Code = bitc::FUNC_CODE_INST_SWITCH; | 
 | 770 |     Vals.push_back(VE.getTypeID(I.getOperand(0)->getType())); | 
| Chris Lattner | d309c75 | 2007-05-01 02:13:26 +0000 | [diff] [blame] | 771 |     for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) | 
 | 772 |       Vals.push_back(VE.getValueID(I.getOperand(i))); | 
 | 773 |     break; | 
| Chris Lattner | 60ce9b5 | 2007-05-01 07:03:37 +0000 | [diff] [blame] | 774 |   case Instruction::Invoke: { | 
| Chris Lattner | a9bb713 | 2007-05-08 05:38:01 +0000 | [diff] [blame] | 775 |     const PointerType *PTy = cast<PointerType>(I.getOperand(0)->getType()); | 
 | 776 |     const FunctionType *FTy = cast<FunctionType>(PTy->getElementType()); | 
| Chris Lattner | d309c75 | 2007-05-01 02:13:26 +0000 | [diff] [blame] | 777 |     Code = bitc::FUNC_CODE_INST_INVOKE; | 
| Chris Lattner | a9bb713 | 2007-05-08 05:38:01 +0000 | [diff] [blame] | 778 |      | 
| Duncan Sands | dc02467 | 2007-11-27 13:23:08 +0000 | [diff] [blame] | 779 |     const InvokeInst *II = cast<InvokeInst>(&I); | 
 | 780 |     Vals.push_back(VE.getParamAttrID(II->getParamAttrs())); | 
 | 781 |     Vals.push_back(II->getCallingConv()); | 
| Chris Lattner | 7337ab9 | 2007-05-06 00:00:00 +0000 | [diff] [blame] | 782 |     Vals.push_back(VE.getValueID(I.getOperand(1)));      // normal dest | 
 | 783 |     Vals.push_back(VE.getValueID(I.getOperand(2)));      // unwind dest | 
 | 784 |     PushValueAndType(I.getOperand(0), InstID, Vals, VE); // callee | 
| Chris Lattner | b9d0c2a | 2007-04-26 05:53:54 +0000 | [diff] [blame] | 785 |      | 
| Chris Lattner | d309c75 | 2007-05-01 02:13:26 +0000 | [diff] [blame] | 786 |     // Emit value #'s for the fixed parameters. | 
| Chris Lattner | d309c75 | 2007-05-01 02:13:26 +0000 | [diff] [blame] | 787 |     for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i) | 
 | 788 |       Vals.push_back(VE.getValueID(I.getOperand(i+3)));  // fixed param. | 
 | 789 |  | 
 | 790 |     // Emit type/value pairs for varargs params. | 
 | 791 |     if (FTy->isVarArg()) { | 
| Chris Lattner | 7337ab9 | 2007-05-06 00:00:00 +0000 | [diff] [blame] | 792 |       for (unsigned i = 3+FTy->getNumParams(), e = I.getNumOperands(); | 
 | 793 |            i != e; ++i) | 
 | 794 |         PushValueAndType(I.getOperand(i), InstID, Vals, VE); // vararg | 
| Chris Lattner | d309c75 | 2007-05-01 02:13:26 +0000 | [diff] [blame] | 795 |     } | 
 | 796 |     break; | 
| Chris Lattner | 60ce9b5 | 2007-05-01 07:03:37 +0000 | [diff] [blame] | 797 |   } | 
| Chris Lattner | b9d0c2a | 2007-04-26 05:53:54 +0000 | [diff] [blame] | 798 |   case Instruction::Unwind: | 
 | 799 |     Code = bitc::FUNC_CODE_INST_UNWIND; | 
 | 800 |     break; | 
 | 801 |   case Instruction::Unreachable: | 
 | 802 |     Code = bitc::FUNC_CODE_INST_UNREACHABLE; | 
| Chris Lattner | 94687ac | 2007-05-06 01:28:01 +0000 | [diff] [blame] | 803 |     AbbrevToUse = FUNCTION_INST_UNREACHABLE_ABBREV; | 
| Chris Lattner | b9d0c2a | 2007-04-26 05:53:54 +0000 | [diff] [blame] | 804 |     break; | 
| Chris Lattner | d309c75 | 2007-05-01 02:13:26 +0000 | [diff] [blame] | 805 |    | 
 | 806 |   case Instruction::PHI: | 
 | 807 |     Code = bitc::FUNC_CODE_INST_PHI; | 
 | 808 |     Vals.push_back(VE.getTypeID(I.getType())); | 
| Chris Lattner | d309c75 | 2007-05-01 02:13:26 +0000 | [diff] [blame] | 809 |     for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) | 
 | 810 |       Vals.push_back(VE.getValueID(I.getOperand(i))); | 
 | 811 |     break; | 
| Chris Lattner | b9d0c2a | 2007-04-26 05:53:54 +0000 | [diff] [blame] | 812 |      | 
| Chris Lattner | d309c75 | 2007-05-01 02:13:26 +0000 | [diff] [blame] | 813 |   case Instruction::Malloc: | 
 | 814 |     Code = bitc::FUNC_CODE_INST_MALLOC; | 
 | 815 |     Vals.push_back(VE.getTypeID(I.getType())); | 
 | 816 |     Vals.push_back(VE.getValueID(I.getOperand(0))); // size. | 
 | 817 |     Vals.push_back(Log2_32(cast<MallocInst>(I).getAlignment())+1); | 
 | 818 |     break; | 
 | 819 |      | 
 | 820 |   case Instruction::Free: | 
 | 821 |     Code = bitc::FUNC_CODE_INST_FREE; | 
| Chris Lattner | abfbf85 | 2007-05-06 00:21:25 +0000 | [diff] [blame] | 822 |     PushValueAndType(I.getOperand(0), InstID, Vals, VE); | 
| Chris Lattner | d309c75 | 2007-05-01 02:13:26 +0000 | [diff] [blame] | 823 |     break; | 
 | 824 |      | 
 | 825 |   case Instruction::Alloca: | 
 | 826 |     Code = bitc::FUNC_CODE_INST_ALLOCA; | 
 | 827 |     Vals.push_back(VE.getTypeID(I.getType())); | 
 | 828 |     Vals.push_back(VE.getValueID(I.getOperand(0))); // size. | 
 | 829 |     Vals.push_back(Log2_32(cast<AllocaInst>(I).getAlignment())+1); | 
 | 830 |     break; | 
 | 831 |      | 
 | 832 |   case Instruction::Load: | 
 | 833 |     Code = bitc::FUNC_CODE_INST_LOAD; | 
| Chris Lattner | 7337ab9 | 2007-05-06 00:00:00 +0000 | [diff] [blame] | 834 |     if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE))  // ptr | 
 | 835 |       AbbrevToUse = FUNCTION_INST_LOAD_ABBREV; | 
 | 836 |        | 
| Chris Lattner | d309c75 | 2007-05-01 02:13:26 +0000 | [diff] [blame] | 837 |     Vals.push_back(Log2_32(cast<LoadInst>(I).getAlignment())+1); | 
 | 838 |     Vals.push_back(cast<LoadInst>(I).isVolatile()); | 
 | 839 |     break; | 
 | 840 |   case Instruction::Store: | 
| Christopher Lamb | fe63fb9 | 2007-12-11 08:59:05 +0000 | [diff] [blame] | 841 |     Code = bitc::FUNC_CODE_INST_STORE2; | 
 | 842 |     PushValueAndType(I.getOperand(1), InstID, Vals, VE);  // ptrty + ptr | 
 | 843 |     Vals.push_back(VE.getValueID(I.getOperand(0)));       // val. | 
| Chris Lattner | d309c75 | 2007-05-01 02:13:26 +0000 | [diff] [blame] | 844 |     Vals.push_back(Log2_32(cast<StoreInst>(I).getAlignment())+1); | 
 | 845 |     Vals.push_back(cast<StoreInst>(I).isVolatile()); | 
 | 846 |     break; | 
 | 847 |   case Instruction::Call: { | 
| Chris Lattner | a9bb713 | 2007-05-08 05:38:01 +0000 | [diff] [blame] | 848 |     const PointerType *PTy = cast<PointerType>(I.getOperand(0)->getType()); | 
 | 849 |     const FunctionType *FTy = cast<FunctionType>(PTy->getElementType()); | 
 | 850 |  | 
| Chris Lattner | d309c75 | 2007-05-01 02:13:26 +0000 | [diff] [blame] | 851 |     Code = bitc::FUNC_CODE_INST_CALL; | 
| Chris Lattner | a9bb713 | 2007-05-08 05:38:01 +0000 | [diff] [blame] | 852 |      | 
| Duncan Sands | dc02467 | 2007-11-27 13:23:08 +0000 | [diff] [blame] | 853 |     const CallInst *CI = cast<CallInst>(&I); | 
 | 854 |     Vals.push_back(VE.getParamAttrID(CI->getParamAttrs())); | 
 | 855 |     Vals.push_back((CI->getCallingConv() << 1) | unsigned(CI->isTailCall())); | 
 | 856 |     PushValueAndType(CI->getOperand(0), InstID, Vals, VE);  // Callee | 
| Chris Lattner | d309c75 | 2007-05-01 02:13:26 +0000 | [diff] [blame] | 857 |      | 
 | 858 |     // Emit value #'s for the fixed parameters. | 
| Chris Lattner | d309c75 | 2007-05-01 02:13:26 +0000 | [diff] [blame] | 859 |     for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i) | 
 | 860 |       Vals.push_back(VE.getValueID(I.getOperand(i+1)));  // fixed param. | 
 | 861 |        | 
| Chris Lattner | 60ce9b5 | 2007-05-01 07:03:37 +0000 | [diff] [blame] | 862 |     // Emit type/value pairs for varargs params. | 
 | 863 |     if (FTy->isVarArg()) { | 
 | 864 |       unsigned NumVarargs = I.getNumOperands()-1-FTy->getNumParams(); | 
| Chris Lattner | 60ce9b5 | 2007-05-01 07:03:37 +0000 | [diff] [blame] | 865 |       for (unsigned i = I.getNumOperands()-NumVarargs, e = I.getNumOperands(); | 
| Chris Lattner | 7337ab9 | 2007-05-06 00:00:00 +0000 | [diff] [blame] | 866 |            i != e; ++i) | 
 | 867 |         PushValueAndType(I.getOperand(i), InstID, Vals, VE);  // varargs | 
| Chris Lattner | d309c75 | 2007-05-01 02:13:26 +0000 | [diff] [blame] | 868 |     } | 
 | 869 |     break; | 
| Chris Lattner | 60ce9b5 | 2007-05-01 07:03:37 +0000 | [diff] [blame] | 870 |   } | 
| Chris Lattner | d309c75 | 2007-05-01 02:13:26 +0000 | [diff] [blame] | 871 |   case Instruction::VAArg: | 
 | 872 |     Code = bitc::FUNC_CODE_INST_VAARG; | 
 | 873 |     Vals.push_back(VE.getTypeID(I.getOperand(0)->getType()));   // valistty | 
 | 874 |     Vals.push_back(VE.getValueID(I.getOperand(0))); // valist. | 
 | 875 |     Vals.push_back(VE.getTypeID(I.getType())); // restype. | 
 | 876 |     break; | 
| Chris Lattner | b9d0c2a | 2007-04-26 05:53:54 +0000 | [diff] [blame] | 877 |   } | 
 | 878 |    | 
 | 879 |   Stream.EmitRecord(Code, Vals, AbbrevToUse); | 
 | 880 |   Vals.clear(); | 
 | 881 | } | 
 | 882 |  | 
| Chris Lattner | be1f993 | 2007-05-01 02:14:57 +0000 | [diff] [blame] | 883 | // Emit names for globals/functions etc. | 
 | 884 | static void WriteValueSymbolTable(const ValueSymbolTable &VST, | 
 | 885 |                                   const ValueEnumerator &VE, | 
 | 886 |                                   BitstreamWriter &Stream) { | 
 | 887 |   if (VST.empty()) return; | 
| Chris Lattner | ff294a4 | 2007-05-05 01:26:50 +0000 | [diff] [blame] | 888 |   Stream.EnterSubblock(bitc::VALUE_SYMTAB_BLOCK_ID, 4); | 
| Chris Lattner | 2e7899d | 2007-05-04 20:34:50 +0000 | [diff] [blame] | 889 |  | 
| Chris Lattner | be1f993 | 2007-05-01 02:14:57 +0000 | [diff] [blame] | 890 |   // FIXME: Set up the abbrev, we know how many values there are! | 
 | 891 |   // FIXME: We know if the type names can use 7-bit ascii. | 
 | 892 |   SmallVector<unsigned, 64> NameVals; | 
 | 893 |    | 
 | 894 |   for (ValueSymbolTable::const_iterator SI = VST.begin(), SE = VST.end(); | 
 | 895 |        SI != SE; ++SI) { | 
| Chris Lattner | 5969830 | 2007-05-04 20:52:02 +0000 | [diff] [blame] | 896 |      | 
 | 897 |     const ValueName &Name = *SI; | 
 | 898 |      | 
 | 899 |     // Figure out the encoding to use for the name. | 
 | 900 |     bool is7Bit = true; | 
| Chris Lattner | ff294a4 | 2007-05-05 01:26:50 +0000 | [diff] [blame] | 901 |     bool isChar6 = true; | 
 | 902 |     for (const char *C = Name.getKeyData(), *E = C+Name.getKeyLength(); | 
 | 903 |          C != E; ++C) { | 
 | 904 |       if (isChar6)  | 
 | 905 |         isChar6 = BitCodeAbbrevOp::isChar6(*C); | 
 | 906 |       if ((unsigned char)*C & 128) { | 
| Chris Lattner | 5969830 | 2007-05-04 20:52:02 +0000 | [diff] [blame] | 907 |         is7Bit = false; | 
| Chris Lattner | ff294a4 | 2007-05-05 01:26:50 +0000 | [diff] [blame] | 908 |         break;  // don't bother scanning the rest. | 
| Chris Lattner | 5969830 | 2007-05-04 20:52:02 +0000 | [diff] [blame] | 909 |       } | 
| Chris Lattner | ff294a4 | 2007-05-05 01:26:50 +0000 | [diff] [blame] | 910 |     } | 
| Chris Lattner | 5969830 | 2007-05-04 20:52:02 +0000 | [diff] [blame] | 911 |      | 
| Chris Lattner | fd1ae95 | 2007-05-04 21:31:13 +0000 | [diff] [blame] | 912 |     unsigned AbbrevToUse = VST_ENTRY_8_ABBREV; | 
| Chris Lattner | be1f993 | 2007-05-01 02:14:57 +0000 | [diff] [blame] | 913 |      | 
| Chris Lattner | fd1ae95 | 2007-05-04 21:31:13 +0000 | [diff] [blame] | 914 |     // VST_ENTRY:   [valueid, namechar x N] | 
 | 915 |     // VST_BBENTRY: [bbid, namechar x N] | 
| Chris Lattner | e825ed5 | 2007-05-03 22:18:21 +0000 | [diff] [blame] | 916 |     unsigned Code; | 
 | 917 |     if (isa<BasicBlock>(SI->getValue())) { | 
 | 918 |       Code = bitc::VST_CODE_BBENTRY; | 
| Chris Lattner | ff294a4 | 2007-05-05 01:26:50 +0000 | [diff] [blame] | 919 |       if (isChar6) | 
 | 920 |         AbbrevToUse = VST_BBENTRY_6_ABBREV; | 
| Chris Lattner | e825ed5 | 2007-05-03 22:18:21 +0000 | [diff] [blame] | 921 |     } else { | 
 | 922 |       Code = bitc::VST_CODE_ENTRY; | 
| Chris Lattner | ff294a4 | 2007-05-05 01:26:50 +0000 | [diff] [blame] | 923 |       if (isChar6) | 
 | 924 |         AbbrevToUse = VST_ENTRY_6_ABBREV; | 
 | 925 |       else if (is7Bit) | 
 | 926 |         AbbrevToUse = VST_ENTRY_7_ABBREV; | 
| Chris Lattner | e825ed5 | 2007-05-03 22:18:21 +0000 | [diff] [blame] | 927 |     } | 
| Chris Lattner | be1f993 | 2007-05-01 02:14:57 +0000 | [diff] [blame] | 928 |      | 
| Chris Lattner | e825ed5 | 2007-05-03 22:18:21 +0000 | [diff] [blame] | 929 |     NameVals.push_back(VE.getValueID(SI->getValue())); | 
| Chris Lattner | 5969830 | 2007-05-04 20:52:02 +0000 | [diff] [blame] | 930 |     for (const char *P = Name.getKeyData(), | 
 | 931 |          *E = Name.getKeyData()+Name.getKeyLength(); P != E; ++P) | 
| Chris Lattner | be1f993 | 2007-05-01 02:14:57 +0000 | [diff] [blame] | 932 |       NameVals.push_back((unsigned char)*P); | 
 | 933 |      | 
 | 934 |     // Emit the finished record. | 
| Chris Lattner | e825ed5 | 2007-05-03 22:18:21 +0000 | [diff] [blame] | 935 |     Stream.EmitRecord(Code, NameVals, AbbrevToUse); | 
| Chris Lattner | be1f993 | 2007-05-01 02:14:57 +0000 | [diff] [blame] | 936 |     NameVals.clear(); | 
 | 937 |   } | 
 | 938 |   Stream.ExitBlock(); | 
 | 939 | } | 
 | 940 |  | 
| Chris Lattner | 8d35c79 | 2007-04-26 03:50:57 +0000 | [diff] [blame] | 941 | /// WriteFunction - Emit a function body to the module stream. | 
| Chris Lattner | 198f34a | 2007-04-26 03:27:58 +0000 | [diff] [blame] | 942 | static void WriteFunction(const Function &F, ValueEnumerator &VE,  | 
 | 943 |                           BitstreamWriter &Stream) { | 
| Chris Lattner | f9f2e83 | 2007-05-06 02:38:57 +0000 | [diff] [blame] | 944 |   Stream.EnterSubblock(bitc::FUNCTION_BLOCK_ID, 4); | 
| Chris Lattner | 8d35c79 | 2007-04-26 03:50:57 +0000 | [diff] [blame] | 945 |   VE.incorporateFunction(F); | 
| Chris Lattner | b9d0c2a | 2007-04-26 05:53:54 +0000 | [diff] [blame] | 946 |  | 
 | 947 |   SmallVector<unsigned, 64> Vals; | 
 | 948 |    | 
 | 949 |   // Emit the number of basic blocks, so the reader can create them ahead of | 
 | 950 |   // time. | 
 | 951 |   Vals.push_back(VE.getBasicBlocks().size()); | 
 | 952 |   Stream.EmitRecord(bitc::FUNC_CODE_DECLAREBLOCKS, Vals); | 
 | 953 |   Vals.clear(); | 
 | 954 |    | 
| Chris Lattner | b9d0c2a | 2007-04-26 05:53:54 +0000 | [diff] [blame] | 955 |   // If there are function-local constants, emit them now. | 
 | 956 |   unsigned CstStart, CstEnd; | 
 | 957 |   VE.getFunctionConstantRange(CstStart, CstEnd); | 
| Chris Lattner | a0f1ecc | 2007-05-05 07:36:14 +0000 | [diff] [blame] | 958 |   WriteConstants(CstStart, CstEnd, VE, Stream, false); | 
| Chris Lattner | b9d0c2a | 2007-04-26 05:53:54 +0000 | [diff] [blame] | 959 |    | 
| Chris Lattner | 7337ab9 | 2007-05-06 00:00:00 +0000 | [diff] [blame] | 960 |   // Keep a running idea of what the instruction ID is.  | 
 | 961 |   unsigned InstID = CstEnd; | 
 | 962 |    | 
| Chris Lattner | b9d0c2a | 2007-04-26 05:53:54 +0000 | [diff] [blame] | 963 |   // Finally, emit all the instructions, in order. | 
 | 964 |   for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) | 
| Chris Lattner | 7337ab9 | 2007-05-06 00:00:00 +0000 | [diff] [blame] | 965 |     for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); | 
 | 966 |          I != E; ++I) { | 
 | 967 |       WriteInstruction(*I, InstID, VE, Stream, Vals); | 
 | 968 |       if (I->getType() != Type::VoidTy) | 
 | 969 |         ++InstID; | 
 | 970 |     } | 
| Chris Lattner | 198f34a | 2007-04-26 03:27:58 +0000 | [diff] [blame] | 971 |    | 
| Chris Lattner | be1f993 | 2007-05-01 02:14:57 +0000 | [diff] [blame] | 972 |   // Emit names for all the instructions etc. | 
 | 973 |   WriteValueSymbolTable(F.getValueSymbolTable(), VE, Stream); | 
 | 974 |      | 
| Chris Lattner | 8d35c79 | 2007-04-26 03:50:57 +0000 | [diff] [blame] | 975 |   VE.purgeFunction(); | 
| Chris Lattner | b9d0c2a | 2007-04-26 05:53:54 +0000 | [diff] [blame] | 976 |   Stream.ExitBlock(); | 
| Chris Lattner | 198f34a | 2007-04-26 03:27:58 +0000 | [diff] [blame] | 977 | } | 
 | 978 |  | 
 | 979 | /// WriteTypeSymbolTable - Emit a block for the specified type symtab. | 
 | 980 | static void WriteTypeSymbolTable(const TypeSymbolTable &TST, | 
 | 981 |                                  const ValueEnumerator &VE, | 
 | 982 |                                  BitstreamWriter &Stream) { | 
 | 983 |   if (TST.empty()) return; | 
 | 984 |    | 
 | 985 |   Stream.EnterSubblock(bitc::TYPE_SYMTAB_BLOCK_ID, 3); | 
 | 986 |    | 
| Chris Lattner | 7a263ea | 2007-05-05 00:47:19 +0000 | [diff] [blame] | 987 |   // 7-bit fixed width VST_CODE_ENTRY strings. | 
 | 988 |   BitCodeAbbrev *Abbv = new BitCodeAbbrev(); | 
 | 989 |   Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_ENTRY)); | 
 | 990 |   Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, | 
 | 991 |                             Log2_32_Ceil(VE.getTypes().size()+1))); | 
 | 992 |   Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); | 
 | 993 |   Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7)); | 
 | 994 |   unsigned V7Abbrev = Stream.EmitAbbrev(Abbv); | 
| Chris Lattner | 198f34a | 2007-04-26 03:27:58 +0000 | [diff] [blame] | 995 |    | 
 | 996 |   SmallVector<unsigned, 64> NameVals; | 
 | 997 |    | 
 | 998 |   for (TypeSymbolTable::const_iterator TI = TST.begin(), TE = TST.end();  | 
 | 999 |        TI != TE; ++TI) { | 
| Chris Lattner | 7a263ea | 2007-05-05 00:47:19 +0000 | [diff] [blame] | 1000 |     // TST_ENTRY: [typeid, namechar x N] | 
| Chris Lattner | 198f34a | 2007-04-26 03:27:58 +0000 | [diff] [blame] | 1001 |     NameVals.push_back(VE.getTypeID(TI->second)); | 
 | 1002 |      | 
 | 1003 |     const std::string &Str = TI->first; | 
| Chris Lattner | 7a263ea | 2007-05-05 00:47:19 +0000 | [diff] [blame] | 1004 |     bool is7Bit = true; | 
 | 1005 |     for (unsigned i = 0, e = Str.size(); i != e; ++i) { | 
 | 1006 |       NameVals.push_back((unsigned char)Str[i]); | 
 | 1007 |       if (Str[i] & 128) | 
 | 1008 |         is7Bit = false; | 
 | 1009 |     } | 
| Chris Lattner | 198f34a | 2007-04-26 03:27:58 +0000 | [diff] [blame] | 1010 |      | 
 | 1011 |     // Emit the finished record. | 
| Chris Lattner | 7a263ea | 2007-05-05 00:47:19 +0000 | [diff] [blame] | 1012 |     Stream.EmitRecord(bitc::VST_CODE_ENTRY, NameVals, is7Bit ? V7Abbrev : 0); | 
| Chris Lattner | 198f34a | 2007-04-26 03:27:58 +0000 | [diff] [blame] | 1013 |     NameVals.clear(); | 
 | 1014 |   } | 
 | 1015 |    | 
 | 1016 |   Stream.ExitBlock(); | 
 | 1017 | } | 
 | 1018 |  | 
| Chris Lattner | 07faafc | 2007-05-04 18:26:27 +0000 | [diff] [blame] | 1019 | // Emit blockinfo, which defines the standard abbreviations etc. | 
| Chris Lattner | a0f1ecc | 2007-05-05 07:36:14 +0000 | [diff] [blame] | 1020 | static void WriteBlockInfo(const ValueEnumerator &VE, BitstreamWriter &Stream) { | 
| Chris Lattner | 07faafc | 2007-05-04 18:26:27 +0000 | [diff] [blame] | 1021 |   // We only want to emit block info records for blocks that have multiple | 
 | 1022 |   // instances: CONSTANTS_BLOCK, FUNCTION_BLOCK and VALUE_SYMTAB_BLOCK.  Other | 
 | 1023 |   // blocks can defined their abbrevs inline. | 
| Chris Lattner | e17b658 | 2007-05-05 00:17:00 +0000 | [diff] [blame] | 1024 |   Stream.EnterBlockInfoBlock(2); | 
| Chris Lattner | 07faafc | 2007-05-04 18:26:27 +0000 | [diff] [blame] | 1025 |    | 
| Chris Lattner | e17b658 | 2007-05-05 00:17:00 +0000 | [diff] [blame] | 1026 |   { // 8-bit fixed-width VST_ENTRY/VST_BBENTRY strings. | 
 | 1027 |     BitCodeAbbrev *Abbv = new BitCodeAbbrev(); | 
 | 1028 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); | 
 | 1029 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); | 
 | 1030 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); | 
 | 1031 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8)); | 
 | 1032 |     if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID,  | 
 | 1033 |                                    Abbv) != VST_ENTRY_8_ABBREV) | 
 | 1034 |       assert(0 && "Unexpected abbrev ordering!"); | 
 | 1035 |   } | 
 | 1036 |    | 
 | 1037 |   { // 7-bit fixed width VST_ENTRY strings. | 
 | 1038 |     BitCodeAbbrev *Abbv = new BitCodeAbbrev(); | 
 | 1039 |     Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_ENTRY)); | 
 | 1040 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); | 
 | 1041 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); | 
 | 1042 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7)); | 
 | 1043 |     if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID, | 
 | 1044 |                                    Abbv) != VST_ENTRY_7_ABBREV) | 
 | 1045 |       assert(0 && "Unexpected abbrev ordering!"); | 
 | 1046 |   } | 
| Chris Lattner | ff294a4 | 2007-05-05 01:26:50 +0000 | [diff] [blame] | 1047 |   { // 6-bit char6 VST_ENTRY strings. | 
 | 1048 |     BitCodeAbbrev *Abbv = new BitCodeAbbrev(); | 
 | 1049 |     Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_ENTRY)); | 
 | 1050 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); | 
 | 1051 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); | 
 | 1052 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6)); | 
 | 1053 |     if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID, | 
 | 1054 |                                    Abbv) != VST_ENTRY_6_ABBREV) | 
 | 1055 |       assert(0 && "Unexpected abbrev ordering!"); | 
 | 1056 |   } | 
 | 1057 |   { // 6-bit char6 VST_BBENTRY strings. | 
| Chris Lattner | e17b658 | 2007-05-05 00:17:00 +0000 | [diff] [blame] | 1058 |     BitCodeAbbrev *Abbv = new BitCodeAbbrev(); | 
 | 1059 |     Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_BBENTRY)); | 
 | 1060 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); | 
 | 1061 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); | 
| Chris Lattner | ff294a4 | 2007-05-05 01:26:50 +0000 | [diff] [blame] | 1062 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6)); | 
| Chris Lattner | e17b658 | 2007-05-05 00:17:00 +0000 | [diff] [blame] | 1063 |     if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID, | 
| Chris Lattner | ff294a4 | 2007-05-05 01:26:50 +0000 | [diff] [blame] | 1064 |                                    Abbv) != VST_BBENTRY_6_ABBREV) | 
| Chris Lattner | e17b658 | 2007-05-05 00:17:00 +0000 | [diff] [blame] | 1065 |       assert(0 && "Unexpected abbrev ordering!"); | 
 | 1066 |   } | 
 | 1067 |    | 
| Chris Lattner | 440168b | 2007-05-05 07:44:49 +0000 | [diff] [blame] | 1068 |    | 
 | 1069 |    | 
| Chris Lattner | a0f1ecc | 2007-05-05 07:36:14 +0000 | [diff] [blame] | 1070 |   { // SETTYPE abbrev for CONSTANTS_BLOCK. | 
 | 1071 |     BitCodeAbbrev *Abbv = new BitCodeAbbrev(); | 
 | 1072 |     Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_SETTYPE)); | 
 | 1073 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, | 
 | 1074 |                               Log2_32_Ceil(VE.getTypes().size()+1))); | 
 | 1075 |     if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID, | 
 | 1076 |                                    Abbv) != CONSTANTS_SETTYPE_ABBREV) | 
 | 1077 |       assert(0 && "Unexpected abbrev ordering!"); | 
 | 1078 |   } | 
 | 1079 |    | 
 | 1080 |   { // INTEGER abbrev for CONSTANTS_BLOCK. | 
 | 1081 |     BitCodeAbbrev *Abbv = new BitCodeAbbrev(); | 
 | 1082 |     Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_INTEGER)); | 
 | 1083 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); | 
 | 1084 |     if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID, | 
 | 1085 |                                    Abbv) != CONSTANTS_INTEGER_ABBREV) | 
 | 1086 |       assert(0 && "Unexpected abbrev ordering!"); | 
 | 1087 |   } | 
 | 1088 |    | 
 | 1089 |   { // CE_CAST abbrev for CONSTANTS_BLOCK. | 
 | 1090 |     BitCodeAbbrev *Abbv = new BitCodeAbbrev(); | 
 | 1091 |     Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_CE_CAST)); | 
 | 1092 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4));  // cast opc | 
 | 1093 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,       // typeid | 
 | 1094 |                               Log2_32_Ceil(VE.getTypes().size()+1))); | 
 | 1095 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));    // value id | 
 | 1096 |  | 
 | 1097 |     if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID, | 
 | 1098 |                                    Abbv) != CONSTANTS_CE_CAST_Abbrev) | 
 | 1099 |       assert(0 && "Unexpected abbrev ordering!"); | 
 | 1100 |   } | 
 | 1101 |   { // NULL abbrev for CONSTANTS_BLOCK. | 
 | 1102 |     BitCodeAbbrev *Abbv = new BitCodeAbbrev(); | 
 | 1103 |     Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_NULL)); | 
 | 1104 |     if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID, | 
 | 1105 |                                    Abbv) != CONSTANTS_NULL_Abbrev) | 
 | 1106 |       assert(0 && "Unexpected abbrev ordering!"); | 
 | 1107 |   } | 
 | 1108 |    | 
| Chris Lattner | 440168b | 2007-05-05 07:44:49 +0000 | [diff] [blame] | 1109 |   // FIXME: This should only use space for first class types! | 
 | 1110 |   | 
 | 1111 |   { // INST_LOAD abbrev for FUNCTION_BLOCK. | 
 | 1112 |     BitCodeAbbrev *Abbv = new BitCodeAbbrev(); | 
 | 1113 |     Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_LOAD)); | 
| Chris Lattner | 440168b | 2007-05-05 07:44:49 +0000 | [diff] [blame] | 1114 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Ptr | 
 | 1115 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // Align | 
 | 1116 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // volatile | 
 | 1117 |     if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, | 
 | 1118 |                                    Abbv) != FUNCTION_INST_LOAD_ABBREV) | 
 | 1119 |       assert(0 && "Unexpected abbrev ordering!"); | 
 | 1120 |   } | 
| Chris Lattner | f9f2e83 | 2007-05-06 02:38:57 +0000 | [diff] [blame] | 1121 |   { // INST_BINOP abbrev for FUNCTION_BLOCK. | 
 | 1122 |     BitCodeAbbrev *Abbv = new BitCodeAbbrev(); | 
 | 1123 |     Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_BINOP)); | 
 | 1124 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LHS | 
 | 1125 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // RHS | 
 | 1126 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // opc | 
 | 1127 |     if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, | 
 | 1128 |                                    Abbv) != FUNCTION_INST_BINOP_ABBREV) | 
 | 1129 |       assert(0 && "Unexpected abbrev ordering!"); | 
 | 1130 |   } | 
 | 1131 |   { // INST_CAST abbrev for FUNCTION_BLOCK. | 
 | 1132 |     BitCodeAbbrev *Abbv = new BitCodeAbbrev(); | 
 | 1133 |     Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_CAST)); | 
 | 1134 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));    // OpVal | 
 | 1135 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,       // dest ty | 
 | 1136 |                               Log2_32_Ceil(VE.getTypes().size()+1))); | 
 | 1137 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4));  // opc | 
 | 1138 |     if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, | 
 | 1139 |                                    Abbv) != FUNCTION_INST_CAST_ABBREV) | 
 | 1140 |       assert(0 && "Unexpected abbrev ordering!"); | 
 | 1141 |   } | 
 | 1142 |    | 
| Chris Lattner | 94687ac | 2007-05-06 01:28:01 +0000 | [diff] [blame] | 1143 |   { // INST_RET abbrev for FUNCTION_BLOCK. | 
 | 1144 |     BitCodeAbbrev *Abbv = new BitCodeAbbrev(); | 
 | 1145 |     Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_RET)); | 
 | 1146 |     if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, | 
 | 1147 |                                    Abbv) != FUNCTION_INST_RET_VOID_ABBREV) | 
 | 1148 |       assert(0 && "Unexpected abbrev ordering!"); | 
 | 1149 |   } | 
 | 1150 |   { // INST_RET abbrev for FUNCTION_BLOCK. | 
 | 1151 |     BitCodeAbbrev *Abbv = new BitCodeAbbrev(); | 
 | 1152 |     Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_RET)); | 
 | 1153 |     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ValID | 
 | 1154 |     if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, | 
 | 1155 |                                    Abbv) != FUNCTION_INST_RET_VAL_ABBREV) | 
 | 1156 |       assert(0 && "Unexpected abbrev ordering!"); | 
 | 1157 |   } | 
 | 1158 |   { // INST_UNREACHABLE abbrev for FUNCTION_BLOCK. | 
 | 1159 |     BitCodeAbbrev *Abbv = new BitCodeAbbrev(); | 
 | 1160 |     Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_UNREACHABLE)); | 
 | 1161 |     if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, | 
 | 1162 |                                    Abbv) != FUNCTION_INST_UNREACHABLE_ABBREV) | 
 | 1163 |       assert(0 && "Unexpected abbrev ordering!"); | 
 | 1164 |   } | 
| Chris Lattner | 440168b | 2007-05-05 07:44:49 +0000 | [diff] [blame] | 1165 |    | 
| Chris Lattner | a0f1ecc | 2007-05-05 07:36:14 +0000 | [diff] [blame] | 1166 |   Stream.ExitBlock(); | 
 | 1167 | } | 
 | 1168 |  | 
 | 1169 |  | 
 | 1170 | /// WriteModule - Emit the specified module to the bitstream. | 
 | 1171 | static void WriteModule(const Module *M, BitstreamWriter &Stream) { | 
 | 1172 |   Stream.EnterSubblock(bitc::MODULE_BLOCK_ID, 3); | 
 | 1173 |    | 
 | 1174 |   // Emit the version number if it is non-zero. | 
 | 1175 |   if (CurVersion) { | 
 | 1176 |     SmallVector<unsigned, 1> Vals; | 
 | 1177 |     Vals.push_back(CurVersion); | 
 | 1178 |     Stream.EmitRecord(bitc::MODULE_CODE_VERSION, Vals); | 
 | 1179 |   } | 
 | 1180 |    | 
 | 1181 |   // Analyze the module, enumerating globals, functions, etc. | 
 | 1182 |   ValueEnumerator VE(M); | 
 | 1183 |  | 
 | 1184 |   // Emit blockinfo, which defines the standard abbreviations etc. | 
 | 1185 |   WriteBlockInfo(VE, Stream); | 
 | 1186 |    | 
 | 1187 |   // Emit information about parameter attributes. | 
 | 1188 |   WriteParamAttrTable(VE, Stream); | 
 | 1189 |    | 
 | 1190 |   // Emit information describing all of the types in the module. | 
 | 1191 |   WriteTypeTable(VE, Stream); | 
 | 1192 |    | 
 | 1193 |   // Emit top-level description of module, including target triple, inline asm, | 
 | 1194 |   // descriptors for global variables, and function prototype info. | 
 | 1195 |   WriteModuleInfo(M, VE, Stream); | 
 | 1196 |    | 
 | 1197 |   // Emit constants. | 
 | 1198 |   WriteModuleConstants(VE, Stream); | 
 | 1199 |    | 
 | 1200 |   // If we have any aggregate values in the value table, purge them - these can | 
 | 1201 |   // only be used to initialize global variables.  Doing so makes the value | 
 | 1202 |   // namespace smaller for code in functions. | 
 | 1203 |   int NumNonAggregates = VE.PurgeAggregateValues(); | 
 | 1204 |   if (NumNonAggregates != -1) { | 
 | 1205 |     SmallVector<unsigned, 1> Vals; | 
 | 1206 |     Vals.push_back(NumNonAggregates); | 
 | 1207 |     Stream.EmitRecord(bitc::MODULE_CODE_PURGEVALS, Vals); | 
 | 1208 |   } | 
 | 1209 |    | 
 | 1210 |   // Emit function bodies. | 
 | 1211 |   for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) | 
 | 1212 |     if (!I->isDeclaration()) | 
 | 1213 |       WriteFunction(*I, VE, Stream); | 
 | 1214 |    | 
 | 1215 |   // Emit the type symbol table information. | 
 | 1216 |   WriteTypeSymbolTable(M->getTypeSymbolTable(), VE, Stream); | 
 | 1217 |    | 
 | 1218 |   // Emit names for globals/functions etc. | 
 | 1219 |   WriteValueSymbolTable(M->getValueSymbolTable(), VE, Stream); | 
 | 1220 |    | 
| Chris Lattner | 07faafc | 2007-05-04 18:26:27 +0000 | [diff] [blame] | 1221 |   Stream.ExitBlock(); | 
 | 1222 | } | 
 | 1223 |  | 
 | 1224 |  | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 1225 | /// WriteBitcodeToFile - Write the specified module to the specified output | 
 | 1226 | /// stream. | 
 | 1227 | void llvm::WriteBitcodeToFile(const Module *M, std::ostream &Out) { | 
 | 1228 |   std::vector<unsigned char> Buffer; | 
 | 1229 |   BitstreamWriter Stream(Buffer); | 
 | 1230 |    | 
 | 1231 |   Buffer.reserve(256*1024); | 
 | 1232 |    | 
 | 1233 |   // Emit the file header. | 
 | 1234 |   Stream.Emit((unsigned)'B', 8); | 
 | 1235 |   Stream.Emit((unsigned)'C', 8); | 
 | 1236 |   Stream.Emit(0x0, 4); | 
 | 1237 |   Stream.Emit(0xC, 4); | 
 | 1238 |   Stream.Emit(0xE, 4); | 
 | 1239 |   Stream.Emit(0xD, 4); | 
 | 1240 |  | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 1241 |   // Emit the module. | 
 | 1242 |   WriteModule(M, Stream); | 
 | 1243 |    | 
 | 1244 |   // Write the generated bitstream to "Out". | 
 | 1245 |   Out.write((char*)&Buffer.front(), Buffer.size()); | 
| Chris Lattner | 4eab2e5 | 2007-05-06 19:19:23 +0000 | [diff] [blame] | 1246 |    | 
 | 1247 |   // Make sure it hits disk now. | 
 | 1248 |   Out.flush(); | 
| Chris Lattner | fd57cec | 2007-04-22 06:24:45 +0000 | [diff] [blame] | 1249 | } |