//===----------------------------------------------------------------------===//
#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/InlineAsm.h"
-#include "llvm/Instructions.h"
-#include "llvm/Module.h"
-#include "llvm/Operator.h"
-#include "llvm/ValueSymbolTable.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/Bitcode/BitstreamWriter.h"
+#include "llvm/Bitcode/LLVMBitCodes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Operator.h"
+#include "llvm/IR/ValueSymbolTable.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Program.h"
+#include "llvm/Support/raw_ostream.h"
#include <cctype>
#include <map>
using namespace llvm;
FUNCTION_INST_CAST_ABBREV,
FUNCTION_INST_RET_VOID_ABBREV,
FUNCTION_INST_RET_VAL_ABBREV,
- FUNCTION_INST_UNREACHABLE_ABBREV,
-
- // SwitchInst Magic
- SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex
+ FUNCTION_INST_UNREACHABLE_ABBREV
};
static unsigned GetEncodedCastOpcode(unsigned Opcode) {
case Instruction::PtrToInt: return bitc::CAST_PTRTOINT;
case Instruction::IntToPtr: return bitc::CAST_INTTOPTR;
case Instruction::BitCast : return bitc::CAST_BITCAST;
+ case Instruction::AddrSpaceCast: return bitc::CAST_ADDRSPACECAST;
}
}
Stream.EmitRecord(Code, Vals, AbbrevToUse);
}
-// Emit information about parameter attributes.
+static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
+ switch (Kind) {
+ case Attribute::Alignment:
+ return bitc::ATTR_KIND_ALIGNMENT;
+ case Attribute::AlwaysInline:
+ return bitc::ATTR_KIND_ALWAYS_INLINE;
+ case Attribute::Builtin:
+ return bitc::ATTR_KIND_BUILTIN;
+ case Attribute::ByVal:
+ return bitc::ATTR_KIND_BY_VAL;
+ case Attribute::Cold:
+ return bitc::ATTR_KIND_COLD;
+ case Attribute::InlineHint:
+ return bitc::ATTR_KIND_INLINE_HINT;
+ case Attribute::InReg:
+ return bitc::ATTR_KIND_IN_REG;
+ case Attribute::MinSize:
+ return bitc::ATTR_KIND_MIN_SIZE;
+ case Attribute::Naked:
+ return bitc::ATTR_KIND_NAKED;
+ case Attribute::Nest:
+ return bitc::ATTR_KIND_NEST;
+ case Attribute::NoAlias:
+ return bitc::ATTR_KIND_NO_ALIAS;
+ case Attribute::NoBuiltin:
+ return bitc::ATTR_KIND_NO_BUILTIN;
+ case Attribute::NoCapture:
+ return bitc::ATTR_KIND_NO_CAPTURE;
+ case Attribute::NoDuplicate:
+ return bitc::ATTR_KIND_NO_DUPLICATE;
+ case Attribute::NoImplicitFloat:
+ return bitc::ATTR_KIND_NO_IMPLICIT_FLOAT;
+ case Attribute::NoInline:
+ return bitc::ATTR_KIND_NO_INLINE;
+ case Attribute::NonLazyBind:
+ return bitc::ATTR_KIND_NON_LAZY_BIND;
+ case Attribute::NoRedZone:
+ return bitc::ATTR_KIND_NO_RED_ZONE;
+ case Attribute::NoReturn:
+ return bitc::ATTR_KIND_NO_RETURN;
+ case Attribute::NoUnwind:
+ return bitc::ATTR_KIND_NO_UNWIND;
+ case Attribute::OptimizeForSize:
+ return bitc::ATTR_KIND_OPTIMIZE_FOR_SIZE;
+ case Attribute::OptimizeNone:
+ return bitc::ATTR_KIND_OPTIMIZE_NONE;
+ case Attribute::ReadNone:
+ return bitc::ATTR_KIND_READ_NONE;
+ case Attribute::ReadOnly:
+ return bitc::ATTR_KIND_READ_ONLY;
+ case Attribute::Returned:
+ return bitc::ATTR_KIND_RETURNED;
+ case Attribute::ReturnsTwice:
+ return bitc::ATTR_KIND_RETURNS_TWICE;
+ case Attribute::SExt:
+ return bitc::ATTR_KIND_S_EXT;
+ case Attribute::StackAlignment:
+ return bitc::ATTR_KIND_STACK_ALIGNMENT;
+ case Attribute::StackProtect:
+ return bitc::ATTR_KIND_STACK_PROTECT;
+ case Attribute::StackProtectReq:
+ return bitc::ATTR_KIND_STACK_PROTECT_REQ;
+ case Attribute::StackProtectStrong:
+ return bitc::ATTR_KIND_STACK_PROTECT_STRONG;
+ case Attribute::StructRet:
+ return bitc::ATTR_KIND_STRUCT_RET;
+ case Attribute::SanitizeAddress:
+ return bitc::ATTR_KIND_SANITIZE_ADDRESS;
+ case Attribute::SanitizeThread:
+ return bitc::ATTR_KIND_SANITIZE_THREAD;
+ case Attribute::SanitizeMemory:
+ return bitc::ATTR_KIND_SANITIZE_MEMORY;
+ case Attribute::UWTable:
+ return bitc::ATTR_KIND_UW_TABLE;
+ case Attribute::ZExt:
+ return bitc::ATTR_KIND_Z_EXT;
+ case Attribute::EndAttrKinds:
+ llvm_unreachable("Can not encode end-attribute kinds marker.");
+ case Attribute::None:
+ llvm_unreachable("Can not encode none-attribute.");
+ }
+
+ llvm_unreachable("Trying to encode unknown attribute");
+}
+
+static void WriteAttributeGroupTable(const ValueEnumerator &VE,
+ BitstreamWriter &Stream) {
+ const std::vector<AttributeSet> &AttrGrps = VE.getAttributeGroups();
+ if (AttrGrps.empty()) return;
+
+ Stream.EnterSubblock(bitc::PARAMATTR_GROUP_BLOCK_ID, 3);
+
+ SmallVector<uint64_t, 64> Record;
+ for (unsigned i = 0, e = AttrGrps.size(); i != e; ++i) {
+ AttributeSet AS = AttrGrps[i];
+ for (unsigned i = 0, e = AS.getNumSlots(); i != e; ++i) {
+ AttributeSet A = AS.getSlotAttributes(i);
+
+ Record.push_back(VE.getAttributeGroupID(A));
+ Record.push_back(AS.getSlotIndex(i));
+
+ for (AttributeSet::iterator I = AS.begin(0), E = AS.end(0);
+ I != E; ++I) {
+ Attribute Attr = *I;
+ if (Attr.isEnumAttribute()) {
+ Record.push_back(0);
+ Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));
+ } else if (Attr.isAlignAttribute()) {
+ Record.push_back(1);
+ Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));
+ Record.push_back(Attr.getValueAsInt());
+ } else {
+ StringRef Kind = Attr.getKindAsString();
+ StringRef Val = Attr.getValueAsString();
+
+ Record.push_back(Val.empty() ? 3 : 4);
+ Record.append(Kind.begin(), Kind.end());
+ Record.push_back(0);
+ if (!Val.empty()) {
+ Record.append(Val.begin(), Val.end());
+ Record.push_back(0);
+ }
+ }
+ }
+
+ Stream.EmitRecord(bitc::PARAMATTR_GRP_CODE_ENTRY, Record);
+ Record.clear();
+ }
+ }
+
+ Stream.ExitBlock();
+}
+
static void WriteAttributeTable(const ValueEnumerator &VE,
BitstreamWriter &Stream) {
- const std::vector<AttrListPtr> &Attrs = VE.getAttributes();
+ const std::vector<AttributeSet> &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 AttrListPtr &A = Attrs[i];
- for (unsigned i = 0, e = A.getNumSlots(); i != e; ++i) {
- const AttributeWithIndex &PAWI = A.getSlot(i);
- Record.push_back(PAWI.Index);
- Record.push_back(Attributes::encodeLLVMAttributesForBitcode(PAWI.Attrs));
- }
+ const AttributeSet &A = Attrs[i];
+ for (unsigned i = 0, e = A.getNumSlots(); i != e; ++i)
+ Record.push_back(VE.getAttributeGroupID(A.getSlotAttributes(i)));
Stream.EmitRecord(bitc::PARAMATTR_CODE_ENTRY, Record);
Record.clear();
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
unsigned StructNamedAbbrev = Stream.EmitAbbrev(Abbv);
-
+
// Abbrev for TYPE_CODE_ARRAY.
Abbv = new BitCodeAbbrev();
Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_ARRAY));
unsigned Code = 0;
switch (T->getTypeID()) {
- default: llvm_unreachable("Unknown type!");
- case Type::VoidTyID: Code = bitc::TYPE_CODE_VOID; break;
- case Type::HalfTyID: Code = bitc::TYPE_CODE_HALF; break;
- case Type::FloatTyID: Code = bitc::TYPE_CODE_FLOAT; break;
- case Type::DoubleTyID: Code = bitc::TYPE_CODE_DOUBLE; break;
- case Type::X86_FP80TyID: Code = bitc::TYPE_CODE_X86_FP80; break;
- case Type::FP128TyID: Code = bitc::TYPE_CODE_FP128; break;
+ case Type::VoidTyID: Code = bitc::TYPE_CODE_VOID; break;
+ case Type::HalfTyID: Code = bitc::TYPE_CODE_HALF; break;
+ case Type::FloatTyID: Code = bitc::TYPE_CODE_FLOAT; break;
+ case Type::DoubleTyID: Code = bitc::TYPE_CODE_DOUBLE; break;
+ case Type::X86_FP80TyID: Code = bitc::TYPE_CODE_X86_FP80; break;
+ case Type::FP128TyID: Code = bitc::TYPE_CODE_FP128; break;
case Type::PPC_FP128TyID: Code = bitc::TYPE_CODE_PPC_FP128; break;
- case Type::LabelTyID: Code = bitc::TYPE_CODE_LABEL; break;
- case Type::MetadataTyID: Code = bitc::TYPE_CODE_METADATA; break;
- case Type::X86_MMXTyID: Code = bitc::TYPE_CODE_X86_MMX; break;
+ case Type::LabelTyID: Code = bitc::TYPE_CODE_LABEL; break;
+ case Type::MetadataTyID: Code = bitc::TYPE_CODE_METADATA; break;
+ case Type::X86_MMXTyID: Code = bitc::TYPE_CODE_X86_MMX; break;
case Type::IntegerTyID:
// INTEGER: [width]
Code = bitc::TYPE_CODE_INTEGER;
for (StructType::element_iterator I = ST->element_begin(),
E = ST->element_end(); I != E; ++I)
TypeVals.push_back(VE.getTypeID(*I));
-
+
if (ST->isLiteral()) {
Code = bitc::TYPE_CODE_STRUCT_ANON;
AbbrevToUse = StructAnonAbbrev;
case GlobalValue::AvailableExternallyLinkage: return 12;
case GlobalValue::LinkerPrivateLinkage: return 13;
case GlobalValue::LinkerPrivateWeakLinkage: return 14;
- case GlobalValue::LinkOnceODRAutoHideLinkage: return 15;
}
llvm_unreachable("Invalid linkage");
}
// descriptors for global variables, and function prototype info.
static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
BitstreamWriter &Stream) {
- // Emit the list of dependent libraries for the Module.
- for (Module::lib_iterator I = M->lib_begin(), E = M->lib_end(); I != E; ++I)
- WriteStringRecord(bitc::MODULE_CODE_DEPLIB, *I, 0/*TODO*/, Stream);
-
// Emit various pieces of data attached to a module.
if (!M->getTargetTriple().empty())
WriteStringRecord(bitc::MODULE_CODE_TRIPLE, M->getTargetTriple(),
// GLOBALVAR: [type, isconst, initid,
// linkage, alignment, section, visibility, threadlocal,
- // unnamed_addr]
+ // unnamed_addr, externally_initialized]
Vals.push_back(VE.getTypeID(GV->getType()));
Vals.push_back(GV->isConstant());
Vals.push_back(GV->isDeclaration() ? 0 :
Vals.push_back(GV->hasSection() ? SectionMap[GV->getSection()] : 0);
if (GV->isThreadLocal() ||
GV->getVisibility() != GlobalValue::DefaultVisibility ||
- GV->hasUnnamedAddr()) {
+ GV->hasUnnamedAddr() || GV->isExternallyInitialized()) {
Vals.push_back(getEncodedVisibility(GV));
Vals.push_back(getEncodedThreadLocalMode(GV));
Vals.push_back(GV->hasUnnamedAddr());
+ Vals.push_back(GV->isExternallyInitialized());
} else {
AbbrevToUse = SimpleGVarAbbrev;
}
// Emit the function proto information.
for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) {
// FUNCTION: [type, callingconv, isproto, linkage, paramattrs, alignment,
- // section, visibility, gc, unnamed_addr]
+ // section, visibility, gc, unnamed_addr, prefix]
Vals.push_back(VE.getTypeID(F->getType()));
Vals.push_back(F->getCallingConv());
Vals.push_back(F->isDeclaration());
Vals.push_back(getEncodedVisibility(F));
Vals.push_back(F->hasGC() ? GCMap[F->getGC()] : 0);
Vals.push_back(F->hasUnnamedAddr());
+ Vals.push_back(F->hasPrefixData() ? (VE.getValueID(F->getPrefixData()) + 1)
+ : 0);
unsigned AbbrevToUse = 0;
Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse);
dyn_cast<PossiblyExactOperator>(V)) {
if (PEO->isExact())
Flags |= 1 << bitc::PEO_EXACT;
+ } else if (const FPMathOperator *FPMO =
+ dyn_cast<const FPMathOperator>(V)) {
+ if (FPMO->hasUnsafeAlgebra())
+ Flags |= FastMathFlags::UnsafeAlgebra;
+ if (FPMO->hasNoNaNs())
+ Flags |= FastMathFlags::NoNaNs;
+ if (FPMO->hasNoInfs())
+ Flags |= FastMathFlags::NoInfs;
+ if (FPMO->hasNoSignedZeros())
+ Flags |= FastMathFlags::NoSignedZeros;
+ if (FPMO->hasAllowReciprocal())
+ Flags |= FastMathFlags::AllowReciprocal;
}
return Flags;
static void WriteMDNode(const MDNode *N,
const ValueEnumerator &VE,
BitstreamWriter &Stream,
- SmallVector<uint64_t, 64> &Record) {
+ SmallVectorImpl<uint64_t> &Record) {
for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
if (N->getOperand(i)) {
Record.push_back(VE.getTypeID(N->getOperand(i)->getType()));
BitstreamWriter &Stream) {
bool StartedMetadataBlock = false;
SmallVector<uint64_t, 64> Record;
- const SmallVector<const MDNode *, 8> &Vals = VE.getFunctionLocalMDValues();
+ const SmallVectorImpl<const MDNode *> &Vals = VE.getFunctionLocalMDValues();
for (unsigned i = 0, e = Vals.size(); i != e; ++i)
if (const MDNode *N = Vals[i])
if (N->isFunctionLocal() && N->getFunction() == &F) {
}
WriteMDNode(N, VE, Stream, Record);
}
-
+
if (StartedMetadataBlock)
Stream.ExitBlock();
}
// Write metadata attachments
// METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]]
SmallVector<std::pair<unsigned, MDNode*>, 4> MDs;
-
+
for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
I != E; ++I) {
MDs.clear();
I->getAllMetadataOtherThanDebugLoc(MDs);
-
+
// If no metadata, ignore instruction.
if (MDs.empty()) continue;
Record.push_back(VE.getInstructionID(I));
-
+
for (unsigned i = 0, e = MDs.size(); i != e; ++i) {
Record.push_back(MDs[i].first);
Record.push_back(VE.getValueID(MDs[i].second));
// Write metadata kinds
// METADATA_KIND - [n x [id, name]]
- SmallVector<StringRef, 4> Names;
+ SmallVector<StringRef, 8> Names;
M->getMDKindNames(Names);
-
+
if (Names.empty()) return;
Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
-
+
for (unsigned MDKindID = 0, e = Names.size(); MDKindID != e; ++MDKindID) {
Record.push_back(MDKindID);
StringRef KName = Names[MDKindID];
Record.append(KName.begin(), KName.end());
-
+
Stream.EmitRecord(bitc::METADATA_KIND, Record, 0);
Record.clear();
}
Vals.push_back((-V << 1) | 1);
}
-static void EmitAPInt(SmallVectorImpl<uint64_t> &Vals,
- unsigned &Code, unsigned &AbbrevToUse, const APInt &Val,
- bool EmitSizeForWideNumbers = false
- ) {
- if (Val.getBitWidth() <= 64) {
- uint64_t V = Val.getSExtValue();
- emitSignedInt64(Vals, V);
- Code = bitc::CST_CODE_INTEGER;
- AbbrevToUse = CONSTANTS_INTEGER_ABBREV;
- } else {
- // Wide integers, > 64 bits in size.
- // We have an arbitrary precision integer value to write whose
- // bit width is > 64. However, in canonical unsigned integer
- // format it is likely that the high bits are going to be zero.
- // So, we only write the number of active words.
- unsigned NWords = Val.getActiveWords();
-
- if (EmitSizeForWideNumbers)
- Vals.push_back(NWords);
-
- const uint64_t *RawWords = Val.getRawData();
- for (unsigned i = 0; i != NWords; ++i) {
- emitSignedInt64(Vals, RawWords[i]);
- }
- Code = bitc::CST_CODE_WIDE_INTEGER;
- }
-}
-
static void WriteConstants(unsigned FirstVal, unsigned LastVal,
const ValueEnumerator &VE,
BitstreamWriter &Stream, bool isGlobal) {
} else if (isa<UndefValue>(C)) {
Code = bitc::CST_CODE_UNDEF;
} else if (const ConstantInt *IV = dyn_cast<ConstantInt>(C)) {
- EmitAPInt(Record, Code, AbbrevToUse, IV->getValue());
+ if (IV->getBitWidth() <= 64) {
+ uint64_t V = IV->getSExtValue();
+ emitSignedInt64(Record, V);
+ Code = bitc::CST_CODE_INTEGER;
+ AbbrevToUse = CONSTANTS_INTEGER_ABBREV;
+ } else { // Wide integers, > 64 bits in size.
+ // We have an arbitrary precision integer value to write whose
+ // bit width is > 64. However, in canonical unsigned integer
+ // format it is likely that the high bits are going to be zero.
+ // So, we only write the number of active words.
+ unsigned NWords = IV->getValue().getActiveWords();
+ const uint64_t *RawWords = IV->getValue().getRawData();
+ for (unsigned i = 0; i != NWords; ++i) {
+ emitSignedInt64(Record, RawWords[i]);
+ }
+ Code = bitc::CST_CODE_WIDE_INTEGER;
+ }
} else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
Code = bitc::CST_CODE_FLOAT;
Type *Ty = CFP->getType();
if (isCStrChar6)
isCStrChar6 = BitCodeAbbrevOp::isChar6(V);
}
-
+
if (isCStrChar6)
AbbrevToUse = CString6Abbrev;
else if (isCStr7)
AbbrevToUse = CString7Abbrev;
- } else if (const ConstantDataSequential *CDS =
+ } else if (const ConstantDataSequential *CDS =
dyn_cast<ConstantDataSequential>(C)) {
Code = bitc::CST_CODE_DATA;
Type *EltTy = CDS->getType()->getElementType();
/// instruction ID, then it is a forward reference, and it also includes the
/// type ID. The value ID that is written is encoded relative to the InstID.
static bool PushValueAndType(const Value *V, unsigned InstID,
- SmallVector<unsigned, 64> &Vals,
+ SmallVectorImpl<unsigned> &Vals,
ValueEnumerator &VE) {
unsigned ValID = VE.getValueID(V);
// Make encoding relative to the InstID.
/// pushValue - Like PushValueAndType, but where the type of the value is
/// omitted (perhaps it was already encoded in an earlier operand).
static void pushValue(const Value *V, unsigned InstID,
- SmallVector<unsigned, 64> &Vals,
+ SmallVectorImpl<unsigned> &Vals,
ValueEnumerator &VE) {
unsigned ValID = VE.getValueID(V);
Vals.push_back(InstID - ValID);
}
-static void pushValue64(const Value *V, unsigned InstID,
- SmallVector<uint64_t, 128> &Vals,
- ValueEnumerator &VE) {
- uint64_t ValID = VE.getValueID(V);
- Vals.push_back(InstID - ValID);
-}
-
static void pushValueSigned(const Value *V, unsigned InstID,
- SmallVector<uint64_t, 128> &Vals,
+ SmallVectorImpl<uint64_t> &Vals,
ValueEnumerator &VE) {
unsigned ValID = VE.getValueID(V);
int64_t diff = ((int32_t)InstID - (int32_t)ValID);
/// WriteInstruction - Emit an instruction to the specified stream.
static void WriteInstruction(const Instruction &I, unsigned InstID,
ValueEnumerator &VE, BitstreamWriter &Stream,
- SmallVector<unsigned, 64> &Vals) {
+ SmallVectorImpl<unsigned> &Vals) {
unsigned Code = 0;
unsigned AbbrevToUse = 0;
VE.setInstructionID(&I);
case Instruction::Br:
{
Code = bitc::FUNC_CODE_INST_BR;
- BranchInst &II = cast<BranchInst>(I);
+ const BranchInst &II = cast<BranchInst>(I);
Vals.push_back(VE.getValueID(II.getSuccessor(0)));
if (II.isConditional()) {
Vals.push_back(VE.getValueID(II.getSuccessor(1)));
break;
case Instruction::Switch:
{
- // Redefine Vals, since here we need to use 64 bit values
- // explicitly to store large APInt numbers.
- SmallVector<uint64_t, 128> Vals64;
-
Code = bitc::FUNC_CODE_INST_SWITCH;
- SwitchInst &SI = cast<SwitchInst>(I);
-
- uint32_t SwitchRecordHeader = SI.hash() | (SWITCH_INST_MAGIC << 16);
- Vals64.push_back(SwitchRecordHeader);
-
- Vals64.push_back(VE.getTypeID(SI.getCondition()->getType()));
- pushValue64(SI.getCondition(), InstID, Vals64, VE);
- Vals64.push_back(VE.getValueID(SI.getDefaultDest()));
- Vals64.push_back(SI.getNumCases());
- for (SwitchInst::CaseIt i = SI.case_begin(), e = SI.case_end();
+ const SwitchInst &SI = cast<SwitchInst>(I);
+ Vals.push_back(VE.getTypeID(SI.getCondition()->getType()));
+ pushValue(SI.getCondition(), InstID, Vals, VE);
+ Vals.push_back(VE.getValueID(SI.getDefaultDest()));
+ for (SwitchInst::ConstCaseIt i = SI.case_begin(), e = SI.case_end();
i != e; ++i) {
- IntegersSubset& CaseRanges = i.getCaseValueEx();
- unsigned Code, Abbrev; // will unused.
-
- if (CaseRanges.isSingleNumber()) {
- Vals64.push_back(1/*NumItems = 1*/);
- Vals64.push_back(true/*IsSingleNumber = true*/);
- EmitAPInt(Vals64, Code, Abbrev, CaseRanges.getSingleNumber(0), true);
- } else {
-
- Vals64.push_back(CaseRanges.getNumItems());
-
- if (CaseRanges.isSingleNumbersOnly()) {
- for (unsigned ri = 0, rn = CaseRanges.getNumItems();
- ri != rn; ++ri) {
-
- Vals64.push_back(true/*IsSingleNumber = true*/);
-
- EmitAPInt(Vals64, Code, Abbrev,
- CaseRanges.getSingleNumber(ri), true);
- }
- } else
- for (unsigned ri = 0, rn = CaseRanges.getNumItems();
- ri != rn; ++ri) {
- IntegersSubset::Range r = CaseRanges.getItem(ri);
- bool IsSingleNumber = CaseRanges.isSingleNumber(ri);
-
- Vals64.push_back(IsSingleNumber);
-
- EmitAPInt(Vals64, Code, Abbrev, r.getLow(), true);
- if (!IsSingleNumber)
- EmitAPInt(Vals64, Code, Abbrev, r.getHigh(), true);
- }
- }
- Vals64.push_back(VE.getValueID(i.getCaseSuccessor()));
+ Vals.push_back(VE.getValueID(i.getCaseValue()));
+ Vals.push_back(VE.getValueID(i.getCaseSuccessor()));
}
-
- Stream.EmitRecord(Code, Vals64, AbbrevToUse);
-
- // Also do expected action - clear external Vals collection:
- Vals.clear();
- return;
}
break;
case Instruction::IndirectBr:
for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i)
Vals.push_back(VE.getValueID(I.getOperand(i)));
break;
-
+
case Instruction::Invoke: {
const InvokeInst *II = cast<InvokeInst>(&I);
const Value *Callee(II->getCalledValue());
unsigned InstID = CstEnd;
bool NeedsMetadataAttachment = false;
-
+
DebugLoc LastDL;
-
+
// Finally, emit all the instructions, in order.
for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
I != E; ++I) {
WriteInstruction(*I, InstID, VE, Stream, Vals);
-
+
if (!I->getType()->isVoidTy())
++InstID;
-
+
// If the instruction has metadata, write a metadata attachment later.
NeedsMetadataAttachment |= I->hasMetadataOtherThanDebugLoc();
-
+
// If the instruction has a debug location, emit it.
DebugLoc DL = I->getDebugLoc();
if (DL.isUnknown()) {
} else {
MDNode *Scope, *IA;
DL.getScopeAndInlinedAt(Scope, IA, I->getContext());
-
+
Vals.push_back(DL.getLine());
Vals.push_back(DL.getCol());
Vals.push_back(Scope ? VE.getValueID(Scope)+1 : 0);
Vals.push_back(IA ? VE.getValueID(IA)+1 : 0);
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals);
Vals.clear();
-
+
LastDL = DL;
}
}
static void WriteBlockInfo(const ValueEnumerator &VE, BitstreamWriter &Stream) {
// We only want to emit block info records for blocks that have multiple
// instances: CONSTANTS_BLOCK, FUNCTION_BLOCK and VALUE_SYMTAB_BLOCK.
- // Other blocks can defined their abbrevs inline.
+ // Other blocks can define their abbrevs inline.
Stream.EnterBlockInfoBlock(2);
{ // 8-bit fixed-width VST_ENTRY/VST_BBENTRY strings.
Stream.ExitBlock();
}
-// Sort the Users based on the order in which the reader parses the bitcode
+// Sort the Users based on the order in which the reader parses the bitcode
// file.
static bool bitcodereader_order(const User *lhs, const User *rhs) {
// TODO: Implement.
for (Module::const_global_iterator I = M->global_begin(), E = M->global_end();
I != E; ++I)
I->removeDeadConstantUsers();
-
+
// Write the global variables.
- for (Module::const_global_iterator GI = M->global_begin(),
+ for (Module::const_global_iterator GI = M->global_begin(),
GE = M->global_end(); GI != GE; ++GI) {
WriteUseList(GI, VE, Stream);
WriteUseList(FI, VE, Stream);
if (!FI->isDeclaration())
WriteFunctionUseList(FI, VE, Stream);
+ if (FI->hasPrefixData())
+ WriteUseList(FI->getPrefixData(), VE, Stream);
}
// Write the aliases.
// Emit blockinfo, which defines the standard abbreviations etc.
WriteBlockInfo(VE, Stream);
+ // Emit information about attribute groups.
+ WriteAttributeGroupTable(VE, Stream);
+
// Emit information about parameter attributes.
WriteAttributeTable(VE, Stream);
/// WriteBitcodeToFile - Write the specified module to the specified output
/// stream.
void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out) {
- SmallVector<char, 1024> Buffer;
+ SmallVector<char, 0> Buffer;
Buffer.reserve(256*1024);
// If this is darwin or another generic macho target, reserve space for the