diff options
author | Stephen Hines <srhines@google.com> | 2015-04-01 18:59:02 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2015-04-01 18:59:02 +0000 |
commit | b518fbbb082e2c154e757b3d2d18c50e53325eb6 (patch) | |
tree | abc35f5fca07f36629ed8f9dd3ef65c96142bc84 | |
parent | 281e2c6b4a390835750ba6897e4bf647c0f9e103 (diff) | |
parent | 2133b9d55fa99617126c7ddb31df0f821a1156ff (diff) | |
download | android_frameworks_compile_slang-b518fbbb082e2c154e757b3d2d18c50e53325eb6.tar.gz android_frameworks_compile_slang-b518fbbb082e2c154e757b3d2d18c50e53325eb6.tar.bz2 android_frameworks_compile_slang-b518fbbb082e2c154e757b3d2d18c50e53325eb6.zip |
am 2133b9d5: Merge "Update slang for LLVM rebase to r230699."
* commit '2133b9d55fa99617126c7ddb31df0f821a1156ff':
Update slang for LLVM rebase to r230699.
-rw-r--r-- | BitWriter_2_9/BitcodeWriter.cpp | 433 | ||||
-rw-r--r-- | BitWriter_2_9/ValueEnumerator.cpp | 283 | ||||
-rw-r--r-- | BitWriter_2_9/ValueEnumerator.h | 44 | ||||
-rw-r--r-- | BitWriter_2_9_func/BitcodeWriter.cpp | 392 | ||||
-rw-r--r-- | BitWriter_2_9_func/ValueEnumerator.cpp | 283 | ||||
-rw-r--r-- | BitWriter_2_9_func/ValueEnumerator.h | 44 | ||||
-rw-r--r-- | BitWriter_3_2/BitcodeWriter.cpp | 577 | ||||
-rw-r--r-- | BitWriter_3_2/ValueEnumerator.cpp | 283 | ||||
-rw-r--r-- | BitWriter_3_2/ValueEnumerator.h | 47 | ||||
-rw-r--r-- | slang_backend.cpp | 15 | ||||
-rw-r--r-- | slang_backend.h | 8 | ||||
-rw-r--r-- | slang_rs_backend.cpp | 12 | ||||
-rw-r--r-- | slang_rs_context.cpp | 4 |
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; |