//===--- Bitcode/Writer/BitcodeWriter.cpp - Bitcode Writer ----------------===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Chris Lattner and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Bitcode writer implementation.
//
//===----------------------------------------------------------------------===//
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/Bitcode/BitstreamWriter.h"
#include "llvm/Bitcode/LLVMBitCodes.h"
#include "ValueEnumerator.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/ParameterAttributes.h"
#include "llvm/TypeSymbolTable.h"
#include "llvm/ValueSymbolTable.h"
#include "llvm/Support/MathExtras.h"
using namespace llvm;
static const unsigned CurVersion = 0;
static unsigned GetEncodedCastOpcode(unsigned Opcode) {
switch (Opcode) {
default: assert(0 && "Unknown cast instruction!");
case Instruction::Trunc : return bitc::CAST_TRUNC;
case Instruction::ZExt : return bitc::CAST_ZEXT;
case Instruction::SExt : return bitc::CAST_SEXT;
case Instruction::FPToUI : return bitc::CAST_FPTOUI;
case Instruction::FPToSI : return bitc::CAST_FPTOSI;
case Instruction::UIToFP : return bitc::CAST_UITOFP;
case Instruction::SIToFP : return bitc::CAST_SITOFP;
case Instruction::FPTrunc : return bitc::CAST_FPTRUNC;
case Instruction::FPExt : return bitc::CAST_FPEXT;
case Instruction::PtrToInt: return bitc::CAST_PTRTOINT;
case Instruction::IntToPtr: return bitc::CAST_INTTOPTR;
case Instruction::BitCast : return bitc::CAST_BITCAST;
}
}
static unsigned GetEncodedBinaryOpcode(unsigned Opcode) {
switch (Opcode) {
default: assert(0 && "Unknown binary instruction!");
case Instruction::Add: return bitc::BINOP_ADD;
case Instruction::Sub: return bitc::BINOP_SUB;
case Instruction::Mul: return bitc::BINOP_MUL;
case Instruction::UDiv: return bitc::BINOP_UDIV;
case Instruction::FDiv:
case Instruction::SDiv: return bitc::BINOP_SDIV;
case Instruction::URem: return bitc::BINOP_UREM;
case Instruction::FRem:
case Instruction::SRem: return bitc::BINOP_SREM;
case Instruction::Shl: return bitc::BINOP_SHL;
case Instruction::LShr: return bitc::BINOP_LSHR;
case Instruction::AShr: return bitc::BINOP_ASHR;
case Instruction::And: return bitc::BINOP_AND;
case Instruction::Or: return bitc::BINOP_OR;
case Instruction::Xor: return bitc::BINOP_XOR;
}
}
static void WriteStringRecord(unsigned Code, const std::string &Str,
unsigned AbbrevToUse, BitstreamWriter &Stream) {
SmallVector<unsigned, 64> Vals;
// Code: [strlen, strchar x N]
Vals.push_back(Str.size());
for (unsigned i = 0, e = Str.size(); i != e; ++i)
Vals.push_back(Str[i]);
// Emit the finished record.
Stream.EmitRecord(Code, Vals, AbbrevToUse);
}
// Emit information about parameter attributes.
static void WriteParamAttrTable(const ValueEnumerator &VE,
BitstreamWriter &Stream) {
const std::vector<const ParamAttrsList*> &Attrs = VE.getParamAttrs();
if (Attrs.empty()) return;
Stream.EnterSubblock(bitc::PARAMATTR_BLOCK_ID, 3);
SmallVector<uint64_t, 64> Record;
for (unsigned i = 0, e = Attrs.size(); i != e; ++i) {
const ParamAttrsList *A = Attrs[i];
for (unsigned op = 0, e = A->size(); op != e; ++op) {
Record.push_back(A->getParamIndex(op));
Record.push_back(A->getParamAttrsAtIndex(op));
}
Stream.EmitRecord(bitc::PARAMATTR_CODE_ENTRY, Record);
Record.clear();
}
Stream.ExitBlock();
}
/// WriteTypeTable - Write out the type table for a module.
static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
const ValueEnumerator::TypeList &TypeList = VE.getTypes();
Stream.EnterSubblock(bitc::TYPE_BLOCK_ID, 4 /*count from # abbrevs */);
SmallVector<uint64_t, 64> TypeVals;
// FIXME: Set up abbrevs now that we know the width of the type fields, etc.
// Emit an entry count so the reader can reserve space.
TypeVals.push_back(TypeList.