summaryrefslogtreecommitdiffstats
path: root/lib/Bitcode/Writer
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Bitcode/Writer')
-rw-r--r--lib/Bitcode/Writer/BitWriter.cpp9
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp210
-rw-r--r--lib/Bitcode/Writer/BitcodeWriterPass.cpp4
-rw-r--r--lib/Bitcode/Writer/ValueEnumerator.cpp64
-rw-r--r--lib/Bitcode/Writer/ValueEnumerator.h52
5 files changed, 210 insertions, 129 deletions
diff --git a/lib/Bitcode/Writer/BitWriter.cpp b/lib/Bitcode/Writer/BitWriter.cpp
index 4288422..9f51c35 100644
--- a/lib/Bitcode/Writer/BitWriter.cpp
+++ b/lib/Bitcode/Writer/BitWriter.cpp
@@ -17,12 +17,11 @@ using namespace llvm;
int LLVMWriteBitcodeToFile(LLVMModuleRef M, const char *Path) {
std::string ErrorInfo;
- raw_fd_ostream OS(Path, ErrorInfo,
- raw_fd_ostream::F_Binary);
-
+ raw_fd_ostream OS(Path, ErrorInfo, raw_fd_ostream::F_Binary);
+
if (!ErrorInfo.empty())
return -1;
-
+
WriteBitcodeToFile(unwrap(M), OS);
return 0;
}
@@ -30,7 +29,7 @@ int LLVMWriteBitcodeToFile(LLVMModuleRef M, const char *Path) {
int LLVMWriteBitcodeToFD(LLVMModuleRef M, int FD, int ShouldClose,
int Unbuffered) {
raw_fd_ostream OS(FD, ShouldClose, Unbuffered);
-
+
WriteBitcodeToFile(unwrap(M), OS);
return 0;
}
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp
index 60c657a..1b73f23 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -12,22 +12,22 @@
//===----------------------------------------------------------------------===//
#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;
@@ -61,7 +61,7 @@ enum {
FUNCTION_INST_RET_VOID_ABBREV,
FUNCTION_INST_RET_VAL_ABBREV,
FUNCTION_INST_UNREACHABLE_ABBREV,
-
+
// SwitchInst Magic
SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex
};
@@ -161,22 +161,66 @@ static void WriteStringRecord(unsigned Code, StringRef Str,
Stream.EmitRecord(Code, Vals, AbbrevToUse);
}
-// Emit information about parameter attributes.
+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(Attr.getKindAsEnum());
+ } else if (Attr.isAlignAttribute()) {
+ Record.push_back(1);
+ Record.push_back(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();
@@ -234,7 +278,7 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
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));
@@ -256,16 +300,16 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
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;
@@ -300,7 +344,7 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
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;
@@ -392,10 +436,6 @@ static unsigned getEncodedThreadLocalMode(const GlobalVariable *GV) {
// 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(),
@@ -494,10 +534,11 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
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;
}
@@ -553,6 +594,18 @@ static uint64_t GetOptimizationFlags(const Value *V) {
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;
@@ -658,7 +711,7 @@ static void WriteFunctionLocalMetadata(const Function &F,
}
WriteMDNode(N, VE, Stream, Record);
}
-
+
if (StartedMetadataBlock)
Stream.ExitBlock();
}
@@ -673,18 +726,18 @@ static void WriteMetadataAttachment(const Function &F,
// 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));
@@ -701,18 +754,18 @@ static void WriteModuleMetadataStore(const Module *M, BitstreamWriter &Stream) {
// 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();
}
@@ -743,10 +796,10 @@ static void EmitAPInt(SmallVectorImpl<uint64_t> &Vals,
// 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]);
@@ -881,12 +934,12 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
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();
@@ -1166,7 +1219,7 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
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)));
@@ -1179,36 +1232,36 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
// 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);
-
+ const 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();
+ for (SwitchInst::ConstCaseIt i = SI.case_begin(), e = SI.case_end();
i != e; ++i) {
- IntegersSubset& CaseRanges = i.getCaseValueEx();
+ const 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);
}
@@ -1217,9 +1270,9 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
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);
@@ -1227,9 +1280,9 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
}
Vals64.push_back(VE.getValueID(i.getCaseSuccessor()));
}
-
+
Stream.EmitRecord(Code, Vals64, AbbrevToUse);
-
+
// Also do expected action - clear external Vals collection:
Vals.clear();
return;
@@ -1243,7 +1296,7 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
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());
@@ -1502,21 +1555,21 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE,
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()) {
@@ -1527,14 +1580,14 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE,
} 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;
}
}
@@ -1709,7 +1762,7 @@ static void WriteBlockInfo(const ValueEnumerator &VE, BitstreamWriter &Stream) {
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.
@@ -1778,9 +1831,9 @@ static void WriteModuleUseLists(const Module *M, ValueEnumerator &VE,
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);
@@ -1821,6 +1874,9 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream) {
// 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);
@@ -1931,7 +1987,7 @@ static void EmitDarwinBCHeaderAndTrailer(SmallVectorImpl<char> &Buffer,
/// 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
diff --git a/lib/Bitcode/Writer/BitcodeWriterPass.cpp b/lib/Bitcode/Writer/BitcodeWriterPass.cpp
index 91e115c..e5e76e2 100644
--- a/lib/Bitcode/Writer/BitcodeWriterPass.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriterPass.cpp
@@ -22,9 +22,9 @@ namespace {
static char ID; // Pass identification, replacement for typeid
explicit WriteBitcodePass(raw_ostream &o)
: ModulePass(ID), OS(o) {}
-
+
const char *getPassName() const { return "Bitcode Writer"; }
-
+
bool runOnModule(Module &M) {
WriteBitcodeToFile(&M, OS);
return false;
diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp
index 1ed9004..8bac6da 100644
--- a/lib/Bitcode/Writer/ValueEnumerator.cpp
+++ b/lib/Bitcode/Writer/ValueEnumerator.cpp
@@ -12,20 +12,20 @@
//===----------------------------------------------------------------------===//
#include "ValueEnumerator.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Module.h"
-#include "llvm/ValueSymbolTable.h"
-#include "llvm/Instructions.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/ValueSymbolTable.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
using namespace llvm;
-static bool isIntegerValue(const std::pair<const Value*, unsigned> &V) {
- return V.first->getType()->isIntegerTy();
+static bool isIntOrIntVectorValue(const std::pair<const Value*, unsigned> &V) {
+ return V.first->getType()->isIntOrIntVectorTy();
}
/// ValueEnumerator - Enumerate module-level information.
@@ -60,7 +60,7 @@ ValueEnumerator::ValueEnumerator(const Module *M) {
I != E; ++I)
EnumerateValue(I->getAliasee());
- // Insert constants and metadata that are named at module level into the slot
+ // Insert constants and metadata that are named at module level into the slot
// pool so that the module symbol table can refer to them...
EnumerateValueSymbolTable(M->getValueSymbolTable());
EnumerateNamedMetadata(M);
@@ -95,7 +95,7 @@ ValueEnumerator::ValueEnumerator(const Module *M) {
I->getAllMetadataOtherThanDebugLoc(MDs);
for (unsigned i = 0, e = MDs.size(); i != e; ++i)
EnumerateMetadata(MDs[i].second);
-
+
if (!I->getDebugLoc().isUnknown()) {
MDNode *Scope, *IA;
I->getDebugLoc().getScopeAndInlinedAt(Scope, IA, I->getContext());
@@ -192,10 +192,11 @@ void ValueEnumerator::OptimizeConstants(unsigned CstStart, unsigned CstEnd) {
CstSortPredicate P(*this);
std::stable_sort(Values.begin()+CstStart, Values.begin()+CstEnd, P);
- // Ensure that integer constants are at the start of the constant pool. This
- // is important so that GEP structure indices come before gep constant exprs.
+ // Ensure that integer and vector of integer constants are at the start of the
+ // constant pool. This is important so that GEP structure indices come before
+ // gep constant exprs.
std::partition(Values.begin()+CstStart, Values.begin()+CstEnd,
- isIntegerValue);
+ isIntOrIntVectorValue);
// Rebuild the modified portion of ValueMap.
for (; CstStart != CstEnd; ++CstStart)
@@ -362,16 +363,16 @@ void ValueEnumerator::EnumerateType(Type *Ty) {
if (StructType *STy = dyn_cast<StructType>(Ty))
if (!STy->isLiteral())
*TypeID = ~0U;
-
+
// Enumerate all of the subtypes before we enumerate this type. This ensures
// that the type will be enumerated in an order that can be directly built.
for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end();
I != E; ++I)
EnumerateType(*I);
-
+
// Refresh the TypeID pointer in case the table rehashed.
TypeID = &TypeMap[Ty];
-
+
// Check to see if we got the pointer another way. This can happen when
// enumerating recursive types that hit the base case deeper than they start.
//
@@ -379,10 +380,10 @@ void ValueEnumerator::EnumerateType(Type *Ty) {
// then emit the definition now that all of its contents are available.
if (*TypeID && *TypeID != ~0U)
return;
-
+
// Add this type now that its contents are all happily enumerated.
Types.push_back(Ty);
-
+
*TypeID = Types.size();
}
@@ -390,7 +391,7 @@ void ValueEnumerator::EnumerateType(Type *Ty) {
// walk through it, enumerating the types of the constant.
void ValueEnumerator::EnumerateOperandType(const Value *V) {
EnumerateType(V->getType());
-
+
if (const Constant *C = dyn_cast<Constant>(V)) {
// If this constant is already enumerated, ignore it, we know its type must
// be enumerated.
@@ -400,11 +401,11 @@ void ValueEnumerator::EnumerateOperandType(const Value *V) {
// them.
for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) {
const Value *Op = C->getOperand(i);
-
+
// Don't enumerate basic blocks here, this happens as operands to
// blockaddress.
if (isa<BasicBlock>(Op)) continue;
-
+
EnumerateOperandType(Op);
}
@@ -417,14 +418,25 @@ void ValueEnumerator::EnumerateOperandType(const Value *V) {
EnumerateMetadata(V);
}
-void ValueEnumerator::EnumerateAttributes(const AttrListPtr &PAL) {
+void ValueEnumerator::EnumerateAttributes(AttributeSet PAL) {
if (PAL.isEmpty()) return; // null is always 0.
+
// Do a lookup.
- unsigned &Entry = AttributeMap[PAL.getRawPointer()];
+ unsigned &Entry = AttributeMap[PAL];
if (Entry == 0) {
// Never saw this before, add it.
- Attributes.push_back(PAL);
- Entry = Attributes.size();
+ Attribute.push_back(PAL);
+ Entry = Attribute.size();
+ }
+
+ // Do lookups for all attribute groups.
+ for (unsigned i = 0, e = PAL.getNumSlots(); i != e; ++i) {
+ AttributeSet AS = PAL.getSlotAttributes(i);
+ unsigned &Entry = AttributeGroupMap[AS];
+ if (Entry == 0) {
+ AttributeGroups.push_back(AS);
+ Entry = AttributeGroups.size();
+ }
}
}
@@ -481,7 +493,7 @@ void ValueEnumerator::incorporateFunction(const Function &F) {
if (N->isFunctionLocal() && N->getFunction())
FnLocalMDVector.push_back(N);
}
-
+
if (!I->getType()->isVoidTy())
EnumerateValue(I);
}
diff --git a/lib/Bitcode/Writer/ValueEnumerator.h b/lib/Bitcode/Writer/ValueEnumerator.h
index 75468e6..0af6164c 100644
--- a/lib/Bitcode/Writer/ValueEnumerator.h
+++ b/lib/Bitcode/Writer/ValueEnumerator.h
@@ -16,7 +16,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Attributes.h"
+#include "llvm/IR/Attributes.h"
#include <vector>
namespace llvm {
@@ -29,7 +29,7 @@ class Function;
class Module;
class MDNode;
class NamedMDNode;
-class AttrListPtr;
+class AttributeSet;
class ValueSymbolTable;
class MDSymbolTable;
class raw_ostream;
@@ -51,15 +51,19 @@ private:
ValueList MDValues;
SmallVector<const MDNode *, 8> FunctionLocalMDs;
ValueMapType MDValueMap;
-
- typedef DenseMap<void*, unsigned> AttributeMapType;
+
+ typedef DenseMap<AttributeSet, unsigned> AttributeGroupMapType;
+ AttributeGroupMapType AttributeGroupMap;
+ std::vector<AttributeSet> AttributeGroups;
+
+ typedef DenseMap<AttributeSet, unsigned> AttributeMapType;
AttributeMapType AttributeMap;
- std::vector<AttrListPtr> Attributes;
-
+ std::vector<AttributeSet> Attribute;
+
/// GlobalBasicBlockIDs - This map memoizes the basic block ID's referenced by
/// the "getGlobalBasicBlockID" method.
mutable DenseMap<const BasicBlock*, unsigned> GlobalBasicBlockIDs;
-
+
typedef DenseMap<const Instruction*, unsigned> InstructionMapType;
InstructionMapType InstructionMap;
unsigned InstructionCount;
@@ -67,7 +71,7 @@ private:
/// BasicBlocks - This contains all the basic blocks for the currently
/// incorporated function. Their reverse mapping is stored in ValueMap.
std::vector<const BasicBlock*> BasicBlocks;
-
+
/// When a function is incorporated, this is the size of the Values list
/// before incorporation.
unsigned NumModuleValues;
@@ -98,33 +102,43 @@ public:
unsigned getInstructionID(const Instruction *I) const;
void setInstructionID(const Instruction *I);
- unsigned getAttributeID(const AttrListPtr &PAL) const {
+ unsigned getAttributeID(AttributeSet PAL) const {
if (PAL.isEmpty()) return 0; // Null maps to zero.
- AttributeMapType::const_iterator I = AttributeMap.find(PAL.getRawPointer());
+ AttributeMapType::const_iterator I = AttributeMap.find(PAL);
assert(I != AttributeMap.end() && "Attribute not in ValueEnumerator!");
return I->second;
}
+ unsigned getAttributeGroupID(AttributeSet PAL) const {
+ if (PAL.isEmpty()) return 0; // Null maps to zero.
+ AttributeGroupMapType::const_iterator I = AttributeGroupMap.find(PAL);
+ assert(I != AttributeGroupMap.end() && "Attribute not in ValueEnumerator!");
+ return I->second;
+ }
+
/// getFunctionConstantRange - Return the range of values that corresponds to
/// function-local constants.
void getFunctionConstantRange(unsigned &Start, unsigned &End) const {
Start = FirstFuncConstantID;
End = FirstInstID;
}
-
+
const ValueList &getValues() const { return Values; }
const ValueList &getMDValues() const { return MDValues; }
- const SmallVector<const MDNode *, 8> &getFunctionLocalMDValues() const {
+ const SmallVector<const MDNode *, 8> &getFunctionLocalMDValues() const {
return FunctionLocalMDs;
}
const TypeList &getTypes() const { return Types; }
const std::vector<const BasicBlock*> &getBasicBlocks() const {
- return BasicBlocks;
+ return BasicBlocks;
+ }
+ const std::vector<AttributeSet> &getAttributes() const {
+ return Attribute;
}
- const std::vector<AttrListPtr> &getAttributes() const {
- return Attributes;
+ const std::vector<AttributeSet> &getAttributeGroups() const {
+ return AttributeGroups;
}
-
+
/// getGlobalBasicBlockID - This returns the function-specific ID for the
/// specified basic block. This is relatively expensive information, so it
/// should only be used by rare constructs such as address-of-label.
@@ -138,7 +152,7 @@ public:
private:
void OptimizeConstants(unsigned CstStart, unsigned CstEnd);
-
+
void EnumerateMDNodeOperands(const MDNode *N);
void EnumerateMetadata(const Value *MD);
void EnumerateFunctionLocalMetadata(const MDNode *N);
@@ -146,8 +160,8 @@ private:
void EnumerateValue(const Value *V);
void EnumerateType(Type *T);
void EnumerateOperandType(const Value *V);
- void EnumerateAttributes(const AttrListPtr &PAL);
-
+ void EnumerateAttributes(AttributeSet PAL);
+
void EnumerateValueSymbolTable(const ValueSymbolTable &ST);
void EnumerateNamedMetadata(const Module *M);
};
OpenPOWER on IntegriCloud