summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/CodeGen/MIRParser
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2017-04-02 17:24:58 +0000
committerdim <dim@FreeBSD.org>2017-04-02 17:24:58 +0000
commit60b571e49a90d38697b3aca23020d9da42fc7d7f (patch)
tree99351324c24d6cb146b6285b6caffa4d26fce188 /contrib/llvm/lib/CodeGen/MIRParser
parentbea1b22c7a9bce1dfdd73e6e5b65bc4752215180 (diff)
downloadFreeBSD-src-60b571e49a90d38697b3aca23020d9da42fc7d7f.zip
FreeBSD-src-60b571e49a90d38697b3aca23020d9da42fc7d7f.tar.gz
Update clang, llvm, lld, lldb, compiler-rt and libc++ to 4.0.0 release:
MFC r309142 (by emaste): Add WITH_LLD_AS_LD build knob If set it installs LLD as /usr/bin/ld. LLD (as of version 3.9) is not capable of linking the world and kernel, but can self-host and link many substantial applications. GNU ld continues to be used for the world and kernel build, regardless of how this knob is set. It is on by default for arm64, and off for all other CPU architectures. Sponsored by: The FreeBSD Foundation MFC r310840: Reapply 310775, now it also builds correctly if lldb is disabled: Move llvm-objdump from CLANG_EXTRAS to installed by default We currently install three tools from binutils 2.17.50: as, ld, and objdump. Work is underway to migrate to a permissively-licensed tool-chain, with one goal being the retirement of binutils 2.17.50. LLVM's llvm-objdump is intended to be compatible with GNU objdump although it is currently missing some options and may have formatting differences. Enable it by default for testing and further investigation. It may later be changed to install as /usr/bin/objdump, it becomes a fully viable replacement. Reviewed by: emaste Differential Revision: https://reviews.freebsd.org/D8879 MFC r312855 (by emaste): Rename LLD_AS_LD to LLD_IS_LD, for consistency with CLANG_IS_CC Reported by: Dan McGregor <dan.mcgregor usask.ca> MFC r313559 | glebius | 2017-02-10 18:34:48 +0100 (Fri, 10 Feb 2017) | 5 lines Don't check struct rtentry on FreeBSD, it is an internal kernel structure. On other systems it may be API structure for SIOCADDRT/SIOCDELRT. Reviewed by: emaste, dim MFC r314152 (by jkim): Remove an assembler flag, which is redundant since r309124. The upstream took care of it by introducing a macro NO_EXEC_STACK_DIRECTIVE. http://llvm.org/viewvc/llvm-project?rev=273500&view=rev Reviewed by: dim MFC r314564: Upgrade our copies of clang, llvm, lld, lldb, compiler-rt and libc++ to 4.0.0 (branches/release_40 296509). The release will follow soon. Please note that from 3.5.0 onwards, clang, llvm and lldb require C++11 support to build; see UPDATING for more information. Also note that as of 4.0.0, lld should be able to link the base system on amd64 and aarch64. See the WITH_LLD_IS_LLD setting in src.conf(5). Though please be aware that this is work in progress. Release notes for llvm, clang and lld will be available here: <http://releases.llvm.org/4.0.0/docs/ReleaseNotes.html> <http://releases.llvm.org/4.0.0/tools/clang/docs/ReleaseNotes.html> <http://releases.llvm.org/4.0.0/tools/lld/docs/ReleaseNotes.html> Thanks to Ed Maste, Jan Beich, Antoine Brodin and Eric Fiselier for their help. Relnotes: yes Exp-run: antoine PR: 215969, 216008 MFC r314708: For now, revert r287232 from upstream llvm trunk (by Daniil Fukalov): [SCEV] limit recursion depth of CompareSCEVComplexity Summary: CompareSCEVComplexity goes too deep (50+ on a quite a big unrolled loop) and runs almost infinite time. Added cache of "equal" SCEV pairs to earlier cutoff of further estimation. Recursion depth limit was also introduced as a parameter. Reviewers: sanjoy Subscribers: mzolotukhin, tstellarAMD, llvm-commits Differential Revision: https://reviews.llvm.org/D26389 This commit is the cause of excessive compile times on skein_block.c (and possibly other files) during kernel builds on amd64. We never saw the problematic behavior described in this upstream commit, so for now it is better to revert it. An upstream bug has been filed here: https://bugs.llvm.org/show_bug.cgi?id=32142 Reported by: mjg MFC r314795: Reapply r287232 from upstream llvm trunk (by Daniil Fukalov): [SCEV] limit recursion depth of CompareSCEVComplexity Summary: CompareSCEVComplexity goes too deep (50+ on a quite a big unrolled loop) and runs almost infinite time. Added cache of "equal" SCEV pairs to earlier cutoff of further estimation. Recursion depth limit was also introduced as a parameter. Reviewers: sanjoy Subscribers: mzolotukhin, tstellarAMD, llvm-commits Differential Revision: https://reviews.llvm.org/D26389 Pull in r296992 from upstream llvm trunk (by Sanjoy Das): [SCEV] Decrease the recursion threshold for CompareValueComplexity Fixes PR32142. r287232 accidentally increased the recursion threshold for CompareValueComplexity from 2 to 32. This change reverses that change by introducing a separate flag for CompareValueComplexity's threshold. The latter revision fixes the excessive compile times for skein_block.c. MFC r314907 | mmel | 2017-03-08 12:40:27 +0100 (Wed, 08 Mar 2017) | 7 lines Unbreak ARMv6 world. The new compiler_rt library imported with clang 4.0.0 have several fatal issues (non-functional __udivsi3 for example) with ARM specific instrict functions. As temporary workaround, until upstream solve these problems, disable all thumb[1][2] related feature. MFC r315016: Update clang, llvm, lld, lldb, compiler-rt and libc++ to 4.0.0 release. We were already very close to the last release candidate, so this is a pretty minor update. Relnotes: yes MFC r316005: Revert r314907, and pull in r298713 from upstream compiler-rt trunk (by Weiming Zhao): builtins: Select correct code fragments when compiling for Thumb1/Thum2/ARM ISA. Summary: Value of __ARM_ARCH_ISA_THUMB isn't based on the actual compilation mode (-mthumb, -marm), it reflect's capability of given CPU. Due to this: - use __tbumb__ and __thumb2__ insteand of __ARM_ARCH_ISA_THUMB - use '.thumb' directive consistently in all affected files - decorate all thumb functions using DEFINE_COMPILERRT_THUMB_FUNCTION() --------- Note: This patch doesn't fix broken Thumb1 variant of __udivsi3 ! Reviewers: weimingz, rengolin, compnerd Subscribers: aemerson, dim Differential Revision: https://reviews.llvm.org/D30938 Discussed with: mmel
Diffstat (limited to 'contrib/llvm/lib/CodeGen/MIRParser')
-rw-r--r--contrib/llvm/lib/CodeGen/MIRParser/MILexer.cpp78
-rw-r--r--contrib/llvm/lib/CodeGen/MIRParser/MILexer.h10
-rw-r--r--contrib/llvm/lib/CodeGen/MIRParser/MIParser.cpp485
-rw-r--r--contrib/llvm/lib/CodeGen/MIRParser/MIParser.h49
-rw-r--r--contrib/llvm/lib/CodeGen/MIRParser/MIRParser.cpp195
5 files changed, 581 insertions, 236 deletions
diff --git a/contrib/llvm/lib/CodeGen/MIRParser/MILexer.cpp b/contrib/llvm/lib/CodeGen/MIRParser/MILexer.cpp
index 6e3de52..1f1ce6e 100644
--- a/contrib/llvm/lib/CodeGen/MIRParser/MILexer.cpp
+++ b/contrib/llvm/lib/CodeGen/MIRParser/MILexer.cpp
@@ -173,14 +173,20 @@ static Cursor lexName(Cursor C, MIToken &Token, MIToken::TokenKind Type,
return C;
}
-static Cursor maybeLexIntegerType(Cursor C, MIToken &Token) {
- if (C.peek() != 'i' || !isdigit(C.peek(1)))
+static Cursor maybeLexIntegerOrScalarType(Cursor C, MIToken &Token) {
+ if ((C.peek() != 'i' && C.peek() != 's' && C.peek() != 'p') ||
+ !isdigit(C.peek(1)))
return None;
+ char Kind = C.peek();
auto Range = C;
- C.advance(); // Skip 'i'
+ C.advance(); // Skip 'i', 's', or 'p'
while (isdigit(C.peek()))
C.advance();
- Token.reset(MIToken::IntegerType, Range.upto(C));
+
+ Token.reset(Kind == 'i'
+ ? MIToken::IntegerType
+ : (Kind == 's' ? MIToken::ScalarType : MIToken::PointerType),
+ Range.upto(C));
return C;
}
@@ -199,12 +205,13 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
.Case("tied-def", MIToken::kw_tied_def)
.Case("frame-setup", MIToken::kw_frame_setup)
.Case("debug-location", MIToken::kw_debug_location)
- .Case(".cfi_same_value", MIToken::kw_cfi_same_value)
- .Case(".cfi_offset", MIToken::kw_cfi_offset)
- .Case(".cfi_def_cfa_register", MIToken::kw_cfi_def_cfa_register)
- .Case(".cfi_def_cfa_offset", MIToken::kw_cfi_def_cfa_offset)
- .Case(".cfi_def_cfa", MIToken::kw_cfi_def_cfa)
+ .Case("same_value", MIToken::kw_cfi_same_value)
+ .Case("offset", MIToken::kw_cfi_offset)
+ .Case("def_cfa_register", MIToken::kw_cfi_def_cfa_register)
+ .Case("def_cfa_offset", MIToken::kw_cfi_def_cfa_offset)
+ .Case("def_cfa", MIToken::kw_cfi_def_cfa)
.Case("blockaddress", MIToken::kw_blockaddress)
+ .Case("intrinsic", MIToken::kw_intrinsic)
.Case("target-index", MIToken::kw_target_index)
.Case("half", MIToken::kw_half)
.Case("float", MIToken::kw_float)
@@ -215,6 +222,7 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
.Case("target-flags", MIToken::kw_target_flags)
.Case("volatile", MIToken::kw_volatile)
.Case("non-temporal", MIToken::kw_non_temporal)
+ .Case("dereferenceable", MIToken::kw_dereferenceable)
.Case("invariant", MIToken::kw_invariant)
.Case("align", MIToken::kw_align)
.Case("stack", MIToken::kw_stack)
@@ -227,11 +235,13 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
.Case("landing-pad", MIToken::kw_landing_pad)
.Case("liveins", MIToken::kw_liveins)
.Case("successors", MIToken::kw_successors)
+ .Case("floatpred", MIToken::kw_floatpred)
+ .Case("intpred", MIToken::kw_intpred)
.Default(MIToken::Identifier);
}
static Cursor maybeLexIdentifier(Cursor C, MIToken &Token) {
- if (!isalpha(C.peek()) && C.peek() != '_' && C.peek() != '.')
+ if (!isalpha(C.peek()) && C.peek() != '_')
return None;
auto Range = C;
while (isIdentifierChar(C.peek()))
@@ -366,6 +376,11 @@ static Cursor lexVirtualRegister(Cursor C, MIToken &Token) {
return C;
}
+/// Returns true for a character allowed in a register name.
+static bool isRegisterChar(char C) {
+ return isIdentifierChar(C) && C != '.';
+}
+
static Cursor maybeLexRegister(Cursor C, MIToken &Token) {
if (C.peek() != '%')
return None;
@@ -373,7 +388,7 @@ static Cursor maybeLexRegister(Cursor C, MIToken &Token) {
return lexVirtualRegister(C, Token);
auto Range = C;
C.advance(); // Skip '%'
- while (isIdentifierChar(C.peek()))
+ while (isRegisterChar(C.peek()))
C.advance();
Token.reset(MIToken::NamedRegister, Range.upto(C))
.setStringValue(Range.upto(C).drop_front(1)); // Drop the '%'
@@ -409,19 +424,6 @@ static bool isValidHexFloatingPointPrefix(char C) {
return C == 'H' || C == 'K' || C == 'L' || C == 'M';
}
-static Cursor maybeLexHexFloatingPointLiteral(Cursor C, MIToken &Token) {
- if (C.peek() != '0' || C.peek(1) != 'x')
- return None;
- Cursor Range = C;
- C.advance(2); // Skip '0x'
- if (isValidHexFloatingPointPrefix(C.peek()))
- C.advance();
- while (isxdigit(C.peek()))
- C.advance();
- Token.reset(MIToken::FloatingPointLiteral, Range.upto(C));
- return C;
-}
-
static Cursor lexFloatingPointLiteral(Cursor Range, Cursor C, MIToken &Token) {
C.advance();
// Skip over [0-9]*([eE][-+]?[0-9]+)?
@@ -438,6 +440,28 @@ static Cursor lexFloatingPointLiteral(Cursor Range, Cursor C, MIToken &Token) {
return C;
}
+static Cursor maybeLexHexadecimalLiteral(Cursor C, MIToken &Token) {
+ if (C.peek() != '0' || (C.peek(1) != 'x' && C.peek(1) != 'X'))
+ return None;
+ Cursor Range = C;
+ C.advance(2);
+ unsigned PrefLen = 2;
+ if (isValidHexFloatingPointPrefix(C.peek())) {
+ C.advance();
+ PrefLen++;
+ }
+ while (isxdigit(C.peek()))
+ C.advance();
+ StringRef StrVal = Range.upto(C);
+ if (StrVal.size() <= PrefLen)
+ return None;
+ if (PrefLen == 2)
+ Token.reset(MIToken::HexLiteral, Range.upto(C));
+ else // It must be 3, which means that there was a floating-point prefix.
+ Token.reset(MIToken::FloatingPointLiteral, Range.upto(C));
+ return C;
+}
+
static Cursor maybeLexNumericalLiteral(Cursor C, MIToken &Token) {
if (!isdigit(C.peek()) && (C.peek() != '-' || !isdigit(C.peek(1))))
return None;
@@ -485,6 +509,8 @@ static MIToken::TokenKind symbolToken(char C) {
switch (C) {
case ',':
return MIToken::comma;
+ case '.':
+ return MIToken::dot;
case '=':
return MIToken::equal;
case ':':
@@ -566,7 +592,7 @@ StringRef llvm::lexMIToken(StringRef Source, MIToken &Token,
return C.remaining();
}
- if (Cursor R = maybeLexIntegerType(C, Token))
+ if (Cursor R = maybeLexIntegerOrScalarType(C, Token))
return R.remaining();
if (Cursor R = maybeLexMachineBasicBlock(C, Token, ErrorCallback))
return R.remaining();
@@ -592,7 +618,7 @@ StringRef llvm::lexMIToken(StringRef Source, MIToken &Token,
return R.remaining();
if (Cursor R = maybeLexExternalSymbol(C, Token, ErrorCallback))
return R.remaining();
- if (Cursor R = maybeLexHexFloatingPointLiteral(C, Token))
+ if (Cursor R = maybeLexHexadecimalLiteral(C, Token))
return R.remaining();
if (Cursor R = maybeLexNumericalLiteral(C, Token))
return R.remaining();
diff --git a/contrib/llvm/lib/CodeGen/MIRParser/MILexer.h b/contrib/llvm/lib/CodeGen/MIRParser/MILexer.h
index 32fc8ab..edba749 100644
--- a/contrib/llvm/lib/CodeGen/MIRParser/MILexer.h
+++ b/contrib/llvm/lib/CodeGen/MIRParser/MILexer.h
@@ -38,6 +38,7 @@ struct MIToken {
underscore,
colon,
coloncolon,
+ dot,
exclaim,
lparen,
rparen,
@@ -53,6 +54,7 @@ struct MIToken {
kw_implicit_define,
kw_def,
kw_dead,
+ kw_dereferenceable,
kw_killed,
kw_undef,
kw_internal,
@@ -67,6 +69,7 @@ struct MIToken {
kw_cfi_def_cfa_offset,
kw_cfi_def_cfa,
kw_blockaddress,
+ kw_intrinsic,
kw_target_index,
kw_half,
kw_float,
@@ -89,6 +92,8 @@ struct MIToken {
kw_landing_pad,
kw_liveins,
kw_successors,
+ kw_floatpred,
+ kw_intpred,
// Named metadata keywords
md_tbaa,
@@ -102,6 +107,8 @@ struct MIToken {
NamedRegister,
MachineBasicBlockLabel,
MachineBasicBlock,
+ PointerType,
+ ScalarType,
StackObject,
FixedStackObject,
NamedGlobalValue,
@@ -111,6 +118,7 @@ struct MIToken {
// Other tokens
IntegerLiteral,
FloatingPointLiteral,
+ HexLiteral,
VirtualRegister,
ConstantPoolItem,
JumpTableIndex,
@@ -160,7 +168,7 @@ public:
bool isMemoryOperandFlag() const {
return Kind == kw_volatile || Kind == kw_non_temporal ||
- Kind == kw_invariant;
+ Kind == kw_dereferenceable || Kind == kw_invariant;
}
bool is(TokenKind K) const { return Kind == K; }
diff --git a/contrib/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/contrib/llvm/lib/CodeGen/MIRParser/MIParser.cpp
index b3fd16f..c8bed08 100644
--- a/contrib/llvm/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/contrib/llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -14,6 +14,7 @@
#include "MIParser.h"
#include "MILexer.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/AsmParser/SlotMapping.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
@@ -26,13 +27,16 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ModuleSlotTracker.h"
#include "llvm/IR/ValueSymbolTable.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetIntrinsicInfo.h"
#include "llvm/Target/TargetSubtargetInfo.h"
+#include <cctype>
using namespace llvm;
@@ -41,6 +45,17 @@ PerFunctionMIParsingState::PerFunctionMIParsingState(MachineFunction &MF,
: MF(MF), SM(&SM), IRSlots(IRSlots) {
}
+VRegInfo &PerFunctionMIParsingState::getVRegInfo(unsigned Num) {
+ auto I = VRegInfos.insert(std::make_pair(Num, nullptr));
+ if (I.second) {
+ MachineRegisterInfo &MRI = MF.getRegInfo();
+ VRegInfo *Info = new (Allocator) VRegInfo;
+ Info->VReg = MRI.createIncompleteVirtualRegister();
+ I.first->second = Info;
+ }
+ return *I.first->second;
+}
+
namespace {
/// A wrapper struct around the 'MachineOperand' struct that includes a source
@@ -65,7 +80,7 @@ class MIParser {
SMDiagnostic &Error;
StringRef Source, CurrentSource;
MIToken Token;
- const PerFunctionMIParsingState &PFS;
+ PerFunctionMIParsingState &PFS;
/// Maps from instruction names to op codes.
StringMap<unsigned> Names2InstrOpCodes;
/// Maps from register names to registers.
@@ -86,7 +101,7 @@ class MIParser {
StringMap<unsigned> Names2BitmaskTargetFlags;
public:
- MIParser(const PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
+ MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
StringRef Source);
/// \p SkipChar gives the number of characters to skip before looking
@@ -109,7 +124,8 @@ public:
bool parse(MachineInstr *&MI);
bool parseStandaloneMBB(MachineBasicBlock *&MBB);
bool parseStandaloneNamedRegister(unsigned &Reg);
- bool parseStandaloneVirtualRegister(unsigned &Reg);
+ bool parseStandaloneVirtualRegister(VRegInfo *&Info);
+ bool parseStandaloneRegister(unsigned &Reg);
bool parseStandaloneStackObject(int &FI);
bool parseStandaloneMDNode(MDNode *&Node);
@@ -119,21 +135,19 @@ public:
bool parseBasicBlockLiveins(MachineBasicBlock &MBB);
bool parseBasicBlockSuccessors(MachineBasicBlock &MBB);
- bool parseRegister(unsigned &Reg);
+ bool parseNamedRegister(unsigned &Reg);
+ bool parseVirtualRegister(VRegInfo *&Info);
+ bool parseRegister(unsigned &Reg, VRegInfo *&VRegInfo);
bool parseRegisterFlag(unsigned &Flags);
bool parseSubRegisterIndex(unsigned &SubReg);
bool parseRegisterTiedDefIndex(unsigned &TiedDefIdx);
- bool parseSize(unsigned &Size);
bool parseRegisterOperand(MachineOperand &Dest,
Optional<unsigned> &TiedDefIdx, bool IsDef = false);
bool parseImmediateOperand(MachineOperand &Dest);
bool parseIRConstant(StringRef::iterator Loc, StringRef Source,
const Constant *&C);
bool parseIRConstant(StringRef::iterator Loc, const Constant *&C);
- bool parseIRType(StringRef::iterator Loc, StringRef Source, unsigned &Read,
- Type *&Ty);
- // \p MustBeSized defines whether or not \p Ty must be sized.
- bool parseIRType(StringRef::iterator Loc, Type *&Ty, bool MustBeSized = true);
+ bool parseLowLevelType(StringRef::iterator Loc, LLT &Ty);
bool parseTypedImmediateOperand(MachineOperand &Dest);
bool parseFPImmediateOperand(MachineOperand &Dest);
bool parseMBBReference(MachineBasicBlock *&MBB);
@@ -155,6 +169,8 @@ public:
bool parseCFIOperand(MachineOperand &Dest);
bool parseIRBlock(BasicBlock *&BB, const Function &F);
bool parseBlockAddressOperand(MachineOperand &Dest);
+ bool parseIntrinsicOperand(MachineOperand &Dest);
+ bool parsePredicateOperand(MachineOperand &Dest);
bool parseTargetIndexOperand(MachineOperand &Dest);
bool parseLiveoutRegisterMaskOperand(MachineOperand &Dest);
bool parseMachineOperand(MachineOperand &Dest,
@@ -181,6 +197,12 @@ private:
/// Return true if an error occurred.
bool getUint64(uint64_t &Result);
+ /// Convert the hexadecimal literal in the current token into an unsigned
+ /// APInt with a minimum bitwidth required to represent the value.
+ ///
+ /// Return true if the literal does not represent an integer value.
+ bool getHexUint(APInt &Result);
+
/// If the current token is of the given kind, consume it and return false.
/// Otherwise report an error and return true.
bool expectAndConsume(MIToken::TokenKind TokenKind);
@@ -254,7 +276,7 @@ private:
} // end anonymous namespace
-MIParser::MIParser(const PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
+MIParser::MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
StringRef Source)
: MF(PFS.MF), Error(Error), Source(Source), CurrentSource(Source), PFS(PFS)
{}
@@ -362,7 +384,7 @@ bool MIParser::parseBasicBlockDefinition(
if (!Name.empty()) {
BB = dyn_cast_or_null<BasicBlock>(
- MF.getFunction()->getValueSymbolTable().lookup(Name));
+ MF.getFunction()->getValueSymbolTable()->lookup(Name));
if (!BB)
return error(Loc, Twine("basic block '") + Name +
"' is not defined in the function '" +
@@ -437,10 +459,24 @@ bool MIParser::parseBasicBlockLiveins(MachineBasicBlock &MBB) {
if (Token.isNot(MIToken::NamedRegister))
return error("expected a named register");
unsigned Reg = 0;
- if (parseRegister(Reg))
+ if (parseNamedRegister(Reg))
return true;
- MBB.addLiveIn(Reg);
lex();
+ LaneBitmask Mask = LaneBitmask::getAll();
+ if (consumeIfPresent(MIToken::colon)) {
+ // Parse lane mask.
+ if (Token.isNot(MIToken::IntegerLiteral) &&
+ Token.isNot(MIToken::HexLiteral))
+ return error("expected a lane mask");
+ static_assert(sizeof(LaneBitmask::Type) == sizeof(unsigned),
+ "Use correct get-function for lane mask");
+ LaneBitmask::Type V;
+ if (getUnsigned(V))
+ return error("invalid lane mask value");
+ Mask = LaneBitmask(V);
+ lex();
+ }
+ MBB.addLiveIn(Reg, Mask);
} while (consumeIfPresent(MIToken::comma));
return false;
}
@@ -461,7 +497,8 @@ bool MIParser::parseBasicBlockSuccessors(MachineBasicBlock &MBB) {
lex();
unsigned Weight = 0;
if (consumeIfPresent(MIToken::lparen)) {
- if (Token.isNot(MIToken::IntegerLiteral))
+ if (Token.isNot(MIToken::IntegerLiteral) &&
+ Token.isNot(MIToken::HexLiteral))
return error("expected an integer literal after '('");
if (getUnsigned(Weight))
return true;
@@ -597,14 +634,6 @@ bool MIParser::parse(MachineInstr *&MI) {
if (Token.isError() || parseInstruction(OpCode, Flags))
return true;
- Type *Ty = nullptr;
- if (isPreISelGenericOpcode(OpCode)) {
- // For generic opcode, a type is mandatory.
- auto Loc = Token.location();
- if (parseIRType(Loc, Ty))
- return true;
- }
-
// Parse the remaining machine operands.
while (!Token.isNewlineOrEOF() && Token.isNot(MIToken::kw_debug_location) &&
Token.isNot(MIToken::coloncolon) && Token.isNot(MIToken::lbrace)) {
@@ -660,8 +689,6 @@ bool MIParser::parse(MachineInstr *&MI) {
// TODO: Check for extraneous machine operands.
MI = MF.CreateMachineInstr(MCID, DebugLocation, /*NoImplicit=*/true);
MI->setFlags(Flags);
- if (Ty)
- MI->setType(Ty);
for (const auto &Operand : Operands)
MI->addOperand(MF, Operand.Operand);
if (assignRegisterTies(*MI, Operands))
@@ -692,7 +719,7 @@ bool MIParser::parseStandaloneNamedRegister(unsigned &Reg) {
lex();
if (Token.isNot(MIToken::NamedRegister))
return error("expected a named register");
- if (parseRegister(Reg))
+ if (parseNamedRegister(Reg))
return true;
lex();
if (Token.isNot(MIToken::Eof))
@@ -700,12 +727,28 @@ bool MIParser::parseStandaloneNamedRegister(unsigned &Reg) {
return false;
}
-bool MIParser::parseStandaloneVirtualRegister(unsigned &Reg) {
+bool MIParser::parseStandaloneVirtualRegister(VRegInfo *&Info) {
lex();
if (Token.isNot(MIToken::VirtualRegister))
return error("expected a virtual register");
- if (parseRegister(Reg))
+ if (parseVirtualRegister(Info))
+ return true;
+ lex();
+ if (Token.isNot(MIToken::Eof))
+ return error("expected end of string after the register reference");
+ return false;
+}
+
+bool MIParser::parseStandaloneRegister(unsigned &Reg) {
+ lex();
+ if (Token.isNot(MIToken::NamedRegister) &&
+ Token.isNot(MIToken::VirtualRegister))
+ return error("expected either a named or virtual register");
+
+ VRegInfo *Info;
+ if (parseRegister(Reg, Info))
return true;
+
lex();
if (Token.isNot(MIToken::Eof))
return error("expected end of string after the register reference");
@@ -800,33 +843,39 @@ bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) {
return false;
}
-bool MIParser::parseRegister(unsigned &Reg) {
+bool MIParser::parseNamedRegister(unsigned &Reg) {
+ assert(Token.is(MIToken::NamedRegister) && "Needs NamedRegister token");
+ StringRef Name = Token.stringValue();
+ if (getRegisterByName(Name, Reg))
+ return error(Twine("unknown register name '") + Name + "'");
+ return false;
+}
+
+bool MIParser::parseVirtualRegister(VRegInfo *&Info) {
+ assert(Token.is(MIToken::VirtualRegister) && "Needs VirtualRegister token");
+ unsigned ID;
+ if (getUnsigned(ID))
+ return true;
+ Info = &PFS.getVRegInfo(ID);
+ return false;
+}
+
+bool MIParser::parseRegister(unsigned &Reg, VRegInfo *&Info) {
switch (Token.kind()) {
case MIToken::underscore:
Reg = 0;
- break;
- case MIToken::NamedRegister: {
- StringRef Name = Token.stringValue();
- if (getRegisterByName(Name, Reg))
- return error(Twine("unknown register name '") + Name + "'");
- break;
- }
- case MIToken::VirtualRegister: {
- unsigned ID;
- if (getUnsigned(ID))
+ return false;
+ case MIToken::NamedRegister:
+ return parseNamedRegister(Reg);
+ case MIToken::VirtualRegister:
+ if (parseVirtualRegister(Info))
return true;
- const auto RegInfo = PFS.VirtualRegisterSlots.find(ID);
- if (RegInfo == PFS.VirtualRegisterSlots.end())
- return error(Twine("use of undefined virtual register '%") + Twine(ID) +
- "'");
- Reg = RegInfo->second;
- break;
- }
+ Reg = Info->VReg;
+ return false;
// TODO: Parse other register kinds.
default:
llvm_unreachable("The current token should be a register");
}
- return false;
}
bool MIParser::parseRegisterFlag(unsigned &Flags) {
@@ -871,10 +920,10 @@ bool MIParser::parseRegisterFlag(unsigned &Flags) {
}
bool MIParser::parseSubRegisterIndex(unsigned &SubReg) {
- assert(Token.is(MIToken::colon));
+ assert(Token.is(MIToken::dot));
lex();
if (Token.isNot(MIToken::Identifier))
- return error("expected a subregister index after ':'");
+ return error("expected a subregister index after '.'");
auto Name = Token.stringValue();
SubReg = getSubRegIndex(Name);
if (!SubReg)
@@ -885,7 +934,7 @@ bool MIParser::parseSubRegisterIndex(unsigned &SubReg) {
bool MIParser::parseRegisterTiedDefIndex(unsigned &TiedDefIdx) {
if (!consumeIfPresent(MIToken::kw_tied_def))
- return error("expected 'tied-def' after '('");
+ return true;
if (Token.isNot(MIToken::IntegerLiteral))
return error("expected an integer literal after 'tied-def'");
if (getUnsigned(TiedDefIdx))
@@ -896,17 +945,6 @@ bool MIParser::parseRegisterTiedDefIndex(unsigned &TiedDefIdx) {
return false;
}
-bool MIParser::parseSize(unsigned &Size) {
- if (Token.isNot(MIToken::IntegerLiteral))
- return error("expected an integer literal for the size");
- if (getUnsigned(Size))
- return true;
- lex();
- if (expectAndConsume(MIToken::rparen))
- return true;
- return false;
-}
-
bool MIParser::assignRegisterTies(MachineInstr &MI,
ArrayRef<ParsedMachineOperand> Operands) {
SmallVector<std::pair<unsigned, unsigned>, 4> TiedRegisterPairs;
@@ -947,7 +985,6 @@ bool MIParser::assignRegisterTies(MachineInstr &MI,
bool MIParser::parseRegisterOperand(MachineOperand &Dest,
Optional<unsigned> &TiedDefIdx,
bool IsDef) {
- unsigned Reg;
unsigned Flags = IsDef ? RegState::Define : 0;
while (Token.isRegisterFlag()) {
if (parseRegisterFlag(Flags))
@@ -955,38 +992,62 @@ bool MIParser::parseRegisterOperand(MachineOperand &Dest,
}
if (!Token.isRegister())
return error("expected a register after register flags");
- if (parseRegister(Reg))
+ unsigned Reg;
+ VRegInfo *RegInfo;
+ if (parseRegister(Reg, RegInfo))
return true;
lex();
unsigned SubReg = 0;
- if (Token.is(MIToken::colon)) {
+ if (Token.is(MIToken::dot)) {
if (parseSubRegisterIndex(SubReg))
return true;
if (!TargetRegisterInfo::isVirtualRegister(Reg))
return error("subregister index expects a virtual register");
}
+ MachineRegisterInfo &MRI = MF.getRegInfo();
if ((Flags & RegState::Define) == 0) {
if (consumeIfPresent(MIToken::lparen)) {
unsigned Idx;
- if (parseRegisterTiedDefIndex(Idx))
- return true;
- TiedDefIdx = Idx;
+ if (!parseRegisterTiedDefIndex(Idx))
+ TiedDefIdx = Idx;
+ else {
+ // Try a redundant low-level type.
+ LLT Ty;
+ if (parseLowLevelType(Token.location(), Ty))
+ return error("expected tied-def or low-level type after '('");
+
+ if (expectAndConsume(MIToken::rparen))
+ return true;
+
+ if (MRI.getType(Reg).isValid() && MRI.getType(Reg) != Ty)
+ return error("inconsistent type for generic virtual register");
+
+ MRI.setType(Reg, Ty);
+ }
}
} else if (consumeIfPresent(MIToken::lparen)) {
- // Virtual registers may have a size with GlobalISel.
+ // Virtual registers may have a tpe with GlobalISel.
if (!TargetRegisterInfo::isVirtualRegister(Reg))
- return error("unexpected size on physical register");
- unsigned Size;
- if (parseSize(Size))
+ return error("unexpected type on physical register");
+
+ LLT Ty;
+ if (parseLowLevelType(Token.location(), Ty))
return true;
- MachineRegisterInfo &MRI = MF.getRegInfo();
- MRI.setSize(Reg, Size);
- } else if (PFS.GenericVRegs.count(Reg)) {
- // Generic virtual registers must have a size.
- // If we end up here this means the size hasn't been specified and
+ if (expectAndConsume(MIToken::rparen))
+ return true;
+
+ if (MRI.getType(Reg).isValid() && MRI.getType(Reg) != Ty)
+ return error("inconsistent type for generic virtual register");
+
+ MRI.setType(Reg, Ty);
+ } else if (TargetRegisterInfo::isVirtualRegister(Reg)) {
+ // Generic virtual registers must have a type.
+ // If we end up here this means the type hasn't been specified and
// this is bad!
- return error("generic virtual registers must have a size");
+ if (RegInfo->Kind == VRegInfo::GENERIC ||
+ RegInfo->Kind == VRegInfo::REGBANK)
+ return error("generic virtual registers must have a type");
}
Dest = MachineOperand::CreateReg(
Reg, Flags & RegState::Define, Flags & RegState::Implicit,
@@ -1010,7 +1071,7 @@ bool MIParser::parseIRConstant(StringRef::iterator Loc, StringRef StringValue,
const Constant *&C) {
auto Source = StringValue.str(); // The source has to be null terminated.
SMDiagnostic Err;
- C = parseConstantValue(Source.c_str(), Err, *MF.getFunction()->getParent(),
+ C = parseConstantValue(Source, Err, *MF.getFunction()->getParent(),
&PFS.IRSlots);
if (!C)
return error(Loc + Err.getColumnNo(), Err.getMessage());
@@ -1024,35 +1085,45 @@ bool MIParser::parseIRConstant(StringRef::iterator Loc, const Constant *&C) {
return false;
}
-bool MIParser::parseIRType(StringRef::iterator Loc, StringRef StringValue,
- unsigned &Read, Type *&Ty) {
- auto Source = StringValue.str(); // The source has to be null terminated.
- SMDiagnostic Err;
- Ty = parseTypeAtBeginning(Source.c_str(), Read, Err,
- *MF.getFunction()->getParent(), &PFS.IRSlots);
- if (!Ty)
- return error(Loc + Err.getColumnNo(), Err.getMessage());
- return false;
-}
+bool MIParser::parseLowLevelType(StringRef::iterator Loc, LLT &Ty) {
+ if (Token.is(MIToken::ScalarType)) {
+ Ty = LLT::scalar(APSInt(Token.range().drop_front()).getZExtValue());
+ lex();
+ return false;
+ } else if (Token.is(MIToken::PointerType)) {
+ const DataLayout &DL = MF.getFunction()->getParent()->getDataLayout();
+ unsigned AS = APSInt(Token.range().drop_front()).getZExtValue();
+ Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS));
+ lex();
+ return false;
+ }
-bool MIParser::parseIRType(StringRef::iterator Loc, Type *&Ty,
- bool MustBeSized) {
- // At this point we enter in the IR world, i.e., to get the correct type,
- // we need to hand off the whole string, not just the current token.
- // E.g., <4 x i64> would give '<' as a token and there is not much
- // the IR parser can do with that.
- unsigned Read = 0;
- if (parseIRType(Loc, StringRef(Loc), Read, Ty))
- return true;
- // The type must be sized, otherwise there is not much the backend
- // can do with it.
- if (MustBeSized && !Ty->isSized())
- return error("expected a sized type");
- // The next token is Read characters from the Loc.
- // However, the current location is not Loc, but Loc + the length of Token.
- // Therefore, subtract the length of Token (range().end() - Loc) to the
- // number of characters to skip before the next token.
- lex(Read - (Token.range().end() - Loc));
+ // Now we're looking for a vector.
+ if (Token.isNot(MIToken::less))
+ return error(Loc,
+ "expected unsized, pN, sN or <N x sM> for GlobalISel type");
+
+ lex();
+
+ if (Token.isNot(MIToken::IntegerLiteral))
+ return error(Loc, "expected <N x sM> for vctor type");
+ uint64_t NumElements = Token.integerValue().getZExtValue();
+ lex();
+
+ if (Token.isNot(MIToken::Identifier) || Token.stringValue() != "x")
+ return error(Loc, "expected '<N x sM>' for vector type");
+ lex();
+
+ if (Token.isNot(MIToken::ScalarType))
+ return error(Loc, "expected '<N x sM>' for vector type");
+ uint64_t ScalarSize = APSInt(Token.range().drop_front()).getZExtValue();
+ lex();
+
+ if (Token.isNot(MIToken::greater))
+ return error(Loc, "expected '<N x sM>' for vector type");
+ lex();
+
+ Ty = LLT::vector(NumElements, ScalarSize);
return false;
}
@@ -1072,7 +1143,8 @@ bool MIParser::parseTypedImmediateOperand(MachineOperand &Dest) {
bool MIParser::parseFPImmediateOperand(MachineOperand &Dest) {
auto Loc = Token.location();
lex();
- if (Token.isNot(MIToken::FloatingPointLiteral))
+ if (Token.isNot(MIToken::FloatingPointLiteral) &&
+ Token.isNot(MIToken::HexLiteral))
return error("expected a floating point literal");
const Constant *C = nullptr;
if (parseIRConstant(Loc, C))
@@ -1082,13 +1154,24 @@ bool MIParser::parseFPImmediateOperand(MachineOperand &Dest) {
}
bool MIParser::getUnsigned(unsigned &Result) {
- assert(Token.hasIntegerValue() && "Expected a token with an integer value");
- const uint64_t Limit = uint64_t(std::numeric_limits<unsigned>::max()) + 1;
- uint64_t Val64 = Token.integerValue().getLimitedValue(Limit);
- if (Val64 == Limit)
- return error("expected 32-bit integer (too large)");
- Result = Val64;
- return false;
+ if (Token.hasIntegerValue()) {
+ const uint64_t Limit = uint64_t(std::numeric_limits<unsigned>::max()) + 1;
+ uint64_t Val64 = Token.integerValue().getLimitedValue(Limit);
+ if (Val64 == Limit)
+ return error("expected 32-bit integer (too large)");
+ Result = Val64;
+ return false;
+ }
+ if (Token.is(MIToken::HexLiteral)) {
+ APInt A;
+ if (getHexUint(A))
+ return true;
+ if (A.getBitWidth() > 32)
+ return error("expected 32-bit integer (too large)");
+ Result = A.getZExtValue();
+ return false;
+ }
+ return true;
}
bool MIParser::parseMBBReference(MachineBasicBlock *&MBB) {
@@ -1128,7 +1211,7 @@ bool MIParser::parseStackFrameIndex(int &FI) {
"'");
StringRef Name;
if (const auto *Alloca =
- MF.getFrameInfo()->getObjectAllocation(ObjectInfo->second))
+ MF.getFrameInfo().getObjectAllocation(ObjectInfo->second))
Name = Alloca->getName();
if (!Token.stringValue().empty() && Token.stringValue() != Name)
return error(Twine("the name of the stack object '%stack.") + Twine(ID) +
@@ -1293,7 +1376,7 @@ bool MIParser::parseCFIRegister(unsigned &Reg) {
if (Token.isNot(MIToken::NamedRegister))
return error("expected a cfi register");
unsigned LLVMReg;
- if (parseRegister(LLVMReg))
+ if (parseNamedRegister(LLVMReg))
return true;
const auto *TRI = MF.getSubtarget().getRegisterInfo();
assert(TRI && "Expected target register info");
@@ -1308,7 +1391,6 @@ bool MIParser::parseCFIRegister(unsigned &Reg) {
bool MIParser::parseCFIOperand(MachineOperand &Dest) {
auto Kind = Token.kind();
lex();
- auto &MMI = MF.getMMI();
int Offset;
unsigned Reg;
unsigned CFIIndex;
@@ -1316,27 +1398,26 @@ bool MIParser::parseCFIOperand(MachineOperand &Dest) {
case MIToken::kw_cfi_same_value:
if (parseCFIRegister(Reg))
return true;
- CFIIndex =
- MMI.addFrameInst(MCCFIInstruction::createSameValue(nullptr, Reg));
+ CFIIndex = MF.addFrameInst(MCCFIInstruction::createSameValue(nullptr, Reg));
break;
case MIToken::kw_cfi_offset:
if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
parseCFIOffset(Offset))
return true;
CFIIndex =
- MMI.addFrameInst(MCCFIInstruction::createOffset(nullptr, Reg, Offset));
+ MF.addFrameInst(MCCFIInstruction::createOffset(nullptr, Reg, Offset));
break;
case MIToken::kw_cfi_def_cfa_register:
if (parseCFIRegister(Reg))
return true;
CFIIndex =
- MMI.addFrameInst(MCCFIInstruction::createDefCfaRegister(nullptr, Reg));
+ MF.addFrameInst(MCCFIInstruction::createDefCfaRegister(nullptr, Reg));
break;
case MIToken::kw_cfi_def_cfa_offset:
if (parseCFIOffset(Offset))
return true;
// NB: MCCFIInstruction::createDefCfaOffset negates the offset.
- CFIIndex = MMI.addFrameInst(
+ CFIIndex = MF.addFrameInst(
MCCFIInstruction::createDefCfaOffset(nullptr, -Offset));
break;
case MIToken::kw_cfi_def_cfa:
@@ -1345,7 +1426,7 @@ bool MIParser::parseCFIOperand(MachineOperand &Dest) {
return true;
// NB: MCCFIInstruction::createDefCfa negates the offset.
CFIIndex =
- MMI.addFrameInst(MCCFIInstruction::createDefCfa(nullptr, Reg, -Offset));
+ MF.addFrameInst(MCCFIInstruction::createDefCfa(nullptr, Reg, -Offset));
break;
default:
// TODO: Parse the other CFI operands.
@@ -1359,7 +1440,7 @@ bool MIParser::parseIRBlock(BasicBlock *&BB, const Function &F) {
switch (Token.kind()) {
case MIToken::NamedIRBlock: {
BB = dyn_cast_or_null<BasicBlock>(
- F.getValueSymbolTable().lookup(Token.stringValue()));
+ F.getValueSymbolTable()->lookup(Token.stringValue()));
if (!BB)
return error(Twine("use of undefined IR block '") + Token.range() + "'");
break;
@@ -1411,6 +1492,93 @@ bool MIParser::parseBlockAddressOperand(MachineOperand &Dest) {
return false;
}
+bool MIParser::parseIntrinsicOperand(MachineOperand &Dest) {
+ assert(Token.is(MIToken::kw_intrinsic));
+ lex();
+ if (expectAndConsume(MIToken::lparen))
+ return error("expected syntax intrinsic(@llvm.whatever)");
+
+ if (Token.isNot(MIToken::NamedGlobalValue))
+ return error("expected syntax intrinsic(@llvm.whatever)");
+
+ std::string Name = Token.stringValue();
+ lex();
+
+ if (expectAndConsume(MIToken::rparen))
+ return error("expected ')' to terminate intrinsic name");
+
+ // Find out what intrinsic we're dealing with, first try the global namespace
+ // and then the target's private intrinsics if that fails.
+ const TargetIntrinsicInfo *TII = MF.getTarget().getIntrinsicInfo();
+ Intrinsic::ID ID = Function::lookupIntrinsicID(Name);
+ if (ID == Intrinsic::not_intrinsic && TII)
+ ID = static_cast<Intrinsic::ID>(TII->lookupName(Name));
+
+ if (ID == Intrinsic::not_intrinsic)
+ return error("unknown intrinsic name");
+ Dest = MachineOperand::CreateIntrinsicID(ID);
+
+ return false;
+}
+
+bool MIParser::parsePredicateOperand(MachineOperand &Dest) {
+ assert(Token.is(MIToken::kw_intpred) || Token.is(MIToken::kw_floatpred));
+ bool IsFloat = Token.is(MIToken::kw_floatpred);
+ lex();
+
+ if (expectAndConsume(MIToken::lparen))
+ return error("expected syntax intpred(whatever) or floatpred(whatever");
+
+ if (Token.isNot(MIToken::Identifier))
+ return error("whatever");
+
+ CmpInst::Predicate Pred;
+ if (IsFloat) {
+ Pred = StringSwitch<CmpInst::Predicate>(Token.stringValue())
+ .Case("false", CmpInst::FCMP_FALSE)
+ .Case("oeq", CmpInst::FCMP_OEQ)
+ .Case("ogt", CmpInst::FCMP_OGT)
+ .Case("oge", CmpInst::FCMP_OGE)
+ .Case("olt", CmpInst::FCMP_OLT)
+ .Case("ole", CmpInst::FCMP_OLE)
+ .Case("one", CmpInst::FCMP_ONE)
+ .Case("ord", CmpInst::FCMP_ORD)
+ .Case("uno", CmpInst::FCMP_UNO)
+ .Case("ueq", CmpInst::FCMP_UEQ)
+ .Case("ugt", CmpInst::FCMP_UGT)
+ .Case("uge", CmpInst::FCMP_UGE)
+ .Case("ult", CmpInst::FCMP_ULT)
+ .Case("ule", CmpInst::FCMP_ULE)
+ .Case("une", CmpInst::FCMP_UNE)
+ .Case("true", CmpInst::FCMP_TRUE)
+ .Default(CmpInst::BAD_FCMP_PREDICATE);
+ if (!CmpInst::isFPPredicate(Pred))
+ return error("invalid floating-point predicate");
+ } else {
+ Pred = StringSwitch<CmpInst::Predicate>(Token.stringValue())
+ .Case("eq", CmpInst::ICMP_EQ)
+ .Case("ne", CmpInst::ICMP_NE)
+ .Case("sgt", CmpInst::ICMP_SGT)
+ .Case("sge", CmpInst::ICMP_SGE)
+ .Case("slt", CmpInst::ICMP_SLT)
+ .Case("sle", CmpInst::ICMP_SLE)
+ .Case("ugt", CmpInst::ICMP_UGT)
+ .Case("uge", CmpInst::ICMP_UGE)
+ .Case("ult", CmpInst::ICMP_ULT)
+ .Case("ule", CmpInst::ICMP_ULE)
+ .Default(CmpInst::BAD_ICMP_PREDICATE);
+ if (!CmpInst::isIntPredicate(Pred))
+ return error("invalid integer predicate");
+ }
+
+ lex();
+ Dest = MachineOperand::CreatePredicate(Pred);
+ if (expectAndConsume(MIToken::rparen))
+ return error("predicate should be terminated by ')'.");
+
+ return false;
+}
+
bool MIParser::parseTargetIndexOperand(MachineOperand &Dest) {
assert(Token.is(MIToken::kw_target_index));
lex();
@@ -1441,8 +1609,8 @@ bool MIParser::parseLiveoutRegisterMaskOperand(MachineOperand &Dest) {
while (true) {
if (Token.isNot(MIToken::NamedRegister))
return error("expected a named register");
- unsigned Reg = 0;
- if (parseRegister(Reg))
+ unsigned Reg;
+ if (parseNamedRegister(Reg))
return true;
lex();
Mask[Reg / 32] |= 1U << (Reg % 32);
@@ -1511,10 +1679,15 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest,
return parseCFIOperand(Dest);
case MIToken::kw_blockaddress:
return parseBlockAddressOperand(Dest);
+ case MIToken::kw_intrinsic:
+ return parseIntrinsicOperand(Dest);
case MIToken::kw_target_index:
return parseTargetIndexOperand(Dest);
case MIToken::kw_liveout:
return parseLiveoutRegisterMaskOperand(Dest);
+ case MIToken::kw_floatpred:
+ case MIToken::kw_intpred:
+ return parsePredicateOperand(Dest);
case MIToken::Error:
return true;
case MIToken::Identifier:
@@ -1523,7 +1696,7 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest,
lex();
break;
}
- // fallthrough
+ LLVM_FALLTHROUGH;
default:
// FIXME: Parse the MCSymbol machine operand.
return error("expected a machine operand");
@@ -1613,7 +1786,7 @@ bool MIParser::parseOperandsOffset(MachineOperand &Op) {
bool MIParser::parseIRValue(const Value *&V) {
switch (Token.kind()) {
case MIToken::NamedIRValue: {
- V = MF.getFunction()->getValueSymbolTable().lookup(Token.stringValue());
+ V = MF.getFunction()->getValueSymbolTable()->lookup(Token.stringValue());
break;
}
case MIToken::IRValue: {
@@ -1647,10 +1820,35 @@ bool MIParser::parseIRValue(const Value *&V) {
}
bool MIParser::getUint64(uint64_t &Result) {
- assert(Token.hasIntegerValue());
- if (Token.integerValue().getActiveBits() > 64)
- return error("expected 64-bit integer (too large)");
- Result = Token.integerValue().getZExtValue();
+ if (Token.hasIntegerValue()) {
+ if (Token.integerValue().getActiveBits() > 64)
+ return error("expected 64-bit integer (too large)");
+ Result = Token.integerValue().getZExtValue();
+ return false;
+ }
+ if (Token.is(MIToken::HexLiteral)) {
+ APInt A;
+ if (getHexUint(A))
+ return true;
+ if (A.getBitWidth() > 64)
+ return error("expected 64-bit integer (too large)");
+ Result = A.getZExtValue();
+ return false;
+ }
+ return true;
+}
+
+bool MIParser::getHexUint(APInt &Result) {
+ assert(Token.is(MIToken::HexLiteral));
+ StringRef S = Token.range();
+ assert(S[0] == '0' && tolower(S[1]) == 'x');
+ // This could be a floating point literal with a special prefix.
+ if (!isxdigit(S[2]))
+ return true;
+ StringRef V = S.substr(2);
+ APInt A(V.size()*4, V, 16);
+ Result = APInt(A.getActiveBits(),
+ ArrayRef<uint64_t>(A.getRawData(), A.getNumWords()));
return false;
}
@@ -1663,6 +1861,9 @@ bool MIParser::parseMemoryOperandFlag(MachineMemOperand::Flags &Flags) {
case MIToken::kw_non_temporal:
Flags |= MachineMemOperand::MONonTemporal;
break;
+ case MIToken::kw_dereferenceable:
+ Flags |= MachineMemOperand::MODereferenceable;
+ break;
case MIToken::kw_invariant:
Flags |= MachineMemOperand::MOInvariant;
break;
@@ -2059,36 +2260,42 @@ bool llvm::parseMachineBasicBlockDefinitions(PerFunctionMIParsingState &PFS,
return MIParser(PFS, Error, Src).parseBasicBlockDefinitions(PFS.MBBSlots);
}
-bool llvm::parseMachineInstructions(const PerFunctionMIParsingState &PFS,
+bool llvm::parseMachineInstructions(PerFunctionMIParsingState &PFS,
StringRef Src, SMDiagnostic &Error) {
return MIParser(PFS, Error, Src).parseBasicBlocks();
}
-bool llvm::parseMBBReference(const PerFunctionMIParsingState &PFS,
+bool llvm::parseMBBReference(PerFunctionMIParsingState &PFS,
MachineBasicBlock *&MBB, StringRef Src,
SMDiagnostic &Error) {
return MIParser(PFS, Error, Src).parseStandaloneMBB(MBB);
}
-bool llvm::parseNamedRegisterReference(const PerFunctionMIParsingState &PFS,
+bool llvm::parseRegisterReference(PerFunctionMIParsingState &PFS,
+ unsigned &Reg, StringRef Src,
+ SMDiagnostic &Error) {
+ return MIParser(PFS, Error, Src).parseStandaloneRegister(Reg);
+}
+
+bool llvm::parseNamedRegisterReference(PerFunctionMIParsingState &PFS,
unsigned &Reg, StringRef Src,
SMDiagnostic &Error) {
return MIParser(PFS, Error, Src).parseStandaloneNamedRegister(Reg);
}
-bool llvm::parseVirtualRegisterReference(const PerFunctionMIParsingState &PFS,
- unsigned &Reg, StringRef Src,
+bool llvm::parseVirtualRegisterReference(PerFunctionMIParsingState &PFS,
+ VRegInfo *&Info, StringRef Src,
SMDiagnostic &Error) {
- return MIParser(PFS, Error, Src).parseStandaloneVirtualRegister(Reg);
+ return MIParser(PFS, Error, Src).parseStandaloneVirtualRegister(Info);
}
-bool llvm::parseStackObjectReference(const PerFunctionMIParsingState &PFS,
+bool llvm::parseStackObjectReference(PerFunctionMIParsingState &PFS,
int &FI, StringRef Src,
SMDiagnostic &Error) {
return MIParser(PFS, Error, Src).parseStandaloneStackObject(FI);
}
-bool llvm::parseMDNode(const PerFunctionMIParsingState &PFS,
+bool llvm::parseMDNode(PerFunctionMIParsingState &PFS,
MDNode *&Node, StringRef Src, SMDiagnostic &Error) {
return MIParser(PFS, Error, Src).parseStandaloneMDNode(Node);
}
diff --git a/contrib/llvm/lib/CodeGen/MIRParser/MIParser.h b/contrib/llvm/lib/CodeGen/MIRParser/MIParser.h
index 18895b9..93a4d84 100644
--- a/contrib/llvm/lib/CodeGen/MIRParser/MIParser.h
+++ b/contrib/llvm/lib/CodeGen/MIRParser/MIParser.h
@@ -26,26 +26,42 @@ class MachineFunction;
class MachineInstr;
class MachineRegisterInfo;
class MDNode;
+class RegisterBank;
struct SlotMapping;
class SMDiagnostic;
class SourceMgr;
+class TargetRegisterClass;
+
+struct VRegInfo {
+ enum uint8_t {
+ UNKNOWN, NORMAL, GENERIC, REGBANK
+ } Kind = UNKNOWN;
+ bool Explicit = false; ///< VReg was explicitly specified in the .mir file.
+ union {
+ const TargetRegisterClass *RC;
+ const RegisterBank *RegBank;
+ } D;
+ unsigned VReg;
+ unsigned PreferredReg = 0;
+};
struct PerFunctionMIParsingState {
+ BumpPtrAllocator Allocator;
MachineFunction &MF;
SourceMgr *SM;
const SlotMapping &IRSlots;
DenseMap<unsigned, MachineBasicBlock *> MBBSlots;
- DenseMap<unsigned, unsigned> VirtualRegisterSlots;
+ DenseMap<unsigned, VRegInfo*> VRegInfos;
DenseMap<unsigned, int> FixedStackObjectSlots;
DenseMap<unsigned, int> StackObjectSlots;
DenseMap<unsigned, unsigned> ConstantPoolSlots;
DenseMap<unsigned, unsigned> JumpTableSlots;
- /// Hold the generic virtual registers.
- SmallSet<unsigned, 8> GenericVRegs;
PerFunctionMIParsingState(MachineFunction &MF, SourceMgr &SM,
const SlotMapping &IRSlots);
+
+ VRegInfo &getVRegInfo(unsigned VReg);
};
/// Parse the machine basic block definitions, and skip the machine
@@ -73,26 +89,29 @@ bool parseMachineBasicBlockDefinitions(PerFunctionMIParsingState &PFS,
/// on the given source string.
///
/// Return true if an error occurred.
-bool parseMachineInstructions(const PerFunctionMIParsingState &PFS,
- StringRef Src, SMDiagnostic &Error);
+bool parseMachineInstructions(PerFunctionMIParsingState &PFS, StringRef Src,
+ SMDiagnostic &Error);
-bool parseMBBReference(const PerFunctionMIParsingState &PFS,
+bool parseMBBReference(PerFunctionMIParsingState &PFS,
MachineBasicBlock *&MBB, StringRef Src,
SMDiagnostic &Error);
-bool parseNamedRegisterReference(const PerFunctionMIParsingState &PFS,
- unsigned &Reg, StringRef Src,
- SMDiagnostic &Error);
+bool parseRegisterReference(PerFunctionMIParsingState &PFS,
+ unsigned &Reg, StringRef Src,
+ SMDiagnostic &Error);
+
+bool parseNamedRegisterReference(PerFunctionMIParsingState &PFS, unsigned &Reg,
+ StringRef Src, SMDiagnostic &Error);
-bool parseVirtualRegisterReference(const PerFunctionMIParsingState &PFS,
- unsigned &Reg, StringRef Src,
+bool parseVirtualRegisterReference(PerFunctionMIParsingState &PFS,
+ VRegInfo *&Info, StringRef Src,
SMDiagnostic &Error);
-bool parseStackObjectReference(const PerFunctionMIParsingState &PFS,
- int &FI, StringRef Src, SMDiagnostic &Error);
+bool parseStackObjectReference(PerFunctionMIParsingState &PFS, int &FI,
+ StringRef Src, SMDiagnostic &Error);
-bool parseMDNode(const PerFunctionMIParsingState &PFS, MDNode *&Node,
- StringRef Src, SMDiagnostic &Error);
+bool parseMDNode(PerFunctionMIParsingState &PFS, MDNode *&Node, StringRef Src,
+ SMDiagnostic &Error);
} // end namespace llvm
diff --git a/contrib/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/contrib/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
index 4aa3df6..3dff114 100644
--- a/contrib/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/contrib/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -102,10 +102,10 @@ public:
/// Return true if error occurred.
bool initializeMachineFunction(MachineFunction &MF);
- bool initializeRegisterInfo(PerFunctionMIParsingState &PFS,
- const yaml::MachineFunction &YamlMF);
+ bool parseRegisterInfo(PerFunctionMIParsingState &PFS,
+ const yaml::MachineFunction &YamlMF);
- void inferRegisterInfo(const PerFunctionMIParsingState &PFS,
+ bool setupRegisterInfo(const PerFunctionMIParsingState &PFS,
const yaml::MachineFunction &YamlMF);
bool initializeFrameInfo(PerFunctionMIParsingState &PFS,
@@ -128,10 +128,10 @@ public:
const yaml::MachineJumpTable &YamlJTI);
private:
- bool parseMDNode(const PerFunctionMIParsingState &PFS, MDNode *&Node,
+ bool parseMDNode(PerFunctionMIParsingState &PFS, MDNode *&Node,
const yaml::StringValue &Source);
- bool parseMBBReference(const PerFunctionMIParsingState &PFS,
+ bool parseMBBReference(PerFunctionMIParsingState &PFS,
MachineBasicBlock *&MBB,
const yaml::StringValue &Source);
@@ -160,6 +160,8 @@ private:
///
/// Return null if the name isn't a register bank.
const RegisterBank *getRegBank(const MachineFunction &MF, StringRef Name);
+
+ void computeFunctionProperties(MachineFunction &MF);
};
} // end namespace llvm
@@ -255,7 +257,8 @@ std::unique_ptr<Module> MIRParserImpl::parse() {
bool MIRParserImpl::parseMachineFunction(yaml::Input &In, Module &M,
bool NoLLVMIR) {
auto MF = llvm::make_unique<yaml::MachineFunction>();
- yaml::yamlize(In, *MF, false);
+ yaml::EmptyContext Ctx;
+ yaml::yamlize(In, *MF, false, Ctx);
if (In.error())
return true;
auto FunctionName = MF->Name;
@@ -279,6 +282,43 @@ void MIRParserImpl::createDummyFunction(StringRef Name, Module &M) {
new UnreachableInst(Context, BB);
}
+static bool isSSA(const MachineFunction &MF) {
+ const MachineRegisterInfo &MRI = MF.getRegInfo();
+ for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
+ unsigned Reg = TargetRegisterInfo::index2VirtReg(I);
+ if (!MRI.hasOneDef(Reg) && !MRI.def_empty(Reg))
+ return false;
+ }
+ return true;
+}
+
+void MIRParserImpl::computeFunctionProperties(MachineFunction &MF) {
+ MachineFunctionProperties &Properties = MF.getProperties();
+
+ bool HasPHI = false;
+ bool HasInlineAsm = false;
+ for (const MachineBasicBlock &MBB : MF) {
+ for (const MachineInstr &MI : MBB) {
+ if (MI.isPHI())
+ HasPHI = true;
+ if (MI.isInlineAsm())
+ HasInlineAsm = true;
+ }
+ }
+ if (!HasPHI)
+ Properties.set(MachineFunctionProperties::Property::NoPHIs);
+ MF.setHasInlineAsm(HasInlineAsm);
+
+ if (isSSA(MF))
+ Properties.set(MachineFunctionProperties::Property::IsSSA);
+ else
+ Properties.reset(MachineFunctionProperties::Property::IsSSA);
+
+ const MachineRegisterInfo &MRI = MF.getRegInfo();
+ if (MRI.getNumVirtRegs() == 0)
+ Properties.set(MachineFunctionProperties::Property::NoVRegs);
+}
+
bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
auto It = Functions.find(MF.getName());
if (It == Functions.end())
@@ -289,11 +329,17 @@ bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
if (YamlMF.Alignment)
MF.setAlignment(YamlMF.Alignment);
MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);
- MF.setHasInlineAsm(YamlMF.HasInlineAsm);
- if (YamlMF.AllVRegsAllocated)
- MF.getProperties().set(MachineFunctionProperties::Property::AllVRegsAllocated);
+
+ if (YamlMF.Legalized)
+ MF.getProperties().set(MachineFunctionProperties::Property::Legalized);
+ if (YamlMF.RegBankSelected)
+ MF.getProperties().set(
+ MachineFunctionProperties::Property::RegBankSelected);
+ if (YamlMF.Selected)
+ MF.getProperties().set(MachineFunctionProperties::Property::Selected);
+
PerFunctionMIParsingState PFS(MF, SM, IRSlots);
- if (initializeRegisterInfo(PFS, YamlMF))
+ if (parseRegisterInfo(PFS, YamlMF))
return true;
if (!YamlMF.Constants.empty()) {
auto *ConstantPool = MF.getConstantPool();
@@ -343,62 +389,60 @@ bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
}
PFS.SM = &SM;
- inferRegisterInfo(PFS, YamlMF);
- // FIXME: This is a temporary workaround until the reserved registers can be
- // serialized.
- MF.getRegInfo().freezeReservedRegs(MF);
+ if (setupRegisterInfo(PFS, YamlMF))
+ return true;
+
+ computeFunctionProperties(MF);
+
MF.verify();
return false;
}
-bool MIRParserImpl::initializeRegisterInfo(PerFunctionMIParsingState &PFS,
- const yaml::MachineFunction &YamlMF) {
+bool MIRParserImpl::parseRegisterInfo(PerFunctionMIParsingState &PFS,
+ const yaml::MachineFunction &YamlMF) {
MachineFunction &MF = PFS.MF;
MachineRegisterInfo &RegInfo = MF.getRegInfo();
- assert(RegInfo.isSSA());
- if (!YamlMF.IsSSA)
- RegInfo.leaveSSA();
assert(RegInfo.tracksLiveness());
if (!YamlMF.TracksRegLiveness)
RegInfo.invalidateLiveness();
- RegInfo.enableSubRegLiveness(YamlMF.TracksSubRegLiveness);
SMDiagnostic Error;
// Parse the virtual register information.
for (const auto &VReg : YamlMF.VirtualRegisters) {
- unsigned Reg;
+ VRegInfo &Info = PFS.getVRegInfo(VReg.ID.Value);
+ if (Info.Explicit)
+ return error(VReg.ID.SourceRange.Start,
+ Twine("redefinition of virtual register '%") +
+ Twine(VReg.ID.Value) + "'");
+ Info.Explicit = true;
+
if (StringRef(VReg.Class.Value).equals("_")) {
- // This is a generic virtual register.
- // The size will be set appropriately when we reach the definition.
- Reg = RegInfo.createGenericVirtualRegister(/*Size*/ 1);
- PFS.GenericVRegs.insert(Reg);
+ Info.Kind = VRegInfo::GENERIC;
} else {
const auto *RC = getRegClass(MF, VReg.Class.Value);
if (RC) {
- Reg = RegInfo.createVirtualRegister(RC);
+ Info.Kind = VRegInfo::NORMAL;
+ Info.D.RC = RC;
} else {
- const auto *RegBank = getRegBank(MF, VReg.Class.Value);
+ const RegisterBank *RegBank = getRegBank(MF, VReg.Class.Value);
if (!RegBank)
return error(
VReg.Class.SourceRange.Start,
Twine("use of undefined register class or register bank '") +
VReg.Class.Value + "'");
- Reg = RegInfo.createGenericVirtualRegister(/*Size*/ 1);
- RegInfo.setRegBank(Reg, *RegBank);
- PFS.GenericVRegs.insert(Reg);
+ Info.Kind = VRegInfo::REGBANK;
+ Info.D.RegBank = RegBank;
}
}
- if (!PFS.VirtualRegisterSlots.insert(std::make_pair(VReg.ID.Value, Reg))
- .second)
- return error(VReg.ID.SourceRange.Start,
- Twine("redefinition of virtual register '%") +
- Twine(VReg.ID.Value) + "'");
+
if (!VReg.PreferredRegister.Value.empty()) {
- unsigned PreferredReg = 0;
- if (parseNamedRegisterReference(PFS, PreferredReg,
- VReg.PreferredRegister.Value, Error))
+ if (Info.Kind != VRegInfo::NORMAL)
+ return error(VReg.Class.SourceRange.Start,
+ Twine("preferred register can only be set for normal vregs"));
+
+ if (parseRegisterReference(PFS, Info.PreferredReg,
+ VReg.PreferredRegister.Value, Error))
return error(Error, VReg.PreferredRegister.SourceRange);
- RegInfo.setSimpleHint(Reg, PreferredReg);
}
}
@@ -409,9 +453,11 @@ bool MIRParserImpl::initializeRegisterInfo(PerFunctionMIParsingState &PFS,
return error(Error, LiveIn.Register.SourceRange);
unsigned VReg = 0;
if (!LiveIn.VirtualRegister.Value.empty()) {
- if (parseVirtualRegisterReference(PFS, VReg, LiveIn.VirtualRegister.Value,
+ VRegInfo *Info;
+ if (parseVirtualRegisterReference(PFS, Info, LiveIn.VirtualRegister.Value,
Error))
return error(Error, LiveIn.VirtualRegister.SourceRange);
+ VReg = Info->VReg;
}
RegInfo.addLiveIn(Reg, VReg);
}
@@ -430,26 +476,57 @@ bool MIRParserImpl::initializeRegisterInfo(PerFunctionMIParsingState &PFS,
return false;
}
-void MIRParserImpl::inferRegisterInfo(const PerFunctionMIParsingState &PFS,
+bool MIRParserImpl::setupRegisterInfo(const PerFunctionMIParsingState &PFS,
const yaml::MachineFunction &YamlMF) {
- if (YamlMF.CalleeSavedRegisters)
- return;
- MachineRegisterInfo &MRI = PFS.MF.getRegInfo();
- for (const MachineBasicBlock &MBB : PFS.MF) {
- for (const MachineInstr &MI : MBB) {
- for (const MachineOperand &MO : MI.operands()) {
- if (!MO.isRegMask())
- continue;
- MRI.addPhysRegsUsedFromRegMask(MO.getRegMask());
+ MachineFunction &MF = PFS.MF;
+ MachineRegisterInfo &MRI = MF.getRegInfo();
+ bool Error = false;
+ // Create VRegs
+ for (auto P : PFS.VRegInfos) {
+ const VRegInfo &Info = *P.second;
+ unsigned Reg = Info.VReg;
+ switch (Info.Kind) {
+ case VRegInfo::UNKNOWN:
+ error(Twine("Cannot determine class/bank of virtual register ") +
+ Twine(P.first) + " in function '" + MF.getName() + "'");
+ Error = true;
+ break;
+ case VRegInfo::NORMAL:
+ MRI.setRegClass(Reg, Info.D.RC);
+ if (Info.PreferredReg != 0)
+ MRI.setSimpleHint(Reg, Info.PreferredReg);
+ break;
+ case VRegInfo::GENERIC:
+ break;
+ case VRegInfo::REGBANK:
+ MRI.setRegBank(Reg, *Info.D.RegBank);
+ break;
+ }
+ }
+
+ // Compute MachineRegisterInfo::UsedPhysRegMask
+ if (!YamlMF.CalleeSavedRegisters) {
+ for (const MachineBasicBlock &MBB : MF) {
+ for (const MachineInstr &MI : MBB) {
+ for (const MachineOperand &MO : MI.operands()) {
+ if (!MO.isRegMask())
+ continue;
+ MRI.addPhysRegsUsedFromRegMask(MO.getRegMask());
+ }
}
}
}
+
+ // FIXME: This is a temporary workaround until the reserved registers can be
+ // serialized.
+ MRI.freezeReservedRegs(MF);
+ return Error;
}
bool MIRParserImpl::initializeFrameInfo(PerFunctionMIParsingState &PFS,
const yaml::MachineFunction &YamlMF) {
MachineFunction &MF = PFS.MF;
- MachineFrameInfo &MFI = *MF.getFrameInfo();
+ MachineFrameInfo &MFI = MF.getFrameInfo();
const Function &F = *MF.getFunction();
const yaml::MachineFrameInfo &YamlMFI = YamlMF.FrameInfo;
MFI.setFrameAddressIsTaken(YamlMFI.IsFrameAddressTaken);
@@ -507,7 +584,7 @@ bool MIRParserImpl::initializeFrameInfo(PerFunctionMIParsingState &PFS,
const yaml::StringValue &Name = Object.Name;
if (!Name.Value.empty()) {
Alloca = dyn_cast_or_null<AllocaInst>(
- F.getValueSymbolTable().lookup(Name.Value));
+ F.getValueSymbolTable()->lookup(Name.Value));
if (!Alloca)
return error(Name.SourceRange.Start,
"alloca instruction named '" + Name.Value +
@@ -597,11 +674,11 @@ bool MIRParserImpl::parseStackObjectsDebugInfo(PerFunctionMIParsingState &PFS,
typecheckMDNode(DIExpr, Expr, Object.DebugExpr, "DIExpression", *this) ||
typecheckMDNode(DILoc, Loc, Object.DebugLoc, "DILocation", *this))
return true;
- PFS.MF.getMMI().setVariableDbgInfo(DIVar, DIExpr, unsigned(FrameIdx), DILoc);
+ PFS.MF.setVariableDbgInfo(DIVar, DIExpr, unsigned(FrameIdx), DILoc);
return false;
}
-bool MIRParserImpl::parseMDNode(const PerFunctionMIParsingState &PFS,
+bool MIRParserImpl::parseMDNode(PerFunctionMIParsingState &PFS,
MDNode *&Node, const yaml::StringValue &Source) {
if (Source.Value.empty())
return false;
@@ -657,7 +734,7 @@ bool MIRParserImpl::initializeJumpTableInfo(PerFunctionMIParsingState &PFS,
return false;
}
-bool MIRParserImpl::parseMBBReference(const PerFunctionMIParsingState &PFS,
+bool MIRParserImpl::parseMBBReference(PerFunctionMIParsingState &PFS,
MachineBasicBlock *&MBB,
const yaml::StringValue &Source) {
SMDiagnostic Error;
@@ -784,6 +861,14 @@ std::unique_ptr<MIRParser>
llvm::createMIRParser(std::unique_ptr<MemoryBuffer> Contents,
LLVMContext &Context) {
auto Filename = Contents->getBufferIdentifier();
+ if (Context.shouldDiscardValueNames()) {
+ Context.diagnose(DiagnosticInfoMIRParser(
+ DS_Error,
+ SMDiagnostic(
+ Filename, SourceMgr::DK_Error,
+ "Can't read MIR with a Context that discards named Values")));
+ return nullptr;
+ }
return llvm::make_unique<MIRParser>(
llvm::make_unique<MIRParserImpl>(std::move(Contents), Filename, Context));
}
OpenPOWER on IntegriCloud