diff options
-rw-r--r-- | llvm/include/llvm/IR/AutoUpgrade.h | 13 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 15 | ||||
-rw-r--r-- | llvm/lib/IR/AutoUpgrade.cpp | 67 | ||||
-rw-r--r-- | llvm/test/Assembler/no-mdstring-upgrades.ll | 10 | ||||
-rw-r--r-- | llvm/test/Assembler/upgrade-loop-metadata.ll | 42 |
6 files changed, 93 insertions, 55 deletions
diff --git a/llvm/include/llvm/IR/AutoUpgrade.h b/llvm/include/llvm/IR/AutoUpgrade.h index a4b3c410c4f..24665c4e367 100644 --- a/llvm/include/llvm/IR/AutoUpgrade.h +++ b/llvm/include/llvm/IR/AutoUpgrade.h @@ -14,13 +14,14 @@ #ifndef LLVM_IR_AUTOUPGRADE_H #define LLVM_IR_AUTOUPGRADE_H -#include <string> +#include "llvm/ADT/StringRef.h" namespace llvm { class CallInst; class Constant; class Function; class Instruction; + class MDNode; class Module; class GlobalVariable; class Type; @@ -64,8 +65,14 @@ namespace llvm { /// info. Return true if module is modified. bool UpgradeDebugInfo(Module &M); - /// Upgrade a metadata string constant in place. - void UpgradeMDStringConstant(std::string &String); + /// Check whether a string looks like an old loop attachment tag. + inline bool mayBeOldLoopAttachmentTag(StringRef Name) { + return Name.startswith("llvm.vectorizer."); + } + + /// Upgrade the loop attachment metadata node. + MDNode *upgradeInstructionLoopAttachment(MDNode &N); + } // End llvm namespace #endif diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 60808755acc..323bb5430c4 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -575,7 +575,6 @@ bool LLParser::parseComdat() { bool LLParser::ParseMDString(MDString *&Result) { std::string Str; if (ParseStringConstant(Str)) return true; - llvm::UpgradeMDStringConstant(Str); Result = MDString::get(Context, Str); return false; } diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index dcaaa7d2975..99bd0b1fbd7 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -166,6 +166,8 @@ class BitcodeReader : public GVMaterializer { SmallVector<Instruction*, 64> InstsWithTBAATag; + bool HasSeenOldLoopTags = false; + /// The set of attributes by index. Index zero in the file is for null, and /// is thus not represented here. As such all indices are off by one. std::vector<AttributeSet> MAttributes; @@ -2385,7 +2387,10 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) { } case bitc::METADATA_STRING: { std::string String(Record.begin(), Record.end()); - llvm::UpgradeMDStringConstant(String); + + // Test for upgrading !llvm.loop. + HasSeenOldLoopTags |= mayBeOldLoopAttachmentTag(String); + Metadata *MD = MDString::get(Context, String); MetadataList.assignValue(MD, NextMetadataNo++); break; @@ -3956,9 +3961,15 @@ std::error_code BitcodeReader::parseMetadataAttachment(Function &F) { MDNode *MD = dyn_cast_or_null<MDNode>(Node); if (!MD) return error("Invalid metadata attachment"); + + if (HasSeenOldLoopTags && I->second == LLVMContext::MD_loop) + MD = upgradeInstructionLoopAttachment(*MD); + Inst->setMetadata(I->second, MD); - if (I->second == LLVMContext::MD_tbaa) + if (I->second == LLVMContext::MD_tbaa) { InstsWithTBAATag.push_back(Inst); + continue; + } } break; } diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index 12c354c89b2..b9cee43b4db 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -894,11 +894,64 @@ bool llvm::UpgradeDebugInfo(Module &M) { return RetCode; } -void llvm::UpgradeMDStringConstant(std::string &String) { - const std::string OldPrefix = "llvm.vectorizer."; - if (String == "llvm.vectorizer.unroll") { - String = "llvm.loop.interleave.count"; - } else if (String.find(OldPrefix) == 0) { - String.replace(0, OldPrefix.size(), "llvm.loop.vectorize."); - } +static bool isOldLoopArgument(Metadata *MD) { + auto *T = dyn_cast_or_null<MDTuple>(MD); + if (!T) + return false; + if (T->getNumOperands() < 1) + return false; + auto *S = dyn_cast_or_null<MDString>(T->getOperand(0)); + if (!S) + return false; + return S->getString().startswith("llvm.vectorizer."); +} + +static MDString *upgradeLoopTag(LLVMContext &C, StringRef OldTag) { + StringRef OldPrefix = "llvm.vectorizer."; + assert(OldTag.startswith(OldPrefix) && "Expected old prefix"); + + if (OldTag == "llvm.vectorizer.unroll") + return MDString::get(C, "llvm.loop.interleave.count"); + + return MDString::get( + C, (Twine("llvm.loop.vectorize.") + OldTag.drop_front(OldPrefix.size())) + .str()); +} + +static Metadata *upgradeLoopArgument(Metadata *MD) { + auto *T = dyn_cast_or_null<MDTuple>(MD); + if (!T) + return MD; + if (T->getNumOperands() < 1) + return MD; + auto *OldTag = dyn_cast_or_null<MDString>(T->getOperand(0)); + if (!OldTag) + return MD; + if (!OldTag->getString().startswith("llvm.vectorizer.")) + return MD; + + // This has an old tag. Upgrade it. + SmallVector<Metadata *, 8> Ops; + Ops.reserve(T->getNumOperands()); + Ops.push_back(upgradeLoopTag(T->getContext(), OldTag->getString())); + for (unsigned I = 1, E = T->getNumOperands(); I != E; ++I) + Ops.push_back(T->getOperand(I)); + + return MDTuple::get(T->getContext(), Ops); +} + +MDNode *llvm::upgradeInstructionLoopAttachment(MDNode &N) { + auto *T = dyn_cast<MDTuple>(&N); + if (!T) + return &N; + + if (!llvm::any_of(T->operands(), isOldLoopArgument)) + return &N; + + SmallVector<Metadata *, 8> Ops; + Ops.reserve(T->getNumOperands()); + for (Metadata *MD : T->operands()) + Ops.push_back(upgradeLoopArgument(MD)); + + return MDTuple::get(T->getContext(), Ops); } diff --git a/llvm/test/Assembler/no-mdstring-upgrades.ll b/llvm/test/Assembler/no-mdstring-upgrades.ll new file mode 100644 index 00000000000..e6d50ac10f5 --- /dev/null +++ b/llvm/test/Assembler/no-mdstring-upgrades.ll @@ -0,0 +1,10 @@ +; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s +; RUN: verify-uselistorder %s +; Make sure arbitrary metadata strings don't get mutated. These may be +; (strange) filenames that are part of debug info. + +; CHECK: !named = !{!0} +!named = !{!0} + +; CHECK: !0 = !{!"llvm.vectorizer.unroll"} +!0 = !{!"llvm.vectorizer.unroll"} diff --git a/llvm/test/Assembler/upgrade-loop-metadata.ll b/llvm/test/Assembler/upgrade-loop-metadata.ll deleted file mode 100644 index d88cb3ee2e2..00000000000 --- a/llvm/test/Assembler/upgrade-loop-metadata.ll +++ /dev/null @@ -1,42 +0,0 @@ -; Test to make sure loop vectorizer metadata is automatically upgraded. -; -; Run using opt as well to ensure that the metadata is upgraded when parsing -; assembly. -; -; RUN: llvm-as < %s | llvm-dis | FileCheck %s -; RUN: opt -S < %s | FileCheck %s -; RUN: verify-uselistorder %s - -define void @_Z28loop_with_vectorize_metadatav() { -entry: - %i = alloca i32, align 4 - store i32 0, i32* %i, align 4 - br label %for.cond - -for.cond: ; preds = %for.inc, %entry - %0 = load i32, i32* %i, align 4 - %cmp = icmp slt i32 %0, 16 - br i1 %cmp, label %for.body, label %for.end, !llvm.loop !1 - -for.body: ; preds = %for.cond - br label %for.inc - -for.inc: ; preds = %for.body - %1 = load i32, i32* %i, align 4 - %inc = add nsw i32 %1, 1 - store i32 %inc, i32* %i, align 4 - br label %for.cond - -for.end: ; preds = %for.cond - ret void -} - -; CHECK: !{!"llvm.loop.interleave.count", i32 4} -; CHECK: !{!"llvm.loop.vectorize.width", i32 8} -; CHECK: !{!"llvm.loop.vectorize.enable", i1 true} - -!0 = !{!"clang version 3.5.0 (trunk 211528)"} -!1 = !{!1, !2, !3, !4, !4} -!2 = !{!"llvm.vectorizer.unroll", i32 4} -!3 = !{!"llvm.vectorizer.width", i32 8} -!4 = !{!"llvm.vectorizer.enable", i1 true} |