diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-08-21 18:13:02 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-08-21 18:13:02 +0000 |
commit | 54db30ce18663e6c2991958f3b5d18362e8e93c4 (patch) | |
tree | 4aa6442802570767398cc83ba484e97b1309bdc2 /contrib/llvm/lib/CodeGen/MIRParser | |
parent | 35284c22e9c8348159b7ce032ea45f2cdeb65298 (diff) | |
parent | e6d1592492a3a379186bfb02bd0f4eda0669c0d5 (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.cpp | 8 | ||||
-rw-r--r-- | contrib/llvm/lib/CodeGen/MIRParser/MILexer.h | 8 | ||||
-rw-r--r-- | contrib/llvm/lib/CodeGen/MIRParser/MIParser.cpp | 574 | ||||
-rw-r--r-- | contrib/llvm/lib/CodeGen/MIRParser/MIParser.h | 125 | ||||
-rw-r--r-- | contrib/llvm/lib/CodeGen/MIRParser/MIRParser.cpp | 184 |
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)) {} |