aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2015-04-01 22:08:55 +0000
committerAndroid Git Automerger <android-git-automerger@android.com>2015-04-01 22:08:55 +0000
commitfddf9027a0fe94cbe1419832adf1ca6e26fd702c (patch)
treeabc35f5fca07f36629ed8f9dd3ef65c96142bc84
parentde3bda48ad92b0f9729719dddf5a58cd26bef5c5 (diff)
parentb672a467222657528b4ec9943d780e9c65ce5f86 (diff)
downloadandroid_frameworks_compile_slang-fddf9027a0fe94cbe1419832adf1ca6e26fd702c.tar.gz
android_frameworks_compile_slang-fddf9027a0fe94cbe1419832adf1ca6e26fd702c.tar.bz2
android_frameworks_compile_slang-fddf9027a0fe94cbe1419832adf1ca6e26fd702c.zip
am b672a467: am b518fbbb: am 2133b9d5: Merge "Update slang for LLVM rebase to r230699."
* commit 'b672a467222657528b4ec9943d780e9c65ce5f86': Update slang for LLVM rebase to r230699.
-rw-r--r--BitWriter_2_9/BitcodeWriter.cpp433
-rw-r--r--BitWriter_2_9/ValueEnumerator.cpp283
-rw-r--r--BitWriter_2_9/ValueEnumerator.h44
-rw-r--r--BitWriter_2_9_func/BitcodeWriter.cpp392
-rw-r--r--BitWriter_2_9_func/ValueEnumerator.cpp283
-rw-r--r--BitWriter_2_9_func/ValueEnumerator.h44
-rw-r--r--BitWriter_3_2/BitcodeWriter.cpp577
-rw-r--r--BitWriter_3_2/ValueEnumerator.cpp283
-rw-r--r--BitWriter_3_2/ValueEnumerator.h47
-rw-r--r--slang_backend.cpp15
-rw-r--r--slang_backend.h8
-rw-r--r--slang_rs_backend.cpp12
-rw-r--r--slang_rs_context.cpp4
13 files changed, 1278 insertions, 1147 deletions
diff --git a/BitWriter_2_9/BitcodeWriter.cpp b/BitWriter_2_9/BitcodeWriter.cpp
index 729b779..0e23213 100644
--- a/BitWriter_2_9/BitcodeWriter.cpp
+++ b/BitWriter_2_9/BitcodeWriter.cpp
@@ -18,6 +18,7 @@
#include "llvm/Bitcode/BitstreamWriter.h"
#include "llvm/Bitcode/LLVMBitCodes.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
@@ -74,7 +75,6 @@ enum {
FUNCTION_INST_UNREACHABLE_ABBREV
};
-
static unsigned GetEncodedCastOpcode(unsigned Opcode) {
switch (Opcode) {
default: llvm_unreachable("Unknown cast instruction!");
@@ -205,26 +205,6 @@ static void WriteTypeSymbolTable(const llvm_2_9::ValueEnumerator &VE,
}
}
-#if 0
- for (TypeSymbolTable::const_iterator TI = TST.begin(), TE = TST.end();
- TI != TE; ++TI) {
- // TST_ENTRY: [typeid, namechar x N]
- NameVals.push_back(VE.getTypeID(TI->second));
-
- const std::string &Str = TI->first;
- bool is7Bit = true;
- for (unsigned i = 0, e = Str.size(); i != e; ++i) {
- NameVals.push_back((unsigned char)Str[i]);
- if (Str[i] & 128)
- is7Bit = false;
- }
-
- // Emit the finished record.
- Stream.EmitRecord(bitc::VST_CODE_ENTRY, NameVals, is7Bit ? V7Abbrev : 0);
- NameVals.clear();
- }
-#endif
-
Stream.ExitBlock();
}
@@ -236,11 +216,12 @@ static void WriteTypeTable(const llvm_2_9::ValueEnumerator &VE,
Stream.EnterSubblock(TYPE_BLOCK_ID_OLD_3_0, 4 /*count from # abbrevs */);
SmallVector<uint64_t, 64> TypeVals;
+ uint64_t NumBits = Log2_32_Ceil(VE.getTypes().size()+1);
+
// Abbrev for TYPE_CODE_POINTER.
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_POINTER));
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
- Log2_32_Ceil(VE.getTypes().size()+1)));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
Abbv->Add(BitCodeAbbrevOp(0)); // Addrspace = 0
unsigned PtrAbbrev = Stream.EmitAbbrev(Abbv);
@@ -250,52 +231,24 @@ static void WriteTypeTable(const llvm_2_9::ValueEnumerator &VE,
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isvararg
Abbv->Add(BitCodeAbbrevOp(0)); // FIXME: DEAD value, remove in LLVM 3.0
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
- Log2_32_Ceil(VE.getTypes().size()+1)));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
unsigned FunctionAbbrev = Stream.EmitAbbrev(Abbv);
-#if 0
- // Abbrev for TYPE_CODE_STRUCT_ANON.
- Abbv = new BitCodeAbbrev();
- Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_ANON));
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ispacked
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
- Log2_32_Ceil(VE.getTypes().size()+1)));
- unsigned StructAnonAbbrev = Stream.EmitAbbrev(Abbv);
-
- // Abbrev for TYPE_CODE_STRUCT_NAME.
- Abbv = new BitCodeAbbrev();
- Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_NAME));
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6));
- unsigned StructNameAbbrev = Stream.EmitAbbrev(Abbv);
-
- // Abbrev for TYPE_CODE_STRUCT_NAMED.
- Abbv = new BitCodeAbbrev();
- Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_NAMED));
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ispacked
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
- Log2_32_Ceil(VE.getTypes().size()+1)));
- unsigned StructNamedAbbrev = Stream.EmitAbbrev(Abbv);
-#endif
// Abbrev for TYPE_CODE_STRUCT.
Abbv = new BitCodeAbbrev();
Abbv->Add(BitCodeAbbrevOp(TYPE_CODE_STRUCT_OLD_3_0));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ispacked
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
- Log2_32_Ceil(VE.getTypes().size()+1)));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
unsigned StructAbbrev = Stream.EmitAbbrev(Abbv);
// Abbrev for TYPE_CODE_ARRAY.
Abbv = new BitCodeAbbrev();
Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_ARRAY));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // size
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
- Log2_32_Ceil(VE.getTypes().size()+1)));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
+
unsigned ArrayAbbrev = Stream.EmitAbbrev(Abbv);
// Emit an entry count so the reader can reserve space.
@@ -387,30 +340,41 @@ static void WriteTypeTable(const llvm_2_9::ValueEnumerator &VE,
WriteTypeSymbolTable(VE, Stream);
}
-static unsigned getEncodedLinkage(const GlobalValue *GV) {
- switch (GV->getLinkage()) {
- case GlobalValue::ExternalLinkage: return 0;
- case GlobalValue::WeakAnyLinkage: return 1;
- case GlobalValue::AppendingLinkage: return 2;
- case GlobalValue::InternalLinkage: return 3;
- case GlobalValue::LinkOnceAnyLinkage: return 4;
- case GlobalValue::ExternalWeakLinkage: return 7;
- case GlobalValue::CommonLinkage: return 8;
- case GlobalValue::PrivateLinkage: return 9;
- case GlobalValue::WeakODRLinkage: return 10;
- case GlobalValue::LinkOnceODRLinkage: return 11;
- case GlobalValue::AvailableExternallyLinkage: return 12;
+static unsigned getEncodedLinkage(const GlobalValue &GV) {
+ switch (GV.getLinkage()) {
+ case GlobalValue::ExternalLinkage:
+ return 0;
+ case GlobalValue::WeakAnyLinkage:
+ return 1;
+ case GlobalValue::AppendingLinkage:
+ return 2;
+ case GlobalValue::InternalLinkage:
+ return 3;
+ case GlobalValue::LinkOnceAnyLinkage:
+ return 4;
+ case GlobalValue::ExternalWeakLinkage:
+ return 7;
+ case GlobalValue::CommonLinkage:
+ return 8;
+ case GlobalValue::PrivateLinkage:
+ return 9;
+ case GlobalValue::WeakODRLinkage:
+ return 10;
+ case GlobalValue::LinkOnceODRLinkage:
+ return 11;
+ case GlobalValue::AvailableExternallyLinkage:
+ return 12;
}
llvm_unreachable("Invalid linkage");
}
-static unsigned getEncodedVisibility(const GlobalValue *GV) {
- switch (GV->getVisibility()) {
- default: llvm_unreachable("Invalid visibility!");
+static unsigned getEncodedVisibility(const GlobalValue &GV) {
+ switch (GV.getVisibility()) {
case GlobalValue::DefaultVisibility: return 0;
case GlobalValue::HiddenVisibility: return 1;
case GlobalValue::ProtectedVisibility: return 2;
}
+ llvm_unreachable("Invalid visibility");
}
// Emit top-level description of module, including target triple, inline asm,
@@ -422,9 +386,9 @@ static void WriteModuleInfo(const Module *M,
if (!M->getTargetTriple().empty())
WriteStringRecord(bitc::MODULE_CODE_TRIPLE, M->getTargetTriple(),
0/*TODO*/, Stream);
- if (M->getDataLayout() != nullptr)
- WriteStringRecord(bitc::MODULE_CODE_DATALAYOUT, M->getDataLayout()->getStringRepresentation(),
- 0/*TODO*/, Stream);
+ const std::string &DL = M->getDataLayoutStr();
+ if (!DL.empty())
+ WriteStringRecord(bitc::MODULE_CODE_DATALAYOUT, DL, 0 /*TODO*/, Stream);
if (!M->getModuleInlineAsm().empty())
WriteStringRecord(bitc::MODULE_CODE_ASM, M->getModuleInlineAsm(),
0/*TODO*/, Stream);
@@ -435,35 +399,35 @@ static void WriteModuleInfo(const Module *M,
std::map<std::string, unsigned> GCMap;
unsigned MaxAlignment = 0;
unsigned MaxGlobalType = 0;
- for (Module::const_global_iterator GV = M->global_begin(),E = M->global_end();
- GV != E; ++GV) {
- MaxAlignment = std::max(MaxAlignment, GV->getAlignment());
- MaxGlobalType = std::max(MaxGlobalType, VE.getTypeID(GV->getType()));
-
- if (!GV->hasSection()) continue;
- // Give section names unique ID's.
- unsigned &Entry = SectionMap[GV->getSection()];
- if (Entry != 0) continue;
- WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, GV->getSection(),
- 0/*TODO*/, Stream);
- Entry = SectionMap.size();
+ for (const GlobalValue &GV : M->globals()) {
+ MaxAlignment = std::max(MaxAlignment, GV.getAlignment());
+ MaxGlobalType = std::max(MaxGlobalType, VE.getTypeID(GV.getType()));
+ if (GV.hasSection()) {
+ // Give section names unique ID's.
+ unsigned &Entry = SectionMap[GV.getSection()];
+ if (!Entry) {
+ WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, GV.getSection(),
+ 0/*TODO*/, Stream);
+ Entry = SectionMap.size();
+ }
+ }
}
- for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) {
- MaxAlignment = std::max(MaxAlignment, F->getAlignment());
- if (F->hasSection()) {
+ for (const Function &F : *M) {
+ MaxAlignment = std::max(MaxAlignment, F.getAlignment());
+ if (F.hasSection()) {
// Give section names unique ID's.
- unsigned &Entry = SectionMap[F->getSection()];
+ unsigned &Entry = SectionMap[F.getSection()];
if (!Entry) {
- WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, F->getSection(),
+ WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, F.getSection(),
0/*TODO*/, Stream);
Entry = SectionMap.size();
}
}
- if (F->hasGC()) {
+ if (F.hasGC()) {
// Same for GC names.
- unsigned &Entry = GCMap[F->getGC()];
+ unsigned &Entry = GCMap[F.getGC()];
if (!Entry) {
- WriteStringRecord(bitc::MODULE_CODE_GCNAME, F->getGC(),
+ WriteStringRecord(bitc::MODULE_CODE_GCNAME, F.getGC(),
0/*TODO*/, Stream);
Entry = GCMap.size();
}
@@ -499,26 +463,25 @@ static void WriteModuleInfo(const Module *M,
// Emit the global variable information.
SmallVector<unsigned, 64> Vals;
- for (Module::const_global_iterator GV = M->global_begin(),E = M->global_end();
- GV != E; ++GV) {
+ for (const GlobalVariable &GV : M->globals()) {
unsigned AbbrevToUse = 0;
// GLOBALVAR: [type, isconst, initid,
// linkage, alignment, section, visibility, threadlocal,
// unnamed_addr]
- Vals.push_back(VE.getTypeID(GV->getType()));
- Vals.push_back(GV->isConstant());
- Vals.push_back(GV->isDeclaration() ? 0 :
- (VE.getValueID(GV->getInitializer()) + 1));
+ Vals.push_back(VE.getTypeID(GV.getType()));
+ Vals.push_back(GV.isConstant());
+ Vals.push_back(GV.isDeclaration() ? 0 :
+ (VE.getValueID(GV.getInitializer()) + 1));
Vals.push_back(getEncodedLinkage(GV));
- Vals.push_back(Log2_32(GV->getAlignment())+1);
- Vals.push_back(GV->hasSection() ? SectionMap[GV->getSection()] : 0);
- if (GV->isThreadLocal() ||
- GV->getVisibility() != GlobalValue::DefaultVisibility ||
- GV->hasUnnamedAddr()) {
+ Vals.push_back(Log2_32(GV.getAlignment())+1);
+ Vals.push_back(GV.hasSection() ? SectionMap[GV.getSection()] : 0);
+ if (GV.isThreadLocal() ||
+ GV.getVisibility() != GlobalValue::DefaultVisibility ||
+ GV.hasUnnamedAddr()) {
Vals.push_back(getEncodedVisibility(GV));
- Vals.push_back(GV->isThreadLocal());
- Vals.push_back(GV->hasUnnamedAddr());
+ Vals.push_back(GV.isThreadLocal());
+ Vals.push_back(GV.hasUnnamedAddr());
} else {
AbbrevToUse = SimpleGVarAbbrev;
}
@@ -528,19 +491,19 @@ static void WriteModuleInfo(const Module *M,
}
// Emit the function proto information.
- for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) {
+ for (const Function &F : *M) {
// FUNCTION: [type, callingconv, isproto, paramattr,
// linkage, alignment, section, visibility, gc, unnamed_addr]
- Vals.push_back(VE.getTypeID(F->getType()));
- Vals.push_back(F->getCallingConv());
- Vals.push_back(F->isDeclaration());
+ Vals.push_back(VE.getTypeID(F.getType()));
+ Vals.push_back(F.getCallingConv());
+ Vals.push_back(F.isDeclaration());
Vals.push_back(getEncodedLinkage(F));
- Vals.push_back(VE.getAttributeID(F->getAttributes()));
- Vals.push_back(Log2_32(F->getAlignment())+1);
- Vals.push_back(F->hasSection() ? SectionMap[F->getSection()] : 0);
+ Vals.push_back(VE.getAttributeID(F.getAttributes()));
+ Vals.push_back(Log2_32(F.getAlignment())+1);
+ Vals.push_back(F.hasSection() ? SectionMap[F.getSection()] : 0);
Vals.push_back(getEncodedVisibility(F));
- Vals.push_back(F->hasGC() ? GCMap[F->getGC()] : 0);
- Vals.push_back(F->hasUnnamedAddr());
+ Vals.push_back(F.hasGC() ? GCMap[F.getGC()] : 0);
+ Vals.push_back(F.hasUnnamedAddr());
unsigned AbbrevToUse = 0;
Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse);
@@ -548,12 +511,11 @@ static void WriteModuleInfo(const Module *M,
}
// Emit the alias information.
- for (Module::const_alias_iterator AI = M->alias_begin(), E = M->alias_end();
- AI != E; ++AI) {
- Vals.push_back(VE.getTypeID(AI->getType()));
- Vals.push_back(VE.getValueID(AI->getAliasee()));
- Vals.push_back(getEncodedLinkage(AI));
- Vals.push_back(getEncodedVisibility(AI));
+ for (const GlobalAlias &A : M->aliases()) {
+ Vals.push_back(VE.getTypeID(A.getType()));
+ Vals.push_back(VE.getValueID(A.getAliasee()));
+ Vals.push_back(getEncodedLinkage(A));
+ Vals.push_back(getEncodedVisibility(A));
unsigned AbbrevToUse = 0;
Stream.EmitRecord(bitc::MODULE_CODE_ALIAS, Vals, AbbrevToUse);
Vals.clear();
@@ -563,14 +525,12 @@ static void WriteModuleInfo(const Module *M,
static uint64_t GetOptimizationFlags(const Value *V) {
uint64_t Flags = 0;
- if (const OverflowingBinaryOperator *OBO =
- dyn_cast<OverflowingBinaryOperator>(V)) {
+ if (const auto *OBO = dyn_cast<OverflowingBinaryOperator>(V)) {
if (OBO->hasNoSignedWrap())
Flags |= 1 << bitc::OBO_NO_SIGNED_WRAP;
if (OBO->hasNoUnsignedWrap())
Flags |= 1 << bitc::OBO_NO_UNSIGNED_WRAP;
- } else if (const PossiblyExactOperator *PEO =
- dyn_cast<PossiblyExactOperator>(V)) {
+ } else if (const auto *PEO = dyn_cast<PossiblyExactOperator>(V)) {
if (PEO->isExact())
Flags |= 1 << bitc::PEO_EXACT;
}
@@ -578,89 +538,154 @@ static uint64_t GetOptimizationFlags(const Value *V) {
return Flags;
}
-static void WriteMDNode(const MDNode *N,
- const llvm_2_9::ValueEnumerator &VE,
- BitstreamWriter &Stream,
- SmallVector<uint64_t, 64> &Record) {
+static void WriteValueAsMetadata(const ValueAsMetadata *MD,
+ const llvm_2_9::ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record) {
+ // Mimic an MDNode with a value as one operand.
+ Value *V = MD->getValue();
+ Record.push_back(VE.getTypeID(V->getType()));
+ Record.push_back(VE.getValueID(V));
+ Stream.EmitRecord(METADATA_NODE_2_7, Record, 0);
+ Record.clear();
+}
+
+static void WriteMDTuple(const MDTuple *N, const llvm_2_9::ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record, unsigned Abbrev) {
for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
- if (N->getOperand(i)) {
- Record.push_back(VE.getTypeID(N->getOperand(i)->getType()));
- Record.push_back(VE.getValueID(N->getOperand(i)));
- } else {
- Record.push_back(VE.getTypeID(Type::getVoidTy(N->getContext())));
+ Metadata *MD = N->getOperand(i);
+ assert(!(MD && isa<LocalAsMetadata>(MD)) &&
+ "Unexpected function-local metadata");
+ if (!MD) {
+ // TODO(srhines): I don't believe this case can exist for RS.
+ Record.push_back(VE.getTypeID(llvm::Type::getVoidTy(N->getContext())));
Record.push_back(0);
+ } else if (const auto *MDC = dyn_cast<ConstantAsMetadata>(MD)) {
+ Record.push_back(VE.getTypeID(MDC->getType()));
+ Record.push_back(VE.getValueID(MDC->getValue()));
+ } else {
+ Record.push_back(VE.getTypeID(
+ llvm::Type::getMetadataTy(N->getContext())));
+ Record.push_back(VE.getMetadataID(MD));
}
}
- unsigned MDCode = N->isFunctionLocal() ? METADATA_FN_NODE_2_7 :
- METADATA_NODE_2_7;
- Stream.EmitRecord(MDCode, Record, 0);
+ Stream.EmitRecord(METADATA_NODE_2_7, Record, Abbrev);
Record.clear();
}
+/*static void WriteMDLocation(const MDLocation *N, const llvm_2_9::ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.push_back(N->isDistinct());
+ Record.push_back(N->getLine());
+ Record.push_back(N->getColumn());
+ Record.push_back(VE.getMetadataID(N->getScope()));
+ Record.push_back(VE.getMetadataOrNullID(N->getInlinedAt()));
+
+ Stream.EmitRecord(bitc::METADATA_LOCATION, Record, Abbrev);
+ Record.clear();
+}
+
+static void WriteGenericDebugNode(const GenericDebugNode *,
+ const llvm_2_9::ValueEnumerator &, BitstreamWriter &,
+ SmallVectorImpl<uint64_t> &, unsigned) {
+ llvm_unreachable("unimplemented");
+}*/
+
static void WriteModuleMetadata(const Module *M,
const llvm_2_9::ValueEnumerator &VE,
BitstreamWriter &Stream) {
- const llvm_2_9::ValueEnumerator::ValueList &Vals = VE.getMDValues();
- bool StartedMetadataBlock = false;
+ const auto &MDs = VE.getMDs();
+ if (MDs.empty() && M->named_metadata_empty())
+ return;
+
+ // RenderScript files *ALWAYS* have metadata!
+ Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
+
unsigned MDSAbbrev = 0;
- SmallVector<uint64_t, 64> Record;
- for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
+ if (VE.hasMDString()) {
+ // Abbrev for METADATA_STRING.
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_STRING));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
+ MDSAbbrev = Stream.EmitAbbrev(Abbv);
+ }
- if (const MDNode *N = dyn_cast<MDNode>(Vals[i].first)) {
- if (!N->isFunctionLocal() || !N->getFunction()) {
- if (!StartedMetadataBlock) {
- Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
- StartedMetadataBlock = true;
- }
- WriteMDNode(N, VE, Stream, Record);
- }
- } else if (const MDString *MDS = dyn_cast<MDString>(Vals[i].first)) {
- if (!StartedMetadataBlock) {
- Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
-
- // Abbrev for METADATA_STRING.
- BitCodeAbbrev *Abbv = new BitCodeAbbrev();
- Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_STRING));
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
- MDSAbbrev = Stream.EmitAbbrev(Abbv);
- StartedMetadataBlock = true;
- }
+ unsigned MDLocationAbbrev = 0;
+ if (VE.hasMDLocation()) {
+ // TODO(srhines): Should be unreachable for RenderScript.
+ // Abbrev for METADATA_LOCATION.
+ //
+ // Assume the column is usually under 128, and always output the inlined-at
+ // location (it's never more expensive than building an array size 1).
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_LOCATION));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+ MDLocationAbbrev = Stream.EmitAbbrev(Abbv);
+ }
- // Code: [strchar x N]
- Record.append(MDS->begin(), MDS->end());
+ unsigned NameAbbrev = 0;
+ if (!M->named_metadata_empty()) {
+ // Abbrev for METADATA_NAME.
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_NAME));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
+ NameAbbrev = Stream.EmitAbbrev(Abbv);
+ }
- // Emit the finished record.
- Stream.EmitRecord(bitc::METADATA_STRING, Record, MDSAbbrev);
- Record.clear();
+ unsigned MDTupleAbbrev = 0;
+ //unsigned GenericDebugNodeAbbrev = 0;
+ SmallVector<uint64_t, 64> Record;
+ for (const Metadata *MD : MDs) {
+ if (const MDNode *N = dyn_cast<MDNode>(MD)) {
+ switch (N->getMetadataID()) {
+ default:
+ llvm_unreachable("Invalid MDNode subclass");
+#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS)
+#define HANDLE_MDNODE_LEAF(CLASS) \
+ case Metadata::CLASS##Kind: \
+ Write##CLASS(cast<CLASS>(N), VE, Stream, Record, CLASS##Abbrev); \
+ continue;
+#include "llvm/IR/Metadata.def"
+ }
+ }
+ if (const auto *MDC = dyn_cast<ConstantAsMetadata>(MD)) {
+ WriteValueAsMetadata(MDC, VE, Stream, Record);
+ continue;
}
+ const MDString *MDS = cast<MDString>(MD);
+ // Code: [strchar x N]
+ Record.append(MDS->bytes_begin(), MDS->bytes_end());
+
+ // Emit the finished record.
+ Stream.EmitRecord(bitc::METADATA_STRING, Record, MDSAbbrev);
+ Record.clear();
}
// Write named metadata.
- for (Module::const_named_metadata_iterator I = M->named_metadata_begin(),
- E = M->named_metadata_end(); I != E; ++I) {
- const NamedMDNode *NMD = I;
- if (!StartedMetadataBlock) {
- Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
- StartedMetadataBlock = true;
- }
-
+ for (const NamedMDNode &NMD : M->named_metadata()) {
// Write name.
- StringRef Str = NMD->getName();
- for (unsigned i = 0, e = Str.size(); i != e; ++i)
- Record.push_back(Str[i]);
- Stream.EmitRecord(bitc::METADATA_NAME, Record, 0/*TODO*/);
+ StringRef Str = NMD.getName();
+ Record.append(Str.bytes_begin(), Str.bytes_end());
+ Stream.EmitRecord(bitc::METADATA_NAME, Record, NameAbbrev);
Record.clear();
// Write named metadata operands.
- for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i)
- Record.push_back(VE.getValueID(NMD->getOperand(i)));
+ for (const MDNode *N : NMD.operands())
+ Record.push_back(VE.getMetadataID(N));
Stream.EmitRecord(METADATA_NAMED_NODE_2_7, Record, 0);
Record.clear();
}
- if (StartedMetadataBlock)
- Stream.ExitBlock();
+ Stream.ExitBlock();
}
static void WriteFunctionLocalMetadata(const Function &F,
@@ -668,16 +693,16 @@ static void WriteFunctionLocalMetadata(const Function &F,
BitstreamWriter &Stream) {
bool StartedMetadataBlock = false;
SmallVector<uint64_t, 64> Record;
- const SmallVector<const MDNode *, 8> &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) {
- if (!StartedMetadataBlock) {
- Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
- StartedMetadataBlock = true;
- }
- WriteMDNode(N, VE, Stream, Record);
- }
+ const SmallVectorImpl<const LocalAsMetadata *> &MDs =
+ VE.getFunctionLocalMDs();
+ for (unsigned i = 0, e = MDs.size(); i != e; ++i) {
+ assert(MDs[i] && "Expected valid function-local metadata");
+ if (!StartedMetadataBlock) {
+ Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
+ StartedMetadataBlock = true;
+ }
+ WriteValueAsMetadata(MDs[i], VE, Stream, Record);
+ }
if (StartedMetadataBlock)
Stream.ExitBlock();
@@ -692,7 +717,7 @@ 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;
+ 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();
@@ -707,7 +732,7 @@ static void WriteMetadataAttachment(const Function &F,
for (unsigned i = 0, e = MDs.size(); i != e; ++i) {
Record.push_back(MDs[i].first);
- Record.push_back(VE.getValueID(MDs[i].second));
+ Record.push_back(VE.getMetadataID(MDs[i].second));
}
Stream.EmitRecord(METADATA_ATTACHMENT_2_7, Record, 0);
Record.clear();
@@ -783,7 +808,7 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
SmallVector<uint64_t, 64> Record;
const llvm_2_9::ValueEnumerator::ValueList &Vals = VE.getValues();
- Type *LastTy = 0;
+ Type *LastTy = nullptr;
for (unsigned i = FirstVal; i != LastVal; ++i) {
const Value *V = Vals[i].first;
// If we need to switch types, do so now.
@@ -1065,9 +1090,9 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
break;
case Instruction::GetElementPtr:
- Code = bitc::FUNC_CODE_INST_GEP;
+ Code = bitc::FUNC_CODE_INST_GEP_OLD;
if (cast<GEPOperator>(&I)->isInBounds())
- Code = bitc::FUNC_CODE_INST_INBOUNDS_GEP;
+ Code = bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD;
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
PushValueAndType(I.getOperand(i), InstID, Vals, VE);
break;
@@ -1150,14 +1175,13 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
{
Code = bitc::FUNC_CODE_INST_SWITCH;
const SwitchInst &SI = cast<SwitchInst>(I);
-
Vals.push_back(VE.getTypeID(SI.getCondition()->getType()));
Vals.push_back(VE.getValueID(SI.getCondition()));
Vals.push_back(VE.getValueID(SI.getDefaultDest()));
for (SwitchInst::ConstCaseIt i = SI.case_begin(), e = SI.case_end();
i != e; ++i) {
- Vals.push_back(VE.getValueID(i.getCaseValue()));
- Vals.push_back(VE.getValueID(i.getCaseSuccessor()));
+ Vals.push_back(VE.getValueID(i.getCaseValue()));
+ Vals.push_back(VE.getValueID(i.getCaseSuccessor()));
}
}
break;
@@ -1379,8 +1403,8 @@ static void WriteFunction(const Function &F, llvm_2_9::ValueEnumerator &VE,
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);
+ Vals.push_back(VE.getMetadataOrNullID(Scope));
+ Vals.push_back(VE.getMetadataOrNullID(IA));
Stream.EmitRecord(FUNC_CODE_DEBUG_LOC_2_7, Vals);
Vals.clear();
@@ -1559,7 +1583,6 @@ static void WriteBlockInfo(const llvm_2_9::ValueEnumerator &VE,
Stream.ExitBlock();
}
-
/// WriteModule - Emit the specified module to the bitstream.
static void WriteModule(const Module *M, BitstreamWriter &Stream) {
Stream.EnterSubblock(bitc::MODULE_BLOCK_ID, 3);
@@ -1572,7 +1595,7 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream) {
}
// Analyze the module, enumerating globals, functions, etc.
- llvm_2_9::ValueEnumerator VE(M);
+ llvm_2_9::ValueEnumerator VE(*M);
// Emit blockinfo, which defines the standard abbreviations etc.
WriteBlockInfo(VE, Stream);
diff --git a/BitWriter_2_9/ValueEnumerator.cpp b/BitWriter_2_9/ValueEnumerator.cpp
index 4b06a0f..75949b3 100644
--- a/BitWriter_2_9/ValueEnumerator.cpp
+++ b/BitWriter_2_9/ValueEnumerator.cpp
@@ -15,6 +15,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
@@ -31,20 +32,21 @@ static bool isIntOrIntVectorValue(const std::pair<const Value*, unsigned> &V) {
}
/// ValueEnumerator - Enumerate module-level information.
-ValueEnumerator::ValueEnumerator(const Module *M) {
+ValueEnumerator::ValueEnumerator(const llvm::Module &M)
+ : HasMDString(false), HasMDLocation(false) {
// Enumerate the global variables.
- for (Module::const_global_iterator I = M->global_begin(),
- E = M->global_end(); I != E; ++I)
+ for (llvm::Module::const_global_iterator I = M.global_begin(), E = M.global_end();
+ I != E; ++I)
EnumerateValue(I);
// Enumerate the functions.
- for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) {
+ for (llvm::Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) {
EnumerateValue(I);
EnumerateAttributes(cast<Function>(I)->getAttributes());
}
// Enumerate the aliases.
- for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
+ for (llvm::Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
I != E; ++I)
EnumerateValue(I);
@@ -52,55 +54,64 @@ ValueEnumerator::ValueEnumerator(const Module *M) {
unsigned FirstConstant = Values.size();
// Enumerate the global variable initializers.
- for (Module::const_global_iterator I = M->global_begin(),
- E = M->global_end(); I != E; ++I)
+ for (llvm::Module::const_global_iterator I = M.global_begin(), E = M.global_end();
+ I != E; ++I)
if (I->hasInitializer())
EnumerateValue(I->getInitializer());
// Enumerate the aliasees.
- for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
+ for (llvm::Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
I != E; ++I)
EnumerateValue(I->getAliasee());
- // Insert constants and metadata that are named at module level into the slot
+ // Enumerate the metadata type.
+ //
+ // TODO: Move this to ValueEnumerator::EnumerateOperandType() once bitcode
+ // only encodes the metadata type when it's used as a value.
+ EnumerateType(Type::getMetadataTy(M.getContext()));
+
+ // 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());
+ EnumerateValueSymbolTable(M.getValueSymbolTable());
EnumerateNamedMetadata(M);
- SmallVector<std::pair<unsigned, MDNode*>, 8> MDs;
+ SmallVector<std::pair<unsigned, MDNode *>, 8> MDs;
// Enumerate types used by function bodies and argument lists.
- for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) {
-
- for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();
- I != E; ++I)
- EnumerateType(I->getType());
-
- 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){
- for (User::const_op_iterator OI = I->op_begin(), E = I->op_end();
- OI != E; ++OI) {
- if (MDNode *MD = dyn_cast<MDNode>(*OI))
- if (MD->isFunctionLocal() && MD->getFunction())
- // These will get enumerated during function-incorporation.
- continue;
- EnumerateOperandType(*OI);
+ for (const Function &F : M) {
+ for (const Argument &A : F.args())
+ EnumerateType(A.getType());
+
+ for (const BasicBlock &BB : F)
+ for (const Instruction &I : BB) {
+ for (const Use &Op : I.operands()) {
+ auto *MD = dyn_cast<MetadataAsValue>(&Op);
+ if (!MD) {
+ EnumerateOperandType(Op);
+ continue;
+ }
+
+ // Local metadata is enumerated during function-incorporation.
+ if (isa<LocalAsMetadata>(MD->getMetadata()))
+ continue;
+
+ EnumerateMetadata(MD->getMetadata());
}
- EnumerateType(I->getType());
- if (const CallInst *CI = dyn_cast<CallInst>(I))
+ EnumerateType(I.getType());
+ if (const CallInst *CI = dyn_cast<CallInst>(&I))
EnumerateAttributes(CI->getAttributes());
- else if (const InvokeInst *II = dyn_cast<InvokeInst>(I))
+ else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I))
EnumerateAttributes(II->getAttributes());
// Enumerate metadata attached with this instruction.
MDs.clear();
- I->getAllMetadataOtherThanDebugLoc(MDs);
+ I.getAllMetadataOtherThanDebugLoc(MDs);
for (unsigned i = 0, e = MDs.size(); i != e; ++i)
EnumerateMetadata(MDs[i].second);
- if (!I->getDebugLoc().isUnknown()) {
+ if (!I.getDebugLoc().isUnknown()) {
MDNode *Scope, *IA;
- I->getDebugLoc().getScopeAndInlinedAt(Scope, IA, I->getContext());
+ I.getDebugLoc().getScopeAndInlinedAt(Scope, IA, I.getContext());
if (Scope) EnumerateMetadata(Scope);
if (IA) EnumerateMetadata(IA);
}
@@ -122,11 +133,8 @@ void ValueEnumerator::setInstructionID(const Instruction *I) {
}
unsigned ValueEnumerator::getValueID(const Value *V) const {
- if (isa<MDNode>(V) || isa<MDString>(V)) {
- ValueMapType::const_iterator I = MDValueMap.find(V);
- assert(I != MDValueMap.end() && "Value not in slotcalculator!");
- return I->second-1;
- }
+ if (auto *MD = dyn_cast<MetadataAsValue>(V))
+ return getMetadataID(MD->getMetadata());
ValueMapType::const_iterator I = ValueMap.find(V);
assert(I != ValueMap.end() && "Value not in slotcalculator!");
@@ -156,12 +164,11 @@ void ValueEnumerator::print(raw_ostream &OS, const ValueMapType &Map,
V->dump();
OS << " Uses(" << std::distance(V->use_begin(),V->use_end()) << "):";
- for (Value::const_use_iterator UI = V->use_begin(), UE = V->use_end();
- UI != UE; ++UI) {
- if (UI != V->use_begin())
+ for (const Use &U : V->uses()) {
+ if (&U != &*V->use_begin())
OS << ",";
- if((*UI)->hasName())
- OS << " " << (*UI)->getName();
+ if(U->hasName())
+ OS << " " << U->getName();
else
OS << " [null]";
@@ -170,6 +177,19 @@ void ValueEnumerator::print(raw_ostream &OS, const ValueMapType &Map,
}
}
+void ValueEnumerator::print(llvm::raw_ostream &OS, const MetadataMapType &Map,
+ const char *Name) const {
+
+ OS << "Map Name: " << Name << "\n";
+ OS << "Size: " << Map.size() << "\n";
+ for (auto I = Map.begin(), E = Map.end(); I != E; ++I) {
+ const llvm::Metadata *MD = I->first;
+ OS << "Metadata: slot = " << I->second << "\n";
+ MD->print(OS);
+ }
+}
+
+
// Optimize constant ordering.
namespace {
struct CstSortPredicate {
@@ -216,9 +236,10 @@ void ValueEnumerator::EnumerateValueSymbolTable(const ValueSymbolTable &VST) {
/// EnumerateNamedMetadata - Insert all of the values referenced by
/// named metadata in the specified module.
-void ValueEnumerator::EnumerateNamedMetadata(const Module *M) {
- for (Module::const_named_metadata_iterator I = M->named_metadata_begin(),
- E = M->named_metadata_end(); I != E; ++I)
+void ValueEnumerator::EnumerateNamedMetadata(const llvm::Module &M) {
+ for (llvm::Module::const_named_metadata_iterator I = M.named_metadata_begin(),
+ E = M.named_metadata_end();
+ I != E; ++I)
EnumerateNamedMDNode(I);
}
@@ -231,84 +252,62 @@ void ValueEnumerator::EnumerateNamedMDNode(const NamedMDNode *MD) {
/// and types referenced by the given MDNode.
void ValueEnumerator::EnumerateMDNodeOperands(const MDNode *N) {
for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
- if (Value *V = N->getOperand(i)) {
- if (isa<MDNode>(V) || isa<MDString>(V))
- EnumerateMetadata(V);
- else if (!isa<Instruction>(V) && !isa<Argument>(V))
- EnumerateValue(V);
- } else
- EnumerateType(Type::getVoidTy(N->getContext()));
+ Metadata *MD = N->getOperand(i);
+ if (!MD)
+ continue;
+ assert(!isa<LocalAsMetadata>(MD) && "MDNodes cannot be function-local");
+ EnumerateMetadata(MD);
}
}
-void ValueEnumerator::EnumerateMetadata(const Value *MD) {
- assert((isa<MDNode>(MD) || isa<MDString>(MD)) && "Invalid metadata kind");
-
- // Enumerate the type of this value.
- EnumerateType(MD->getType());
+void ValueEnumerator::EnumerateMetadata(const llvm::Metadata *MD) {
+ assert(
+ (isa<MDNode>(MD) || isa<MDString>(MD) || isa<ConstantAsMetadata>(MD)) &&
+ "Invalid metadata kind");
- const MDNode *N = dyn_cast<MDNode>(MD);
+ // Insert a dummy ID to block the co-recursive call to
+ // EnumerateMDNodeOperands() from re-visiting MD in a cyclic graph.
+ //
+ // Return early if there's already an ID.
+ if (!MDValueMap.insert(std::make_pair(MD, 0)).second)
+ return;
- // In the module-level pass, skip function-local nodes themselves, but
- // do walk their operands.
- if (N && N->isFunctionLocal() && N->getFunction()) {
+ // Visit operands first to minimize RAUW.
+ if (auto *N = dyn_cast<MDNode>(MD))
EnumerateMDNodeOperands(N);
- return;
- }
+ else if (auto *C = dyn_cast<ConstantAsMetadata>(MD))
+ EnumerateValue(C->getValue());
- // Check to see if it's already in!
- unsigned &MDValueID = MDValueMap[MD];
- if (MDValueID) {
- // Increment use count.
- MDValues[MDValueID-1].second++;
- return;
- }
- MDValues.push_back(std::make_pair(MD, 1U));
- MDValueID = MDValues.size();
+ HasMDString |= isa<MDString>(MD);
+ HasMDLocation |= isa<MDLocation>(MD);
- // Enumerate all non-function-local operands.
- if (N)
- EnumerateMDNodeOperands(N);
+ // Replace the dummy ID inserted above with the correct one. MDValueMap may
+ // have changed by inserting operands, so we need a fresh lookup here.
+ MDs.push_back(MD);
+ MDValueMap[MD] = MDs.size();
}
/// EnumerateFunctionLocalMetadataa - Incorporate function-local metadata
-/// information reachable from the given MDNode.
-void ValueEnumerator::EnumerateFunctionLocalMetadata(const MDNode *N) {
- assert(N->isFunctionLocal() && N->getFunction() &&
- "EnumerateFunctionLocalMetadata called on non-function-local mdnode!");
-
- // Enumerate the type of this value.
- EnumerateType(N->getType());
-
+/// information reachable from the metadata.
+void ValueEnumerator::EnumerateFunctionLocalMetadata(
+ const llvm::LocalAsMetadata *Local) {
// Check to see if it's already in!
- unsigned &MDValueID = MDValueMap[N];
- if (MDValueID) {
- // Increment use count.
- MDValues[MDValueID-1].second++;
+ unsigned &MDValueID = MDValueMap[Local];
+ if (MDValueID)
return;
- }
- MDValues.push_back(std::make_pair(N, 1U));
- MDValueID = MDValues.size();
-
- // To incoroporate function-local information visit all function-local
- // MDNodes and all function-local values they reference.
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
- if (Value *V = N->getOperand(i)) {
- if (MDNode *O = dyn_cast<MDNode>(V)) {
- if (O->isFunctionLocal() && O->getFunction())
- EnumerateFunctionLocalMetadata(O);
- } else if (isa<Instruction>(V) || isa<Argument>(V))
- EnumerateValue(V);
- }
- // Also, collect all function-local MDNodes for easy access.
- FunctionLocalMDs.push_back(N);
+ MDs.push_back(Local);
+ MDValueID = MDs.size();
+
+ EnumerateValue(Local->getValue());
+
+ // Also, collect all function-local metadata for easy access.
+ FunctionLocalMDs.push_back(Local);
}
void ValueEnumerator::EnumerateValue(const Value *V) {
assert(!V->getType()->isVoidTy() && "Can't insert void values!");
- assert(!isa<MDNode>(V) && !isa<MDString>(V) &&
- "EnumerateValue doesn't handle Metadata!");
+ assert(!isa<MetadataAsValue>(V) && "EnumerateValue doesn't handle Metadata!");
// Check to see if it's already in!
unsigned &ValueID = ValueMap[V];
@@ -378,9 +377,8 @@ void ValueEnumerator::EnumerateType(Type *Ty) {
// 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);
+ for (Type *SubTy : Ty->subtypes())
+ EnumerateType(SubTy);
// Refresh the TypeID pointer in case the table rehashed.
TypeID = &TypeMap[Ty];
@@ -404,30 +402,35 @@ void ValueEnumerator::EnumerateType(Type *Ty) {
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.
- if (ValueMap.count(V)) return;
+ if (auto *MD = dyn_cast<MetadataAsValue>(V)) {
+ assert(!isa<LocalAsMetadata>(MD->getMetadata()) &&
+ "Function-local metadata should be left for later");
- // This constant may have operands, make sure to enumerate the types in
- // them.
- for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) {
- const Value *Op = C->getOperand(i);
+ EnumerateMetadata(MD->getMetadata());
+ return;
+ }
- // Don't enumerate basic blocks here, this happens as operands to
- // blockaddress.
- if (isa<BasicBlock>(Op)) continue;
+ const Constant *C = dyn_cast<Constant>(V);
+ if (!C)
+ return;
- EnumerateOperandType(Op);
- }
+ // If this constant is already enumerated, ignore it, we know its type must
+ // be enumerated.
+ if (ValueMap.count(C))
+ return;
- if (const MDNode *N = dyn_cast<MDNode>(V)) {
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
- if (Value *Elem = N->getOperand(i))
- EnumerateOperandType(Elem);
- }
- } else if (isa<MDString>(V) || isa<MDNode>(V))
- EnumerateMetadata(V);
+ // This constant may have operands, make sure to enumerate the types in
+ // 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);
+ }
}
void ValueEnumerator::EnumerateAttributes(AttributeSet PAL) {
@@ -455,7 +458,7 @@ void ValueEnumerator::EnumerateAttributes(AttributeSet PAL) {
void ValueEnumerator::incorporateFunction(const Function &F) {
InstructionCount = 0;
NumModuleValues = Values.size();
- NumModuleMDValues = MDValues.size();
+ NumModuleMDs = MDs.size();
// Adding function arguments to the value table.
for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end();
@@ -486,24 +489,16 @@ void ValueEnumerator::incorporateFunction(const Function &F) {
FirstInstID = Values.size();
- SmallVector<MDNode *, 8> FnLocalMDVector;
+ SmallVector<llvm::LocalAsMetadata *, 8> FnLocalMDVector;
// Add all of the instructions.
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) {
for (User::const_op_iterator OI = I->op_begin(), E = I->op_end();
OI != E; ++OI) {
- if (MDNode *MD = dyn_cast<MDNode>(*OI))
- if (MD->isFunctionLocal() && MD->getFunction())
+ if (auto *MD = dyn_cast<llvm::MetadataAsValue>(&*OI))
+ if (auto *Local = dyn_cast<LocalAsMetadata>(MD->getMetadata()))
// Enumerate metadata after the instructions they might refer to.
- FnLocalMDVector.push_back(MD);
- }
-
- SmallVector<std::pair<unsigned, MDNode*>, 8> MDs;
- I->getAllMetadataOtherThanDebugLoc(MDs);
- for (unsigned i = 0, e = MDs.size(); i != e; ++i) {
- MDNode *N = MDs[i].second;
- if (N->isFunctionLocal() && N->getFunction())
- FnLocalMDVector.push_back(N);
+ FnLocalMDVector.push_back(Local);
}
if (!I->getType()->isVoidTy())
@@ -520,13 +515,13 @@ void ValueEnumerator::purgeFunction() {
/// Remove purged values from the ValueMap.
for (unsigned i = NumModuleValues, e = Values.size(); i != e; ++i)
ValueMap.erase(Values[i].first);
- for (unsigned i = NumModuleMDValues, e = MDValues.size(); i != e; ++i)
- MDValueMap.erase(MDValues[i].first);
+ for (unsigned i = NumModuleMDs, e = MDs.size(); i != e; ++i)
+ MDValueMap.erase(MDs[i]);
for (unsigned i = 0, e = BasicBlocks.size(); i != e; ++i)
ValueMap.erase(BasicBlocks[i]);
Values.resize(NumModuleValues);
- MDValues.resize(NumModuleMDValues);
+ MDs.resize(NumModuleMDs);
BasicBlocks.clear();
FunctionLocalMDs.clear();
}
diff --git a/BitWriter_2_9/ValueEnumerator.h b/BitWriter_2_9/ValueEnumerator.h
index 9fec214..7d8a746 100644
--- a/BitWriter_2_9/ValueEnumerator.h
+++ b/BitWriter_2_9/ValueEnumerator.h
@@ -27,6 +27,8 @@ class Instruction;
class BasicBlock;
class Function;
class Module;
+class Metadata;
+class LocalAsMetadata;
class MDNode;
class NamedMDNode;
class AttributeSet;
@@ -52,9 +54,14 @@ private:
typedef llvm::DenseMap<const llvm::Value*, unsigned> ValueMapType;
ValueMapType ValueMap;
ValueList Values;
- ValueList MDValues;
- llvm::SmallVector<const llvm::MDNode *, 8> FunctionLocalMDs;
- ValueMapType MDValueMap;
+
+
+ std::vector<const llvm::Metadata *> MDs;
+ llvm::SmallVector<const llvm::LocalAsMetadata *, 8> FunctionLocalMDs;
+ typedef llvm::DenseMap<const llvm::Metadata *, unsigned> MetadataMapType;
+ MetadataMapType MDValueMap;
+ bool HasMDString;
+ bool HasMDLocation;
typedef llvm::DenseMap<llvm::AttributeSet, unsigned> AttributeGroupMapType;
AttributeGroupMapType AttributeGroupMap;
@@ -82,20 +89,33 @@ private:
/// When a function is incorporated, this is the size of the MDValues list
/// before incorporation.
- unsigned NumModuleMDValues;
+ unsigned NumModuleMDs;
unsigned FirstFuncConstantID;
unsigned FirstInstID;
- ValueEnumerator(const ValueEnumerator &); // DO NOT IMPLEMENT
- void operator=(const ValueEnumerator &); // DO NOT IMPLEMENT
+ ValueEnumerator(const ValueEnumerator &) = delete;
+ void operator=(const ValueEnumerator &) = delete;
public:
- ValueEnumerator(const llvm::Module *M);
+ ValueEnumerator(const llvm::Module &M);
void dump() const;
void print(llvm::raw_ostream &OS, const ValueMapType &Map, const char *Name) const;
+ void print(llvm::raw_ostream &OS, const MetadataMapType &Map,
+ const char *Name) const;
unsigned getValueID(const llvm::Value *V) const;
+ unsigned getMetadataID(const llvm::Metadata *MD) const {
+ auto ID = getMetadataOrNullID(MD);
+ assert(ID != 0 && "Metadata not in slotcalculator!");
+ return ID - 1;
+ }
+ unsigned getMetadataOrNullID(const llvm::Metadata *MD) const {
+ return MDValueMap.lookup(MD);
+ }
+
+ bool hasMDString() const { return HasMDString; }
+ bool hasMDLocation() const { return HasMDLocation; }
unsigned getTypeID(llvm::Type *T) const {
TypeMapType::const_iterator I = TypeMap.find(T);
@@ -128,8 +148,8 @@ public:
}
const ValueList &getValues() const { return Values; }
- const ValueList &getMDValues() const { return MDValues; }
- const llvm::SmallVector<const llvm::MDNode *, 8> &getFunctionLocalMDValues() const {
+ const std::vector<const llvm::Metadata *> &getMDs() const { return MDs; }
+ const llvm::SmallVectorImpl<const llvm::LocalAsMetadata *> &getFunctionLocalMDs() const {
return FunctionLocalMDs;
}
const TypeList &getTypes() const { return Types; }
@@ -158,8 +178,8 @@ private:
void OptimizeConstants(unsigned CstStart, unsigned CstEnd);
void EnumerateMDNodeOperands(const llvm::MDNode *N);
- void EnumerateMetadata(const llvm::Value *MD);
- void EnumerateFunctionLocalMetadata(const llvm::MDNode *N);
+ void EnumerateMetadata(const llvm::Metadata *MD);
+ void EnumerateFunctionLocalMetadata(const llvm::LocalAsMetadata *Local);
void EnumerateNamedMDNode(const llvm::NamedMDNode *NMD);
void EnumerateValue(const llvm::Value *V);
void EnumerateType(llvm::Type *T);
@@ -167,7 +187,7 @@ private:
void EnumerateAttributes(llvm::AttributeSet PAL);
void EnumerateValueSymbolTable(const llvm::ValueSymbolTable &ST);
- void EnumerateNamedMetadata(const llvm::Module *M);
+ void EnumerateNamedMetadata(const llvm::Module &M);
};
} // end llvm_2_9 namespace
diff --git a/BitWriter_2_9_func/BitcodeWriter.cpp b/BitWriter_2_9_func/BitcodeWriter.cpp
index 3577398..6a4b6fb 100644
--- a/BitWriter_2_9_func/BitcodeWriter.cpp
+++ b/BitWriter_2_9_func/BitcodeWriter.cpp
@@ -18,6 +18,7 @@
#include "llvm/Bitcode/BitstreamWriter.h"
#include "llvm/Bitcode/LLVMBitCodes.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
@@ -59,7 +60,6 @@ enum {
FUNCTION_INST_UNREACHABLE_ABBREV
};
-
static unsigned GetEncodedCastOpcode(unsigned Opcode) {
switch (Opcode) {
default: llvm_unreachable("Unknown cast instruction!");
@@ -187,11 +187,12 @@ static void WriteTypeTable(const llvm_2_9_func::ValueEnumerator &VE,
Stream.EnterSubblock(bitc::TYPE_BLOCK_ID_NEW, 4 /*count from # abbrevs */);
SmallVector<uint64_t, 64> TypeVals;
+ uint64_t NumBits = Log2_32_Ceil(VE.getTypes().size()+1);
+
// Abbrev for TYPE_CODE_POINTER.
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_POINTER));
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
- Log2_32_Ceil(VE.getTypes().size()+1)));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
Abbv->Add(BitCodeAbbrevOp(0)); // Addrspace = 0
unsigned PtrAbbrev = Stream.EmitAbbrev(Abbv);
@@ -201,8 +202,7 @@ static void WriteTypeTable(const llvm_2_9_func::ValueEnumerator &VE,
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isvararg
Abbv->Add(BitCodeAbbrevOp(0)); // FIXME: DEAD value, remove in LLVM 3.0
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
- Log2_32_Ceil(VE.getTypes().size()+1)));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
unsigned FunctionAbbrev = Stream.EmitAbbrev(Abbv);
// Abbrev for TYPE_CODE_STRUCT_ANON.
@@ -210,8 +210,7 @@ static void WriteTypeTable(const llvm_2_9_func::ValueEnumerator &VE,
Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_ANON));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ispacked
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
- Log2_32_Ceil(VE.getTypes().size()+1)));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
unsigned StructAnonAbbrev = Stream.EmitAbbrev(Abbv);
// Abbrev for TYPE_CODE_STRUCT_NAME.
@@ -226,16 +225,15 @@ static void WriteTypeTable(const llvm_2_9_func::ValueEnumerator &VE,
Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_NAMED));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ispacked
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
- Log2_32_Ceil(VE.getTypes().size()+1)));
+ 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));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // size
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
- Log2_32_Ceil(VE.getTypes().size()+1)));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
+
unsigned ArrayAbbrev = Stream.EmitAbbrev(Abbv);
// Emit an entry count so the reader can reserve space.
@@ -295,7 +293,7 @@ static void WriteTypeTable(const llvm_2_9_func::ValueEnumerator &VE,
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;
@@ -341,30 +339,41 @@ static void WriteTypeTable(const llvm_2_9_func::ValueEnumerator &VE,
Stream.ExitBlock();
}
-static unsigned getEncodedLinkage(const GlobalValue *GV) {
- switch (GV->getLinkage()) {
- case GlobalValue::ExternalLinkage: return 0;
- case GlobalValue::WeakAnyLinkage: return 1;
- case GlobalValue::AppendingLinkage: return 2;
- case GlobalValue::InternalLinkage: return 3;
- case GlobalValue::LinkOnceAnyLinkage: return 4;
- case GlobalValue::ExternalWeakLinkage: return 7;
- case GlobalValue::CommonLinkage: return 8;
- case GlobalValue::PrivateLinkage: return 9;
- case GlobalValue::WeakODRLinkage: return 10;
- case GlobalValue::LinkOnceODRLinkage: return 11;
- case GlobalValue::AvailableExternallyLinkage: return 12;
+static unsigned getEncodedLinkage(const GlobalValue &GV) {
+ switch (GV.getLinkage()) {
+ case GlobalValue::ExternalLinkage:
+ return 0;
+ case GlobalValue::WeakAnyLinkage:
+ return 1;
+ case GlobalValue::AppendingLinkage:
+ return 2;
+ case GlobalValue::InternalLinkage:
+ return 3;
+ case GlobalValue::LinkOnceAnyLinkage:
+ return 4;
+ case GlobalValue::ExternalWeakLinkage:
+ return 7;
+ case GlobalValue::CommonLinkage:
+ return 8;
+ case GlobalValue::PrivateLinkage:
+ return 9;
+ case GlobalValue::WeakODRLinkage:
+ return 10;
+ case GlobalValue::LinkOnceODRLinkage:
+ return 11;
+ case GlobalValue::AvailableExternallyLinkage:
+ return 12;
}
llvm_unreachable("Invalid linkage");
}
-static unsigned getEncodedVisibility(const GlobalValue *GV) {
- switch (GV->getVisibility()) {
- default: llvm_unreachable("Invalid visibility!");
+static unsigned getEncodedVisibility(const GlobalValue &GV) {
+ switch (GV.getVisibility()) {
case GlobalValue::DefaultVisibility: return 0;
case GlobalValue::HiddenVisibility: return 1;
case GlobalValue::ProtectedVisibility: return 2;
}
+ llvm_unreachable("Invalid visibility");
}
// Emit top-level description of module, including target triple, inline asm,
@@ -376,9 +385,9 @@ static void WriteModuleInfo(const Module *M,
if (!M->getTargetTriple().empty())
WriteStringRecord(bitc::MODULE_CODE_TRIPLE, M->getTargetTriple(),
0/*TODO*/, Stream);
- if (M->getDataLayout() != nullptr)
- WriteStringRecord(bitc::MODULE_CODE_DATALAYOUT, M->getDataLayout()->getStringRepresentation(),
- 0/*TODO*/, Stream);
+ const std::string &DL = M->getDataLayoutStr();
+ if (!DL.empty())
+ WriteStringRecord(bitc::MODULE_CODE_DATALAYOUT, DL, 0 /*TODO*/, Stream);
if (!M->getModuleInlineAsm().empty())
WriteStringRecord(bitc::MODULE_CODE_ASM, M->getModuleInlineAsm(),
0/*TODO*/, Stream);
@@ -389,35 +398,35 @@ static void WriteModuleInfo(const Module *M,
std::map<std::string, unsigned> GCMap;
unsigned MaxAlignment = 0;
unsigned MaxGlobalType = 0;
- for (Module::const_global_iterator GV = M->global_begin(),E = M->global_end();
- GV != E; ++GV) {
- MaxAlignment = std::max(MaxAlignment, GV->getAlignment());
- MaxGlobalType = std::max(MaxGlobalType, VE.getTypeID(GV->getType()));
-
- if (!GV->hasSection()) continue;
- // Give section names unique ID's.
- unsigned &Entry = SectionMap[GV->getSection()];
- if (Entry != 0) continue;
- WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, GV->getSection(),
- 0/*TODO*/, Stream);
- Entry = SectionMap.size();
+ for (const GlobalValue &GV : M->globals()) {
+ MaxAlignment = std::max(MaxAlignment, GV.getAlignment());
+ MaxGlobalType = std::max(MaxGlobalType, VE.getTypeID(GV.getType()));
+ if (GV.hasSection()) {
+ // Give section names unique ID's.
+ unsigned &Entry = SectionMap[GV.getSection()];
+ if (!Entry) {
+ WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, GV.getSection(),
+ 0/*TODO*/, Stream);
+ Entry = SectionMap.size();
+ }
+ }
}
- for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) {
- MaxAlignment = std::max(MaxAlignment, F->getAlignment());
- if (F->hasSection()) {
+ for (const Function &F : *M) {
+ MaxAlignment = std::max(MaxAlignment, F.getAlignment());
+ if (F.hasSection()) {
// Give section names unique ID's.
- unsigned &Entry = SectionMap[F->getSection()];
+ unsigned &Entry = SectionMap[F.getSection()];
if (!Entry) {
- WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, F->getSection(),
+ WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, F.getSection(),
0/*TODO*/, Stream);
Entry = SectionMap.size();
}
}
- if (F->hasGC()) {
+ if (F.hasGC()) {
// Same for GC names.
- unsigned &Entry = GCMap[F->getGC()];
+ unsigned &Entry = GCMap[F.getGC()];
if (!Entry) {
- WriteStringRecord(bitc::MODULE_CODE_GCNAME, F->getGC(),
+ WriteStringRecord(bitc::MODULE_CODE_GCNAME, F.getGC(),
0/*TODO*/, Stream);
Entry = GCMap.size();
}
@@ -453,26 +462,25 @@ static void WriteModuleInfo(const Module *M,
// Emit the global variable information.
SmallVector<unsigned, 64> Vals;
- for (Module::const_global_iterator GV = M->global_begin(),E = M->global_end();
- GV != E; ++GV) {
+ for (const GlobalVariable &GV : M->globals()) {
unsigned AbbrevToUse = 0;
// GLOBALVAR: [type, isconst, initid,
// linkage, alignment, section, visibility, threadlocal,
// unnamed_addr]
- Vals.push_back(VE.getTypeID(GV->getType()));
- Vals.push_back(GV->isConstant());
- Vals.push_back(GV->isDeclaration() ? 0 :
- (VE.getValueID(GV->getInitializer()) + 1));
+ Vals.push_back(VE.getTypeID(GV.getType()));
+ Vals.push_back(GV.isConstant());
+ Vals.push_back(GV.isDeclaration() ? 0 :
+ (VE.getValueID(GV.getInitializer()) + 1));
Vals.push_back(getEncodedLinkage(GV));
- Vals.push_back(Log2_32(GV->getAlignment())+1);
- Vals.push_back(GV->hasSection() ? SectionMap[GV->getSection()] : 0);
- if (GV->isThreadLocal() ||
- GV->getVisibility() != GlobalValue::DefaultVisibility ||
- GV->hasUnnamedAddr()) {
+ Vals.push_back(Log2_32(GV.getAlignment())+1);
+ Vals.push_back(GV.hasSection() ? SectionMap[GV.getSection()] : 0);
+ if (GV.isThreadLocal() ||
+ GV.getVisibility() != GlobalValue::DefaultVisibility ||
+ GV.hasUnnamedAddr()) {
Vals.push_back(getEncodedVisibility(GV));
- Vals.push_back(GV->isThreadLocal());
- Vals.push_back(GV->hasUnnamedAddr());
+ Vals.push_back(GV.isThreadLocal());
+ Vals.push_back(GV.hasUnnamedAddr());
} else {
AbbrevToUse = SimpleGVarAbbrev;
}
@@ -482,19 +490,19 @@ static void WriteModuleInfo(const Module *M,
}
// Emit the function proto information.
- for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) {
+ for (const Function &F : *M) {
// FUNCTION: [type, callingconv, isproto, paramattr,
// linkage, alignment, section, visibility, gc, unnamed_addr]
- Vals.push_back(VE.getTypeID(F->getType()));
- Vals.push_back(F->getCallingConv());
- Vals.push_back(F->isDeclaration());
+ Vals.push_back(VE.getTypeID(F.getType()));
+ Vals.push_back(F.getCallingConv());
+ Vals.push_back(F.isDeclaration());
Vals.push_back(getEncodedLinkage(F));
- Vals.push_back(VE.getAttributeID(F->getAttributes()));
- Vals.push_back(Log2_32(F->getAlignment())+1);
- Vals.push_back(F->hasSection() ? SectionMap[F->getSection()] : 0);
+ Vals.push_back(VE.getAttributeID(F.getAttributes()));
+ Vals.push_back(Log2_32(F.getAlignment())+1);
+ Vals.push_back(F.hasSection() ? SectionMap[F.getSection()] : 0);
Vals.push_back(getEncodedVisibility(F));
- Vals.push_back(F->hasGC() ? GCMap[F->getGC()] : 0);
- Vals.push_back(F->hasUnnamedAddr());
+ Vals.push_back(F.hasGC() ? GCMap[F.getGC()] : 0);
+ Vals.push_back(F.hasUnnamedAddr());
unsigned AbbrevToUse = 0;
Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse);
@@ -502,12 +510,11 @@ static void WriteModuleInfo(const Module *M,
}
// Emit the alias information.
- for (Module::const_alias_iterator AI = M->alias_begin(), E = M->alias_end();
- AI != E; ++AI) {
- Vals.push_back(VE.getTypeID(AI->getType()));
- Vals.push_back(VE.getValueID(AI->getAliasee()));
- Vals.push_back(getEncodedLinkage(AI));
- Vals.push_back(getEncodedVisibility(AI));
+ for (const GlobalAlias &A : M->aliases()) {
+ Vals.push_back(VE.getTypeID(A.getType()));
+ Vals.push_back(VE.getValueID(A.getAliasee()));
+ Vals.push_back(getEncodedLinkage(A));
+ Vals.push_back(getEncodedVisibility(A));
unsigned AbbrevToUse = 0;
Stream.EmitRecord(bitc::MODULE_CODE_ALIAS, Vals, AbbrevToUse);
Vals.clear();
@@ -517,14 +524,12 @@ static void WriteModuleInfo(const Module *M,
static uint64_t GetOptimizationFlags(const Value *V) {
uint64_t Flags = 0;
- if (const OverflowingBinaryOperator *OBO =
- dyn_cast<OverflowingBinaryOperator>(V)) {
+ if (const auto *OBO = dyn_cast<OverflowingBinaryOperator>(V)) {
if (OBO->hasNoSignedWrap())
Flags |= 1 << bitc::OBO_NO_SIGNED_WRAP;
if (OBO->hasNoUnsignedWrap())
Flags |= 1 << bitc::OBO_NO_UNSIGNED_WRAP;
- } else if (const PossiblyExactOperator *PEO =
- dyn_cast<PossiblyExactOperator>(V)) {
+ } else if (const auto *PEO = dyn_cast<PossiblyExactOperator>(V)) {
if (PEO->isExact())
Flags |= 1 << bitc::PEO_EXACT;
}
@@ -532,89 +537,154 @@ static uint64_t GetOptimizationFlags(const Value *V) {
return Flags;
}
-static void WriteMDNode(const MDNode *N,
- const llvm_2_9_func::ValueEnumerator &VE,
- BitstreamWriter &Stream,
- SmallVector<uint64_t, 64> &Record) {
+static void WriteValueAsMetadata(const ValueAsMetadata *MD,
+ const llvm_2_9_func::ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record) {
+ // Mimic an MDNode with a value as one operand.
+ Value *V = MD->getValue();
+ Record.push_back(VE.getTypeID(V->getType()));
+ Record.push_back(VE.getValueID(V));
+ Stream.EmitRecord(bitc::METADATA_OLD_NODE, Record, 0);
+ Record.clear();
+}
+
+static void WriteMDTuple(const MDTuple *N, const llvm_2_9_func::ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record, unsigned Abbrev) {
for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
- if (N->getOperand(i)) {
- Record.push_back(VE.getTypeID(N->getOperand(i)->getType()));
- Record.push_back(VE.getValueID(N->getOperand(i)));
- } else {
- Record.push_back(VE.getTypeID(Type::getVoidTy(N->getContext())));
+ Metadata *MD = N->getOperand(i);
+ assert(!(MD && isa<LocalAsMetadata>(MD)) &&
+ "Unexpected function-local metadata");
+ if (!MD) {
+ // TODO(srhines): I don't believe this case can exist for RS.
+ Record.push_back(VE.getTypeID(llvm::Type::getVoidTy(N->getContext())));
Record.push_back(0);
+ } else if (const auto *MDC = dyn_cast<ConstantAsMetadata>(MD)) {
+ Record.push_back(VE.getTypeID(MDC->getType()));
+ Record.push_back(VE.getValueID(MDC->getValue()));
+ } else {
+ Record.push_back(VE.getTypeID(
+ llvm::Type::getMetadataTy(N->getContext())));
+ Record.push_back(VE.getMetadataID(MD));
}
}
- unsigned MDCode = N->isFunctionLocal() ? bitc::METADATA_FN_NODE :
- bitc::METADATA_NODE;
- Stream.EmitRecord(MDCode, Record, 0);
+ Stream.EmitRecord(bitc::METADATA_OLD_NODE, Record, Abbrev);
Record.clear();
}
+/*static void WriteMDLocation(const MDLocation *N, const llvm_2_9_func::ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.push_back(N->isDistinct());
+ Record.push_back(N->getLine());
+ Record.push_back(N->getColumn());
+ Record.push_back(VE.getMetadataID(N->getScope()));
+ Record.push_back(VE.getMetadataOrNullID(N->getInlinedAt()));
+
+ Stream.EmitRecord(bitc::METADATA_LOCATION, Record, Abbrev);
+ Record.clear();
+}
+
+static void WriteGenericDebugNode(const GenericDebugNode *,
+ const llvm_2_9_func::ValueEnumerator &, BitstreamWriter &,
+ SmallVectorImpl<uint64_t> &, unsigned) {
+ llvm_unreachable("unimplemented");
+}*/
+
static void WriteModuleMetadata(const Module *M,
const llvm_2_9_func::ValueEnumerator &VE,
BitstreamWriter &Stream) {
- const llvm_2_9_func::ValueEnumerator::ValueList &Vals = VE.getMDValues();
- bool StartedMetadataBlock = false;
+ const auto &MDs = VE.getMDs();
+ if (MDs.empty() && M->named_metadata_empty())
+ return;
+
+ // RenderScript files *ALWAYS* have metadata!
+ Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
+
unsigned MDSAbbrev = 0;
- SmallVector<uint64_t, 64> Record;
- for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
+ if (VE.hasMDString()) {
+ // Abbrev for METADATA_STRING.
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_STRING));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
+ MDSAbbrev = Stream.EmitAbbrev(Abbv);
+ }
- if (const MDNode *N = dyn_cast<MDNode>(Vals[i].first)) {
- if (!N->isFunctionLocal() || !N->getFunction()) {
- if (!StartedMetadataBlock) {
- Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
- StartedMetadataBlock = true;
- }
- WriteMDNode(N, VE, Stream, Record);
- }
- } else if (const MDString *MDS = dyn_cast<MDString>(Vals[i].first)) {
- if (!StartedMetadataBlock) {
- Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
-
- // Abbrev for METADATA_STRING.
- BitCodeAbbrev *Abbv = new BitCodeAbbrev();
- Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_STRING));
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
- MDSAbbrev = Stream.EmitAbbrev(Abbv);
- StartedMetadataBlock = true;
- }
+ unsigned MDLocationAbbrev = 0;
+ if (VE.hasMDLocation()) {
+ // TODO(srhines): Should be unreachable for RenderScript.
+ // Abbrev for METADATA_LOCATION.
+ //
+ // Assume the column is usually under 128, and always output the inlined-at
+ // location (it's never more expensive than building an array size 1).
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_LOCATION));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+ MDLocationAbbrev = Stream.EmitAbbrev(Abbv);
+ }
- // Code: [strchar x N]
- Record.append(MDS->begin(), MDS->end());
+ unsigned NameAbbrev = 0;
+ if (!M->named_metadata_empty()) {
+ // Abbrev for METADATA_NAME.
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_NAME));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
+ NameAbbrev = Stream.EmitAbbrev(Abbv);
+ }
- // Emit the finished record.
- Stream.EmitRecord(bitc::METADATA_STRING, Record, MDSAbbrev);
- Record.clear();
+ unsigned MDTupleAbbrev = 0;
+ //unsigned GenericDebugNodeAbbrev = 0;
+ SmallVector<uint64_t, 64> Record;
+ for (const Metadata *MD : MDs) {
+ if (const MDNode *N = dyn_cast<MDNode>(MD)) {
+ switch (N->getMetadataID()) {
+ default:
+ llvm_unreachable("Invalid MDNode subclass");
+#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS)
+#define HANDLE_MDNODE_LEAF(CLASS) \
+ case Metadata::CLASS##Kind: \
+ Write##CLASS(cast<CLASS>(N), VE, Stream, Record, CLASS##Abbrev); \
+ continue;
+#include "llvm/IR/Metadata.def"
+ }
}
+ if (const auto *MDC = dyn_cast<ConstantAsMetadata>(MD)) {
+ WriteValueAsMetadata(MDC, VE, Stream, Record);
+ continue;
+ }
+ const MDString *MDS = cast<MDString>(MD);
+ // Code: [strchar x N]
+ Record.append(MDS->bytes_begin(), MDS->bytes_end());
+
+ // Emit the finished record.
+ Stream.EmitRecord(bitc::METADATA_STRING, Record, MDSAbbrev);
+ Record.clear();
}
// Write named metadata.
- for (Module::const_named_metadata_iterator I = M->named_metadata_begin(),
- E = M->named_metadata_end(); I != E; ++I) {
- const NamedMDNode *NMD = I;
- if (!StartedMetadataBlock) {
- Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
- StartedMetadataBlock = true;
- }
-
+ for (const NamedMDNode &NMD : M->named_metadata()) {
// Write name.
- StringRef Str = NMD->getName();
- for (unsigned i = 0, e = Str.size(); i != e; ++i)
- Record.push_back(Str[i]);
- Stream.EmitRecord(bitc::METADATA_NAME, Record, 0/*TODO*/);
+ StringRef Str = NMD.getName();
+ Record.append(Str.bytes_begin(), Str.bytes_end());
+ Stream.EmitRecord(bitc::METADATA_NAME, Record, NameAbbrev);
Record.clear();
// Write named metadata operands.
- for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i)
- Record.push_back(VE.getValueID(NMD->getOperand(i)));
+ for (const MDNode *N : NMD.operands())
+ Record.push_back(VE.getMetadataID(N));
Stream.EmitRecord(bitc::METADATA_NAMED_NODE, Record, 0);
Record.clear();
}
- if (StartedMetadataBlock)
- Stream.ExitBlock();
+ Stream.ExitBlock();
}
static void WriteFunctionLocalMetadata(const Function &F,
@@ -622,16 +692,16 @@ static void WriteFunctionLocalMetadata(const Function &F,
BitstreamWriter &Stream) {
bool StartedMetadataBlock = false;
SmallVector<uint64_t, 64> Record;
- const SmallVector<const MDNode *, 8> &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) {
- if (!StartedMetadataBlock) {
- Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
- StartedMetadataBlock = true;
- }
- WriteMDNode(N, VE, Stream, Record);
- }
+ const SmallVectorImpl<const LocalAsMetadata *> &MDs =
+ VE.getFunctionLocalMDs();
+ for (unsigned i = 0, e = MDs.size(); i != e; ++i) {
+ assert(MDs[i] && "Expected valid function-local metadata");
+ if (!StartedMetadataBlock) {
+ Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
+ StartedMetadataBlock = true;
+ }
+ WriteValueAsMetadata(MDs[i], VE, Stream, Record);
+ }
if (StartedMetadataBlock)
Stream.ExitBlock();
@@ -646,7 +716,7 @@ 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;
+ 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();
@@ -661,7 +731,7 @@ static void WriteMetadataAttachment(const Function &F,
for (unsigned i = 0, e = MDs.size(); i != e; ++i) {
Record.push_back(MDs[i].first);
- Record.push_back(VE.getValueID(MDs[i].second));
+ Record.push_back(VE.getMetadataID(MDs[i].second));
}
Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0);
Record.clear();
@@ -737,7 +807,7 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
SmallVector<uint64_t, 64> Record;
const llvm_2_9_func::ValueEnumerator::ValueList &Vals = VE.getValues();
- Type *LastTy = 0;
+ Type *LastTy = nullptr;
for (unsigned i = FirstVal; i != LastVal; ++i) {
const Value *V = Vals[i].first;
// If we need to switch types, do so now.
@@ -1019,9 +1089,9 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
break;
case Instruction::GetElementPtr:
- Code = bitc::FUNC_CODE_INST_GEP;
+ Code = bitc::FUNC_CODE_INST_GEP_OLD;
if (cast<GEPOperator>(&I)->isInBounds())
- Code = bitc::FUNC_CODE_INST_INBOUNDS_GEP;
+ Code = bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD;
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
PushValueAndType(I.getOperand(i), InstID, Vals, VE);
break;
@@ -1104,14 +1174,13 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
{
Code = bitc::FUNC_CODE_INST_SWITCH;
const SwitchInst &SI = cast<SwitchInst>(I);
-
Vals.push_back(VE.getTypeID(SI.getCondition()->getType()));
Vals.push_back(VE.getValueID(SI.getCondition()));
Vals.push_back(VE.getValueID(SI.getDefaultDest()));
for (SwitchInst::ConstCaseIt i = SI.case_begin(), e = SI.case_end();
i != e; ++i) {
- Vals.push_back(VE.getValueID(i.getCaseValue()));
- Vals.push_back(VE.getValueID(i.getCaseSuccessor()));
+ Vals.push_back(VE.getValueID(i.getCaseValue()));
+ Vals.push_back(VE.getValueID(i.getCaseSuccessor()));
}
}
break;
@@ -1396,8 +1465,8 @@ static void WriteFunction(const Function &F, llvm_2_9_func::ValueEnumerator &VE,
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);
+ Vals.push_back(VE.getMetadataOrNullID(Scope));
+ Vals.push_back(VE.getMetadataOrNullID(IA));
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals);
Vals.clear();
@@ -1576,7 +1645,6 @@ static void WriteBlockInfo(const llvm_2_9_func::ValueEnumerator &VE,
Stream.ExitBlock();
}
-
/// WriteModule - Emit the specified module to the bitstream.
static void WriteModule(const Module *M, BitstreamWriter &Stream) {
Stream.EnterSubblock(bitc::MODULE_BLOCK_ID, 3);
@@ -1589,7 +1657,7 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream) {
}
// Analyze the module, enumerating globals, functions, etc.
- llvm_2_9_func::ValueEnumerator VE(M);
+ llvm_2_9_func::ValueEnumerator VE(*M);
// Emit blockinfo, which defines the standard abbreviations etc.
WriteBlockInfo(VE, Stream);
diff --git a/BitWriter_2_9_func/ValueEnumerator.cpp b/BitWriter_2_9_func/ValueEnumerator.cpp
index a5ff58c..07217f6 100644
--- a/BitWriter_2_9_func/ValueEnumerator.cpp
+++ b/BitWriter_2_9_func/ValueEnumerator.cpp
@@ -15,6 +15,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
@@ -31,20 +32,21 @@ static bool isIntOrIntVectorValue(const std::pair<const Value*, unsigned> &V) {
}
/// ValueEnumerator - Enumerate module-level information.
-ValueEnumerator::ValueEnumerator(const Module *M) {
+ValueEnumerator::ValueEnumerator(const llvm::Module &M)
+ : HasMDString(false), HasMDLocation(false) {
// Enumerate the global variables.
- for (Module::const_global_iterator I = M->global_begin(),
- E = M->global_end(); I != E; ++I)
+ for (llvm::Module::const_global_iterator I = M.global_begin(), E = M.global_end();
+ I != E; ++I)
EnumerateValue(I);
// Enumerate the functions.
- for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) {
+ for (llvm::Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) {
EnumerateValue(I);
EnumerateAttributes(cast<Function>(I)->getAttributes());
}
// Enumerate the aliases.
- for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
+ for (llvm::Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
I != E; ++I)
EnumerateValue(I);
@@ -52,55 +54,64 @@ ValueEnumerator::ValueEnumerator(const Module *M) {
unsigned FirstConstant = Values.size();
// Enumerate the global variable initializers.
- for (Module::const_global_iterator I = M->global_begin(),
- E = M->global_end(); I != E; ++I)
+ for (llvm::Module::const_global_iterator I = M.global_begin(), E = M.global_end();
+ I != E; ++I)
if (I->hasInitializer())
EnumerateValue(I->getInitializer());
// Enumerate the aliasees.
- for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
+ for (llvm::Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
I != E; ++I)
EnumerateValue(I->getAliasee());
- // Insert constants and metadata that are named at module level into the slot
+ // Enumerate the metadata type.
+ //
+ // TODO: Move this to ValueEnumerator::EnumerateOperandType() once bitcode
+ // only encodes the metadata type when it's used as a value.
+ EnumerateType(Type::getMetadataTy(M.getContext()));
+
+ // 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());
+ EnumerateValueSymbolTable(M.getValueSymbolTable());
EnumerateNamedMetadata(M);
- SmallVector<std::pair<unsigned, MDNode*>, 8> MDs;
+ SmallVector<std::pair<unsigned, MDNode *>, 8> MDs;
// Enumerate types used by function bodies and argument lists.
- for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) {
-
- for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();
- I != E; ++I)
- EnumerateType(I->getType());
-
- 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){
- for (User::const_op_iterator OI = I->op_begin(), E = I->op_end();
- OI != E; ++OI) {
- if (MDNode *MD = dyn_cast<MDNode>(*OI))
- if (MD->isFunctionLocal() && MD->getFunction())
- // These will get enumerated during function-incorporation.
- continue;
- EnumerateOperandType(*OI);
+ for (const Function &F : M) {
+ for (const Argument &A : F.args())
+ EnumerateType(A.getType());
+
+ for (const BasicBlock &BB : F)
+ for (const Instruction &I : BB) {
+ for (const Use &Op : I.operands()) {
+ auto *MD = dyn_cast<MetadataAsValue>(&Op);
+ if (!MD) {
+ EnumerateOperandType(Op);
+ continue;
+ }
+
+ // Local metadata is enumerated during function-incorporation.
+ if (isa<LocalAsMetadata>(MD->getMetadata()))
+ continue;
+
+ EnumerateMetadata(MD->getMetadata());
}
- EnumerateType(I->getType());
- if (const CallInst *CI = dyn_cast<CallInst>(I))
+ EnumerateType(I.getType());
+ if (const CallInst *CI = dyn_cast<CallInst>(&I))
EnumerateAttributes(CI->getAttributes());
- else if (const InvokeInst *II = dyn_cast<InvokeInst>(I))
+ else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I))
EnumerateAttributes(II->getAttributes());
// Enumerate metadata attached with this instruction.
MDs.clear();
- I->getAllMetadataOtherThanDebugLoc(MDs);
+ I.getAllMetadataOtherThanDebugLoc(MDs);
for (unsigned i = 0, e = MDs.size(); i != e; ++i)
EnumerateMetadata(MDs[i].second);
- if (!I->getDebugLoc().isUnknown()) {
+ if (!I.getDebugLoc().isUnknown()) {
MDNode *Scope, *IA;
- I->getDebugLoc().getScopeAndInlinedAt(Scope, IA, I->getContext());
+ I.getDebugLoc().getScopeAndInlinedAt(Scope, IA, I.getContext());
if (Scope) EnumerateMetadata(Scope);
if (IA) EnumerateMetadata(IA);
}
@@ -122,11 +133,8 @@ void ValueEnumerator::setInstructionID(const Instruction *I) {
}
unsigned ValueEnumerator::getValueID(const Value *V) const {
- if (isa<MDNode>(V) || isa<MDString>(V)) {
- ValueMapType::const_iterator I = MDValueMap.find(V);
- assert(I != MDValueMap.end() && "Value not in slotcalculator!");
- return I->second-1;
- }
+ if (auto *MD = dyn_cast<MetadataAsValue>(V))
+ return getMetadataID(MD->getMetadata());
ValueMapType::const_iterator I = ValueMap.find(V);
assert(I != ValueMap.end() && "Value not in slotcalculator!");
@@ -156,12 +164,11 @@ void ValueEnumerator::print(raw_ostream &OS, const ValueMapType &Map,
V->dump();
OS << " Uses(" << std::distance(V->use_begin(),V->use_end()) << "):";
- for (Value::const_use_iterator UI = V->use_begin(), UE = V->use_end();
- UI != UE; ++UI) {
- if (UI != V->use_begin())
+ for (const Use &U : V->uses()) {
+ if (&U != &*V->use_begin())
OS << ",";
- if((*UI)->hasName())
- OS << " " << (*UI)->getName();
+ if(U->hasName())
+ OS << " " << U->getName();
else
OS << " [null]";
@@ -170,6 +177,19 @@ void ValueEnumerator::print(raw_ostream &OS, const ValueMapType &Map,
}
}
+void ValueEnumerator::print(llvm::raw_ostream &OS, const MetadataMapType &Map,
+ const char *Name) const {
+
+ OS << "Map Name: " << Name << "\n";
+ OS << "Size: " << Map.size() << "\n";
+ for (auto I = Map.begin(), E = Map.end(); I != E; ++I) {
+ const llvm::Metadata *MD = I->first;
+ OS << "Metadata: slot = " << I->second << "\n";
+ MD->print(OS);
+ }
+}
+
+
// Optimize constant ordering.
namespace {
struct CstSortPredicate {
@@ -216,9 +236,10 @@ void ValueEnumerator::EnumerateValueSymbolTable(const ValueSymbolTable &VST) {
/// EnumerateNamedMetadata - Insert all of the values referenced by
/// named metadata in the specified module.
-void ValueEnumerator::EnumerateNamedMetadata(const Module *M) {
- for (Module::const_named_metadata_iterator I = M->named_metadata_begin(),
- E = M->named_metadata_end(); I != E; ++I)
+void ValueEnumerator::EnumerateNamedMetadata(const llvm::Module &M) {
+ for (llvm::Module::const_named_metadata_iterator I = M.named_metadata_begin(),
+ E = M.named_metadata_end();
+ I != E; ++I)
EnumerateNamedMDNode(I);
}
@@ -231,84 +252,62 @@ void ValueEnumerator::EnumerateNamedMDNode(const NamedMDNode *MD) {
/// and types referenced by the given MDNode.
void ValueEnumerator::EnumerateMDNodeOperands(const MDNode *N) {
for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
- if (Value *V = N->getOperand(i)) {
- if (isa<MDNode>(V) || isa<MDString>(V))
- EnumerateMetadata(V);
- else if (!isa<Instruction>(V) && !isa<Argument>(V))
- EnumerateValue(V);
- } else
- EnumerateType(Type::getVoidTy(N->getContext()));
+ Metadata *MD = N->getOperand(i);
+ if (!MD)
+ continue;
+ assert(!isa<LocalAsMetadata>(MD) && "MDNodes cannot be function-local");
+ EnumerateMetadata(MD);
}
}
-void ValueEnumerator::EnumerateMetadata(const Value *MD) {
- assert((isa<MDNode>(MD) || isa<MDString>(MD)) && "Invalid metadata kind");
-
- // Enumerate the type of this value.
- EnumerateType(MD->getType());
+void ValueEnumerator::EnumerateMetadata(const llvm::Metadata *MD) {
+ assert(
+ (isa<MDNode>(MD) || isa<MDString>(MD) || isa<ConstantAsMetadata>(MD)) &&
+ "Invalid metadata kind");
- const MDNode *N = dyn_cast<MDNode>(MD);
+ // Insert a dummy ID to block the co-recursive call to
+ // EnumerateMDNodeOperands() from re-visiting MD in a cyclic graph.
+ //
+ // Return early if there's already an ID.
+ if (!MDValueMap.insert(std::make_pair(MD, 0)).second)
+ return;
- // In the module-level pass, skip function-local nodes themselves, but
- // do walk their operands.
- if (N && N->isFunctionLocal() && N->getFunction()) {
+ // Visit operands first to minimize RAUW.
+ if (auto *N = dyn_cast<MDNode>(MD))
EnumerateMDNodeOperands(N);
- return;
- }
+ else if (auto *C = dyn_cast<ConstantAsMetadata>(MD))
+ EnumerateValue(C->getValue());
- // Check to see if it's already in!
- unsigned &MDValueID = MDValueMap[MD];
- if (MDValueID) {
- // Increment use count.
- MDValues[MDValueID-1].second++;
- return;
- }
- MDValues.push_back(std::make_pair(MD, 1U));
- MDValueID = MDValues.size();
+ HasMDString |= isa<MDString>(MD);
+ HasMDLocation |= isa<MDLocation>(MD);
- // Enumerate all non-function-local operands.
- if (N)
- EnumerateMDNodeOperands(N);
+ // Replace the dummy ID inserted above with the correct one. MDValueMap may
+ // have changed by inserting operands, so we need a fresh lookup here.
+ MDs.push_back(MD);
+ MDValueMap[MD] = MDs.size();
}
/// EnumerateFunctionLocalMetadataa - Incorporate function-local metadata
-/// information reachable from the given MDNode.
-void ValueEnumerator::EnumerateFunctionLocalMetadata(const MDNode *N) {
- assert(N->isFunctionLocal() && N->getFunction() &&
- "EnumerateFunctionLocalMetadata called on non-function-local mdnode!");
-
- // Enumerate the type of this value.
- EnumerateType(N->getType());
-
+/// information reachable from the metadata.
+void ValueEnumerator::EnumerateFunctionLocalMetadata(
+ const llvm::LocalAsMetadata *Local) {
// Check to see if it's already in!
- unsigned &MDValueID = MDValueMap[N];
- if (MDValueID) {
- // Increment use count.
- MDValues[MDValueID-1].second++;
+ unsigned &MDValueID = MDValueMap[Local];
+ if (MDValueID)
return;
- }
- MDValues.push_back(std::make_pair(N, 1U));
- MDValueID = MDValues.size();
-
- // To incoroporate function-local information visit all function-local
- // MDNodes and all function-local values they reference.
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
- if (Value *V = N->getOperand(i)) {
- if (MDNode *O = dyn_cast<MDNode>(V)) {
- if (O->isFunctionLocal() && O->getFunction())
- EnumerateFunctionLocalMetadata(O);
- } else if (isa<Instruction>(V) || isa<Argument>(V))
- EnumerateValue(V);
- }
- // Also, collect all function-local MDNodes for easy access.
- FunctionLocalMDs.push_back(N);
+ MDs.push_back(Local);
+ MDValueID = MDs.size();
+
+ EnumerateValue(Local->getValue());
+
+ // Also, collect all function-local metadata for easy access.
+ FunctionLocalMDs.push_back(Local);
}
void ValueEnumerator::EnumerateValue(const Value *V) {
assert(!V->getType()->isVoidTy() && "Can't insert void values!");
- assert(!isa<MDNode>(V) && !isa<MDString>(V) &&
- "EnumerateValue doesn't handle Metadata!");
+ assert(!isa<MetadataAsValue>(V) && "EnumerateValue doesn't handle Metadata!");
// Check to see if it's already in!
unsigned &ValueID = ValueMap[V];
@@ -378,9 +377,8 @@ void ValueEnumerator::EnumerateType(Type *Ty) {
// 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);
+ for (Type *SubTy : Ty->subtypes())
+ EnumerateType(SubTy);
// Refresh the TypeID pointer in case the table rehashed.
TypeID = &TypeMap[Ty];
@@ -404,30 +402,35 @@ void ValueEnumerator::EnumerateType(Type *Ty) {
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.
- if (ValueMap.count(V)) return;
+ if (auto *MD = dyn_cast<MetadataAsValue>(V)) {
+ assert(!isa<LocalAsMetadata>(MD->getMetadata()) &&
+ "Function-local metadata should be left for later");
- // This constant may have operands, make sure to enumerate the types in
- // them.
- for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) {
- const Value *Op = C->getOperand(i);
+ EnumerateMetadata(MD->getMetadata());
+ return;
+ }
- // Don't enumerate basic blocks here, this happens as operands to
- // blockaddress.
- if (isa<BasicBlock>(Op)) continue;
+ const Constant *C = dyn_cast<Constant>(V);
+ if (!C)
+ return;
- EnumerateOperandType(Op);
- }
+ // If this constant is already enumerated, ignore it, we know its type must
+ // be enumerated.
+ if (ValueMap.count(C))
+ return;
- if (const MDNode *N = dyn_cast<MDNode>(V)) {
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
- if (Value *Elem = N->getOperand(i))
- EnumerateOperandType(Elem);
- }
- } else if (isa<MDString>(V) || isa<MDNode>(V))
- EnumerateMetadata(V);
+ // This constant may have operands, make sure to enumerate the types in
+ // 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);
+ }
}
void ValueEnumerator::EnumerateAttributes(AttributeSet PAL) {
@@ -455,7 +458,7 @@ void ValueEnumerator::EnumerateAttributes(AttributeSet PAL) {
void ValueEnumerator::incorporateFunction(const Function &F) {
InstructionCount = 0;
NumModuleValues = Values.size();
- NumModuleMDValues = MDValues.size();
+ NumModuleMDs = MDs.size();
// Adding function arguments to the value table.
for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end();
@@ -486,24 +489,16 @@ void ValueEnumerator::incorporateFunction(const Function &F) {
FirstInstID = Values.size();
- SmallVector<MDNode *, 8> FnLocalMDVector;
+ SmallVector<llvm::LocalAsMetadata *, 8> FnLocalMDVector;
// Add all of the instructions.
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) {
for (User::const_op_iterator OI = I->op_begin(), E = I->op_end();
OI != E; ++OI) {
- if (MDNode *MD = dyn_cast<MDNode>(*OI))
- if (MD->isFunctionLocal() && MD->getFunction())
+ if (auto *MD = dyn_cast<llvm::MetadataAsValue>(&*OI))
+ if (auto *Local = dyn_cast<LocalAsMetadata>(MD->getMetadata()))
// Enumerate metadata after the instructions they might refer to.
- FnLocalMDVector.push_back(MD);
- }
-
- SmallVector<std::pair<unsigned, MDNode*>, 8> MDs;
- I->getAllMetadataOtherThanDebugLoc(MDs);
- for (unsigned i = 0, e = MDs.size(); i != e; ++i) {
- MDNode *N = MDs[i].second;
- if (N->isFunctionLocal() && N->getFunction())
- FnLocalMDVector.push_back(N);
+ FnLocalMDVector.push_back(Local);
}
if (!I->getType()->isVoidTy())
@@ -520,13 +515,13 @@ void ValueEnumerator::purgeFunction() {
/// Remove purged values from the ValueMap.
for (unsigned i = NumModuleValues, e = Values.size(); i != e; ++i)
ValueMap.erase(Values[i].first);
- for (unsigned i = NumModuleMDValues, e = MDValues.size(); i != e; ++i)
- MDValueMap.erase(MDValues[i].first);
+ for (unsigned i = NumModuleMDs, e = MDs.size(); i != e; ++i)
+ MDValueMap.erase(MDs[i]);
for (unsigned i = 0, e = BasicBlocks.size(); i != e; ++i)
ValueMap.erase(BasicBlocks[i]);
Values.resize(NumModuleValues);
- MDValues.resize(NumModuleMDValues);
+ MDs.resize(NumModuleMDs);
BasicBlocks.clear();
FunctionLocalMDs.clear();
}
diff --git a/BitWriter_2_9_func/ValueEnumerator.h b/BitWriter_2_9_func/ValueEnumerator.h
index 9cade7a..a1b1a7e 100644
--- a/BitWriter_2_9_func/ValueEnumerator.h
+++ b/BitWriter_2_9_func/ValueEnumerator.h
@@ -27,6 +27,8 @@ class Instruction;
class BasicBlock;
class Function;
class Module;
+class Metadata;
+class LocalAsMetadata;
class MDNode;
class NamedMDNode;
class AttributeSet;
@@ -52,9 +54,14 @@ private:
typedef llvm::DenseMap<const llvm::Value*, unsigned> ValueMapType;
ValueMapType ValueMap;
ValueList Values;
- ValueList MDValues;
- llvm::SmallVector<const llvm::MDNode *, 8> FunctionLocalMDs;
- ValueMapType MDValueMap;
+
+
+ std::vector<const llvm::Metadata *> MDs;
+ llvm::SmallVector<const llvm::LocalAsMetadata *, 8> FunctionLocalMDs;
+ typedef llvm::DenseMap<const llvm::Metadata *, unsigned> MetadataMapType;
+ MetadataMapType MDValueMap;
+ bool HasMDString;
+ bool HasMDLocation;
typedef llvm::DenseMap<llvm::AttributeSet, unsigned> AttributeGroupMapType;
AttributeGroupMapType AttributeGroupMap;
@@ -82,20 +89,33 @@ private:
/// When a function is incorporated, this is the size of the MDValues list
/// before incorporation.
- unsigned NumModuleMDValues;
+ unsigned NumModuleMDs;
unsigned FirstFuncConstantID;
unsigned FirstInstID;
- ValueEnumerator(const ValueEnumerator &); // DO NOT IMPLEMENT
- void operator=(const ValueEnumerator &); // DO NOT IMPLEMENT
+ ValueEnumerator(const ValueEnumerator &) = delete;
+ void operator=(const ValueEnumerator &) = delete;
public:
- ValueEnumerator(const llvm::Module *M);
+ ValueEnumerator(const llvm::Module &M);
void dump() const;
void print(llvm::raw_ostream &OS, const ValueMapType &Map, const char *Name) const;
+ void print(llvm::raw_ostream &OS, const MetadataMapType &Map,
+ const char *Name) const;
unsigned getValueID(const llvm::Value *V) const;
+ unsigned getMetadataID(const llvm::Metadata *MD) const {
+ auto ID = getMetadataOrNullID(MD);
+ assert(ID != 0 && "Metadata not in slotcalculator!");
+ return ID - 1;
+ }
+ unsigned getMetadataOrNullID(const llvm::Metadata *MD) const {
+ return MDValueMap.lookup(MD);
+ }
+
+ bool hasMDString() const { return HasMDString; }
+ bool hasMDLocation() const { return HasMDLocation; }
unsigned getTypeID(llvm::Type *T) const {
TypeMapType::const_iterator I = TypeMap.find(T);
@@ -128,8 +148,8 @@ public:
}
const ValueList &getValues() const { return Values; }
- const ValueList &getMDValues() const { return MDValues; }
- const llvm::SmallVector<const llvm::MDNode *, 8> &getFunctionLocalMDValues() const {
+ const std::vector<const llvm::Metadata *> &getMDs() const { return MDs; }
+ const llvm::SmallVectorImpl<const llvm::LocalAsMetadata *> &getFunctionLocalMDs() const {
return FunctionLocalMDs;
}
const TypeList &getTypes() const { return Types; }
@@ -158,8 +178,8 @@ private:
void OptimizeConstants(unsigned CstStart, unsigned CstEnd);
void EnumerateMDNodeOperands(const llvm::MDNode *N);
- void EnumerateMetadata(const llvm::Value *MD);
- void EnumerateFunctionLocalMetadata(const llvm::MDNode *N);
+ void EnumerateMetadata(const llvm::Metadata *MD);
+ void EnumerateFunctionLocalMetadata(const llvm::LocalAsMetadata *Local);
void EnumerateNamedMDNode(const llvm::NamedMDNode *NMD);
void EnumerateValue(const llvm::Value *V);
void EnumerateType(llvm::Type *T);
@@ -167,7 +187,7 @@ private:
void EnumerateAttributes(llvm::AttributeSet PAL);
void EnumerateValueSymbolTable(const llvm::ValueSymbolTable &ST);
- void EnumerateNamedMetadata(const llvm::Module *M);
+ void EnumerateNamedMetadata(const llvm::Module &M);
};
} // End llvm_2_9_func namespace
diff --git a/BitWriter_3_2/BitcodeWriter.cpp b/BitWriter_3_2/BitcodeWriter.cpp
index e551035..9e3bfbe 100644
--- a/BitWriter_3_2/BitcodeWriter.cpp
+++ b/BitWriter_3_2/BitcodeWriter.cpp
@@ -18,11 +18,13 @@
#include "llvm/Bitcode/BitstreamWriter.h"
#include "llvm/Bitcode/LLVMBitCodes.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugInfoMetadata.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/UseListOrder.h"
#include "llvm/IR/ValueSymbolTable.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
@@ -33,13 +35,9 @@
#include <map>
using namespace llvm;
-static bool EnablePreserveUseListOrdering = false;
-
/// These are manifest constants used by the bitcode writer. They do not need to
/// be kept in sync with the reader, but need to be consistent within this file.
enum {
- CurVersion = 0,
-
// VALUE_SYMTAB_BLOCK abbrev id's.
VST_ENTRY_8_ABBREV = bitc::FIRST_APPLICATION_ABBREV,
VST_ENTRY_7_ABBREV,
@@ -59,10 +57,7 @@ enum {
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) {
@@ -346,25 +341,36 @@ static void WriteTypeTable(const llvm_3_2::ValueEnumerator &VE,
Stream.ExitBlock();
}
-static unsigned getEncodedLinkage(const GlobalValue *GV) {
- switch (GV->getLinkage()) {
- case GlobalValue::ExternalLinkage: return 0;
- case GlobalValue::WeakAnyLinkage: return 1;
- case GlobalValue::AppendingLinkage: return 2;
- case GlobalValue::InternalLinkage: return 3;
- case GlobalValue::LinkOnceAnyLinkage: return 4;
- case GlobalValue::ExternalWeakLinkage: return 7;
- case GlobalValue::CommonLinkage: return 8;
- case GlobalValue::PrivateLinkage: return 9;
- case GlobalValue::WeakODRLinkage: return 10;
- case GlobalValue::LinkOnceODRLinkage: return 11;
- case GlobalValue::AvailableExternallyLinkage: return 12;
+static unsigned getEncodedLinkage(const GlobalValue &GV) {
+ switch (GV.getLinkage()) {
+ case GlobalValue::ExternalLinkage:
+ return 0;
+ case GlobalValue::WeakAnyLinkage:
+ return 1;
+ case GlobalValue::AppendingLinkage:
+ return 2;
+ case GlobalValue::InternalLinkage:
+ return 3;
+ case GlobalValue::LinkOnceAnyLinkage:
+ return 4;
+ case GlobalValue::ExternalWeakLinkage:
+ return 7;
+ case GlobalValue::CommonLinkage:
+ return 8;
+ case GlobalValue::PrivateLinkage:
+ return 9;
+ case GlobalValue::WeakODRLinkage:
+ return 10;
+ case GlobalValue::LinkOnceODRLinkage:
+ return 11;
+ case GlobalValue::AvailableExternallyLinkage:
+ return 12;
}
llvm_unreachable("Invalid linkage");
}
-static unsigned getEncodedVisibility(const GlobalValue *GV) {
- switch (GV->getVisibility()) {
+static unsigned getEncodedVisibility(const GlobalValue &GV) {
+ switch (GV.getVisibility()) {
case GlobalValue::DefaultVisibility: return 0;
case GlobalValue::HiddenVisibility: return 1;
case GlobalValue::ProtectedVisibility: return 2;
@@ -372,8 +378,8 @@ static unsigned getEncodedVisibility(const GlobalValue *GV) {
llvm_unreachable("Invalid visibility");
}
-static unsigned getEncodedThreadLocalMode(const GlobalVariable *GV) {
- switch (GV->getThreadLocalMode()) {
+static unsigned getEncodedThreadLocalMode(const GlobalVariable &GV) {
+ switch (GV.getThreadLocalMode()) {
case GlobalVariable::NotThreadLocal: return 0;
case GlobalVariable::GeneralDynamicTLSModel: return 1;
case GlobalVariable::LocalDynamicTLSModel: return 2;
@@ -392,9 +398,9 @@ static void WriteModuleInfo(const Module *M,
if (!M->getTargetTriple().empty())
WriteStringRecord(bitc::MODULE_CODE_TRIPLE, M->getTargetTriple(),
0/*TODO*/, Stream);
- if (!M->getDataLayoutStr().empty())
- WriteStringRecord(bitc::MODULE_CODE_DATALAYOUT, M->getDataLayoutStr(),
- 0/*TODO*/, Stream);
+ const std::string &DL = M->getDataLayoutStr();
+ if (!DL.empty())
+ WriteStringRecord(bitc::MODULE_CODE_DATALAYOUT, DL, 0 /*TODO*/, Stream);
if (!M->getModuleInlineAsm().empty())
WriteStringRecord(bitc::MODULE_CODE_ASM, M->getModuleInlineAsm(),
0/*TODO*/, Stream);
@@ -405,36 +411,35 @@ static void WriteModuleInfo(const Module *M,
std::map<std::string, unsigned> GCMap;
unsigned MaxAlignment = 0;
unsigned MaxGlobalType = 0;
- for (Module::const_global_iterator GV = M->global_begin(),E = M->global_end();
- GV != E; ++GV) {
- MaxAlignment = std::max(MaxAlignment, GV->getAlignment());
- MaxGlobalType = std::max(MaxGlobalType, VE.getTypeID(GV->getType()));
- if (GV->hasSection()) {
+ for (const GlobalValue &GV : M->globals()) {
+ MaxAlignment = std::max(MaxAlignment, GV.getAlignment());
+ MaxGlobalType = std::max(MaxGlobalType, VE.getTypeID(GV.getType()));
+ if (GV.hasSection()) {
// Give section names unique ID's.
- unsigned &Entry = SectionMap[GV->getSection()];
+ unsigned &Entry = SectionMap[GV.getSection()];
if (!Entry) {
- WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, GV->getSection(),
+ WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, GV.getSection(),
0/*TODO*/, Stream);
Entry = SectionMap.size();
}
}
}
- for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) {
- MaxAlignment = std::max(MaxAlignment, F->getAlignment());
- if (F->hasSection()) {
+ for (const Function &F : *M) {
+ MaxAlignment = std::max(MaxAlignment, F.getAlignment());
+ if (F.hasSection()) {
// Give section names unique ID's.
- unsigned &Entry = SectionMap[F->getSection()];
+ unsigned &Entry = SectionMap[F.getSection()];
if (!Entry) {
- WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, F->getSection(),
+ WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, F.getSection(),
0/*TODO*/, Stream);
Entry = SectionMap.size();
}
}
- if (F->hasGC()) {
+ if (F.hasGC()) {
// Same for GC names.
- unsigned &Entry = GCMap[F->getGC()];
+ unsigned &Entry = GCMap[F.getGC()];
if (!Entry) {
- WriteStringRecord(bitc::MODULE_CODE_GCNAME, F->getGC(),
+ WriteStringRecord(bitc::MODULE_CODE_GCNAME, F.getGC(),
0/*TODO*/, Stream);
Entry = GCMap.size();
}
@@ -470,27 +475,26 @@ static void WriteModuleInfo(const Module *M,
// Emit the global variable information.
SmallVector<unsigned, 64> Vals;
- for (Module::const_global_iterator GV = M->global_begin(),E = M->global_end();
- GV != E; ++GV) {
+ for (const GlobalVariable &GV : M->globals()) {
unsigned AbbrevToUse = 0;
// GLOBALVAR: [type, isconst, initid,
// linkage, alignment, section, visibility, threadlocal,
// unnamed_addr]
- Vals.push_back(VE.getTypeID(GV->getType()));
- Vals.push_back(GV->isConstant());
- Vals.push_back(GV->isDeclaration() ? 0 :
- (VE.getValueID(GV->getInitializer()) + 1));
+ Vals.push_back(VE.getTypeID(GV.getType()));
+ Vals.push_back(GV.isConstant());
+ Vals.push_back(GV.isDeclaration() ? 0 :
+ (VE.getValueID(GV.getInitializer()) + 1));
Vals.push_back(getEncodedLinkage(GV));
- Vals.push_back(Log2_32(GV->getAlignment())+1);
- Vals.push_back(GV->hasSection() ? SectionMap[GV->getSection()] : 0);
- if (GV->isThreadLocal() ||
- GV->getVisibility() != GlobalValue::DefaultVisibility ||
- GV->hasUnnamedAddr() || GV->isExternallyInitialized()) {
+ Vals.push_back(Log2_32(GV.getAlignment())+1);
+ Vals.push_back(GV.hasSection() ? SectionMap[GV.getSection()] : 0);
+ if (GV.isThreadLocal() ||
+ GV.getVisibility() != GlobalValue::DefaultVisibility ||
+ GV.hasUnnamedAddr() || GV.isExternallyInitialized()) {
Vals.push_back(getEncodedVisibility(GV));
Vals.push_back(getEncodedThreadLocalMode(GV));
- Vals.push_back(GV->hasUnnamedAddr());
- Vals.push_back(GV->isExternallyInitialized());
+ Vals.push_back(GV.hasUnnamedAddr());
+ Vals.push_back(GV.isExternallyInitialized());
} else {
AbbrevToUse = SimpleGVarAbbrev;
}
@@ -500,19 +504,19 @@ static void WriteModuleInfo(const Module *M,
}
// Emit the function proto information.
- for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) {
+ for (const Function &F : *M) {
// FUNCTION: [type, callingconv, isproto, linkage, paramattrs, alignment,
// section, visibility, gc, unnamed_addr]
- Vals.push_back(VE.getTypeID(F->getType()));
- Vals.push_back(F->getCallingConv());
- Vals.push_back(F->isDeclaration());
+ Vals.push_back(VE.getTypeID(F.getType()));
+ Vals.push_back(F.getCallingConv());
+ Vals.push_back(F.isDeclaration());
Vals.push_back(getEncodedLinkage(F));
- Vals.push_back(VE.getAttributeID(F->getAttributes()));
- Vals.push_back(Log2_32(F->getAlignment())+1);
- Vals.push_back(F->hasSection() ? SectionMap[F->getSection()] : 0);
+ Vals.push_back(VE.getAttributeID(F.getAttributes()));
+ Vals.push_back(Log2_32(F.getAlignment())+1);
+ Vals.push_back(F.hasSection() ? SectionMap[F.getSection()] : 0);
Vals.push_back(getEncodedVisibility(F));
- Vals.push_back(F->hasGC() ? GCMap[F->getGC()] : 0);
- Vals.push_back(F->hasUnnamedAddr());
+ Vals.push_back(F.hasGC() ? GCMap[F.getGC()] : 0);
+ Vals.push_back(F.hasUnnamedAddr());
unsigned AbbrevToUse = 0;
Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse);
@@ -520,13 +524,12 @@ static void WriteModuleInfo(const Module *M,
}
// Emit the alias information.
- for (Module::const_alias_iterator AI = M->alias_begin(), E = M->alias_end();
- AI != E; ++AI) {
+ for (const GlobalAlias &A : M->aliases()) {
// ALIAS: [alias type, aliasee val#, linkage, visibility]
- Vals.push_back(VE.getTypeID(AI->getType()));
- Vals.push_back(VE.getValueID(AI->getAliasee()));
- Vals.push_back(getEncodedLinkage(AI));
- Vals.push_back(getEncodedVisibility(AI));
+ Vals.push_back(VE.getTypeID(A.getType()));
+ Vals.push_back(VE.getValueID(A.getAliasee()));
+ Vals.push_back(getEncodedLinkage(A));
+ Vals.push_back(getEncodedVisibility(A));
unsigned AbbrevToUse = 0;
Stream.EmitRecord(bitc::MODULE_CODE_ALIAS, Vals, AbbrevToUse);
Vals.clear();
@@ -536,18 +539,15 @@ static void WriteModuleInfo(const Module *M,
static uint64_t GetOptimizationFlags(const Value *V) {
uint64_t Flags = 0;
- if (const OverflowingBinaryOperator *OBO =
- dyn_cast<OverflowingBinaryOperator>(V)) {
+ if (const auto *OBO = dyn_cast<OverflowingBinaryOperator>(V)) {
if (OBO->hasNoSignedWrap())
Flags |= 1 << bitc::OBO_NO_SIGNED_WRAP;
if (OBO->hasNoUnsignedWrap())
Flags |= 1 << bitc::OBO_NO_UNSIGNED_WRAP;
- } else if (const PossiblyExactOperator *PEO =
- dyn_cast<PossiblyExactOperator>(V)) {
+ } else if (const auto *PEO = dyn_cast<PossiblyExactOperator>(V)) {
if (PEO->isExact())
Flags |= 1 << bitc::PEO_EXACT;
- } else if (const FPMathOperator *FPMO =
- dyn_cast<const FPMathOperator>(V)) {
+ } else if (const auto *FPMO = dyn_cast<FPMathOperator>(V)) {
// FIXME(srhines): We don't handle fast math in llvm-rs-cc today.
if (false) {
if (FPMO->hasUnsafeAlgebra())
@@ -566,89 +566,154 @@ static uint64_t GetOptimizationFlags(const Value *V) {
return Flags;
}
-static void WriteMDNode(const MDNode *N,
- const llvm_3_2::ValueEnumerator &VE,
- BitstreamWriter &Stream,
- SmallVector<uint64_t, 64> &Record) {
+static void WriteValueAsMetadata(const ValueAsMetadata *MD,
+ const llvm_3_2::ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record) {
+ // Mimic an MDNode with a value as one operand.
+ Value *V = MD->getValue();
+ Record.push_back(VE.getTypeID(V->getType()));
+ Record.push_back(VE.getValueID(V));
+ Stream.EmitRecord(bitc::METADATA_OLD_NODE, Record, 0);
+ Record.clear();
+}
+
+static void WriteMDTuple(const MDTuple *N, const llvm_3_2::ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record, unsigned Abbrev) {
for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
- if (N->getOperand(i)) {
- Record.push_back(VE.getTypeID(N->getOperand(i)->getType()));
- Record.push_back(VE.getValueID(N->getOperand(i)));
- } else {
- Record.push_back(VE.getTypeID(Type::getVoidTy(N->getContext())));
+ Metadata *MD = N->getOperand(i);
+ assert(!(MD && isa<LocalAsMetadata>(MD)) &&
+ "Unexpected function-local metadata");
+ if (!MD) {
+ // TODO(srhines): I don't believe this case can exist for RS.
+ Record.push_back(VE.getTypeID(llvm::Type::getVoidTy(N->getContext())));
Record.push_back(0);
+ } else if (const auto *MDC = dyn_cast<ConstantAsMetadata>(MD)) {
+ Record.push_back(VE.getTypeID(MDC->getType()));
+ Record.push_back(VE.getValueID(MDC->getValue()));
+ } else {
+ Record.push_back(VE.getTypeID(
+ llvm::Type::getMetadataTy(N->getContext())));
+ Record.push_back(VE.getMetadataID(MD));
}
}
- unsigned MDCode = N->isFunctionLocal() ? bitc::METADATA_FN_NODE :
- bitc::METADATA_NODE;
- Stream.EmitRecord(MDCode, Record, 0);
+ Stream.EmitRecord(bitc::METADATA_OLD_NODE, Record, Abbrev);
Record.clear();
}
+/*static void WriteMDLocation(const MDLocation *N, const llvm_3_2::ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.push_back(N->isDistinct());
+ Record.push_back(N->getLine());
+ Record.push_back(N->getColumn());
+ Record.push_back(VE.getMetadataID(N->getScope()));
+ Record.push_back(VE.getMetadataOrNullID(N->getInlinedAt()));
+
+ Stream.EmitRecord(bitc::METADATA_LOCATION, Record, Abbrev);
+ Record.clear();
+}
+
+static void WriteGenericDebugNode(const GenericDebugNode *,
+ const llvm_3_2::ValueEnumerator &, BitstreamWriter &,
+ SmallVectorImpl<uint64_t> &, unsigned) {
+ llvm_unreachable("unimplemented");
+}*/
+
static void WriteModuleMetadata(const Module *M,
const llvm_3_2::ValueEnumerator &VE,
BitstreamWriter &Stream) {
- const llvm_3_2::ValueEnumerator::ValueList &Vals = VE.getMDValues();
- bool StartedMetadataBlock = false;
+ const auto &MDs = VE.getMDs();
+ if (MDs.empty() && M->named_metadata_empty())
+ return;
+
+ // RenderScript files *ALWAYS* have metadata!
+ Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
+
unsigned MDSAbbrev = 0;
- SmallVector<uint64_t, 64> Record;
- for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
+ if (VE.hasMDString()) {
+ // Abbrev for METADATA_STRING.
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_STRING));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
+ MDSAbbrev = Stream.EmitAbbrev(Abbv);
+ }
- if (const MDNode *N = dyn_cast<MDNode>(Vals[i].first)) {
- if (!N->isFunctionLocal() || !N->getFunction()) {
- if (!StartedMetadataBlock) {
- Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
- StartedMetadataBlock = true;
- }
- WriteMDNode(N, VE, Stream, Record);
- }
- } else if (const MDString *MDS = dyn_cast<MDString>(Vals[i].first)) {
- if (!StartedMetadataBlock) {
- Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
-
- // Abbrev for METADATA_STRING.
- BitCodeAbbrev *Abbv = new BitCodeAbbrev();
- Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_STRING));
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
- MDSAbbrev = Stream.EmitAbbrev(Abbv);
- StartedMetadataBlock = true;
- }
+ unsigned MDLocationAbbrev = 0;
+ if (VE.hasMDLocation()) {
+ // TODO(srhines): Should be unreachable for RenderScript.
+ // Abbrev for METADATA_LOCATION.
+ //
+ // Assume the column is usually under 128, and always output the inlined-at
+ // location (it's never more expensive than building an array size 1).
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_LOCATION));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+ MDLocationAbbrev = Stream.EmitAbbrev(Abbv);
+ }
- // Code: [strchar x N]
- Record.append(MDS->begin(), MDS->end());
+ unsigned NameAbbrev = 0;
+ if (!M->named_metadata_empty()) {
+ // Abbrev for METADATA_NAME.
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_NAME));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
+ NameAbbrev = Stream.EmitAbbrev(Abbv);
+ }
- // Emit the finished record.
- Stream.EmitRecord(bitc::METADATA_STRING, Record, MDSAbbrev);
- Record.clear();
+ unsigned MDTupleAbbrev = 0;
+ //unsigned GenericDebugNodeAbbrev = 0;
+ SmallVector<uint64_t, 64> Record;
+ for (const Metadata *MD : MDs) {
+ if (const MDNode *N = dyn_cast<MDNode>(MD)) {
+ switch (N->getMetadataID()) {
+ default:
+ llvm_unreachable("Invalid MDNode subclass");
+#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS)
+#define HANDLE_MDNODE_LEAF(CLASS) \
+ case Metadata::CLASS##Kind: \
+ Write##CLASS(cast<CLASS>(N), VE, Stream, Record, CLASS##Abbrev); \
+ continue;
+#include "llvm/IR/Metadata.def"
+ }
}
+ if (const auto *MDC = dyn_cast<ConstantAsMetadata>(MD)) {
+ WriteValueAsMetadata(MDC, VE, Stream, Record);
+ continue;
+ }
+ const MDString *MDS = cast<MDString>(MD);
+ // Code: [strchar x N]
+ Record.append(MDS->bytes_begin(), MDS->bytes_end());
+
+ // Emit the finished record.
+ Stream.EmitRecord(bitc::METADATA_STRING, Record, MDSAbbrev);
+ Record.clear();
}
// Write named metadata.
- for (Module::const_named_metadata_iterator I = M->named_metadata_begin(),
- E = M->named_metadata_end(); I != E; ++I) {
- const NamedMDNode *NMD = I;
- if (!StartedMetadataBlock) {
- Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
- StartedMetadataBlock = true;
- }
-
+ for (const NamedMDNode &NMD : M->named_metadata()) {
// Write name.
- StringRef Str = NMD->getName();
- for (unsigned i = 0, e = Str.size(); i != e; ++i)
- Record.push_back(Str[i]);
- Stream.EmitRecord(bitc::METADATA_NAME, Record, 0/*TODO*/);
+ StringRef Str = NMD.getName();
+ Record.append(Str.bytes_begin(), Str.bytes_end());
+ Stream.EmitRecord(bitc::METADATA_NAME, Record, NameAbbrev);
Record.clear();
// Write named metadata operands.
- for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i)
- Record.push_back(VE.getValueID(NMD->getOperand(i)));
+ for (const MDNode *N : NMD.operands())
+ Record.push_back(VE.getMetadataID(N));
Stream.EmitRecord(bitc::METADATA_NAMED_NODE, Record, 0);
Record.clear();
}
- if (StartedMetadataBlock)
- Stream.ExitBlock();
+ Stream.ExitBlock();
}
static void WriteFunctionLocalMetadata(const Function &F,
@@ -656,16 +721,16 @@ static void WriteFunctionLocalMetadata(const Function &F,
BitstreamWriter &Stream) {
bool StartedMetadataBlock = false;
SmallVector<uint64_t, 64> Record;
- const SmallVector<const MDNode *, 8> &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) {
- if (!StartedMetadataBlock) {
- Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
- StartedMetadataBlock = true;
- }
- WriteMDNode(N, VE, Stream, Record);
- }
+ const SmallVectorImpl<const LocalAsMetadata *> &MDs =
+ VE.getFunctionLocalMDs();
+ for (unsigned i = 0, e = MDs.size(); i != e; ++i) {
+ assert(MDs[i] && "Expected valid function-local metadata");
+ if (!StartedMetadataBlock) {
+ Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
+ StartedMetadataBlock = true;
+ }
+ WriteValueAsMetadata(MDs[i], VE, Stream, Record);
+ }
if (StartedMetadataBlock)
Stream.ExitBlock();
@@ -680,7 +745,7 @@ 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;
+ 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();
@@ -695,7 +760,7 @@ static void WriteMetadataAttachment(const Function &F,
for (unsigned i = 0, e = MDs.size(); i != e; ++i) {
Record.push_back(MDs[i].first);
- Record.push_back(VE.getValueID(MDs[i].second));
+ Record.push_back(VE.getMetadataID(MDs[i].second));
}
Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0);
Record.clear();
@@ -728,39 +793,11 @@ static void WriteModuleMetadataStore(const Module *M, BitstreamWriter &Stream) {
Stream.ExitBlock();
}
-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();
- if ((int64_t)V >= 0)
- Vals.push_back(V << 1);
- else
- Vals.push_back((-V << 1) | 1);
- 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) {
- int64_t V = RawWords[i];
- if (V >= 0)
- Vals.push_back(V << 1);
- else
- Vals.push_back((-V << 1) | 1);
- }
- Code = bitc::CST_CODE_WIDE_INTEGER;
- }
+static void emitSignedInt64(SmallVectorImpl<uint64_t> &Vals, uint64_t V) {
+ if ((int64_t)V >= 0)
+ Vals.push_back(V << 1);
+ else
+ Vals.push_back((-V << 1) | 1);
}
static void WriteConstants(unsigned FirstVal, unsigned LastVal,
@@ -806,7 +843,7 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
SmallVector<uint64_t, 64> Record;
const llvm_3_2::ValueEnumerator::ValueList &Vals = VE.getValues();
- Type *LastTy = 0;
+ Type *LastTy = nullptr;
for (unsigned i = FirstVal; i != LastVal; ++i) {
const Value *V = Vals[i].first;
// If we need to switch types, do so now.
@@ -846,7 +883,23 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
} 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();
@@ -1077,9 +1130,9 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
break;
case Instruction::GetElementPtr:
- Code = bitc::FUNC_CODE_INST_GEP;
+ Code = bitc::FUNC_CODE_INST_GEP_OLD;
if (cast<GEPOperator>(&I)->isInBounds())
- Code = bitc::FUNC_CODE_INST_INBOUNDS_GEP;
+ Code = bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD;
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
PushValueAndType(I.getOperand(i), InstID, Vals, VE);
break;
@@ -1241,13 +1294,14 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
break;
}
- case Instruction::Alloca:
+ case Instruction::Alloca: {
Code = bitc::FUNC_CODE_INST_ALLOCA;
Vals.push_back(VE.getTypeID(I.getType()));
Vals.push_back(VE.getTypeID(I.getOperand(0)->getType()));
Vals.push_back(VE.getValueID(I.getOperand(0))); // size.
Vals.push_back(Log2_32(cast<AllocaInst>(I).getAlignment())+1);
break;
+ }
case Instruction::Load:
if (cast<LoadInst>(I).isAtomic()) {
@@ -1286,7 +1340,7 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
Vals.push_back(VE.getValueID(I.getOperand(2))); // newval.
Vals.push_back(cast<AtomicCmpXchgInst>(I).isVolatile());
Vals.push_back(GetEncodedOrdering(
- cast<AtomicCmpXchgInst>(I).getSuccessOrdering()));
+ cast<AtomicCmpXchgInst>(I).getSuccessOrdering()));
Vals.push_back(GetEncodedSynchScope(
cast<AtomicCmpXchgInst>(I).getSynchScope()));
break;
@@ -1399,6 +1453,39 @@ static void WriteValueSymbolTable(const ValueSymbolTable &VST,
Stream.ExitBlock();
}
+static void WriteUseList(llvm_3_2::ValueEnumerator &VE, UseListOrder &&Order,
+ BitstreamWriter &Stream) {
+ assert(Order.Shuffle.size() >= 2 && "Shuffle too small");
+ unsigned Code;
+ if (isa<BasicBlock>(Order.V))
+ Code = bitc::USELIST_CODE_BB;
+ else
+ Code = bitc::USELIST_CODE_DEFAULT;
+
+ SmallVector<uint64_t, 64> Record;
+ for (unsigned I : Order.Shuffle)
+ Record.push_back(I);
+ Record.push_back(VE.getValueID(Order.V));
+ Stream.EmitRecord(Code, Record);
+}
+
+static void WriteUseListBlock(const Function *F, llvm_3_2::ValueEnumerator &VE,
+ BitstreamWriter &Stream) {
+ auto hasMore = [&]() {
+ return !VE.UseListOrders.empty() && VE.UseListOrders.back().F == F;
+ };
+ if (!hasMore())
+ // Nothing to do.
+ return;
+
+ Stream.EnterSubblock(bitc::USELIST_BLOCK_ID, 3);
+ while (hasMore()) {
+ WriteUseList(VE, std::move(VE.UseListOrders.back()), Stream);
+ VE.UseListOrders.pop_back();
+ }
+ Stream.ExitBlock();
+}
+
/// WriteFunction - Emit a function body to the module stream.
static void WriteFunction(const Function &F, llvm_3_2::ValueEnumerator &VE,
BitstreamWriter &Stream) {
@@ -1450,11 +1537,12 @@ static void WriteFunction(const Function &F, llvm_3_2::ValueEnumerator &VE,
} else {
MDNode *Scope, *IA;
DL.getScopeAndInlinedAt(Scope, IA, I->getContext());
+ assert(Scope && "Expected valid scope");
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);
+ Vals.push_back(VE.getMetadataOrNullID(Scope));
+ Vals.push_back(VE.getMetadataOrNullID(IA));
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals);
Vals.clear();
@@ -1467,6 +1555,8 @@ static void WriteFunction(const Function &F, llvm_3_2::ValueEnumerator &VE,
if (NeedsMetadataAttachment)
WriteMetadataAttachment(F, VE, Stream);
+ if (shouldPreserveBitcodeUseListOrder())
+ WriteUseListBlock(&F, VE, Stream);
VE.purgeFunction();
Stream.ExitBlock();
}
@@ -1633,117 +1723,20 @@ static void WriteBlockInfo(const llvm_3_2::ValueEnumerator &VE,
Stream.ExitBlock();
}
-// 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.
- return true;
-}
-
-static void WriteUseList(const Value *V, const llvm_3_2::ValueEnumerator &VE,
- BitstreamWriter &Stream) {
-
- // One or zero uses can't get out of order.
- if (V->use_empty() || V->hasNUses(1))
- return;
-
- // Make a copy of the in-memory use-list for sorting.
- unsigned UseListSize = std::distance(V->use_begin(), V->use_end());
- SmallVector<const User*, 8> UseList;
- UseList.reserve(UseListSize);
- for (Value::const_use_iterator I = V->use_begin(), E = V->use_end();
- I != E; ++I) {
- const Use &use = *I;
- UseList.push_back(use.getUser());
- }
-
- // Sort the copy based on the order read by the BitcodeReader.
- std::sort(UseList.begin(), UseList.end(), bitcodereader_order);
-
- // TODO: Generate a diff between the BitcodeWriter in-memory use-list and the
- // sorted list (i.e., the expected BitcodeReader in-memory use-list).
-
- // TODO: Emit the USELIST_CODE_ENTRYs.
-}
-
-static void WriteFunctionUseList(const Function *F,
- llvm_3_2::ValueEnumerator &VE,
- BitstreamWriter &Stream) {
- VE.incorporateFunction(*F);
-
- for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
- AI != AE; ++AI)
- WriteUseList(AI, VE, Stream);
- for (Function::const_iterator BB = F->begin(), FE = F->end(); BB != FE;
- ++BB) {
- WriteUseList(BB, VE, Stream);
- for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end(); II != IE;
- ++II) {
- WriteUseList(II, VE, Stream);
- for (User::const_op_iterator OI = II->op_begin(), E = II->op_end();
- OI != E; ++OI) {
- if ((isa<Constant>(*OI) && !isa<GlobalValue>(*OI)) ||
- isa<InlineAsm>(*OI))
- WriteUseList(*OI, VE, Stream);
- }
- }
- }
- VE.purgeFunction();
-}
-
-// Emit use-lists.
-static void WriteModuleUseLists(const Module *M, llvm_3_2::ValueEnumerator &VE,
- BitstreamWriter &Stream) {
- Stream.EnterSubblock(bitc::USELIST_BLOCK_ID, 3);
-
- // XXX: this modifies the module, but in a way that should never change the
- // behavior of any pass or codegen in LLVM. The problem is that GVs may
- // contain entries in the use_list that do not exist in the Module and are
- // not stored in the .bc file.
- 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(),
- GE = M->global_end(); GI != GE; ++GI) {
- WriteUseList(GI, VE, Stream);
-
- // Write the global variable initializers.
- if (GI->hasInitializer())
- WriteUseList(GI->getInitializer(), VE, Stream);
- }
-
- // Write the functions.
- for (Module::const_iterator FI = M->begin(), FE = M->end(); FI != FE; ++FI) {
- WriteUseList(FI, VE, Stream);
- if (!FI->isDeclaration())
- WriteFunctionUseList(FI, VE, Stream);
- }
-
- // Write the aliases.
- for (Module::const_alias_iterator AI = M->alias_begin(), AE = M->alias_end();
- AI != AE; ++AI) {
- WriteUseList(AI, VE, Stream);
- WriteUseList(AI->getAliasee(), VE, Stream);
- }
-
- Stream.ExitBlock();
-}
-
/// WriteModule - Emit the specified module to the bitstream.
static void WriteModule(const Module *M, BitstreamWriter &Stream) {
Stream.EnterSubblock(bitc::MODULE_BLOCK_ID, 3);
- // Emit the version number if it is non-zero.
+ SmallVector<unsigned, 1> Vals;
+ // TODO(srhines): RenderScript is always version 0 for now.
+ unsigned CurVersion = 0;
if (CurVersion) {
- SmallVector<unsigned, 1> Vals;
Vals.push_back(CurVersion);
Stream.EmitRecord(bitc::MODULE_CODE_VERSION, Vals);
}
// Analyze the module, enumerating globals, functions, etc.
- llvm_3_2::ValueEnumerator VE(M);
+ llvm_3_2::ValueEnumerator VE(*M);
// Emit blockinfo, which defines the standard abbreviations etc.
WriteBlockInfo(VE, Stream);
@@ -1770,9 +1763,9 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream) {
// Emit names for globals/functions etc.
WriteValueSymbolTable(M->getValueSymbolTable(), VE, Stream);
- // Emit use-lists.
- if (EnablePreserveUseListOrdering)
- WriteModuleUseLists(M, VE, Stream);
+ // Emit module-level use-lists.
+ if (shouldPreserveBitcodeUseListOrder())
+ WriteUseListBlock(nullptr, VE, Stream);
// Emit function bodies.
for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F)
@@ -1858,7 +1851,7 @@ static void EmitDarwinBCHeaderAndTrailer(SmallVectorImpl<char> &Buffer,
/// WriteBitcodeToFile - Write the specified module to the specified output
/// stream.
void llvm_3_2::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/BitWriter_3_2/ValueEnumerator.cpp b/BitWriter_3_2/ValueEnumerator.cpp
index 47dd2d0..919e9df 100644
--- a/BitWriter_3_2/ValueEnumerator.cpp
+++ b/BitWriter_3_2/ValueEnumerator.cpp
@@ -15,6 +15,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
@@ -31,20 +32,21 @@ static bool isIntOrIntVectorValue(const std::pair<const Value*, unsigned> &V) {
}
/// ValueEnumerator - Enumerate module-level information.
-ValueEnumerator::ValueEnumerator(const Module *M) {
+ValueEnumerator::ValueEnumerator(const llvm::Module &M)
+ : HasMDString(false), HasMDLocation(false) {
// Enumerate the global variables.
- for (Module::const_global_iterator I = M->global_begin(),
- E = M->global_end(); I != E; ++I)
+ for (llvm::Module::const_global_iterator I = M.global_begin(), E = M.global_end();
+ I != E; ++I)
EnumerateValue(I);
// Enumerate the functions.
- for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) {
+ for (llvm::Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) {
EnumerateValue(I);
EnumerateAttributes(cast<Function>(I)->getAttributes());
}
// Enumerate the aliases.
- for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
+ for (llvm::Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
I != E; ++I)
EnumerateValue(I);
@@ -52,55 +54,64 @@ ValueEnumerator::ValueEnumerator(const Module *M) {
unsigned FirstConstant = Values.size();
// Enumerate the global variable initializers.
- for (Module::const_global_iterator I = M->global_begin(),
- E = M->global_end(); I != E; ++I)
+ for (llvm::Module::const_global_iterator I = M.global_begin(), E = M.global_end();
+ I != E; ++I)
if (I->hasInitializer())
EnumerateValue(I->getInitializer());
// Enumerate the aliasees.
- for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
+ for (llvm::Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
I != E; ++I)
EnumerateValue(I->getAliasee());
- // Insert constants and metadata that are named at module level into the slot
+ // Enumerate the metadata type.
+ //
+ // TODO: Move this to ValueEnumerator::EnumerateOperandType() once bitcode
+ // only encodes the metadata type when it's used as a value.
+ EnumerateType(Type::getMetadataTy(M.getContext()));
+
+ // 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());
+ EnumerateValueSymbolTable(M.getValueSymbolTable());
EnumerateNamedMetadata(M);
- SmallVector<std::pair<unsigned, MDNode*>, 8> MDs;
+ SmallVector<std::pair<unsigned, MDNode *>, 8> MDs;
// Enumerate types used by function bodies and argument lists.
- for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) {
-
- for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();
- I != E; ++I)
- EnumerateType(I->getType());
-
- 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){
- for (User::const_op_iterator OI = I->op_begin(), E = I->op_end();
- OI != E; ++OI) {
- if (MDNode *MD = dyn_cast<MDNode>(*OI))
- if (MD->isFunctionLocal() && MD->getFunction())
- // These will get enumerated during function-incorporation.
- continue;
- EnumerateOperandType(*OI);
+ for (const Function &F : M) {
+ for (const Argument &A : F.args())
+ EnumerateType(A.getType());
+
+ for (const BasicBlock &BB : F)
+ for (const Instruction &I : BB) {
+ for (const Use &Op : I.operands()) {
+ auto *MD = dyn_cast<MetadataAsValue>(&Op);
+ if (!MD) {
+ EnumerateOperandType(Op);
+ continue;
+ }
+
+ // Local metadata is enumerated during function-incorporation.
+ if (isa<LocalAsMetadata>(MD->getMetadata()))
+ continue;
+
+ EnumerateMetadata(MD->getMetadata());
}
- EnumerateType(I->getType());
- if (const CallInst *CI = dyn_cast<CallInst>(I))
+ EnumerateType(I.getType());
+ if (const CallInst *CI = dyn_cast<CallInst>(&I))
EnumerateAttributes(CI->getAttributes());
- else if (const InvokeInst *II = dyn_cast<InvokeInst>(I))
+ else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I))
EnumerateAttributes(II->getAttributes());
// Enumerate metadata attached with this instruction.
MDs.clear();
- I->getAllMetadataOtherThanDebugLoc(MDs);
+ I.getAllMetadataOtherThanDebugLoc(MDs);
for (unsigned i = 0, e = MDs.size(); i != e; ++i)
EnumerateMetadata(MDs[i].second);
- if (!I->getDebugLoc().isUnknown()) {
+ if (!I.getDebugLoc().isUnknown()) {
MDNode *Scope, *IA;
- I->getDebugLoc().getScopeAndInlinedAt(Scope, IA, I->getContext());
+ I.getDebugLoc().getScopeAndInlinedAt(Scope, IA, I.getContext());
if (Scope) EnumerateMetadata(Scope);
if (IA) EnumerateMetadata(IA);
}
@@ -122,11 +133,8 @@ void ValueEnumerator::setInstructionID(const Instruction *I) {
}
unsigned ValueEnumerator::getValueID(const Value *V) const {
- if (isa<MDNode>(V) || isa<MDString>(V)) {
- ValueMapType::const_iterator I = MDValueMap.find(V);
- assert(I != MDValueMap.end() && "Value not in slotcalculator!");
- return I->second-1;
- }
+ if (auto *MD = dyn_cast<MetadataAsValue>(V))
+ return getMetadataID(MD->getMetadata());
ValueMapType::const_iterator I = ValueMap.find(V);
assert(I != ValueMap.end() && "Value not in slotcalculator!");
@@ -156,12 +164,11 @@ void ValueEnumerator::print(raw_ostream &OS, const ValueMapType &Map,
V->dump();
OS << " Uses(" << std::distance(V->use_begin(),V->use_end()) << "):";
- for (Value::const_use_iterator UI = V->use_begin(), UE = V->use_end();
- UI != UE; ++UI) {
- if (UI != V->use_begin())
+ for (const Use &U : V->uses()) {
+ if (&U != &*V->use_begin())
OS << ",";
- if((*UI)->hasName())
- OS << " " << (*UI)->getName();
+ if(U->hasName())
+ OS << " " << U->getName();
else
OS << " [null]";
@@ -170,6 +177,19 @@ void ValueEnumerator::print(raw_ostream &OS, const ValueMapType &Map,
}
}
+void ValueEnumerator::print(llvm::raw_ostream &OS, const MetadataMapType &Map,
+ const char *Name) const {
+
+ OS << "Map Name: " << Name << "\n";
+ OS << "Size: " << Map.size() << "\n";
+ for (auto I = Map.begin(), E = Map.end(); I != E; ++I) {
+ const llvm::Metadata *MD = I->first;
+ OS << "Metadata: slot = " << I->second << "\n";
+ MD->print(OS);
+ }
+}
+
+
// Optimize constant ordering.
namespace {
struct CstSortPredicate {
@@ -216,9 +236,10 @@ void ValueEnumerator::EnumerateValueSymbolTable(const ValueSymbolTable &VST) {
/// EnumerateNamedMetadata - Insert all of the values referenced by
/// named metadata in the specified module.
-void ValueEnumerator::EnumerateNamedMetadata(const Module *M) {
- for (Module::const_named_metadata_iterator I = M->named_metadata_begin(),
- E = M->named_metadata_end(); I != E; ++I)
+void ValueEnumerator::EnumerateNamedMetadata(const llvm::Module &M) {
+ for (llvm::Module::const_named_metadata_iterator I = M.named_metadata_begin(),
+ E = M.named_metadata_end();
+ I != E; ++I)
EnumerateNamedMDNode(I);
}
@@ -231,84 +252,62 @@ void ValueEnumerator::EnumerateNamedMDNode(const NamedMDNode *MD) {
/// and types referenced by the given MDNode.
void ValueEnumerator::EnumerateMDNodeOperands(const MDNode *N) {
for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
- if (Value *V = N->getOperand(i)) {
- if (isa<MDNode>(V) || isa<MDString>(V))
- EnumerateMetadata(V);
- else if (!isa<Instruction>(V) && !isa<Argument>(V))
- EnumerateValue(V);
- } else
- EnumerateType(Type::getVoidTy(N->getContext()));
+ Metadata *MD = N->getOperand(i);
+ if (!MD)
+ continue;
+ assert(!isa<LocalAsMetadata>(MD) && "MDNodes cannot be function-local");
+ EnumerateMetadata(MD);
}
}
-void ValueEnumerator::EnumerateMetadata(const Value *MD) {
- assert((isa<MDNode>(MD) || isa<MDString>(MD)) && "Invalid metadata kind");
-
- // Enumerate the type of this value.
- EnumerateType(MD->getType());
+void ValueEnumerator::EnumerateMetadata(const llvm::Metadata *MD) {
+ assert(
+ (isa<MDNode>(MD) || isa<MDString>(MD) || isa<ConstantAsMetadata>(MD)) &&
+ "Invalid metadata kind");
- const MDNode *N = dyn_cast<MDNode>(MD);
+ // Insert a dummy ID to block the co-recursive call to
+ // EnumerateMDNodeOperands() from re-visiting MD in a cyclic graph.
+ //
+ // Return early if there's already an ID.
+ if (!MDValueMap.insert(std::make_pair(MD, 0)).second)
+ return;
- // In the module-level pass, skip function-local nodes themselves, but
- // do walk their operands.
- if (N && N->isFunctionLocal() && N->getFunction()) {
+ // Visit operands first to minimize RAUW.
+ if (auto *N = dyn_cast<MDNode>(MD))
EnumerateMDNodeOperands(N);
- return;
- }
+ else if (auto *C = dyn_cast<ConstantAsMetadata>(MD))
+ EnumerateValue(C->getValue());
- // Check to see if it's already in!
- unsigned &MDValueID = MDValueMap[MD];
- if (MDValueID) {
- // Increment use count.
- MDValues[MDValueID-1].second++;
- return;
- }
- MDValues.push_back(std::make_pair(MD, 1U));
- MDValueID = MDValues.size();
+ HasMDString |= isa<MDString>(MD);
+ HasMDLocation |= isa<MDLocation>(MD);
- // Enumerate all non-function-local operands.
- if (N)
- EnumerateMDNodeOperands(N);
+ // Replace the dummy ID inserted above with the correct one. MDValueMap may
+ // have changed by inserting operands, so we need a fresh lookup here.
+ MDs.push_back(MD);
+ MDValueMap[MD] = MDs.size();
}
/// EnumerateFunctionLocalMetadataa - Incorporate function-local metadata
-/// information reachable from the given MDNode.
-void ValueEnumerator::EnumerateFunctionLocalMetadata(const MDNode *N) {
- assert(N->isFunctionLocal() && N->getFunction() &&
- "EnumerateFunctionLocalMetadata called on non-function-local mdnode!");
-
- // Enumerate the type of this value.
- EnumerateType(N->getType());
-
+/// information reachable from the metadata.
+void ValueEnumerator::EnumerateFunctionLocalMetadata(
+ const llvm::LocalAsMetadata *Local) {
// Check to see if it's already in!
- unsigned &MDValueID = MDValueMap[N];
- if (MDValueID) {
- // Increment use count.
- MDValues[MDValueID-1].second++;
+ unsigned &MDValueID = MDValueMap[Local];
+ if (MDValueID)
return;
- }
- MDValues.push_back(std::make_pair(N, 1U));
- MDValueID = MDValues.size();
-
- // To incoroporate function-local information visit all function-local
- // MDNodes and all function-local values they reference.
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
- if (Value *V = N->getOperand(i)) {
- if (MDNode *O = dyn_cast<MDNode>(V)) {
- if (O->isFunctionLocal() && O->getFunction())
- EnumerateFunctionLocalMetadata(O);
- } else if (isa<Instruction>(V) || isa<Argument>(V))
- EnumerateValue(V);
- }
- // Also, collect all function-local MDNodes for easy access.
- FunctionLocalMDs.push_back(N);
+ MDs.push_back(Local);
+ MDValueID = MDs.size();
+
+ EnumerateValue(Local->getValue());
+
+ // Also, collect all function-local metadata for easy access.
+ FunctionLocalMDs.push_back(Local);
}
void ValueEnumerator::EnumerateValue(const Value *V) {
assert(!V->getType()->isVoidTy() && "Can't insert void values!");
- assert(!isa<MDNode>(V) && !isa<MDString>(V) &&
- "EnumerateValue doesn't handle Metadata!");
+ assert(!isa<MetadataAsValue>(V) && "EnumerateValue doesn't handle Metadata!");
// Check to see if it's already in!
unsigned &ValueID = ValueMap[V];
@@ -378,9 +377,8 @@ void ValueEnumerator::EnumerateType(Type *Ty) {
// 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);
+ for (Type *SubTy : Ty->subtypes())
+ EnumerateType(SubTy);
// Refresh the TypeID pointer in case the table rehashed.
TypeID = &TypeMap[Ty];
@@ -404,30 +402,35 @@ void ValueEnumerator::EnumerateType(Type *Ty) {
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.
- if (ValueMap.count(V)) return;
+ if (auto *MD = dyn_cast<MetadataAsValue>(V)) {
+ assert(!isa<LocalAsMetadata>(MD->getMetadata()) &&
+ "Function-local metadata should be left for later");
- // This constant may have operands, make sure to enumerate the types in
- // them.
- for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) {
- const Value *Op = C->getOperand(i);
+ EnumerateMetadata(MD->getMetadata());
+ return;
+ }
- // Don't enumerate basic blocks here, this happens as operands to
- // blockaddress.
- if (isa<BasicBlock>(Op)) continue;
+ const Constant *C = dyn_cast<Constant>(V);
+ if (!C)
+ return;
- EnumerateOperandType(Op);
- }
+ // If this constant is already enumerated, ignore it, we know its type must
+ // be enumerated.
+ if (ValueMap.count(C))
+ return;
- if (const MDNode *N = dyn_cast<MDNode>(V)) {
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
- if (Value *Elem = N->getOperand(i))
- EnumerateOperandType(Elem);
- }
- } else if (isa<MDString>(V) || isa<MDNode>(V))
- EnumerateMetadata(V);
+ // This constant may have operands, make sure to enumerate the types in
+ // 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);
+ }
}
void ValueEnumerator::EnumerateAttributes(AttributeSet PAL) {
@@ -455,7 +458,7 @@ void ValueEnumerator::EnumerateAttributes(AttributeSet PAL) {
void ValueEnumerator::incorporateFunction(const Function &F) {
InstructionCount = 0;
NumModuleValues = Values.size();
- NumModuleMDValues = MDValues.size();
+ NumModuleMDs = MDs.size();
// Adding function arguments to the value table.
for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end();
@@ -486,24 +489,16 @@ void ValueEnumerator::incorporateFunction(const Function &F) {
FirstInstID = Values.size();
- SmallVector<MDNode *, 8> FnLocalMDVector;
+ SmallVector<llvm::LocalAsMetadata *, 8> FnLocalMDVector;
// Add all of the instructions.
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) {
for (User::const_op_iterator OI = I->op_begin(), E = I->op_end();
OI != E; ++OI) {
- if (MDNode *MD = dyn_cast<MDNode>(*OI))
- if (MD->isFunctionLocal() && MD->getFunction())
+ if (auto *MD = dyn_cast<llvm::MetadataAsValue>(&*OI))
+ if (auto *Local = dyn_cast<LocalAsMetadata>(MD->getMetadata()))
// Enumerate metadata after the instructions they might refer to.
- FnLocalMDVector.push_back(MD);
- }
-
- SmallVector<std::pair<unsigned, MDNode*>, 8> MDs;
- I->getAllMetadataOtherThanDebugLoc(MDs);
- for (unsigned i = 0, e = MDs.size(); i != e; ++i) {
- MDNode *N = MDs[i].second;
- if (N->isFunctionLocal() && N->getFunction())
- FnLocalMDVector.push_back(N);
+ FnLocalMDVector.push_back(Local);
}
if (!I->getType()->isVoidTy())
@@ -520,13 +515,13 @@ void ValueEnumerator::purgeFunction() {
/// Remove purged values from the ValueMap.
for (unsigned i = NumModuleValues, e = Values.size(); i != e; ++i)
ValueMap.erase(Values[i].first);
- for (unsigned i = NumModuleMDValues, e = MDValues.size(); i != e; ++i)
- MDValueMap.erase(MDValues[i].first);
+ for (unsigned i = NumModuleMDs, e = MDs.size(); i != e; ++i)
+ MDValueMap.erase(MDs[i]);
for (unsigned i = 0, e = BasicBlocks.size(); i != e; ++i)
ValueMap.erase(BasicBlocks[i]);
Values.resize(NumModuleValues);
- MDValues.resize(NumModuleMDValues);
+ MDs.resize(NumModuleMDs);
BasicBlocks.clear();
FunctionLocalMDs.clear();
}
diff --git a/BitWriter_3_2/ValueEnumerator.h b/BitWriter_3_2/ValueEnumerator.h
index 0b1c8ea..2895a21 100644
--- a/BitWriter_3_2/ValueEnumerator.h
+++ b/BitWriter_3_2/ValueEnumerator.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/Attributes.h"
+#include "llvm/IR/UseListOrder.h"
#include <vector>
namespace llvm {
@@ -27,6 +28,8 @@ class Instruction;
class BasicBlock;
class Function;
class Module;
+class Metadata;
+class LocalAsMetadata;
class MDNode;
class NamedMDNode;
class AttributeSet;
@@ -44,6 +47,8 @@ public:
// For each value, we remember its Value* and occurrence frequency.
typedef std::vector<std::pair<const llvm::Value*, unsigned> > ValueList;
+
+ llvm::UseListOrderStack UseListOrders;
private:
typedef llvm::DenseMap<llvm::Type*, unsigned> TypeMapType;
TypeMapType TypeMap;
@@ -52,9 +57,14 @@ private:
typedef llvm::DenseMap<const llvm::Value*, unsigned> ValueMapType;
ValueMapType ValueMap;
ValueList Values;
- ValueList MDValues;
- llvm::SmallVector<const llvm::MDNode *, 8> FunctionLocalMDs;
- ValueMapType MDValueMap;
+
+
+ std::vector<const llvm::Metadata *> MDs;
+ llvm::SmallVector<const llvm::LocalAsMetadata *, 8> FunctionLocalMDs;
+ typedef llvm::DenseMap<const llvm::Metadata *, unsigned> MetadataMapType;
+ MetadataMapType MDValueMap;
+ bool HasMDString;
+ bool HasMDLocation;
typedef llvm::DenseMap<llvm::AttributeSet, unsigned> AttributeGroupMapType;
AttributeGroupMapType AttributeGroupMap;
@@ -82,20 +92,33 @@ private:
/// When a function is incorporated, this is the size of the MDValues list
/// before incorporation.
- unsigned NumModuleMDValues;
+ unsigned NumModuleMDs;
unsigned FirstFuncConstantID;
unsigned FirstInstID;
- ValueEnumerator(const ValueEnumerator &); // DO NOT IMPLEMENT
- void operator=(const ValueEnumerator &); // DO NOT IMPLEMENT
+ ValueEnumerator(const ValueEnumerator &) = delete;
+ void operator=(const ValueEnumerator &) = delete;
public:
- ValueEnumerator(const llvm::Module *M);
+ ValueEnumerator(const llvm::Module &M);
void dump() const;
void print(llvm::raw_ostream &OS, const ValueMapType &Map, const char *Name) const;
+ void print(llvm::raw_ostream &OS, const MetadataMapType &Map,
+ const char *Name) const;
unsigned getValueID(const llvm::Value *V) const;
+ unsigned getMetadataID(const llvm::Metadata *MD) const {
+ auto ID = getMetadataOrNullID(MD);
+ assert(ID != 0 && "Metadata not in slotcalculator!");
+ return ID - 1;
+ }
+ unsigned getMetadataOrNullID(const llvm::Metadata *MD) const {
+ return MDValueMap.lookup(MD);
+ }
+
+ bool hasMDString() const { return HasMDString; }
+ bool hasMDLocation() const { return HasMDLocation; }
unsigned getTypeID(llvm::Type *T) const {
TypeMapType::const_iterator I = TypeMap.find(T);
@@ -128,8 +151,8 @@ public:
}
const ValueList &getValues() const { return Values; }
- const ValueList &getMDValues() const { return MDValues; }
- const llvm::SmallVector<const llvm::MDNode *, 8> &getFunctionLocalMDValues() const {
+ const std::vector<const llvm::Metadata *> &getMDs() const { return MDs; }
+ const llvm::SmallVectorImpl<const llvm::LocalAsMetadata *> &getFunctionLocalMDs() const {
return FunctionLocalMDs;
}
const TypeList &getTypes() const { return Types; }
@@ -158,8 +181,8 @@ private:
void OptimizeConstants(unsigned CstStart, unsigned CstEnd);
void EnumerateMDNodeOperands(const llvm::MDNode *N);
- void EnumerateMetadata(const llvm::Value *MD);
- void EnumerateFunctionLocalMetadata(const llvm::MDNode *N);
+ void EnumerateMetadata(const llvm::Metadata *MD);
+ void EnumerateFunctionLocalMetadata(const llvm::LocalAsMetadata *Local);
void EnumerateNamedMDNode(const llvm::NamedMDNode *NMD);
void EnumerateValue(const llvm::Value *V);
void EnumerateType(llvm::Type *T);
@@ -167,7 +190,7 @@ private:
void EnumerateAttributes(llvm::AttributeSet PAL);
void EnumerateValueSymbolTable(const llvm::ValueSymbolTable &ST);
- void EnumerateNamedMetadata(const llvm::Module *M);
+ void EnumerateNamedMetadata(const llvm::Module &M);
};
} // End llvm_3_2 namespace
diff --git a/slang_backend.cpp b/slang_backend.cpp
index 4c6a3b9..6aa082c 100644
--- a/slang_backend.cpp
+++ b/slang_backend.cpp
@@ -64,7 +64,7 @@ namespace slang {
void Backend::CreateFunctionPasses() {
if (!mPerFunctionPasses) {
- mPerFunctionPasses = new llvm::FunctionPassManager(mpModule);
+ mPerFunctionPasses = new llvm::legacy::FunctionPassManager(mpModule);
mPerFunctionPasses->add(new llvm::DataLayoutPass());
llvm::PassManagerBuilder PMBuilder;
@@ -75,7 +75,7 @@ void Backend::CreateFunctionPasses() {
void Backend::CreateModulePasses() {
if (!mPerModulePasses) {
- mPerModulePasses = new llvm::PassManager();
+ mPerModulePasses = new llvm::legacy::PassManager();
mPerModulePasses->add(new llvm::DataLayoutPass());
llvm::PassManagerBuilder PMBuilder;
@@ -107,7 +107,7 @@ bool Backend::CreateCodeGenPasses() {
if (mCodeGenPasses) {
return true;
} else {
- mCodeGenPasses = new llvm::FunctionPassManager(mpModule);
+ mCodeGenPasses = new llvm::legacy::FunctionPassManager(mpModule);
mCodeGenPasses->add(new llvm::DataLayoutPass());
}
@@ -222,8 +222,7 @@ Backend::Backend(clang::DiagnosticsEngine *DiagEngine,
mPragmas(Pragmas) {
FormattedOutStream.setStream(*mpOS,
llvm::formatted_raw_ostream::PRESERVE_STREAM);
- mGen = CreateLLVMCodeGen(mDiagEngine, "", mCodeGenOpts,
- mTargetOpts, mLLVMContext);
+ mGen = CreateLLVMCodeGen(mDiagEngine, "", mCodeGenOpts, mLLVMContext);
}
void Backend::Initialize(clang::ASTContext &Ctx) {
@@ -282,7 +281,7 @@ void Backend::HandleTranslationUnit(clang::ASTContext &Ctx) {
for (PragmaList::const_iterator I = mPragmas->begin(), E = mPragmas->end();
I != E;
I++) {
- llvm::SmallVector<llvm::Value*, 2> Pragma;
+ llvm::SmallVector<llvm::Metadata*, 2> Pragma;
// Name goes first
Pragma.push_back(llvm::MDString::get(mLLVMContext, I->first));
// And then value
@@ -335,13 +334,13 @@ void Backend::HandleTranslationUnit(clang::ASTContext &Ctx) {
break;
}
case Slang::OT_LLVMAssembly: {
- llvm::PassManager *LLEmitPM = new llvm::PassManager();
+ llvm::legacy::PassManager *LLEmitPM = new llvm::legacy::PassManager();
LLEmitPM->add(llvm::createPrintModulePass(FormattedOutStream));
LLEmitPM->run(*mpModule);
break;
}
case Slang::OT_Bitcode: {
- llvm::PassManager *BCEmitPM = new llvm::PassManager();
+ llvm::legacy::PassManager *BCEmitPM = new llvm::legacy::PassManager();
std::string BCStr;
llvm::raw_string_ostream Bitcode(BCStr);
unsigned int TargetAPI = getTargetAPI();
diff --git a/slang_backend.h b/slang_backend.h
index 4254aca..f7075dd 100644
--- a/slang_backend.h
+++ b/slang_backend.h
@@ -19,7 +19,7 @@
#include "clang/AST/ASTConsumer.h"
-#include "llvm/PassManager.h"
+#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Support/FormattedStream.h"
@@ -60,11 +60,11 @@ class Backend : public clang::ASTConsumer {
// Passes
// Passes apply on function scope in a translation unit
- llvm::FunctionPassManager *mPerFunctionPasses;
+ llvm::legacy::FunctionPassManager *mPerFunctionPasses;
// Passes apply on module scope
- llvm::PassManager *mPerModulePasses;
+ llvm::legacy::PassManager *mPerModulePasses;
// Passes for code emission
- llvm::FunctionPassManager *mCodeGenPasses;
+ llvm::legacy::FunctionPassManager *mCodeGenPasses;
llvm::formatted_raw_ostream FormattedOutStream;
diff --git a/slang_rs_backend.cpp b/slang_rs_backend.cpp
index 4d1998e..eb59077 100644
--- a/slang_rs_backend.cpp
+++ b/slang_rs_backend.cpp
@@ -185,7 +185,7 @@ void RSBackend::dumpExportVarInfo(llvm::Module *M) {
if (mExportVarMetadata == nullptr)
mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN);
- llvm::SmallVector<llvm::Value*, 2> ExportVarInfo;
+ llvm::SmallVector<llvm::Metadata *, 2> ExportVarInfo;
// We emit slot information (#rs_object_slots) for any reference counted
// RS type or pointer (which can also be bound).
@@ -270,7 +270,7 @@ void RSBackend::dumpExportFunctionInfo(llvm::Module *M) {
mExportFuncMetadata =
M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN);
- llvm::SmallVector<llvm::Value*, 1> ExportFuncInfo;
+ llvm::SmallVector<llvm::Metadata *, 1> ExportFuncInfo;
for (RSContext::const_export_func_iterator
I = mContext->export_funcs_begin(),
@@ -415,8 +415,8 @@ void RSBackend::dumpExportForEachInfo(llvm::Module *M) {
M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_MN);
}
- llvm::SmallVector<llvm::Value*, 1> ExportForEachName;
- llvm::SmallVector<llvm::Value*, 1> ExportForEachInfo;
+ llvm::SmallVector<llvm::Metadata *, 1> ExportForEachName;
+ llvm::SmallVector<llvm::Metadata *, 1> ExportForEachInfo;
for (RSContext::const_export_foreach_iterator
I = mContext->export_foreach_begin(),
@@ -443,7 +443,7 @@ void RSBackend::dumpExportForEachInfo(llvm::Module *M) {
}
void RSBackend::dumpExportTypeInfo(llvm::Module *M) {
- llvm::SmallVector<llvm::Value*, 1> ExportTypeInfo;
+ llvm::SmallVector<llvm::Metadata *, 1> ExportTypeInfo;
for (RSContext::const_export_type_iterator
I = mContext->export_types_begin(),
@@ -474,7 +474,7 @@ void RSBackend::dumpExportTypeInfo(llvm::Module *M) {
StructInfoMetadataName.append(ET->getName());
llvm::NamedMDNode *StructInfoMetadata =
M->getOrInsertNamedMetadata(StructInfoMetadataName);
- llvm::SmallVector<llvm::Value*, 3> FieldInfo;
+ llvm::SmallVector<llvm::Metadata *, 3> FieldInfo;
slangAssert(StructInfoMetadata->getNumOperands() == 0 &&
"Metadata with same name was created before");
diff --git a/slang_rs_context.cpp b/slang_rs_context.cpp
index 608d6cb..81b3b49 100644
--- a/slang_rs_context.cpp
+++ b/slang_rs_context.cpp
@@ -132,10 +132,10 @@ bool RSContext::processExportType(const llvm::StringRef &Name) {
// found
return false;
- clang::DeclContext::lookup_const_result R = TUDecl->lookup(II);
+ clang::DeclContext::lookup_result R = TUDecl->lookup(II);
RSExportType *ET = nullptr;
- for (clang::DeclContext::lookup_const_iterator I = R.begin(), E = R.end();
+ for (clang::DeclContext::lookup_iterator I = R.begin(), E = R.end();
I != E;
I++) {
clang::NamedDecl *const ND = *I;