summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff options
context:
space:
mode:
authorTeresa Johnson <tejohnson@google.com>2015-12-17 17:14:09 +0000
committerTeresa Johnson <tejohnson@google.com>2015-12-17 17:14:09 +0000
commite5a619173274bf2a9033ea1c8b2346f1bee2766b (patch)
treedf1a23654ddaef760e878af89977d13945649896 /llvm/lib/Bitcode/Reader/BitcodeReader.cpp
parentcaaa3aa07c8fa129c8032597f2d0317637a1569a (diff)
downloadbcm5719-llvm-e5a619173274bf2a9033ea1c8b2346f1bee2766b.tar.gz
bcm5719-llvm-e5a619173274bf2a9033ea1c8b2346f1bee2766b.zip
[ThinLTO] Metadata linking for imported functions
Summary: Second patch split out from http://reviews.llvm.org/D14752. Maps metadata as a post-pass from each module when importing complete, suturing up final metadata to the temporary metadata left on the imported instructions. This entails saving the mapping from bitcode value id to temporary metadata in the importing pass, and from bitcode value id to final metadata during the metadata linking postpass. Depends on D14825. Reviewers: dexonsmith, joker.eph Subscribers: davidxl, llvm-commits, joker.eph Differential Revision: http://reviews.llvm.org/D14838 llvm-svn: 255909
Diffstat (limited to 'llvm/lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp45
1 files changed, 44 insertions, 1 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 0905b5fb6d2..ff08f55d43f 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -97,6 +97,7 @@ public:
class BitcodeReaderMDValueList {
unsigned NumFwdRefs;
bool AnyFwdRefs;
+ bool SavedFwdRefs;
unsigned MinFwdRef;
unsigned MaxFwdRef;
std::vector<TrackingMDRef> MDValuePtrs;
@@ -104,7 +105,12 @@ class BitcodeReaderMDValueList {
LLVMContext &Context;
public:
BitcodeReaderMDValueList(LLVMContext &C)
- : NumFwdRefs(0), AnyFwdRefs(false), Context(C) {}
+ : NumFwdRefs(0), AnyFwdRefs(false), SavedFwdRefs(false), Context(C) {}
+ ~BitcodeReaderMDValueList() {
+ // Assert that we either replaced all forward references, or saved
+ // them for later replacement.
+ assert(!NumFwdRefs || SavedFwdRefs);
+ }
// vector compatibility methods
unsigned size() const { return MDValuePtrs.size(); }
@@ -115,6 +121,8 @@ public:
void pop_back() { MDValuePtrs.pop_back(); }
bool empty() const { return MDValuePtrs.empty(); }
+ void savedFwdRefs() { SavedFwdRefs = true; }
+
Metadata *operator[](unsigned i) const {
assert(i < MDValuePtrs.size());
return MDValuePtrs[i];
@@ -274,6 +282,14 @@ public:
void setStripDebugInfo() override;
+ /// Save the mapping between the metadata values and the corresponding
+ /// value id that were recorded in the MDValueList during parsing. If
+ /// OnlyTempMD is true, then only record those entries that are still
+ /// temporary metadata. This interface is used when metadata linking is
+ /// performed as a postpass, such as during function importing.
+ void saveMDValueList(DenseMap<const Metadata *, unsigned> &MDValueToValIDMap,
+ bool OnlyTempMD) override;
+
private:
/// Parse the "IDENTIFICATION_BLOCK_ID" block, populate the
// ProducerIdentification data member, and do some basic enforcement on the
@@ -1069,6 +1085,9 @@ Metadata *BitcodeReaderMDValueList::getValueFwdRef(unsigned Idx) {
MinFwdRef = MaxFwdRef = Idx;
}
++NumFwdRefs;
+ // Reset flag to ensure that we save this forward reference if we
+ // are delaying metadata mapping (e.g. for function importing).
+ SavedFwdRefs = false;
// Create and return a placeholder, which will later be RAUW'd.
Metadata *MD = MDNode::getTemporary(Context, None).release();
@@ -3062,6 +3081,30 @@ std::error_code BitcodeReader::materializeMetadata() {
void BitcodeReader::setStripDebugInfo() { StripDebugInfo = true; }
+void BitcodeReader::saveMDValueList(
+ DenseMap<const Metadata *, unsigned> &MDValueToValIDMap, bool OnlyTempMD) {
+ for (unsigned ValID = 0; ValID < MDValueList.size(); ++ValID) {
+ Metadata *MD = MDValueList[ValID];
+ auto *N = dyn_cast_or_null<MDNode>(MD);
+ // Save all values if !OnlyTempMD, otherwise just the temporary metadata.
+ if (!OnlyTempMD || (N && N->isTemporary())) {
+ // Will call this after materializing each function, in order to
+ // handle remapping of the function's instructions/metadata.
+ // See if we already have an entry in that case.
+ if (OnlyTempMD && MDValueToValIDMap.count(MD)) {
+ assert(MDValueToValIDMap[MD] == ValID &&
+ "Inconsistent metadata value id");
+ continue;
+ }
+ MDValueToValIDMap[MD] = ValID;
+ // Flag that we saved the forward refs (temporary metadata) for error
+ // checking during MDValueList destruction.
+ if (OnlyTempMD)
+ MDValueList.savedFwdRefs();
+ }
+ }
+}
+
/// When we see the block for a function body, remember where it is and then
/// skip it. This lets us lazily deserialize the functions.
std::error_code BitcodeReader::rememberAndSkipFunctionBody() {
OpenPOWER on IntegriCloud