aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/CodeGen/MIRParser
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-08-21 18:13:02 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-08-21 18:13:02 +0000
commit54db30ce18663e6c2991958f3b5d18362e8e93c4 (patch)
tree4aa6442802570767398cc83ba484e97b1309bdc2 /contrib/llvm/lib/CodeGen/MIRParser
parent35284c22e9c8348159b7ce032ea45f2cdeb65298 (diff)
parente6d1592492a3a379186bfb02bd0f4eda0669c0d5 (diff)
Merge llvm trunk r366426, resolve conflicts, and update FREEBSD-Xlist.
Notes
Notes: svn path=/projects/clang900-import/; revision=351344
Diffstat (limited to 'contrib/llvm/lib/CodeGen/MIRParser')
-rw-r--r--contrib/llvm/lib/CodeGen/MIRParser/MILexer.cpp8
-rw-r--r--contrib/llvm/lib/CodeGen/MIRParser/MILexer.h8
-rw-r--r--contrib/llvm/lib/CodeGen/MIRParser/MIParser.cpp574
-rw-r--r--contrib/llvm/lib/CodeGen/MIRParser/MIParser.h125
-rw-r--r--contrib/llvm/lib/CodeGen/MIRParser/MIRParser.cpp184
5 files changed, 418 insertions, 481 deletions
diff --git a/contrib/llvm/lib/CodeGen/MIRParser/MILexer.cpp b/contrib/llvm/lib/CodeGen/MIRParser/MILexer.cpp
index 265877c2f5b4..4899bd3f5811 100644
--- a/contrib/llvm/lib/CodeGen/MIRParser/MILexer.cpp
+++ b/contrib/llvm/lib/CodeGen/MIRParser/MILexer.cpp
@@ -1,9 +1,8 @@
//===- MILexer.cpp - Machine instructions lexer implementation ------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -205,6 +204,7 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
.Case("nuw" , MIToken::kw_nuw)
.Case("nsw" , MIToken::kw_nsw)
.Case("exact" , MIToken::kw_exact)
+ .Case("fpexcept", MIToken::kw_fpexcept)
.Case("debug-location", MIToken::kw_debug_location)
.Case("same_value", MIToken::kw_cfi_same_value)
.Case("offset", MIToken::kw_cfi_offset)
diff --git a/contrib/llvm/lib/CodeGen/MIRParser/MILexer.h b/contrib/llvm/lib/CodeGen/MIRParser/MILexer.h
index ceff79087d81..0fe3f9f706db 100644
--- a/contrib/llvm/lib/CodeGen/MIRParser/MILexer.h
+++ b/contrib/llvm/lib/CodeGen/MIRParser/MILexer.h
@@ -1,9 +1,8 @@
//===- MILexer.h - Lexer for machine instructions ---------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -74,6 +73,7 @@ struct MIToken {
kw_nuw,
kw_nsw,
kw_exact,
+ kw_fpexcept,
kw_debug_location,
kw_cfi_same_value,
kw_cfi_offset,
diff --git a/contrib/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/contrib/llvm/lib/CodeGen/MIRParser/MIParser.cpp
index 6f2d8bb53ac8..c0b800a0b870 100644
--- a/contrib/llvm/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/contrib/llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -1,9 +1,8 @@
//===- MIParser.cpp - Machine instructions parser implementation ----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -11,7 +10,7 @@
//
//===----------------------------------------------------------------------===//
-#include "MIParser.h"
+#include "llvm/CodeGen/MIRParser/MIParser.h"
#include "MILexer.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APSInt.h"
@@ -27,6 +26,8 @@
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/AsmParser/SlotMapping.h"
+#include "llvm/CodeGen/GlobalISel/RegisterBank.h"
+#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
#include "llvm/CodeGen/MIRPrinter.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
@@ -81,12 +82,242 @@
using namespace llvm;
+void PerTargetMIParsingState::setTarget(
+ const TargetSubtargetInfo &NewSubtarget) {
+
+ // If the subtarget changed, over conservatively assume everything is invalid.
+ if (&Subtarget == &NewSubtarget)
+ return;
+
+ Names2InstrOpCodes.clear();
+ Names2Regs.clear();
+ Names2RegMasks.clear();
+ Names2SubRegIndices.clear();
+ Names2TargetIndices.clear();
+ Names2DirectTargetFlags.clear();
+ Names2BitmaskTargetFlags.clear();
+ Names2MMOTargetFlags.clear();
+
+ initNames2RegClasses();
+ initNames2RegBanks();
+}
+
+void PerTargetMIParsingState::initNames2Regs() {
+ if (!Names2Regs.empty())
+ return;
+
+ // The '%noreg' register is the register 0.
+ Names2Regs.insert(std::make_pair("noreg", 0));
+ const auto *TRI = Subtarget.getRegisterInfo();
+ assert(TRI && "Expected target register info");
+
+ for (unsigned I = 0, E = TRI->getNumRegs(); I < E; ++I) {
+ bool WasInserted =
+ Names2Regs.insert(std::make_pair(StringRef(TRI->getName(I)).lower(), I))
+ .second;
+ (void)WasInserted;
+ assert(WasInserted && "Expected registers to be unique case-insensitively");
+ }
+}
+
+bool PerTargetMIParsingState::getRegisterByName(StringRef RegName,
+ unsigned &Reg) {
+ initNames2Regs();
+ auto RegInfo = Names2Regs.find(RegName);
+ if (RegInfo == Names2Regs.end())
+ return true;
+ Reg = RegInfo->getValue();
+ return false;
+}
+
+void PerTargetMIParsingState::initNames2InstrOpCodes() {
+ if (!Names2InstrOpCodes.empty())
+ return;
+ const auto *TII = Subtarget.getInstrInfo();
+ assert(TII && "Expected target instruction info");
+ for (unsigned I = 0, E = TII->getNumOpcodes(); I < E; ++I)
+ Names2InstrOpCodes.insert(std::make_pair(StringRef(TII->getName(I)), I));
+}
+
+bool PerTargetMIParsingState::parseInstrName(StringRef InstrName,
+ unsigned &OpCode) {
+ initNames2InstrOpCodes();
+ auto InstrInfo = Names2InstrOpCodes.find(InstrName);
+ if (InstrInfo == Names2InstrOpCodes.end())
+ return true;
+ OpCode = InstrInfo->getValue();
+ return false;
+}
+
+void PerTargetMIParsingState::initNames2RegMasks() {
+ if (!Names2RegMasks.empty())
+ return;
+ const auto *TRI = Subtarget.getRegisterInfo();
+ assert(TRI && "Expected target register info");
+ ArrayRef<const uint32_t *> RegMasks = TRI->getRegMasks();
+ ArrayRef<const char *> RegMaskNames = TRI->getRegMaskNames();
+ assert(RegMasks.size() == RegMaskNames.size());
+ for (size_t I = 0, E = RegMasks.size(); I < E; ++I)
+ Names2RegMasks.insert(
+ std::make_pair(StringRef(RegMaskNames[I]).lower(), RegMasks[I]));
+}
+
+const uint32_t *PerTargetMIParsingState::getRegMask(StringRef Identifier) {
+ initNames2RegMasks();
+ auto RegMaskInfo = Names2RegMasks.find(Identifier);
+ if (RegMaskInfo == Names2RegMasks.end())
+ return nullptr;
+ return RegMaskInfo->getValue();
+}
+
+void PerTargetMIParsingState::initNames2SubRegIndices() {
+ if (!Names2SubRegIndices.empty())
+ return;
+ const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
+ for (unsigned I = 1, E = TRI->getNumSubRegIndices(); I < E; ++I)
+ Names2SubRegIndices.insert(
+ std::make_pair(TRI->getSubRegIndexName(I), I));
+}
+
+unsigned PerTargetMIParsingState::getSubRegIndex(StringRef Name) {
+ initNames2SubRegIndices();
+ auto SubRegInfo = Names2SubRegIndices.find(Name);
+ if (SubRegInfo == Names2SubRegIndices.end())
+ return 0;
+ return SubRegInfo->getValue();
+}
+
+void PerTargetMIParsingState::initNames2TargetIndices() {
+ if (!Names2TargetIndices.empty())
+ return;
+ const auto *TII = Subtarget.getInstrInfo();
+ assert(TII && "Expected target instruction info");
+ auto Indices = TII->getSerializableTargetIndices();
+ for (const auto &I : Indices)
+ Names2TargetIndices.insert(std::make_pair(StringRef(I.second), I.first));
+}
+
+bool PerTargetMIParsingState::getTargetIndex(StringRef Name, int &Index) {
+ initNames2TargetIndices();
+ auto IndexInfo = Names2TargetIndices.find(Name);
+ if (IndexInfo == Names2TargetIndices.end())
+ return true;
+ Index = IndexInfo->second;
+ return false;
+}
+
+void PerTargetMIParsingState::initNames2DirectTargetFlags() {
+ if (!Names2DirectTargetFlags.empty())
+ return;
+
+ const auto *TII = Subtarget.getInstrInfo();
+ assert(TII && "Expected target instruction info");
+ auto Flags = TII->getSerializableDirectMachineOperandTargetFlags();
+ for (const auto &I : Flags)
+ Names2DirectTargetFlags.insert(
+ std::make_pair(StringRef(I.second), I.first));
+}
+
+bool PerTargetMIParsingState::getDirectTargetFlag(StringRef Name,
+ unsigned &Flag) {
+ initNames2DirectTargetFlags();
+ auto FlagInfo = Names2DirectTargetFlags.find(Name);
+ if (FlagInfo == Names2DirectTargetFlags.end())
+ return true;
+ Flag = FlagInfo->second;
+ return false;
+}
+
+void PerTargetMIParsingState::initNames2BitmaskTargetFlags() {
+ if (!Names2BitmaskTargetFlags.empty())
+ return;
+
+ const auto *TII = Subtarget.getInstrInfo();
+ assert(TII && "Expected target instruction info");
+ auto Flags = TII->getSerializableBitmaskMachineOperandTargetFlags();
+ for (const auto &I : Flags)
+ Names2BitmaskTargetFlags.insert(
+ std::make_pair(StringRef(I.second), I.first));
+}
+
+bool PerTargetMIParsingState::getBitmaskTargetFlag(StringRef Name,
+ unsigned &Flag) {
+ initNames2BitmaskTargetFlags();
+ auto FlagInfo = Names2BitmaskTargetFlags.find(Name);
+ if (FlagInfo == Names2BitmaskTargetFlags.end())
+ return true;
+ Flag = FlagInfo->second;
+ return false;
+}
+
+void PerTargetMIParsingState::initNames2MMOTargetFlags() {
+ if (!Names2MMOTargetFlags.empty())
+ return;
+
+ const auto *TII = Subtarget.getInstrInfo();
+ assert(TII && "Expected target instruction info");
+ auto Flags = TII->getSerializableMachineMemOperandTargetFlags();
+ for (const auto &I : Flags)
+ Names2MMOTargetFlags.insert(std::make_pair(StringRef(I.second), I.first));
+}
+
+bool PerTargetMIParsingState::getMMOTargetFlag(StringRef Name,
+ MachineMemOperand::Flags &Flag) {
+ initNames2MMOTargetFlags();
+ auto FlagInfo = Names2MMOTargetFlags.find(Name);
+ if (FlagInfo == Names2MMOTargetFlags.end())
+ return true;
+ Flag = FlagInfo->second;
+ return false;
+}
+
+void PerTargetMIParsingState::initNames2RegClasses() {
+ if (!Names2RegClasses.empty())
+ return;
+
+ const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
+ for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E; ++I) {
+ const auto *RC = TRI->getRegClass(I);
+ Names2RegClasses.insert(
+ std::make_pair(StringRef(TRI->getRegClassName(RC)).lower(), RC));
+ }
+}
+
+void PerTargetMIParsingState::initNames2RegBanks() {
+ if (!Names2RegBanks.empty())
+ return;
+
+ const RegisterBankInfo *RBI = Subtarget.getRegBankInfo();
+ // If the target does not support GlobalISel, we may not have a
+ // register bank info.
+ if (!RBI)
+ return;
+
+ for (unsigned I = 0, E = RBI->getNumRegBanks(); I < E; ++I) {
+ const auto &RegBank = RBI->getRegBank(I);
+ Names2RegBanks.insert(
+ std::make_pair(StringRef(RegBank.getName()).lower(), &RegBank));
+ }
+}
+
+const TargetRegisterClass *
+PerTargetMIParsingState::getRegClass(StringRef Name) {
+ auto RegClassInfo = Names2RegClasses.find(Name);
+ if (RegClassInfo == Names2RegClasses.end())
+ return nullptr;
+ return RegClassInfo->getValue();
+}
+
+const RegisterBank *PerTargetMIParsingState::getRegBank(StringRef Name) {
+ auto RegBankInfo = Names2RegBanks.find(Name);
+ if (RegBankInfo == Names2RegBanks.end())
+ return nullptr;
+ return RegBankInfo->getValue();
+}
+
PerFunctionMIParsingState::PerFunctionMIParsingState(MachineFunction &MF,
- SourceMgr &SM, const SlotMapping &IRSlots,
- const Name2RegClassMap &Names2RegClasses,
- const Name2RegBankMap &Names2RegBanks)
- : MF(MF), SM(&SM), IRSlots(IRSlots), Names2RegClasses(Names2RegClasses),
- Names2RegBanks(Names2RegBanks) {
+ SourceMgr &SM, const SlotMapping &IRSlots, PerTargetMIParsingState &T)
+ : MF(MF), SM(&SM), IRSlots(IRSlots), Target(T) {
}
VRegInfo &PerFunctionMIParsingState::getVRegInfo(unsigned Num) {
@@ -137,26 +368,10 @@ class MIParser {
StringRef Source, CurrentSource;
MIToken Token;
PerFunctionMIParsingState &PFS;
- /// Maps from instruction names to op codes.
- StringMap<unsigned> Names2InstrOpCodes;
- /// Maps from register names to registers.
- StringMap<unsigned> Names2Regs;
- /// Maps from register mask names to register masks.
- StringMap<const uint32_t *> Names2RegMasks;
- /// Maps from subregister names to subregister indices.
- StringMap<unsigned> Names2SubRegIndices;
/// Maps from slot numbers to function's unnamed basic blocks.
DenseMap<unsigned, const BasicBlock *> Slots2BasicBlocks;
/// Maps from slot numbers to function's unnamed values.
DenseMap<unsigned, const Value *> Slots2Values;
- /// Maps from target index names to target indices.
- StringMap<int> Names2TargetIndices;
- /// Maps from direct target flag names to the direct target flag values.
- StringMap<unsigned> Names2DirectTargetFlags;
- /// Maps from direct target flag names to the bitmask target flag values.
- StringMap<unsigned> Names2BitmaskTargetFlags;
- /// Maps from MMO target flag names to MMO target flag values.
- StringMap<MachineMemOperand::Flags> Names2MMOTargetFlags;
public:
MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
@@ -281,12 +496,6 @@ private:
/// Otherwise return false.
bool consumeIfPresent(MIToken::TokenKind TokenKind);
- void initNames2InstrOpCodes();
-
- /// Try to convert an instruction name to an opcode. Return true if the
- /// instruction name is invalid.
- bool parseInstrName(StringRef InstrName, unsigned &OpCode);
-
bool parseInstruction(unsigned &OpCode, unsigned &Flags);
bool assignRegisterTies(MachineInstr &MI,
@@ -295,62 +504,11 @@ private:
bool verifyImplicitOperands(ArrayRef<ParsedMachineOperand> Operands,
const MCInstrDesc &MCID);
- void initNames2Regs();
-
- /// Try to convert a register name to a register number. Return true if the
- /// register name is invalid.
- bool getRegisterByName(StringRef RegName, unsigned &Reg);
-
- void initNames2RegMasks();
-
- /// Check if the given identifier is a name of a register mask.
- ///
- /// Return null if the identifier isn't a register mask.
- const uint32_t *getRegMask(StringRef Identifier);
-
- void initNames2SubRegIndices();
-
- /// Check if the given identifier is a name of a subregister index.
- ///
- /// Return 0 if the name isn't a subregister index class.
- unsigned getSubRegIndex(StringRef Name);
-
const BasicBlock *getIRBlock(unsigned Slot);
const BasicBlock *getIRBlock(unsigned Slot, const Function &F);
const Value *getIRValue(unsigned Slot);
- void initNames2TargetIndices();
-
- /// Try to convert a name of target index to the corresponding target index.
- ///
- /// Return true if the name isn't a name of a target index.
- bool getTargetIndex(StringRef Name, int &Index);
-
- void initNames2DirectTargetFlags();
-
- /// Try to convert a name of a direct target flag to the corresponding
- /// target flag.
- ///
- /// Return true if the name isn't a name of a direct flag.
- bool getDirectTargetFlag(StringRef Name, unsigned &Flag);
-
- void initNames2BitmaskTargetFlags();
-
- /// Try to convert a name of a bitmask target flag to the corresponding
- /// target flag.
- ///
- /// Return true if the name isn't a name of a bitmask target flag.
- bool getBitmaskTargetFlag(StringRef Name, unsigned &Flag);
-
- void initNames2MMOTargetFlags();
-
- /// Try to convert a name of a MachineMemOperand target flag to the
- /// corresponding target flag.
- ///
- /// Return true if the name isn't a name of a target MMO flag.
- bool getMMOTargetFlag(StringRef Name, MachineMemOperand::Flags &Flag);
-
/// Get or create an MCSymbol for a given name.
MCSymbol *getOrCreateMCSymbol(StringRef Name);
@@ -978,7 +1136,8 @@ bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) {
Token.is(MIToken::kw_reassoc) ||
Token.is(MIToken::kw_nuw) ||
Token.is(MIToken::kw_nsw) ||
- Token.is(MIToken::kw_exact)) {
+ Token.is(MIToken::kw_exact) ||
+ Token.is(MIToken::kw_fpexcept)) {
// Mine frame and fast math flags
if (Token.is(MIToken::kw_frame_setup))
Flags |= MachineInstr::FrameSetup;
@@ -1004,13 +1163,15 @@ bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) {
Flags |= MachineInstr::NoSWrap;
if (Token.is(MIToken::kw_exact))
Flags |= MachineInstr::IsExact;
+ if (Token.is(MIToken::kw_fpexcept))
+ Flags |= MachineInstr::FPExcept;
lex();
}
if (Token.isNot(MIToken::Identifier))
return error("expected a machine instruction");
StringRef InstrName = Token.stringValue();
- if (parseInstrName(InstrName, OpCode))
+ if (PFS.Target.parseInstrName(InstrName, OpCode))
return error(Twine("unknown machine instruction name '") + InstrName + "'");
lex();
return false;
@@ -1019,7 +1180,7 @@ bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) {
bool MIParser::parseNamedRegister(unsigned &Reg) {
assert(Token.is(MIToken::NamedRegister) && "Needs NamedRegister token");
StringRef Name = Token.stringValue();
- if (getRegisterByName(Name, Reg))
+ if (PFS.Target.getRegisterByName(Name, Reg))
return error(Twine("unknown register name '") + Name + "'");
return false;
}
@@ -1070,21 +1231,20 @@ bool MIParser::parseRegisterClassOrBank(VRegInfo &RegInfo) {
StringRef Name = Token.stringValue();
// Was it a register class?
- auto RCNameI = PFS.Names2RegClasses.find(Name);
- if (RCNameI != PFS.Names2RegClasses.end()) {
+ const TargetRegisterClass *RC = PFS.Target.getRegClass(Name);
+ if (RC) {
lex();
- const TargetRegisterClass &RC = *RCNameI->getValue();
switch (RegInfo.Kind) {
case VRegInfo::UNKNOWN:
case VRegInfo::NORMAL:
RegInfo.Kind = VRegInfo::NORMAL;
- if (RegInfo.Explicit && RegInfo.D.RC != &RC) {
+ if (RegInfo.Explicit && RegInfo.D.RC != RC) {
const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
return error(Loc, Twine("conflicting register classes, previously: ") +
Twine(TRI.getRegClassName(RegInfo.D.RC)));
}
- RegInfo.D.RC = &RC;
+ RegInfo.D.RC = RC;
RegInfo.Explicit = true;
return false;
@@ -1098,10 +1258,9 @@ bool MIParser::parseRegisterClassOrBank(VRegInfo &RegInfo) {
// Should be a register bank or a generic register.
const RegisterBank *RegBank = nullptr;
if (Name != "_") {
- auto RBNameI = PFS.Names2RegBanks.find(Name);
- if (RBNameI == PFS.Names2RegBanks.end())
+ RegBank = PFS.Target.getRegBank(Name);
+ if (!RegBank)
return error(Loc, "expected '_', register class, or register bank name");
- RegBank = RBNameI->getValue();
}
lex();
@@ -1173,7 +1332,7 @@ bool MIParser::parseSubRegisterIndex(unsigned &SubReg) {
if (Token.isNot(MIToken::Identifier))
return error("expected a subregister index after '.'");
auto Name = Token.stringValue();
- SubReg = getSubRegIndex(Name);
+ SubReg = PFS.Target.getSubRegIndex(Name);
if (!SubReg)
return error(Twine("use of unknown subregister index '") + Name + "'");
lex();
@@ -1341,6 +1500,19 @@ bool MIParser::parseIRConstant(StringRef::iterator Loc, const Constant *&C) {
return false;
}
+// See LLT implemntation for bit size limits.
+static bool verifyScalarSize(uint64_t Size) {
+ return Size != 0 && isUInt<16>(Size);
+}
+
+static bool verifyVectorElementCount(uint64_t NumElts) {
+ return NumElts != 0 && isUInt<16>(NumElts);
+}
+
+static bool verifyAddrSpace(uint64_t AddrSpace) {
+ return isUInt<24>(AddrSpace);
+}
+
bool MIParser::parseLowLevelType(StringRef::iterator Loc, LLT &Ty) {
if (Token.range().front() == 's' || Token.range().front() == 'p') {
StringRef SizeStr = Token.range().drop_front();
@@ -1349,12 +1521,19 @@ bool MIParser::parseLowLevelType(StringRef::iterator Loc, LLT &Ty) {
}
if (Token.range().front() == 's') {
- Ty = LLT::scalar(APSInt(Token.range().drop_front()).getZExtValue());
+ auto ScalarSize = APSInt(Token.range().drop_front()).getZExtValue();
+ if (!verifyScalarSize(ScalarSize))
+ return error("invalid size for scalar type");
+
+ Ty = LLT::scalar(ScalarSize);
lex();
return false;
} else if (Token.range().front() == 'p') {
const DataLayout &DL = MF.getDataLayout();
- unsigned AS = APSInt(Token.range().drop_front()).getZExtValue();
+ uint64_t AS = APSInt(Token.range().drop_front()).getZExtValue();
+ if (!verifyAddrSpace(AS))
+ return error("invalid address space number");
+
Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS));
lex();
return false;
@@ -1369,6 +1548,9 @@ bool MIParser::parseLowLevelType(StringRef::iterator Loc, LLT &Ty) {
if (Token.isNot(MIToken::IntegerLiteral))
return error(Loc, "expected <M x sN> or <M x pA> for vector type");
uint64_t NumElements = Token.integerValue().getZExtValue();
+ if (!verifyVectorElementCount(NumElements))
+ return error("invalid number of vector elements");
+
lex();
if (Token.isNot(MIToken::Identifier) || Token.stringValue() != "x")
@@ -1381,11 +1563,17 @@ bool MIParser::parseLowLevelType(StringRef::iterator Loc, LLT &Ty) {
if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit))
return error("expected integers after 's'/'p' type character");
- if (Token.range().front() == 's')
- Ty = LLT::scalar(APSInt(Token.range().drop_front()).getZExtValue());
- else if (Token.range().front() == 'p') {
+ if (Token.range().front() == 's') {
+ auto ScalarSize = APSInt(Token.range().drop_front()).getZExtValue();
+ if (!verifyScalarSize(ScalarSize))
+ return error("invalid size for scalar type");
+ Ty = LLT::scalar(ScalarSize);
+ } else if (Token.range().front() == 'p') {
const DataLayout &DL = MF.getDataLayout();
- unsigned AS = APSInt(Token.range().drop_front()).getZExtValue();
+ uint64_t AS = APSInt(Token.range().drop_front()).getZExtValue();
+ if (!verifyAddrSpace(AS))
+ return error("invalid address space number");
+
Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS));
} else
return error(Loc, "expected <M x sN> or <M x pA> for vector type");
@@ -1625,7 +1813,7 @@ bool MIParser::parseMCSymbolOperand(MachineOperand &Dest) {
bool MIParser::parseSubRegisterIndexOperand(MachineOperand &Dest) {
assert(Token.is(MIToken::SubRegisterIndex));
StringRef Name = Token.stringValue();
- unsigned SubRegIndex = getSubRegIndex(Token.stringValue());
+ unsigned SubRegIndex = PFS.Target.getSubRegIndex(Token.stringValue());
if (SubRegIndex == 0)
return error(Twine("unknown subregister index '") + Name + "'");
lex();
@@ -1669,6 +1857,11 @@ bool MIParser::parseDIExpression(MDNode *&Expr) {
Elements.push_back(Op);
continue;
}
+ if (unsigned Enc = dwarf::getAttributeEncoding(Token.stringValue())) {
+ lex();
+ Elements.push_back(Enc);
+ continue;
+ }
return error(Twine("invalid DWARF op '") + Token.stringValue() + "'");
}
@@ -2100,7 +2293,7 @@ bool MIParser::parseTargetIndexOperand(MachineOperand &Dest) {
if (Token.isNot(MIToken::Identifier))
return error("expected the name of the target index");
int Index = 0;
- if (getTargetIndex(Token.stringValue(), Index))
+ if (PFS.Target.getTargetIndex(Token.stringValue(), Index))
return error("use of undefined target index '" + Token.stringValue() + "'");
lex();
if (expectAndConsume(MIToken::rparen))
@@ -2242,7 +2435,7 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest,
case MIToken::Error:
return true;
case MIToken::Identifier:
- if (const auto *RegMask = getRegMask(Token.stringValue())) {
+ if (const auto *RegMask = PFS.Target.getRegMask(Token.stringValue())) {
Dest = MachineOperand::CreateRegMask(RegMask);
lex();
break;
@@ -2268,8 +2461,8 @@ bool MIParser::parseMachineOperandAndTargetFlags(
return true;
if (Token.isNot(MIToken::Identifier))
return error("expected the name of the target flag");
- if (getDirectTargetFlag(Token.stringValue(), TF)) {
- if (getBitmaskTargetFlag(Token.stringValue(), TF))
+ if (PFS.Target.getDirectTargetFlag(Token.stringValue(), TF)) {
+ if (PFS.Target.getBitmaskTargetFlag(Token.stringValue(), TF))
return error("use of undefined target flag '" + Token.stringValue() +
"'");
}
@@ -2279,7 +2472,7 @@ bool MIParser::parseMachineOperandAndTargetFlags(
if (Token.isNot(MIToken::Identifier))
return error("expected the name of the target flag");
unsigned BitFlag = 0;
- if (getBitmaskTargetFlag(Token.stringValue(), BitFlag))
+ if (PFS.Target.getBitmaskTargetFlag(Token.stringValue(), BitFlag))
return error("use of undefined target flag '" + Token.stringValue() +
"'");
// TODO: Report an error when using a duplicate bit target flag.
@@ -2325,6 +2518,10 @@ bool MIParser::parseAlignment(unsigned &Alignment) {
if (getUnsigned(Alignment))
return true;
lex();
+
+ if (!isPowerOf2_32(Alignment))
+ return error("expected a power-of-2 literal after 'align'");
+
return false;
}
@@ -2436,7 +2633,7 @@ bool MIParser::parseMemoryOperandFlag(MachineMemOperand::Flags &Flags) {
break;
case MIToken::StringConstant: {
MachineMemOperand::Flags TF;
- if (getMMOTargetFlag(Token.stringValue(), TF))
+ if (PFS.Target.getMMOTargetFlag(Token.stringValue(), TF))
return error("use of undefined target MMO flag '" + Token.stringValue() +
"'");
Flags |= TF;
@@ -2711,87 +2908,6 @@ bool MIParser::parsePreOrPostInstrSymbol(MCSymbol *&Symbol) {
return false;
}
-void MIParser::initNames2InstrOpCodes() {
- if (!Names2InstrOpCodes.empty())
- return;
- const auto *TII = MF.getSubtarget().getInstrInfo();
- assert(TII && "Expected target instruction info");
- for (unsigned I = 0, E = TII->getNumOpcodes(); I < E; ++I)
- Names2InstrOpCodes.insert(std::make_pair(StringRef(TII->getName(I)), I));
-}
-
-bool MIParser::parseInstrName(StringRef InstrName, unsigned &OpCode) {
- initNames2InstrOpCodes();
- auto InstrInfo = Names2InstrOpCodes.find(InstrName);
- if (InstrInfo == Names2InstrOpCodes.end())
- return true;
- OpCode = InstrInfo->getValue();
- return false;
-}
-
-void MIParser::initNames2Regs() {
- if (!Names2Regs.empty())
- return;
- // The '%noreg' register is the register 0.
- Names2Regs.insert(std::make_pair("noreg", 0));
- const auto *TRI = MF.getSubtarget().getRegisterInfo();
- assert(TRI && "Expected target register info");
- for (unsigned I = 0, E = TRI->getNumRegs(); I < E; ++I) {
- bool WasInserted =
- Names2Regs.insert(std::make_pair(StringRef(TRI->getName(I)).lower(), I))
- .second;
- (void)WasInserted;
- assert(WasInserted && "Expected registers to be unique case-insensitively");
- }
-}
-
-bool MIParser::getRegisterByName(StringRef RegName, unsigned &Reg) {
- initNames2Regs();
- auto RegInfo = Names2Regs.find(RegName);
- if (RegInfo == Names2Regs.end())
- return true;
- Reg = RegInfo->getValue();
- return false;
-}
-
-void MIParser::initNames2RegMasks() {
- if (!Names2RegMasks.empty())
- return;
- const auto *TRI = MF.getSubtarget().getRegisterInfo();
- assert(TRI && "Expected target register info");
- ArrayRef<const uint32_t *> RegMasks = TRI->getRegMasks();
- ArrayRef<const char *> RegMaskNames = TRI->getRegMaskNames();
- assert(RegMasks.size() == RegMaskNames.size());
- for (size_t I = 0, E = RegMasks.size(); I < E; ++I)
- Names2RegMasks.insert(
- std::make_pair(StringRef(RegMaskNames[I]).lower(), RegMasks[I]));
-}
-
-const uint32_t *MIParser::getRegMask(StringRef Identifier) {
- initNames2RegMasks();
- auto RegMaskInfo = Names2RegMasks.find(Identifier);
- if (RegMaskInfo == Names2RegMasks.end())
- return nullptr;
- return RegMaskInfo->getValue();
-}
-
-void MIParser::initNames2SubRegIndices() {
- if (!Names2SubRegIndices.empty())
- return;
- const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
- for (unsigned I = 1, E = TRI->getNumSubRegIndices(); I < E; ++I)
- Names2SubRegIndices.insert(
- std::make_pair(StringRef(TRI->getSubRegIndexName(I)).lower(), I));
-}
-
-unsigned MIParser::getSubRegIndex(StringRef Name) {
- initNames2SubRegIndices();
- auto SubRegInfo = Names2SubRegIndices.find(Name);
- if (SubRegInfo == Names2SubRegIndices.end())
- return 0;
- return SubRegInfo->getValue();
-}
-
static void initSlots2BasicBlocks(
const Function &F,
DenseMap<unsigned, const BasicBlock *> &Slots2BasicBlocks) {
@@ -2861,86 +2977,6 @@ const Value *MIParser::getIRValue(unsigned Slot) {
return ValueInfo->second;
}
-void MIParser::initNames2TargetIndices() {
- if (!Names2TargetIndices.empty())
- return;
- const auto *TII = MF.getSubtarget().getInstrInfo();
- assert(TII && "Expected target instruction info");
- auto Indices = TII->getSerializableTargetIndices();
- for (const auto &I : Indices)
- Names2TargetIndices.insert(std::make_pair(StringRef(I.second), I.first));
-}
-
-bool MIParser::getTargetIndex(StringRef Name, int &Index) {
- initNames2TargetIndices();
- auto IndexInfo = Names2TargetIndices.find(Name);
- if (IndexInfo == Names2TargetIndices.end())
- return true;
- Index = IndexInfo->second;
- return false;
-}
-
-void MIParser::initNames2DirectTargetFlags() {
- if (!Names2DirectTargetFlags.empty())
- return;
- const auto *TII = MF.getSubtarget().getInstrInfo();
- assert(TII && "Expected target instruction info");
- auto Flags = TII->getSerializableDirectMachineOperandTargetFlags();
- for (const auto &I : Flags)
- Names2DirectTargetFlags.insert(
- std::make_pair(StringRef(I.second), I.first));
-}
-
-bool MIParser::getDirectTargetFlag(StringRef Name, unsigned &Flag) {
- initNames2DirectTargetFlags();
- auto FlagInfo = Names2DirectTargetFlags.find(Name);
- if (FlagInfo == Names2DirectTargetFlags.end())
- return true;
- Flag = FlagInfo->second;
- return false;
-}
-
-void MIParser::initNames2BitmaskTargetFlags() {
- if (!Names2BitmaskTargetFlags.empty())
- return;
- const auto *TII = MF.getSubtarget().getInstrInfo();
- assert(TII && "Expected target instruction info");
- auto Flags = TII->getSerializableBitmaskMachineOperandTargetFlags();
- for (const auto &I : Flags)
- Names2BitmaskTargetFlags.insert(
- std::make_pair(StringRef(I.second), I.first));
-}
-
-bool MIParser::getBitmaskTargetFlag(StringRef Name, unsigned &Flag) {
- initNames2BitmaskTargetFlags();
- auto FlagInfo = Names2BitmaskTargetFlags.find(Name);
- if (FlagInfo == Names2BitmaskTargetFlags.end())
- return true;
- Flag = FlagInfo->second;
- return false;
-}
-
-void MIParser::initNames2MMOTargetFlags() {
- if (!Names2MMOTargetFlags.empty())
- return;
- const auto *TII = MF.getSubtarget().getInstrInfo();
- assert(TII && "Expected target instruction info");
- auto Flags = TII->getSerializableMachineMemOperandTargetFlags();
- for (const auto &I : Flags)
- Names2MMOTargetFlags.insert(
- std::make_pair(StringRef(I.second), I.first));
-}
-
-bool MIParser::getMMOTargetFlag(StringRef Name,
- MachineMemOperand::Flags &Flag) {
- initNames2MMOTargetFlags();
- auto FlagInfo = Names2MMOTargetFlags.find(Name);
- if (FlagInfo == Names2MMOTargetFlags.end())
- return true;
- Flag = FlagInfo->second;
- return false;
-}
-
MCSymbol *MIParser::getOrCreateMCSymbol(StringRef Name) {
// FIXME: Currently we can't recognize temporary or local symbols and call all
// of the appropriate forms to create them. However, this handles basic cases
diff --git a/contrib/llvm/lib/CodeGen/MIRParser/MIParser.h b/contrib/llvm/lib/CodeGen/MIRParser/MIParser.h
deleted file mode 100644
index b06ceb21b740..000000000000
--- a/contrib/llvm/lib/CodeGen/MIRParser/MIParser.h
+++ /dev/null
@@ -1,125 +0,0 @@
-//===- MIParser.h - Machine Instructions Parser -----------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the function that parses the machine instructions.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIB_CODEGEN_MIRPARSER_MIPARSER_H
-#define LLVM_LIB_CODEGEN_MIRPARSER_MIPARSER_H
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/Support/Allocator.h"
-
-namespace llvm {
-
-class MachineBasicBlock;
-class MachineFunction;
-class MDNode;
-class RegisterBank;
-struct SlotMapping;
-class SMDiagnostic;
-class SourceMgr;
-class StringRef;
-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;
-};
-
-using Name2RegClassMap = StringMap<const TargetRegisterClass *>;
-using Name2RegBankMap = StringMap<const RegisterBank *>;
-
-struct PerFunctionMIParsingState {
- BumpPtrAllocator Allocator;
- MachineFunction &MF;
- SourceMgr *SM;
- const SlotMapping &IRSlots;
- const Name2RegClassMap &Names2RegClasses;
- const Name2RegBankMap &Names2RegBanks;
-
- DenseMap<unsigned, MachineBasicBlock *> MBBSlots;
- DenseMap<unsigned, VRegInfo*> VRegInfos;
- StringMap<VRegInfo*> VRegInfosNamed;
- DenseMap<unsigned, int> FixedStackObjectSlots;
- DenseMap<unsigned, int> StackObjectSlots;
- DenseMap<unsigned, unsigned> ConstantPoolSlots;
- DenseMap<unsigned, unsigned> JumpTableSlots;
-
- PerFunctionMIParsingState(MachineFunction &MF, SourceMgr &SM,
- const SlotMapping &IRSlots,
- const Name2RegClassMap &Names2RegClasses,
- const Name2RegBankMap &Names2RegBanks);
-
- VRegInfo &getVRegInfo(unsigned Num);
- VRegInfo &getVRegInfoNamed(StringRef RegName);
-};
-
-/// Parse the machine basic block definitions, and skip the machine
-/// instructions.
-///
-/// This function runs the first parsing pass on the machine function's body.
-/// It parses only the machine basic block definitions and creates the machine
-/// basic blocks in the given machine function.
-///
-/// The machine instructions aren't parsed during the first pass because all
-/// the machine basic blocks aren't defined yet - this makes it impossible to
-/// resolve the machine basic block references.
-///
-/// Return true if an error occurred.
-bool parseMachineBasicBlockDefinitions(PerFunctionMIParsingState &PFS,
- StringRef Src, SMDiagnostic &Error);
-
-/// Parse the machine instructions.
-///
-/// This function runs the second parsing pass on the machine function's body.
-/// It skips the machine basic block definitions and parses only the machine
-/// instructions and basic block attributes like liveins and successors.
-///
-/// The second parsing pass assumes that the first parsing pass already ran
-/// on the given source string.
-///
-/// Return true if an error occurred.
-bool parseMachineInstructions(PerFunctionMIParsingState &PFS, StringRef Src,
- SMDiagnostic &Error);
-
-bool parseMBBReference(PerFunctionMIParsingState &PFS,
- MachineBasicBlock *&MBB, 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(PerFunctionMIParsingState &PFS,
- VRegInfo *&Info, StringRef Src,
- SMDiagnostic &Error);
-
-bool parseStackObjectReference(PerFunctionMIParsingState &PFS, int &FI,
- StringRef Src, SMDiagnostic &Error);
-
-bool parseMDNode(PerFunctionMIParsingState &PFS, MDNode *&Node, StringRef Src,
- SMDiagnostic &Error);
-
-} // end namespace llvm
-
-#endif // LLVM_LIB_CODEGEN_MIRPARSER_MIPARSER_H
diff --git a/contrib/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/contrib/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
index 00da92a92ec6..b242934def80 100644
--- a/contrib/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/contrib/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -1,9 +1,8 @@
//===- MIRParser.cpp - MIR serialization format parser implementation -----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -13,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/MIRParser/MIRParser.h"
-#include "MIParser.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
@@ -22,12 +20,14 @@
#include "llvm/AsmParser/SlotMapping.h"
#include "llvm/CodeGen/GlobalISel/RegisterBank.h"
#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
+#include "llvm/CodeGen/MIRParser/MIParser.h"
#include "llvm/CodeGen/MIRYamlMapping.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DiagnosticInfo.h"
@@ -40,6 +40,7 @@
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/YAMLTraits.h"
+#include "llvm/Target/TargetMachine.h"
#include <memory>
using namespace llvm;
@@ -54,10 +55,8 @@ class MIRParserImpl {
StringRef Filename;
LLVMContext &Context;
SlotMapping IRSlots;
- /// Maps from register class names to register classes.
- Name2RegClassMap Names2RegClasses;
- /// Maps from register bank names to register banks.
- Name2RegBankMap Names2RegBanks;
+ std::unique_ptr<PerTargetMIParsingState> Target;
+
/// True when the MIR file doesn't have LLVM IR. Dummy IR functions are
/// created and inserted into the given module when this is true.
bool NoLLVMIR = false;
@@ -117,6 +116,9 @@ public:
bool initializeFrameInfo(PerFunctionMIParsingState &PFS,
const yaml::MachineFunction &YamlMF);
+ bool initializeCallSiteInfo(PerFunctionMIParsingState &PFS,
+ const yaml::MachineFunction &YamlMF);
+
bool parseCalleeSavedRegister(PerFunctionMIParsingState &PFS,
std::vector<CalleeSavedInfo> &CSIInfo,
const yaml::StringValue &RegisterSource,
@@ -151,20 +153,6 @@ private:
SMDiagnostic diagFromBlockStringDiag(const SMDiagnostic &Error,
SMRange SourceRange);
- void initNames2RegClasses(const MachineFunction &MF);
- void initNames2RegBanks(const MachineFunction &MF);
-
- /// Check if the given identifier is a name of a register class.
- ///
- /// Return null if the name isn't a register class.
- const TargetRegisterClass *getRegClass(const MachineFunction &MF,
- StringRef Name);
-
- /// Check if the given identifier is a name of a register bank.
- ///
- /// Return null if the name isn't a register bank.
- const RegisterBank *getRegBank(const MachineFunction &MF, StringRef Name);
-
void computeFunctionProperties(MachineFunction &MF);
};
@@ -271,8 +259,9 @@ bool MIRParserImpl::parseMachineFunctions(Module &M, MachineModuleInfo &MMI) {
/// Create an empty function with the given name.
static Function *createDummyFunction(StringRef Name, Module &M) {
auto &Context = M.getContext();
- Function *F = cast<Function>(M.getOrInsertFunction(
- Name, FunctionType::get(Type::getVoidTy(Context), false)));
+ Function *F =
+ Function::Create(FunctionType::get(Type::getVoidTy(Context), false),
+ Function::ExternalLinkage, Name, M);
BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
new UnreachableInst(Context, BB);
return F;
@@ -282,6 +271,11 @@ bool MIRParserImpl::parseMachineFunction(Module &M, MachineModuleInfo &MMI) {
// Parse the yaml.
yaml::MachineFunction YamlMF;
yaml::EmptyContext Ctx;
+
+ const LLVMTargetMachine &TM = MMI.getTarget();
+ YamlMF.MachineFuncInfo = std::unique_ptr<yaml::MachineFunctionInfo>(
+ TM.createDefaultFuncInfoYAML());
+
yaml::yamlize(In, YamlMF, false, Ctx);
if (In.error())
return true;
@@ -346,12 +340,58 @@ void MIRParserImpl::computeFunctionProperties(MachineFunction &MF) {
Properties.set(MachineFunctionProperties::Property::NoVRegs);
}
+bool MIRParserImpl::initializeCallSiteInfo(
+ PerFunctionMIParsingState &PFS, const yaml::MachineFunction &YamlMF) {
+ MachineFunction &MF = PFS.MF;
+ SMDiagnostic Error;
+ const LLVMTargetMachine &TM = MF.getTarget();
+ for (auto YamlCSInfo : YamlMF.CallSitesInfo) {
+ yaml::CallSiteInfo::MachineInstrLoc MILoc = YamlCSInfo.CallLocation;
+ if (MILoc.BlockNum >= MF.size())
+ return error(Twine(MF.getName()) +
+ Twine(" call instruction block out of range.") +
+ " Unable to reference bb:" + Twine(MILoc.BlockNum));
+ auto CallB = std::next(MF.begin(), MILoc.BlockNum);
+ if (MILoc.Offset >= CallB->size())
+ return error(Twine(MF.getName()) +
+ Twine(" call instruction offset out of range.") +
+ "Unable to reference instruction at bb: " +
+ Twine(MILoc.BlockNum) + " at offset:" + Twine(MILoc.Offset));
+ auto CallI = std::next(CallB->begin(), MILoc.Offset);
+ if (!CallI->isCall())
+ return error(Twine(MF.getName()) +
+ Twine(" call site info should reference call "
+ "instruction. Instruction at bb:") +
+ Twine(MILoc.BlockNum) + " at offset:" + Twine(MILoc.Offset) +
+ " is not a call instruction");
+ MachineFunction::CallSiteInfo CSInfo;
+ for (auto ArgRegPair : YamlCSInfo.ArgForwardingRegs) {
+ unsigned Reg = 0;
+ if (parseNamedRegisterReference(PFS, Reg, ArgRegPair.Reg.Value, Error))
+ return error(Error, ArgRegPair.Reg.SourceRange);
+ CSInfo.emplace_back(Reg, ArgRegPair.ArgNo);
+ }
+
+ if (TM.Options.EnableDebugEntryValues)
+ MF.addCallArgsForwardingRegs(&*CallI, std::move(CSInfo));
+ }
+
+ if (YamlMF.CallSitesInfo.size() && !TM.Options.EnableDebugEntryValues)
+ return error(Twine("Call site info provided but not used"));
+ return false;
+}
+
bool
MIRParserImpl::initializeMachineFunction(const yaml::MachineFunction &YamlMF,
MachineFunction &MF) {
// TODO: Recreate the machine function.
- initNames2RegClasses(MF);
- initNames2RegBanks(MF);
+ if (Target) {
+ // Avoid clearing state if we're using the same subtarget again.
+ Target->setTarget(MF.getSubtarget());
+ } else {
+ Target.reset(new PerTargetMIParsingState(MF.getSubtarget()));
+ }
+
if (YamlMF.Alignment)
MF.setAlignment(YamlMF.Alignment);
MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);
@@ -367,8 +407,7 @@ MIRParserImpl::initializeMachineFunction(const yaml::MachineFunction &YamlMF,
if (YamlMF.FailedISel)
MF.getProperties().set(MachineFunctionProperties::Property::FailedISel);
- PerFunctionMIParsingState PFS(MF, SM, IRSlots, Names2RegClasses,
- Names2RegBanks);
+ PerFunctionMIParsingState PFS(MF, SM, IRSlots, *Target);
if (parseRegisterInfo(PFS, YamlMF))
return true;
if (!YamlMF.Constants.empty()) {
@@ -419,8 +458,32 @@ MIRParserImpl::initializeMachineFunction(const yaml::MachineFunction &YamlMF,
if (setupRegisterInfo(PFS, YamlMF))
return true;
+ if (YamlMF.MachineFuncInfo) {
+ const LLVMTargetMachine &TM = MF.getTarget();
+ // Note this is called after the initial constructor of the
+ // MachineFunctionInfo based on the MachineFunction, which may depend on the
+ // IR.
+
+ SMRange SrcRange;
+ if (TM.parseMachineFunctionInfo(*YamlMF.MachineFuncInfo, PFS, Error,
+ SrcRange)) {
+ return error(Error, SrcRange);
+ }
+ }
+
+ // Set the reserved registers after parsing MachineFuncInfo. The target may
+ // have been recording information used to select the reserved registers
+ // there.
+ // FIXME: This is a temporary workaround until the reserved registers can be
+ // serialized.
+ MachineRegisterInfo &MRI = MF.getRegInfo();
+ MRI.freezeReservedRegs(MF);
+
computeFunctionProperties(MF);
+ if (initializeCallSiteInfo(PFS, YamlMF))
+ return false;
+
MF.getSubtarget().mirFileLoaded(MF);
MF.verify();
@@ -449,12 +512,12 @@ bool MIRParserImpl::parseRegisterInfo(PerFunctionMIParsingState &PFS,
Info.Kind = VRegInfo::GENERIC;
Info.D.RegBank = nullptr;
} else {
- const auto *RC = getRegClass(MF, VReg.Class.Value);
+ const auto *RC = Target->getRegClass(VReg.Class.Value);
if (RC) {
Info.Kind = VRegInfo::NORMAL;
Info.D.RC = RC;
} else {
- const RegisterBank *RegBank = getRegBank(MF, VReg.Class.Value);
+ const RegisterBank *RegBank = Target->getRegBank(VReg.Class.Value);
if (!RegBank)
return error(
VReg.Class.SourceRange.Start,
@@ -557,9 +620,6 @@ bool MIRParserImpl::setupRegisterInfo(const PerFunctionMIParsingState &PFS,
}
}
- // FIXME: This is a temporary workaround until the reserved registers can be
- // serialized.
- MRI.freezeReservedRegs(MF);
return Error;
}
@@ -567,6 +627,7 @@ bool MIRParserImpl::initializeFrameInfo(PerFunctionMIParsingState &PFS,
const yaml::MachineFunction &YamlMF) {
MachineFunction &MF = PFS.MF;
MachineFrameInfo &MFI = MF.getFrameInfo();
+ const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
const Function &F = MF.getFunction();
const yaml::MachineFrameInfo &YamlMFI = YamlMF.FrameInfo;
MFI.setFrameAddressIsTaken(YamlMFI.IsFrameAddressTaken);
@@ -608,8 +669,12 @@ bool MIRParserImpl::initializeFrameInfo(PerFunctionMIParsingState &PFS,
Object.IsImmutable, Object.IsAliased);
else
ObjectIdx = MFI.CreateFixedSpillStackObject(Object.Size, Object.Offset);
- MFI.setObjectAlignment(ObjectIdx, Object.Alignment);
+
+ if (!TFI->isSupportedStackID(Object.StackID))
+ return error(Object.ID.SourceRange.Start,
+ Twine("StackID is not supported by target"));
MFI.setStackID(ObjectIdx, Object.StackID);
+ MFI.setObjectAlignment(ObjectIdx, Object.Alignment);
if (!PFS.FixedStackObjectSlots.insert(std::make_pair(Object.ID.Value,
ObjectIdx))
.second)
@@ -637,14 +702,17 @@ bool MIRParserImpl::initializeFrameInfo(PerFunctionMIParsingState &PFS,
"' isn't defined in the function '" + F.getName() +
"'");
}
+ if (!TFI->isSupportedStackID(Object.StackID))
+ return error(Object.ID.SourceRange.Start,
+ Twine("StackID is not supported by target"));
if (Object.Type == yaml::MachineStackObject::VariableSized)
ObjectIdx = MFI.CreateVariableSizedObject(Object.Alignment, Alloca);
else
ObjectIdx = MFI.CreateStackObject(
Object.Size, Object.Alignment,
- Object.Type == yaml::MachineStackObject::SpillSlot, Alloca);
+ Object.Type == yaml::MachineStackObject::SpillSlot, Alloca,
+ Object.StackID);
MFI.setObjectOffset(ObjectIdx, Object.Offset);
- MFI.setStackID(ObjectIdx, Object.StackID);
if (!PFS.StackObjectSlots.insert(std::make_pair(Object.ID.Value, ObjectIdx))
.second)
@@ -844,48 +912,6 @@ SMDiagnostic MIRParserImpl::diagFromBlockStringDiag(const SMDiagnostic &Error,
Error.getFixIts());
}
-void MIRParserImpl::initNames2RegClasses(const MachineFunction &MF) {
- if (!Names2RegClasses.empty())
- return;
- const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
- for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E; ++I) {
- const auto *RC = TRI->getRegClass(I);
- Names2RegClasses.insert(
- std::make_pair(StringRef(TRI->getRegClassName(RC)).lower(), RC));
- }
-}
-
-void MIRParserImpl::initNames2RegBanks(const MachineFunction &MF) {
- if (!Names2RegBanks.empty())
- return;
- const RegisterBankInfo *RBI = MF.getSubtarget().getRegBankInfo();
- // If the target does not support GlobalISel, we may not have a
- // register bank info.
- if (!RBI)
- return;
- for (unsigned I = 0, E = RBI->getNumRegBanks(); I < E; ++I) {
- const auto &RegBank = RBI->getRegBank(I);
- Names2RegBanks.insert(
- std::make_pair(StringRef(RegBank.getName()).lower(), &RegBank));
- }
-}
-
-const TargetRegisterClass *MIRParserImpl::getRegClass(const MachineFunction &MF,
- StringRef Name) {
- auto RegClassInfo = Names2RegClasses.find(Name);
- if (RegClassInfo == Names2RegClasses.end())
- return nullptr;
- return RegClassInfo->getValue();
-}
-
-const RegisterBank *MIRParserImpl::getRegBank(const MachineFunction &MF,
- StringRef Name) {
- auto RegBankInfo = Names2RegBanks.find(Name);
- if (RegBankInfo == Names2RegBanks.end())
- return nullptr;
- return RegBankInfo->getValue();
-}
-
MIRParser::MIRParser(std::unique_ptr<MIRParserImpl> Impl)
: Impl(std::move(Impl)) {}