IR: Stop upgrading !llvm.loop attachments via MDString

Remove logic to upgrade !llvm.loop by changing the MDString tag
directly.  This old logic would check (and change) arbitrary strings
that had nothing to do with loop metadata.  Instead, check !llvm.loop
attachments directly, and change which strings get attached.

Rather than updating the assembly-based upgrade, drop it entirely.  It
has been quite a while since we supported upgrading textual IR.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@264373 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan P. N. Exon Smith 2016-03-25 00:56:13 +00:00
parent 1adb3816e9
commit 7ad5ddeb72
6 changed files with 93 additions and 55 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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"}

View File

@ -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}