10b57cec5SDimitry Andric //===- MIParser.cpp - Machine instructions parser implementation ----------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the parsing of machine instructions.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric #include "llvm/CodeGen/MIRParser/MIParser.h"
140b57cec5SDimitry Andric #include "MILexer.h"
150b57cec5SDimitry Andric #include "llvm/ADT/APInt.h"
160b57cec5SDimitry Andric #include "llvm/ADT/APSInt.h"
170b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
180b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
190b57cec5SDimitry Andric #include "llvm/ADT/None.h"
200b57cec5SDimitry Andric #include "llvm/ADT/Optional.h"
210b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
220b57cec5SDimitry Andric #include "llvm/ADT/StringMap.h"
230b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
240b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h"
250b57cec5SDimitry Andric #include "llvm/ADT/Twine.h"
260b57cec5SDimitry Andric #include "llvm/Analysis/MemoryLocation.h"
270b57cec5SDimitry Andric #include "llvm/AsmParser/Parser.h"
280b57cec5SDimitry Andric #include "llvm/AsmParser/SlotMapping.h"
290b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/RegisterBank.h"
300b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
31480093f4SDimitry Andric #include "llvm/CodeGen/MIRFormatter.h"
320b57cec5SDimitry Andric #include "llvm/CodeGen/MIRPrinter.h"
330b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
340b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
350b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
360b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
370b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
380b57cec5SDimitry Andric #include "llvm/CodeGen/MachineMemOperand.h"
390b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
400b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
410b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
420b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
430b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
440b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h"
450b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
460b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h"
470b57cec5SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
480b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h"
490b57cec5SDimitry Andric #include "llvm/IR/Function.h"
500b57cec5SDimitry Andric #include "llvm/IR/InstrTypes.h"
510b57cec5SDimitry Andric #include "llvm/IR/Instructions.h"
520b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h"
530b57cec5SDimitry Andric #include "llvm/IR/Metadata.h"
540b57cec5SDimitry Andric #include "llvm/IR/Module.h"
550b57cec5SDimitry Andric #include "llvm/IR/ModuleSlotTracker.h"
560b57cec5SDimitry Andric #include "llvm/IR/Type.h"
570b57cec5SDimitry Andric #include "llvm/IR/Value.h"
580b57cec5SDimitry Andric #include "llvm/IR/ValueSymbolTable.h"
590b57cec5SDimitry Andric #include "llvm/MC/LaneBitmask.h"
600b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
610b57cec5SDimitry Andric #include "llvm/MC/MCDwarf.h"
620b57cec5SDimitry Andric #include "llvm/MC/MCInstrDesc.h"
630b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
640b57cec5SDimitry Andric #include "llvm/Support/AtomicOrdering.h"
650b57cec5SDimitry Andric #include "llvm/Support/BranchProbability.h"
660b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
670b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
680b57cec5SDimitry Andric #include "llvm/Support/LowLevelTypeImpl.h"
690b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
700b57cec5SDimitry Andric #include "llvm/Support/SMLoc.h"
710b57cec5SDimitry Andric #include "llvm/Support/SourceMgr.h"
720b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
730b57cec5SDimitry Andric #include "llvm/Target/TargetIntrinsicInfo.h"
740b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h"
750b57cec5SDimitry Andric #include <algorithm>
760b57cec5SDimitry Andric #include <cassert>
770b57cec5SDimitry Andric #include <cctype>
780b57cec5SDimitry Andric #include <cstddef>
790b57cec5SDimitry Andric #include <cstdint>
800b57cec5SDimitry Andric #include <limits>
810b57cec5SDimitry Andric #include <string>
820b57cec5SDimitry Andric #include <utility>
830b57cec5SDimitry Andric
840b57cec5SDimitry Andric using namespace llvm;
850b57cec5SDimitry Andric
setTarget(const TargetSubtargetInfo & NewSubtarget)860b57cec5SDimitry Andric void PerTargetMIParsingState::setTarget(
870b57cec5SDimitry Andric const TargetSubtargetInfo &NewSubtarget) {
880b57cec5SDimitry Andric
890b57cec5SDimitry Andric // If the subtarget changed, over conservatively assume everything is invalid.
900b57cec5SDimitry Andric if (&Subtarget == &NewSubtarget)
910b57cec5SDimitry Andric return;
920b57cec5SDimitry Andric
930b57cec5SDimitry Andric Names2InstrOpCodes.clear();
940b57cec5SDimitry Andric Names2Regs.clear();
950b57cec5SDimitry Andric Names2RegMasks.clear();
960b57cec5SDimitry Andric Names2SubRegIndices.clear();
970b57cec5SDimitry Andric Names2TargetIndices.clear();
980b57cec5SDimitry Andric Names2DirectTargetFlags.clear();
990b57cec5SDimitry Andric Names2BitmaskTargetFlags.clear();
1000b57cec5SDimitry Andric Names2MMOTargetFlags.clear();
1010b57cec5SDimitry Andric
1020b57cec5SDimitry Andric initNames2RegClasses();
1030b57cec5SDimitry Andric initNames2RegBanks();
1040b57cec5SDimitry Andric }
1050b57cec5SDimitry Andric
initNames2Regs()1060b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2Regs() {
1070b57cec5SDimitry Andric if (!Names2Regs.empty())
1080b57cec5SDimitry Andric return;
1090b57cec5SDimitry Andric
1100b57cec5SDimitry Andric // The '%noreg' register is the register 0.
1110b57cec5SDimitry Andric Names2Regs.insert(std::make_pair("noreg", 0));
1120b57cec5SDimitry Andric const auto *TRI = Subtarget.getRegisterInfo();
1130b57cec5SDimitry Andric assert(TRI && "Expected target register info");
1140b57cec5SDimitry Andric
1150b57cec5SDimitry Andric for (unsigned I = 0, E = TRI->getNumRegs(); I < E; ++I) {
1160b57cec5SDimitry Andric bool WasInserted =
1170b57cec5SDimitry Andric Names2Regs.insert(std::make_pair(StringRef(TRI->getName(I)).lower(), I))
1180b57cec5SDimitry Andric .second;
1190b57cec5SDimitry Andric (void)WasInserted;
1200b57cec5SDimitry Andric assert(WasInserted && "Expected registers to be unique case-insensitively");
1210b57cec5SDimitry Andric }
1220b57cec5SDimitry Andric }
1230b57cec5SDimitry Andric
getRegisterByName(StringRef RegName,Register & Reg)1240b57cec5SDimitry Andric bool PerTargetMIParsingState::getRegisterByName(StringRef RegName,
1255ffd83dbSDimitry Andric Register &Reg) {
1260b57cec5SDimitry Andric initNames2Regs();
1270b57cec5SDimitry Andric auto RegInfo = Names2Regs.find(RegName);
1280b57cec5SDimitry Andric if (RegInfo == Names2Regs.end())
1290b57cec5SDimitry Andric return true;
1300b57cec5SDimitry Andric Reg = RegInfo->getValue();
1310b57cec5SDimitry Andric return false;
1320b57cec5SDimitry Andric }
1330b57cec5SDimitry Andric
initNames2InstrOpCodes()1340b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2InstrOpCodes() {
1350b57cec5SDimitry Andric if (!Names2InstrOpCodes.empty())
1360b57cec5SDimitry Andric return;
1370b57cec5SDimitry Andric const auto *TII = Subtarget.getInstrInfo();
1380b57cec5SDimitry Andric assert(TII && "Expected target instruction info");
1390b57cec5SDimitry Andric for (unsigned I = 0, E = TII->getNumOpcodes(); I < E; ++I)
1400b57cec5SDimitry Andric Names2InstrOpCodes.insert(std::make_pair(StringRef(TII->getName(I)), I));
1410b57cec5SDimitry Andric }
1420b57cec5SDimitry Andric
parseInstrName(StringRef InstrName,unsigned & OpCode)1430b57cec5SDimitry Andric bool PerTargetMIParsingState::parseInstrName(StringRef InstrName,
1440b57cec5SDimitry Andric unsigned &OpCode) {
1450b57cec5SDimitry Andric initNames2InstrOpCodes();
1460b57cec5SDimitry Andric auto InstrInfo = Names2InstrOpCodes.find(InstrName);
1470b57cec5SDimitry Andric if (InstrInfo == Names2InstrOpCodes.end())
1480b57cec5SDimitry Andric return true;
1490b57cec5SDimitry Andric OpCode = InstrInfo->getValue();
1500b57cec5SDimitry Andric return false;
1510b57cec5SDimitry Andric }
1520b57cec5SDimitry Andric
initNames2RegMasks()1530b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2RegMasks() {
1540b57cec5SDimitry Andric if (!Names2RegMasks.empty())
1550b57cec5SDimitry Andric return;
1560b57cec5SDimitry Andric const auto *TRI = Subtarget.getRegisterInfo();
1570b57cec5SDimitry Andric assert(TRI && "Expected target register info");
1580b57cec5SDimitry Andric ArrayRef<const uint32_t *> RegMasks = TRI->getRegMasks();
1590b57cec5SDimitry Andric ArrayRef<const char *> RegMaskNames = TRI->getRegMaskNames();
1600b57cec5SDimitry Andric assert(RegMasks.size() == RegMaskNames.size());
1610b57cec5SDimitry Andric for (size_t I = 0, E = RegMasks.size(); I < E; ++I)
1620b57cec5SDimitry Andric Names2RegMasks.insert(
1630b57cec5SDimitry Andric std::make_pair(StringRef(RegMaskNames[I]).lower(), RegMasks[I]));
1640b57cec5SDimitry Andric }
1650b57cec5SDimitry Andric
getRegMask(StringRef Identifier)1660b57cec5SDimitry Andric const uint32_t *PerTargetMIParsingState::getRegMask(StringRef Identifier) {
1670b57cec5SDimitry Andric initNames2RegMasks();
1680b57cec5SDimitry Andric auto RegMaskInfo = Names2RegMasks.find(Identifier);
1690b57cec5SDimitry Andric if (RegMaskInfo == Names2RegMasks.end())
1700b57cec5SDimitry Andric return nullptr;
1710b57cec5SDimitry Andric return RegMaskInfo->getValue();
1720b57cec5SDimitry Andric }
1730b57cec5SDimitry Andric
initNames2SubRegIndices()1740b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2SubRegIndices() {
1750b57cec5SDimitry Andric if (!Names2SubRegIndices.empty())
1760b57cec5SDimitry Andric return;
1770b57cec5SDimitry Andric const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
1780b57cec5SDimitry Andric for (unsigned I = 1, E = TRI->getNumSubRegIndices(); I < E; ++I)
1790b57cec5SDimitry Andric Names2SubRegIndices.insert(
1800b57cec5SDimitry Andric std::make_pair(TRI->getSubRegIndexName(I), I));
1810b57cec5SDimitry Andric }
1820b57cec5SDimitry Andric
getSubRegIndex(StringRef Name)1830b57cec5SDimitry Andric unsigned PerTargetMIParsingState::getSubRegIndex(StringRef Name) {
1840b57cec5SDimitry Andric initNames2SubRegIndices();
1850b57cec5SDimitry Andric auto SubRegInfo = Names2SubRegIndices.find(Name);
1860b57cec5SDimitry Andric if (SubRegInfo == Names2SubRegIndices.end())
1870b57cec5SDimitry Andric return 0;
1880b57cec5SDimitry Andric return SubRegInfo->getValue();
1890b57cec5SDimitry Andric }
1900b57cec5SDimitry Andric
initNames2TargetIndices()1910b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2TargetIndices() {
1920b57cec5SDimitry Andric if (!Names2TargetIndices.empty())
1930b57cec5SDimitry Andric return;
1940b57cec5SDimitry Andric const auto *TII = Subtarget.getInstrInfo();
1950b57cec5SDimitry Andric assert(TII && "Expected target instruction info");
1960b57cec5SDimitry Andric auto Indices = TII->getSerializableTargetIndices();
1970b57cec5SDimitry Andric for (const auto &I : Indices)
1980b57cec5SDimitry Andric Names2TargetIndices.insert(std::make_pair(StringRef(I.second), I.first));
1990b57cec5SDimitry Andric }
2000b57cec5SDimitry Andric
getTargetIndex(StringRef Name,int & Index)2010b57cec5SDimitry Andric bool PerTargetMIParsingState::getTargetIndex(StringRef Name, int &Index) {
2020b57cec5SDimitry Andric initNames2TargetIndices();
2030b57cec5SDimitry Andric auto IndexInfo = Names2TargetIndices.find(Name);
2040b57cec5SDimitry Andric if (IndexInfo == Names2TargetIndices.end())
2050b57cec5SDimitry Andric return true;
2060b57cec5SDimitry Andric Index = IndexInfo->second;
2070b57cec5SDimitry Andric return false;
2080b57cec5SDimitry Andric }
2090b57cec5SDimitry Andric
initNames2DirectTargetFlags()2100b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2DirectTargetFlags() {
2110b57cec5SDimitry Andric if (!Names2DirectTargetFlags.empty())
2120b57cec5SDimitry Andric return;
2130b57cec5SDimitry Andric
2140b57cec5SDimitry Andric const auto *TII = Subtarget.getInstrInfo();
2150b57cec5SDimitry Andric assert(TII && "Expected target instruction info");
2160b57cec5SDimitry Andric auto Flags = TII->getSerializableDirectMachineOperandTargetFlags();
2170b57cec5SDimitry Andric for (const auto &I : Flags)
2180b57cec5SDimitry Andric Names2DirectTargetFlags.insert(
2190b57cec5SDimitry Andric std::make_pair(StringRef(I.second), I.first));
2200b57cec5SDimitry Andric }
2210b57cec5SDimitry Andric
getDirectTargetFlag(StringRef Name,unsigned & Flag)2220b57cec5SDimitry Andric bool PerTargetMIParsingState::getDirectTargetFlag(StringRef Name,
2230b57cec5SDimitry Andric unsigned &Flag) {
2240b57cec5SDimitry Andric initNames2DirectTargetFlags();
2250b57cec5SDimitry Andric auto FlagInfo = Names2DirectTargetFlags.find(Name);
2260b57cec5SDimitry Andric if (FlagInfo == Names2DirectTargetFlags.end())
2270b57cec5SDimitry Andric return true;
2280b57cec5SDimitry Andric Flag = FlagInfo->second;
2290b57cec5SDimitry Andric return false;
2300b57cec5SDimitry Andric }
2310b57cec5SDimitry Andric
initNames2BitmaskTargetFlags()2320b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2BitmaskTargetFlags() {
2330b57cec5SDimitry Andric if (!Names2BitmaskTargetFlags.empty())
2340b57cec5SDimitry Andric return;
2350b57cec5SDimitry Andric
2360b57cec5SDimitry Andric const auto *TII = Subtarget.getInstrInfo();
2370b57cec5SDimitry Andric assert(TII && "Expected target instruction info");
2380b57cec5SDimitry Andric auto Flags = TII->getSerializableBitmaskMachineOperandTargetFlags();
2390b57cec5SDimitry Andric for (const auto &I : Flags)
2400b57cec5SDimitry Andric Names2BitmaskTargetFlags.insert(
2410b57cec5SDimitry Andric std::make_pair(StringRef(I.second), I.first));
2420b57cec5SDimitry Andric }
2430b57cec5SDimitry Andric
getBitmaskTargetFlag(StringRef Name,unsigned & Flag)2440b57cec5SDimitry Andric bool PerTargetMIParsingState::getBitmaskTargetFlag(StringRef Name,
2450b57cec5SDimitry Andric unsigned &Flag) {
2460b57cec5SDimitry Andric initNames2BitmaskTargetFlags();
2470b57cec5SDimitry Andric auto FlagInfo = Names2BitmaskTargetFlags.find(Name);
2480b57cec5SDimitry Andric if (FlagInfo == Names2BitmaskTargetFlags.end())
2490b57cec5SDimitry Andric return true;
2500b57cec5SDimitry Andric Flag = FlagInfo->second;
2510b57cec5SDimitry Andric return false;
2520b57cec5SDimitry Andric }
2530b57cec5SDimitry Andric
initNames2MMOTargetFlags()2540b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2MMOTargetFlags() {
2550b57cec5SDimitry Andric if (!Names2MMOTargetFlags.empty())
2560b57cec5SDimitry Andric return;
2570b57cec5SDimitry Andric
2580b57cec5SDimitry Andric const auto *TII = Subtarget.getInstrInfo();
2590b57cec5SDimitry Andric assert(TII && "Expected target instruction info");
2600b57cec5SDimitry Andric auto Flags = TII->getSerializableMachineMemOperandTargetFlags();
2610b57cec5SDimitry Andric for (const auto &I : Flags)
2620b57cec5SDimitry Andric Names2MMOTargetFlags.insert(std::make_pair(StringRef(I.second), I.first));
2630b57cec5SDimitry Andric }
2640b57cec5SDimitry Andric
getMMOTargetFlag(StringRef Name,MachineMemOperand::Flags & Flag)2650b57cec5SDimitry Andric bool PerTargetMIParsingState::getMMOTargetFlag(StringRef Name,
2660b57cec5SDimitry Andric MachineMemOperand::Flags &Flag) {
2670b57cec5SDimitry Andric initNames2MMOTargetFlags();
2680b57cec5SDimitry Andric auto FlagInfo = Names2MMOTargetFlags.find(Name);
2690b57cec5SDimitry Andric if (FlagInfo == Names2MMOTargetFlags.end())
2700b57cec5SDimitry Andric return true;
2710b57cec5SDimitry Andric Flag = FlagInfo->second;
2720b57cec5SDimitry Andric return false;
2730b57cec5SDimitry Andric }
2740b57cec5SDimitry Andric
initNames2RegClasses()2750b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2RegClasses() {
2760b57cec5SDimitry Andric if (!Names2RegClasses.empty())
2770b57cec5SDimitry Andric return;
2780b57cec5SDimitry Andric
2790b57cec5SDimitry Andric const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
2800b57cec5SDimitry Andric for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E; ++I) {
2810b57cec5SDimitry Andric const auto *RC = TRI->getRegClass(I);
2820b57cec5SDimitry Andric Names2RegClasses.insert(
2830b57cec5SDimitry Andric std::make_pair(StringRef(TRI->getRegClassName(RC)).lower(), RC));
2840b57cec5SDimitry Andric }
2850b57cec5SDimitry Andric }
2860b57cec5SDimitry Andric
initNames2RegBanks()2870b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2RegBanks() {
2880b57cec5SDimitry Andric if (!Names2RegBanks.empty())
2890b57cec5SDimitry Andric return;
2900b57cec5SDimitry Andric
2910b57cec5SDimitry Andric const RegisterBankInfo *RBI = Subtarget.getRegBankInfo();
2920b57cec5SDimitry Andric // If the target does not support GlobalISel, we may not have a
2930b57cec5SDimitry Andric // register bank info.
2940b57cec5SDimitry Andric if (!RBI)
2950b57cec5SDimitry Andric return;
2960b57cec5SDimitry Andric
2970b57cec5SDimitry Andric for (unsigned I = 0, E = RBI->getNumRegBanks(); I < E; ++I) {
2980b57cec5SDimitry Andric const auto &RegBank = RBI->getRegBank(I);
2990b57cec5SDimitry Andric Names2RegBanks.insert(
3000b57cec5SDimitry Andric std::make_pair(StringRef(RegBank.getName()).lower(), &RegBank));
3010b57cec5SDimitry Andric }
3020b57cec5SDimitry Andric }
3030b57cec5SDimitry Andric
3040b57cec5SDimitry Andric const TargetRegisterClass *
getRegClass(StringRef Name)3050b57cec5SDimitry Andric PerTargetMIParsingState::getRegClass(StringRef Name) {
3060b57cec5SDimitry Andric auto RegClassInfo = Names2RegClasses.find(Name);
3070b57cec5SDimitry Andric if (RegClassInfo == Names2RegClasses.end())
3080b57cec5SDimitry Andric return nullptr;
3090b57cec5SDimitry Andric return RegClassInfo->getValue();
3100b57cec5SDimitry Andric }
3110b57cec5SDimitry Andric
getRegBank(StringRef Name)3120b57cec5SDimitry Andric const RegisterBank *PerTargetMIParsingState::getRegBank(StringRef Name) {
3130b57cec5SDimitry Andric auto RegBankInfo = Names2RegBanks.find(Name);
3140b57cec5SDimitry Andric if (RegBankInfo == Names2RegBanks.end())
3150b57cec5SDimitry Andric return nullptr;
3160b57cec5SDimitry Andric return RegBankInfo->getValue();
3170b57cec5SDimitry Andric }
3180b57cec5SDimitry Andric
PerFunctionMIParsingState(MachineFunction & MF,SourceMgr & SM,const SlotMapping & IRSlots,PerTargetMIParsingState & T)3190b57cec5SDimitry Andric PerFunctionMIParsingState::PerFunctionMIParsingState(MachineFunction &MF,
3200b57cec5SDimitry Andric SourceMgr &SM, const SlotMapping &IRSlots, PerTargetMIParsingState &T)
3210b57cec5SDimitry Andric : MF(MF), SM(&SM), IRSlots(IRSlots), Target(T) {
3220b57cec5SDimitry Andric }
3230b57cec5SDimitry Andric
getVRegInfo(Register Num)3245ffd83dbSDimitry Andric VRegInfo &PerFunctionMIParsingState::getVRegInfo(Register Num) {
3250b57cec5SDimitry Andric auto I = VRegInfos.insert(std::make_pair(Num, nullptr));
3260b57cec5SDimitry Andric if (I.second) {
3270b57cec5SDimitry Andric MachineRegisterInfo &MRI = MF.getRegInfo();
3280b57cec5SDimitry Andric VRegInfo *Info = new (Allocator) VRegInfo;
3290b57cec5SDimitry Andric Info->VReg = MRI.createIncompleteVirtualRegister();
3300b57cec5SDimitry Andric I.first->second = Info;
3310b57cec5SDimitry Andric }
3320b57cec5SDimitry Andric return *I.first->second;
3330b57cec5SDimitry Andric }
3340b57cec5SDimitry Andric
getVRegInfoNamed(StringRef RegName)3350b57cec5SDimitry Andric VRegInfo &PerFunctionMIParsingState::getVRegInfoNamed(StringRef RegName) {
3360b57cec5SDimitry Andric assert(RegName != "" && "Expected named reg.");
3370b57cec5SDimitry Andric
3380b57cec5SDimitry Andric auto I = VRegInfosNamed.insert(std::make_pair(RegName.str(), nullptr));
3390b57cec5SDimitry Andric if (I.second) {
3400b57cec5SDimitry Andric VRegInfo *Info = new (Allocator) VRegInfo;
3410b57cec5SDimitry Andric Info->VReg = MF.getRegInfo().createIncompleteVirtualRegister(RegName);
3420b57cec5SDimitry Andric I.first->second = Info;
3430b57cec5SDimitry Andric }
3440b57cec5SDimitry Andric return *I.first->second;
3450b57cec5SDimitry Andric }
3460b57cec5SDimitry Andric
mapValueToSlot(const Value * V,ModuleSlotTracker & MST,DenseMap<unsigned,const Value * > & Slots2Values)347480093f4SDimitry Andric static void mapValueToSlot(const Value *V, ModuleSlotTracker &MST,
348480093f4SDimitry Andric DenseMap<unsigned, const Value *> &Slots2Values) {
349480093f4SDimitry Andric int Slot = MST.getLocalSlot(V);
350480093f4SDimitry Andric if (Slot == -1)
351480093f4SDimitry Andric return;
352480093f4SDimitry Andric Slots2Values.insert(std::make_pair(unsigned(Slot), V));
353480093f4SDimitry Andric }
354480093f4SDimitry Andric
355480093f4SDimitry Andric /// Creates the mapping from slot numbers to function's unnamed IR values.
initSlots2Values(const Function & F,DenseMap<unsigned,const Value * > & Slots2Values)356480093f4SDimitry Andric static void initSlots2Values(const Function &F,
357480093f4SDimitry Andric DenseMap<unsigned, const Value *> &Slots2Values) {
358480093f4SDimitry Andric ModuleSlotTracker MST(F.getParent(), /*ShouldInitializeAllMetadata=*/false);
359480093f4SDimitry Andric MST.incorporateFunction(F);
360480093f4SDimitry Andric for (const auto &Arg : F.args())
361480093f4SDimitry Andric mapValueToSlot(&Arg, MST, Slots2Values);
362480093f4SDimitry Andric for (const auto &BB : F) {
363480093f4SDimitry Andric mapValueToSlot(&BB, MST, Slots2Values);
364480093f4SDimitry Andric for (const auto &I : BB)
365480093f4SDimitry Andric mapValueToSlot(&I, MST, Slots2Values);
366480093f4SDimitry Andric }
367480093f4SDimitry Andric }
368480093f4SDimitry Andric
getIRValue(unsigned Slot)369480093f4SDimitry Andric const Value* PerFunctionMIParsingState::getIRValue(unsigned Slot) {
370480093f4SDimitry Andric if (Slots2Values.empty())
371480093f4SDimitry Andric initSlots2Values(MF.getFunction(), Slots2Values);
372af732203SDimitry Andric return Slots2Values.lookup(Slot);
373480093f4SDimitry Andric }
374480093f4SDimitry Andric
3750b57cec5SDimitry Andric namespace {
3760b57cec5SDimitry Andric
3770b57cec5SDimitry Andric /// A wrapper struct around the 'MachineOperand' struct that includes a source
3780b57cec5SDimitry Andric /// range and other attributes.
3790b57cec5SDimitry Andric struct ParsedMachineOperand {
3800b57cec5SDimitry Andric MachineOperand Operand;
3810b57cec5SDimitry Andric StringRef::iterator Begin;
3820b57cec5SDimitry Andric StringRef::iterator End;
3830b57cec5SDimitry Andric Optional<unsigned> TiedDefIdx;
3840b57cec5SDimitry Andric
ParsedMachineOperand__anond099e40f0111::ParsedMachineOperand3850b57cec5SDimitry Andric ParsedMachineOperand(const MachineOperand &Operand, StringRef::iterator Begin,
3860b57cec5SDimitry Andric StringRef::iterator End, Optional<unsigned> &TiedDefIdx)
3870b57cec5SDimitry Andric : Operand(Operand), Begin(Begin), End(End), TiedDefIdx(TiedDefIdx) {
3880b57cec5SDimitry Andric if (TiedDefIdx)
3890b57cec5SDimitry Andric assert(Operand.isReg() && Operand.isUse() &&
3900b57cec5SDimitry Andric "Only used register operands can be tied");
3910b57cec5SDimitry Andric }
3920b57cec5SDimitry Andric };
3930b57cec5SDimitry Andric
3940b57cec5SDimitry Andric class MIParser {
3950b57cec5SDimitry Andric MachineFunction &MF;
3960b57cec5SDimitry Andric SMDiagnostic &Error;
3970b57cec5SDimitry Andric StringRef Source, CurrentSource;
398*5f7ddb14SDimitry Andric SMRange SourceRange;
3990b57cec5SDimitry Andric MIToken Token;
4000b57cec5SDimitry Andric PerFunctionMIParsingState &PFS;
4010b57cec5SDimitry Andric /// Maps from slot numbers to function's unnamed basic blocks.
4020b57cec5SDimitry Andric DenseMap<unsigned, const BasicBlock *> Slots2BasicBlocks;
4030b57cec5SDimitry Andric
4040b57cec5SDimitry Andric public:
4050b57cec5SDimitry Andric MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
4060b57cec5SDimitry Andric StringRef Source);
407*5f7ddb14SDimitry Andric MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
408*5f7ddb14SDimitry Andric StringRef Source, SMRange SourceRange);
4090b57cec5SDimitry Andric
4100b57cec5SDimitry Andric /// \p SkipChar gives the number of characters to skip before looking
4110b57cec5SDimitry Andric /// for the next token.
4120b57cec5SDimitry Andric void lex(unsigned SkipChar = 0);
4130b57cec5SDimitry Andric
4140b57cec5SDimitry Andric /// Report an error at the current location with the given message.
4150b57cec5SDimitry Andric ///
4160b57cec5SDimitry Andric /// This function always return true.
4170b57cec5SDimitry Andric bool error(const Twine &Msg);
4180b57cec5SDimitry Andric
4190b57cec5SDimitry Andric /// Report an error at the given location with the given message.
4200b57cec5SDimitry Andric ///
4210b57cec5SDimitry Andric /// This function always return true.
4220b57cec5SDimitry Andric bool error(StringRef::iterator Loc, const Twine &Msg);
4230b57cec5SDimitry Andric
4240b57cec5SDimitry Andric bool
4250b57cec5SDimitry Andric parseBasicBlockDefinitions(DenseMap<unsigned, MachineBasicBlock *> &MBBSlots);
4260b57cec5SDimitry Andric bool parseBasicBlocks();
4270b57cec5SDimitry Andric bool parse(MachineInstr *&MI);
4280b57cec5SDimitry Andric bool parseStandaloneMBB(MachineBasicBlock *&MBB);
4295ffd83dbSDimitry Andric bool parseStandaloneNamedRegister(Register &Reg);
4300b57cec5SDimitry Andric bool parseStandaloneVirtualRegister(VRegInfo *&Info);
4315ffd83dbSDimitry Andric bool parseStandaloneRegister(Register &Reg);
4320b57cec5SDimitry Andric bool parseStandaloneStackObject(int &FI);
4330b57cec5SDimitry Andric bool parseStandaloneMDNode(MDNode *&Node);
434*5f7ddb14SDimitry Andric bool parseMachineMetadata();
435*5f7ddb14SDimitry Andric bool parseMDTuple(MDNode *&MD, bool IsDistinct);
436*5f7ddb14SDimitry Andric bool parseMDNodeVector(SmallVectorImpl<Metadata *> &Elts);
437*5f7ddb14SDimitry Andric bool parseMetadata(Metadata *&MD);
4380b57cec5SDimitry Andric
4390b57cec5SDimitry Andric bool
4400b57cec5SDimitry Andric parseBasicBlockDefinition(DenseMap<unsigned, MachineBasicBlock *> &MBBSlots);
4410b57cec5SDimitry Andric bool parseBasicBlock(MachineBasicBlock &MBB,
4420b57cec5SDimitry Andric MachineBasicBlock *&AddFalthroughFrom);
4430b57cec5SDimitry Andric bool parseBasicBlockLiveins(MachineBasicBlock &MBB);
4440b57cec5SDimitry Andric bool parseBasicBlockSuccessors(MachineBasicBlock &MBB);
4450b57cec5SDimitry Andric
4465ffd83dbSDimitry Andric bool parseNamedRegister(Register &Reg);
4470b57cec5SDimitry Andric bool parseVirtualRegister(VRegInfo *&Info);
4480b57cec5SDimitry Andric bool parseNamedVirtualRegister(VRegInfo *&Info);
4495ffd83dbSDimitry Andric bool parseRegister(Register &Reg, VRegInfo *&VRegInfo);
4500b57cec5SDimitry Andric bool parseRegisterFlag(unsigned &Flags);
4510b57cec5SDimitry Andric bool parseRegisterClassOrBank(VRegInfo &RegInfo);
4520b57cec5SDimitry Andric bool parseSubRegisterIndex(unsigned &SubReg);
4530b57cec5SDimitry Andric bool parseRegisterTiedDefIndex(unsigned &TiedDefIdx);
4540b57cec5SDimitry Andric bool parseRegisterOperand(MachineOperand &Dest,
4550b57cec5SDimitry Andric Optional<unsigned> &TiedDefIdx, bool IsDef = false);
4560b57cec5SDimitry Andric bool parseImmediateOperand(MachineOperand &Dest);
4570b57cec5SDimitry Andric bool parseIRConstant(StringRef::iterator Loc, StringRef StringValue,
4580b57cec5SDimitry Andric const Constant *&C);
4590b57cec5SDimitry Andric bool parseIRConstant(StringRef::iterator Loc, const Constant *&C);
4600b57cec5SDimitry Andric bool parseLowLevelType(StringRef::iterator Loc, LLT &Ty);
4610b57cec5SDimitry Andric bool parseTypedImmediateOperand(MachineOperand &Dest);
4620b57cec5SDimitry Andric bool parseFPImmediateOperand(MachineOperand &Dest);
4630b57cec5SDimitry Andric bool parseMBBReference(MachineBasicBlock *&MBB);
4640b57cec5SDimitry Andric bool parseMBBOperand(MachineOperand &Dest);
4650b57cec5SDimitry Andric bool parseStackFrameIndex(int &FI);
4660b57cec5SDimitry Andric bool parseStackObjectOperand(MachineOperand &Dest);
4670b57cec5SDimitry Andric bool parseFixedStackFrameIndex(int &FI);
4680b57cec5SDimitry Andric bool parseFixedStackObjectOperand(MachineOperand &Dest);
4690b57cec5SDimitry Andric bool parseGlobalValue(GlobalValue *&GV);
4700b57cec5SDimitry Andric bool parseGlobalAddressOperand(MachineOperand &Dest);
4710b57cec5SDimitry Andric bool parseConstantPoolIndexOperand(MachineOperand &Dest);
4720b57cec5SDimitry Andric bool parseSubRegisterIndexOperand(MachineOperand &Dest);
4730b57cec5SDimitry Andric bool parseJumpTableIndexOperand(MachineOperand &Dest);
4740b57cec5SDimitry Andric bool parseExternalSymbolOperand(MachineOperand &Dest);
4750b57cec5SDimitry Andric bool parseMCSymbolOperand(MachineOperand &Dest);
4760b57cec5SDimitry Andric bool parseMDNode(MDNode *&Node);
4770b57cec5SDimitry Andric bool parseDIExpression(MDNode *&Expr);
4780b57cec5SDimitry Andric bool parseDILocation(MDNode *&Expr);
4790b57cec5SDimitry Andric bool parseMetadataOperand(MachineOperand &Dest);
4800b57cec5SDimitry Andric bool parseCFIOffset(int &Offset);
4815ffd83dbSDimitry Andric bool parseCFIRegister(Register &Reg);
482*5f7ddb14SDimitry Andric bool parseCFIAddressSpace(unsigned &AddressSpace);
4830b57cec5SDimitry Andric bool parseCFIEscapeValues(std::string& Values);
4840b57cec5SDimitry Andric bool parseCFIOperand(MachineOperand &Dest);
4850b57cec5SDimitry Andric bool parseIRBlock(BasicBlock *&BB, const Function &F);
4860b57cec5SDimitry Andric bool parseBlockAddressOperand(MachineOperand &Dest);
4870b57cec5SDimitry Andric bool parseIntrinsicOperand(MachineOperand &Dest);
4880b57cec5SDimitry Andric bool parsePredicateOperand(MachineOperand &Dest);
4898bcb0991SDimitry Andric bool parseShuffleMaskOperand(MachineOperand &Dest);
4900b57cec5SDimitry Andric bool parseTargetIndexOperand(MachineOperand &Dest);
4910b57cec5SDimitry Andric bool parseCustomRegisterMaskOperand(MachineOperand &Dest);
4920b57cec5SDimitry Andric bool parseLiveoutRegisterMaskOperand(MachineOperand &Dest);
493480093f4SDimitry Andric bool parseMachineOperand(const unsigned OpCode, const unsigned OpIdx,
494480093f4SDimitry Andric MachineOperand &Dest,
4950b57cec5SDimitry Andric Optional<unsigned> &TiedDefIdx);
496480093f4SDimitry Andric bool parseMachineOperandAndTargetFlags(const unsigned OpCode,
497480093f4SDimitry Andric const unsigned OpIdx,
498480093f4SDimitry Andric MachineOperand &Dest,
4990b57cec5SDimitry Andric Optional<unsigned> &TiedDefIdx);
5000b57cec5SDimitry Andric bool parseOffset(int64_t &Offset);
5010b57cec5SDimitry Andric bool parseAlignment(unsigned &Alignment);
5020b57cec5SDimitry Andric bool parseAddrspace(unsigned &Addrspace);
5035ffd83dbSDimitry Andric bool parseSectionID(Optional<MBBSectionID> &SID);
5040b57cec5SDimitry Andric bool parseOperandsOffset(MachineOperand &Op);
5050b57cec5SDimitry Andric bool parseIRValue(const Value *&V);
5060b57cec5SDimitry Andric bool parseMemoryOperandFlag(MachineMemOperand::Flags &Flags);
5070b57cec5SDimitry Andric bool parseMemoryPseudoSourceValue(const PseudoSourceValue *&PSV);
5080b57cec5SDimitry Andric bool parseMachinePointerInfo(MachinePointerInfo &Dest);
5090b57cec5SDimitry Andric bool parseOptionalScope(LLVMContext &Context, SyncScope::ID &SSID);
5100b57cec5SDimitry Andric bool parseOptionalAtomicOrdering(AtomicOrdering &Order);
5110b57cec5SDimitry Andric bool parseMachineMemoryOperand(MachineMemOperand *&Dest);
5120b57cec5SDimitry Andric bool parsePreOrPostInstrSymbol(MCSymbol *&Symbol);
513480093f4SDimitry Andric bool parseHeapAllocMarker(MDNode *&Node);
514480093f4SDimitry Andric
515480093f4SDimitry Andric bool parseTargetImmMnemonic(const unsigned OpCode, const unsigned OpIdx,
516480093f4SDimitry Andric MachineOperand &Dest, const MIRFormatter &MF);
5170b57cec5SDimitry Andric
5180b57cec5SDimitry Andric private:
5190b57cec5SDimitry Andric /// Convert the integer literal in the current token into an unsigned integer.
5200b57cec5SDimitry Andric ///
5210b57cec5SDimitry Andric /// Return true if an error occurred.
5220b57cec5SDimitry Andric bool getUnsigned(unsigned &Result);
5230b57cec5SDimitry Andric
5240b57cec5SDimitry Andric /// Convert the integer literal in the current token into an uint64.
5250b57cec5SDimitry Andric ///
5260b57cec5SDimitry Andric /// Return true if an error occurred.
5270b57cec5SDimitry Andric bool getUint64(uint64_t &Result);
5280b57cec5SDimitry Andric
5290b57cec5SDimitry Andric /// Convert the hexadecimal literal in the current token into an unsigned
5300b57cec5SDimitry Andric /// APInt with a minimum bitwidth required to represent the value.
5310b57cec5SDimitry Andric ///
5320b57cec5SDimitry Andric /// Return true if the literal does not represent an integer value.
5330b57cec5SDimitry Andric bool getHexUint(APInt &Result);
5340b57cec5SDimitry Andric
5350b57cec5SDimitry Andric /// If the current token is of the given kind, consume it and return false.
5360b57cec5SDimitry Andric /// Otherwise report an error and return true.
5370b57cec5SDimitry Andric bool expectAndConsume(MIToken::TokenKind TokenKind);
5380b57cec5SDimitry Andric
5390b57cec5SDimitry Andric /// If the current token is of the given kind, consume it and return true.
5400b57cec5SDimitry Andric /// Otherwise return false.
5410b57cec5SDimitry Andric bool consumeIfPresent(MIToken::TokenKind TokenKind);
5420b57cec5SDimitry Andric
5430b57cec5SDimitry Andric bool parseInstruction(unsigned &OpCode, unsigned &Flags);
5440b57cec5SDimitry Andric
5450b57cec5SDimitry Andric bool assignRegisterTies(MachineInstr &MI,
5460b57cec5SDimitry Andric ArrayRef<ParsedMachineOperand> Operands);
5470b57cec5SDimitry Andric
5480b57cec5SDimitry Andric bool verifyImplicitOperands(ArrayRef<ParsedMachineOperand> Operands,
5490b57cec5SDimitry Andric const MCInstrDesc &MCID);
5500b57cec5SDimitry Andric
5510b57cec5SDimitry Andric const BasicBlock *getIRBlock(unsigned Slot);
5520b57cec5SDimitry Andric const BasicBlock *getIRBlock(unsigned Slot, const Function &F);
5530b57cec5SDimitry Andric
5540b57cec5SDimitry Andric /// Get or create an MCSymbol for a given name.
5550b57cec5SDimitry Andric MCSymbol *getOrCreateMCSymbol(StringRef Name);
5560b57cec5SDimitry Andric
5570b57cec5SDimitry Andric /// parseStringConstant
5580b57cec5SDimitry Andric /// ::= StringConstant
5590b57cec5SDimitry Andric bool parseStringConstant(std::string &Result);
560*5f7ddb14SDimitry Andric
561*5f7ddb14SDimitry Andric /// Map the location in the MI string to the corresponding location specified
562*5f7ddb14SDimitry Andric /// in `SourceRange`.
563*5f7ddb14SDimitry Andric SMLoc mapSMLoc(StringRef::iterator Loc);
5640b57cec5SDimitry Andric };
5650b57cec5SDimitry Andric
5660b57cec5SDimitry Andric } // end anonymous namespace
5670b57cec5SDimitry Andric
MIParser(PerFunctionMIParsingState & PFS,SMDiagnostic & Error,StringRef Source)5680b57cec5SDimitry Andric MIParser::MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
5690b57cec5SDimitry Andric StringRef Source)
5700b57cec5SDimitry Andric : MF(PFS.MF), Error(Error), Source(Source), CurrentSource(Source), PFS(PFS)
5710b57cec5SDimitry Andric {}
5720b57cec5SDimitry Andric
MIParser(PerFunctionMIParsingState & PFS,SMDiagnostic & Error,StringRef Source,SMRange SourceRange)573*5f7ddb14SDimitry Andric MIParser::MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
574*5f7ddb14SDimitry Andric StringRef Source, SMRange SourceRange)
575*5f7ddb14SDimitry Andric : MF(PFS.MF), Error(Error), Source(Source), CurrentSource(Source),
576*5f7ddb14SDimitry Andric SourceRange(SourceRange), PFS(PFS) {}
577*5f7ddb14SDimitry Andric
lex(unsigned SkipChar)5780b57cec5SDimitry Andric void MIParser::lex(unsigned SkipChar) {
5790b57cec5SDimitry Andric CurrentSource = lexMIToken(
5805ffd83dbSDimitry Andric CurrentSource.slice(SkipChar, StringRef::npos), Token,
5810b57cec5SDimitry Andric [this](StringRef::iterator Loc, const Twine &Msg) { error(Loc, Msg); });
5820b57cec5SDimitry Andric }
5830b57cec5SDimitry Andric
error(const Twine & Msg)5840b57cec5SDimitry Andric bool MIParser::error(const Twine &Msg) { return error(Token.location(), Msg); }
5850b57cec5SDimitry Andric
error(StringRef::iterator Loc,const Twine & Msg)5860b57cec5SDimitry Andric bool MIParser::error(StringRef::iterator Loc, const Twine &Msg) {
5870b57cec5SDimitry Andric const SourceMgr &SM = *PFS.SM;
5880b57cec5SDimitry Andric assert(Loc >= Source.data() && Loc <= (Source.data() + Source.size()));
5890b57cec5SDimitry Andric const MemoryBuffer &Buffer = *SM.getMemoryBuffer(SM.getMainFileID());
5900b57cec5SDimitry Andric if (Loc >= Buffer.getBufferStart() && Loc <= Buffer.getBufferEnd()) {
5910b57cec5SDimitry Andric // Create an ordinary diagnostic when the source manager's buffer is the
5920b57cec5SDimitry Andric // source string.
5930b57cec5SDimitry Andric Error = SM.GetMessage(SMLoc::getFromPointer(Loc), SourceMgr::DK_Error, Msg);
5940b57cec5SDimitry Andric return true;
5950b57cec5SDimitry Andric }
5960b57cec5SDimitry Andric // Create a diagnostic for a YAML string literal.
5970b57cec5SDimitry Andric Error = SMDiagnostic(SM, SMLoc(), Buffer.getBufferIdentifier(), 1,
5980b57cec5SDimitry Andric Loc - Source.data(), SourceMgr::DK_Error, Msg.str(),
5990b57cec5SDimitry Andric Source, None, None);
6000b57cec5SDimitry Andric return true;
6010b57cec5SDimitry Andric }
6020b57cec5SDimitry Andric
mapSMLoc(StringRef::iterator Loc)603*5f7ddb14SDimitry Andric SMLoc MIParser::mapSMLoc(StringRef::iterator Loc) {
604*5f7ddb14SDimitry Andric assert(SourceRange.isValid() && "Invalid source range");
605*5f7ddb14SDimitry Andric assert(Loc >= Source.data() && Loc <= (Source.data() + Source.size()));
606*5f7ddb14SDimitry Andric return SMLoc::getFromPointer(SourceRange.Start.getPointer() +
607*5f7ddb14SDimitry Andric (Loc - Source.data()));
608*5f7ddb14SDimitry Andric }
609*5f7ddb14SDimitry Andric
610480093f4SDimitry Andric typedef function_ref<bool(StringRef::iterator Loc, const Twine &)>
611480093f4SDimitry Andric ErrorCallbackType;
612480093f4SDimitry Andric
toString(MIToken::TokenKind TokenKind)6130b57cec5SDimitry Andric static const char *toString(MIToken::TokenKind TokenKind) {
6140b57cec5SDimitry Andric switch (TokenKind) {
6150b57cec5SDimitry Andric case MIToken::comma:
6160b57cec5SDimitry Andric return "','";
6170b57cec5SDimitry Andric case MIToken::equal:
6180b57cec5SDimitry Andric return "'='";
6190b57cec5SDimitry Andric case MIToken::colon:
6200b57cec5SDimitry Andric return "':'";
6210b57cec5SDimitry Andric case MIToken::lparen:
6220b57cec5SDimitry Andric return "'('";
6230b57cec5SDimitry Andric case MIToken::rparen:
6240b57cec5SDimitry Andric return "')'";
6250b57cec5SDimitry Andric default:
6260b57cec5SDimitry Andric return "<unknown token>";
6270b57cec5SDimitry Andric }
6280b57cec5SDimitry Andric }
6290b57cec5SDimitry Andric
expectAndConsume(MIToken::TokenKind TokenKind)6300b57cec5SDimitry Andric bool MIParser::expectAndConsume(MIToken::TokenKind TokenKind) {
6310b57cec5SDimitry Andric if (Token.isNot(TokenKind))
6320b57cec5SDimitry Andric return error(Twine("expected ") + toString(TokenKind));
6330b57cec5SDimitry Andric lex();
6340b57cec5SDimitry Andric return false;
6350b57cec5SDimitry Andric }
6360b57cec5SDimitry Andric
consumeIfPresent(MIToken::TokenKind TokenKind)6370b57cec5SDimitry Andric bool MIParser::consumeIfPresent(MIToken::TokenKind TokenKind) {
6380b57cec5SDimitry Andric if (Token.isNot(TokenKind))
6390b57cec5SDimitry Andric return false;
6400b57cec5SDimitry Andric lex();
6410b57cec5SDimitry Andric return true;
6420b57cec5SDimitry Andric }
6430b57cec5SDimitry Andric
6445ffd83dbSDimitry Andric // Parse Machine Basic Block Section ID.
parseSectionID(Optional<MBBSectionID> & SID)6455ffd83dbSDimitry Andric bool MIParser::parseSectionID(Optional<MBBSectionID> &SID) {
6465ffd83dbSDimitry Andric assert(Token.is(MIToken::kw_bbsections));
6475ffd83dbSDimitry Andric lex();
6485ffd83dbSDimitry Andric if (Token.is(MIToken::IntegerLiteral)) {
6495ffd83dbSDimitry Andric unsigned Value = 0;
6505ffd83dbSDimitry Andric if (getUnsigned(Value))
6515ffd83dbSDimitry Andric return error("Unknown Section ID");
6525ffd83dbSDimitry Andric SID = MBBSectionID{Value};
6535ffd83dbSDimitry Andric } else {
6545ffd83dbSDimitry Andric const StringRef &S = Token.stringValue();
6555ffd83dbSDimitry Andric if (S == "Exception")
6565ffd83dbSDimitry Andric SID = MBBSectionID::ExceptionSectionID;
6575ffd83dbSDimitry Andric else if (S == "Cold")
6585ffd83dbSDimitry Andric SID = MBBSectionID::ColdSectionID;
6595ffd83dbSDimitry Andric else
6605ffd83dbSDimitry Andric return error("Unknown Section ID");
6615ffd83dbSDimitry Andric }
6625ffd83dbSDimitry Andric lex();
6635ffd83dbSDimitry Andric return false;
6645ffd83dbSDimitry Andric }
6655ffd83dbSDimitry Andric
parseBasicBlockDefinition(DenseMap<unsigned,MachineBasicBlock * > & MBBSlots)6660b57cec5SDimitry Andric bool MIParser::parseBasicBlockDefinition(
6670b57cec5SDimitry Andric DenseMap<unsigned, MachineBasicBlock *> &MBBSlots) {
6680b57cec5SDimitry Andric assert(Token.is(MIToken::MachineBasicBlockLabel));
6690b57cec5SDimitry Andric unsigned ID = 0;
6700b57cec5SDimitry Andric if (getUnsigned(ID))
6710b57cec5SDimitry Andric return true;
6720b57cec5SDimitry Andric auto Loc = Token.location();
6730b57cec5SDimitry Andric auto Name = Token.stringValue();
6740b57cec5SDimitry Andric lex();
6750b57cec5SDimitry Andric bool HasAddressTaken = false;
6760b57cec5SDimitry Andric bool IsLandingPad = false;
6775ffd83dbSDimitry Andric bool IsEHFuncletEntry = false;
6785ffd83dbSDimitry Andric Optional<MBBSectionID> SectionID;
6790b57cec5SDimitry Andric unsigned Alignment = 0;
6800b57cec5SDimitry Andric BasicBlock *BB = nullptr;
6810b57cec5SDimitry Andric if (consumeIfPresent(MIToken::lparen)) {
6820b57cec5SDimitry Andric do {
6830b57cec5SDimitry Andric // TODO: Report an error when multiple same attributes are specified.
6840b57cec5SDimitry Andric switch (Token.kind()) {
6850b57cec5SDimitry Andric case MIToken::kw_address_taken:
6860b57cec5SDimitry Andric HasAddressTaken = true;
6870b57cec5SDimitry Andric lex();
6880b57cec5SDimitry Andric break;
6890b57cec5SDimitry Andric case MIToken::kw_landing_pad:
6900b57cec5SDimitry Andric IsLandingPad = true;
6910b57cec5SDimitry Andric lex();
6920b57cec5SDimitry Andric break;
6935ffd83dbSDimitry Andric case MIToken::kw_ehfunclet_entry:
6945ffd83dbSDimitry Andric IsEHFuncletEntry = true;
6955ffd83dbSDimitry Andric lex();
6965ffd83dbSDimitry Andric break;
6970b57cec5SDimitry Andric case MIToken::kw_align:
6980b57cec5SDimitry Andric if (parseAlignment(Alignment))
6990b57cec5SDimitry Andric return true;
7000b57cec5SDimitry Andric break;
7010b57cec5SDimitry Andric case MIToken::IRBlock:
7020b57cec5SDimitry Andric // TODO: Report an error when both name and ir block are specified.
7030b57cec5SDimitry Andric if (parseIRBlock(BB, MF.getFunction()))
7040b57cec5SDimitry Andric return true;
7050b57cec5SDimitry Andric lex();
7060b57cec5SDimitry Andric break;
7075ffd83dbSDimitry Andric case MIToken::kw_bbsections:
7085ffd83dbSDimitry Andric if (parseSectionID(SectionID))
7095ffd83dbSDimitry Andric return true;
7105ffd83dbSDimitry Andric break;
7110b57cec5SDimitry Andric default:
7120b57cec5SDimitry Andric break;
7130b57cec5SDimitry Andric }
7140b57cec5SDimitry Andric } while (consumeIfPresent(MIToken::comma));
7150b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
7160b57cec5SDimitry Andric return true;
7170b57cec5SDimitry Andric }
7180b57cec5SDimitry Andric if (expectAndConsume(MIToken::colon))
7190b57cec5SDimitry Andric return true;
7200b57cec5SDimitry Andric
7210b57cec5SDimitry Andric if (!Name.empty()) {
7220b57cec5SDimitry Andric BB = dyn_cast_or_null<BasicBlock>(
7230b57cec5SDimitry Andric MF.getFunction().getValueSymbolTable()->lookup(Name));
7240b57cec5SDimitry Andric if (!BB)
7250b57cec5SDimitry Andric return error(Loc, Twine("basic block '") + Name +
7260b57cec5SDimitry Andric "' is not defined in the function '" +
7270b57cec5SDimitry Andric MF.getName() + "'");
7280b57cec5SDimitry Andric }
7290b57cec5SDimitry Andric auto *MBB = MF.CreateMachineBasicBlock(BB);
7300b57cec5SDimitry Andric MF.insert(MF.end(), MBB);
7310b57cec5SDimitry Andric bool WasInserted = MBBSlots.insert(std::make_pair(ID, MBB)).second;
7320b57cec5SDimitry Andric if (!WasInserted)
7330b57cec5SDimitry Andric return error(Loc, Twine("redefinition of machine basic block with id #") +
7340b57cec5SDimitry Andric Twine(ID));
7350b57cec5SDimitry Andric if (Alignment)
7368bcb0991SDimitry Andric MBB->setAlignment(Align(Alignment));
7370b57cec5SDimitry Andric if (HasAddressTaken)
7380b57cec5SDimitry Andric MBB->setHasAddressTaken();
7390b57cec5SDimitry Andric MBB->setIsEHPad(IsLandingPad);
7405ffd83dbSDimitry Andric MBB->setIsEHFuncletEntry(IsEHFuncletEntry);
7415ffd83dbSDimitry Andric if (SectionID.hasValue()) {
7425ffd83dbSDimitry Andric MBB->setSectionID(SectionID.getValue());
7435ffd83dbSDimitry Andric MF.setBBSectionsType(BasicBlockSection::List);
7445ffd83dbSDimitry Andric }
7450b57cec5SDimitry Andric return false;
7460b57cec5SDimitry Andric }
7470b57cec5SDimitry Andric
parseBasicBlockDefinitions(DenseMap<unsigned,MachineBasicBlock * > & MBBSlots)7480b57cec5SDimitry Andric bool MIParser::parseBasicBlockDefinitions(
7490b57cec5SDimitry Andric DenseMap<unsigned, MachineBasicBlock *> &MBBSlots) {
7500b57cec5SDimitry Andric lex();
7510b57cec5SDimitry Andric // Skip until the first machine basic block.
7520b57cec5SDimitry Andric while (Token.is(MIToken::Newline))
7530b57cec5SDimitry Andric lex();
7540b57cec5SDimitry Andric if (Token.isErrorOrEOF())
7550b57cec5SDimitry Andric return Token.isError();
7560b57cec5SDimitry Andric if (Token.isNot(MIToken::MachineBasicBlockLabel))
7570b57cec5SDimitry Andric return error("expected a basic block definition before instructions");
7580b57cec5SDimitry Andric unsigned BraceDepth = 0;
7590b57cec5SDimitry Andric do {
7600b57cec5SDimitry Andric if (parseBasicBlockDefinition(MBBSlots))
7610b57cec5SDimitry Andric return true;
7620b57cec5SDimitry Andric bool IsAfterNewline = false;
7630b57cec5SDimitry Andric // Skip until the next machine basic block.
7640b57cec5SDimitry Andric while (true) {
7650b57cec5SDimitry Andric if ((Token.is(MIToken::MachineBasicBlockLabel) && IsAfterNewline) ||
7660b57cec5SDimitry Andric Token.isErrorOrEOF())
7670b57cec5SDimitry Andric break;
7680b57cec5SDimitry Andric else if (Token.is(MIToken::MachineBasicBlockLabel))
7690b57cec5SDimitry Andric return error("basic block definition should be located at the start of "
7700b57cec5SDimitry Andric "the line");
7710b57cec5SDimitry Andric else if (consumeIfPresent(MIToken::Newline)) {
7720b57cec5SDimitry Andric IsAfterNewline = true;
7730b57cec5SDimitry Andric continue;
7740b57cec5SDimitry Andric }
7750b57cec5SDimitry Andric IsAfterNewline = false;
7760b57cec5SDimitry Andric if (Token.is(MIToken::lbrace))
7770b57cec5SDimitry Andric ++BraceDepth;
7780b57cec5SDimitry Andric if (Token.is(MIToken::rbrace)) {
7790b57cec5SDimitry Andric if (!BraceDepth)
7800b57cec5SDimitry Andric return error("extraneous closing brace ('}')");
7810b57cec5SDimitry Andric --BraceDepth;
7820b57cec5SDimitry Andric }
7830b57cec5SDimitry Andric lex();
7840b57cec5SDimitry Andric }
7850b57cec5SDimitry Andric // Verify that we closed all of the '{' at the end of a file or a block.
7860b57cec5SDimitry Andric if (!Token.isError() && BraceDepth)
7870b57cec5SDimitry Andric return error("expected '}'"); // FIXME: Report a note that shows '{'.
7880b57cec5SDimitry Andric } while (!Token.isErrorOrEOF());
7890b57cec5SDimitry Andric return Token.isError();
7900b57cec5SDimitry Andric }
7910b57cec5SDimitry Andric
parseBasicBlockLiveins(MachineBasicBlock & MBB)7920b57cec5SDimitry Andric bool MIParser::parseBasicBlockLiveins(MachineBasicBlock &MBB) {
7930b57cec5SDimitry Andric assert(Token.is(MIToken::kw_liveins));
7940b57cec5SDimitry Andric lex();
7950b57cec5SDimitry Andric if (expectAndConsume(MIToken::colon))
7960b57cec5SDimitry Andric return true;
7970b57cec5SDimitry Andric if (Token.isNewlineOrEOF()) // Allow an empty list of liveins.
7980b57cec5SDimitry Andric return false;
7990b57cec5SDimitry Andric do {
8000b57cec5SDimitry Andric if (Token.isNot(MIToken::NamedRegister))
8010b57cec5SDimitry Andric return error("expected a named register");
8025ffd83dbSDimitry Andric Register Reg;
8030b57cec5SDimitry Andric if (parseNamedRegister(Reg))
8040b57cec5SDimitry Andric return true;
8050b57cec5SDimitry Andric lex();
8060b57cec5SDimitry Andric LaneBitmask Mask = LaneBitmask::getAll();
8070b57cec5SDimitry Andric if (consumeIfPresent(MIToken::colon)) {
8080b57cec5SDimitry Andric // Parse lane mask.
8090b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) &&
8100b57cec5SDimitry Andric Token.isNot(MIToken::HexLiteral))
8110b57cec5SDimitry Andric return error("expected a lane mask");
8125ffd83dbSDimitry Andric static_assert(sizeof(LaneBitmask::Type) == sizeof(uint64_t),
8130b57cec5SDimitry Andric "Use correct get-function for lane mask");
8140b57cec5SDimitry Andric LaneBitmask::Type V;
8155ffd83dbSDimitry Andric if (getUint64(V))
8160b57cec5SDimitry Andric return error("invalid lane mask value");
8170b57cec5SDimitry Andric Mask = LaneBitmask(V);
8180b57cec5SDimitry Andric lex();
8190b57cec5SDimitry Andric }
8200b57cec5SDimitry Andric MBB.addLiveIn(Reg, Mask);
8210b57cec5SDimitry Andric } while (consumeIfPresent(MIToken::comma));
8220b57cec5SDimitry Andric return false;
8230b57cec5SDimitry Andric }
8240b57cec5SDimitry Andric
parseBasicBlockSuccessors(MachineBasicBlock & MBB)8250b57cec5SDimitry Andric bool MIParser::parseBasicBlockSuccessors(MachineBasicBlock &MBB) {
8260b57cec5SDimitry Andric assert(Token.is(MIToken::kw_successors));
8270b57cec5SDimitry Andric lex();
8280b57cec5SDimitry Andric if (expectAndConsume(MIToken::colon))
8290b57cec5SDimitry Andric return true;
8300b57cec5SDimitry Andric if (Token.isNewlineOrEOF()) // Allow an empty list of successors.
8310b57cec5SDimitry Andric return false;
8320b57cec5SDimitry Andric do {
8330b57cec5SDimitry Andric if (Token.isNot(MIToken::MachineBasicBlock))
8340b57cec5SDimitry Andric return error("expected a machine basic block reference");
8350b57cec5SDimitry Andric MachineBasicBlock *SuccMBB = nullptr;
8360b57cec5SDimitry Andric if (parseMBBReference(SuccMBB))
8370b57cec5SDimitry Andric return true;
8380b57cec5SDimitry Andric lex();
8390b57cec5SDimitry Andric unsigned Weight = 0;
8400b57cec5SDimitry Andric if (consumeIfPresent(MIToken::lparen)) {
8410b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) &&
8420b57cec5SDimitry Andric Token.isNot(MIToken::HexLiteral))
8430b57cec5SDimitry Andric return error("expected an integer literal after '('");
8440b57cec5SDimitry Andric if (getUnsigned(Weight))
8450b57cec5SDimitry Andric return true;
8460b57cec5SDimitry Andric lex();
8470b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
8480b57cec5SDimitry Andric return true;
8490b57cec5SDimitry Andric }
8500b57cec5SDimitry Andric MBB.addSuccessor(SuccMBB, BranchProbability::getRaw(Weight));
8510b57cec5SDimitry Andric } while (consumeIfPresent(MIToken::comma));
8520b57cec5SDimitry Andric MBB.normalizeSuccProbs();
8530b57cec5SDimitry Andric return false;
8540b57cec5SDimitry Andric }
8550b57cec5SDimitry Andric
parseBasicBlock(MachineBasicBlock & MBB,MachineBasicBlock * & AddFalthroughFrom)8560b57cec5SDimitry Andric bool MIParser::parseBasicBlock(MachineBasicBlock &MBB,
8570b57cec5SDimitry Andric MachineBasicBlock *&AddFalthroughFrom) {
8580b57cec5SDimitry Andric // Skip the definition.
8590b57cec5SDimitry Andric assert(Token.is(MIToken::MachineBasicBlockLabel));
8600b57cec5SDimitry Andric lex();
8610b57cec5SDimitry Andric if (consumeIfPresent(MIToken::lparen)) {
8620b57cec5SDimitry Andric while (Token.isNot(MIToken::rparen) && !Token.isErrorOrEOF())
8630b57cec5SDimitry Andric lex();
8640b57cec5SDimitry Andric consumeIfPresent(MIToken::rparen);
8650b57cec5SDimitry Andric }
8660b57cec5SDimitry Andric consumeIfPresent(MIToken::colon);
8670b57cec5SDimitry Andric
8680b57cec5SDimitry Andric // Parse the liveins and successors.
8690b57cec5SDimitry Andric // N.B: Multiple lists of successors and liveins are allowed and they're
8700b57cec5SDimitry Andric // merged into one.
8710b57cec5SDimitry Andric // Example:
8720b57cec5SDimitry Andric // liveins: %edi
8730b57cec5SDimitry Andric // liveins: %esi
8740b57cec5SDimitry Andric //
8750b57cec5SDimitry Andric // is equivalent to
8760b57cec5SDimitry Andric // liveins: %edi, %esi
8770b57cec5SDimitry Andric bool ExplicitSuccessors = false;
8780b57cec5SDimitry Andric while (true) {
8790b57cec5SDimitry Andric if (Token.is(MIToken::kw_successors)) {
8800b57cec5SDimitry Andric if (parseBasicBlockSuccessors(MBB))
8810b57cec5SDimitry Andric return true;
8820b57cec5SDimitry Andric ExplicitSuccessors = true;
8830b57cec5SDimitry Andric } else if (Token.is(MIToken::kw_liveins)) {
8840b57cec5SDimitry Andric if (parseBasicBlockLiveins(MBB))
8850b57cec5SDimitry Andric return true;
8860b57cec5SDimitry Andric } else if (consumeIfPresent(MIToken::Newline)) {
8870b57cec5SDimitry Andric continue;
8880b57cec5SDimitry Andric } else
8890b57cec5SDimitry Andric break;
8900b57cec5SDimitry Andric if (!Token.isNewlineOrEOF())
8910b57cec5SDimitry Andric return error("expected line break at the end of a list");
8920b57cec5SDimitry Andric lex();
8930b57cec5SDimitry Andric }
8940b57cec5SDimitry Andric
8950b57cec5SDimitry Andric // Parse the instructions.
8960b57cec5SDimitry Andric bool IsInBundle = false;
8970b57cec5SDimitry Andric MachineInstr *PrevMI = nullptr;
8980b57cec5SDimitry Andric while (!Token.is(MIToken::MachineBasicBlockLabel) &&
8990b57cec5SDimitry Andric !Token.is(MIToken::Eof)) {
9000b57cec5SDimitry Andric if (consumeIfPresent(MIToken::Newline))
9010b57cec5SDimitry Andric continue;
9020b57cec5SDimitry Andric if (consumeIfPresent(MIToken::rbrace)) {
9030b57cec5SDimitry Andric // The first parsing pass should verify that all closing '}' have an
9040b57cec5SDimitry Andric // opening '{'.
9050b57cec5SDimitry Andric assert(IsInBundle);
9060b57cec5SDimitry Andric IsInBundle = false;
9070b57cec5SDimitry Andric continue;
9080b57cec5SDimitry Andric }
9090b57cec5SDimitry Andric MachineInstr *MI = nullptr;
9100b57cec5SDimitry Andric if (parse(MI))
9110b57cec5SDimitry Andric return true;
9120b57cec5SDimitry Andric MBB.insert(MBB.end(), MI);
9130b57cec5SDimitry Andric if (IsInBundle) {
9140b57cec5SDimitry Andric PrevMI->setFlag(MachineInstr::BundledSucc);
9150b57cec5SDimitry Andric MI->setFlag(MachineInstr::BundledPred);
9160b57cec5SDimitry Andric }
9170b57cec5SDimitry Andric PrevMI = MI;
9180b57cec5SDimitry Andric if (Token.is(MIToken::lbrace)) {
9190b57cec5SDimitry Andric if (IsInBundle)
9200b57cec5SDimitry Andric return error("nested instruction bundles are not allowed");
9210b57cec5SDimitry Andric lex();
9220b57cec5SDimitry Andric // This instruction is the start of the bundle.
9230b57cec5SDimitry Andric MI->setFlag(MachineInstr::BundledSucc);
9240b57cec5SDimitry Andric IsInBundle = true;
9250b57cec5SDimitry Andric if (!Token.is(MIToken::Newline))
9260b57cec5SDimitry Andric // The next instruction can be on the same line.
9270b57cec5SDimitry Andric continue;
9280b57cec5SDimitry Andric }
9290b57cec5SDimitry Andric assert(Token.isNewlineOrEOF() && "MI is not fully parsed");
9300b57cec5SDimitry Andric lex();
9310b57cec5SDimitry Andric }
9320b57cec5SDimitry Andric
9330b57cec5SDimitry Andric // Construct successor list by searching for basic block machine operands.
9340b57cec5SDimitry Andric if (!ExplicitSuccessors) {
9350b57cec5SDimitry Andric SmallVector<MachineBasicBlock*,4> Successors;
9360b57cec5SDimitry Andric bool IsFallthrough;
9370b57cec5SDimitry Andric guessSuccessors(MBB, Successors, IsFallthrough);
9380b57cec5SDimitry Andric for (MachineBasicBlock *Succ : Successors)
9390b57cec5SDimitry Andric MBB.addSuccessor(Succ);
9400b57cec5SDimitry Andric
9410b57cec5SDimitry Andric if (IsFallthrough) {
9420b57cec5SDimitry Andric AddFalthroughFrom = &MBB;
9430b57cec5SDimitry Andric } else {
9440b57cec5SDimitry Andric MBB.normalizeSuccProbs();
9450b57cec5SDimitry Andric }
9460b57cec5SDimitry Andric }
9470b57cec5SDimitry Andric
9480b57cec5SDimitry Andric return false;
9490b57cec5SDimitry Andric }
9500b57cec5SDimitry Andric
parseBasicBlocks()9510b57cec5SDimitry Andric bool MIParser::parseBasicBlocks() {
9520b57cec5SDimitry Andric lex();
9530b57cec5SDimitry Andric // Skip until the first machine basic block.
9540b57cec5SDimitry Andric while (Token.is(MIToken::Newline))
9550b57cec5SDimitry Andric lex();
9560b57cec5SDimitry Andric if (Token.isErrorOrEOF())
9570b57cec5SDimitry Andric return Token.isError();
9580b57cec5SDimitry Andric // The first parsing pass should have verified that this token is a MBB label
9590b57cec5SDimitry Andric // in the 'parseBasicBlockDefinitions' method.
9600b57cec5SDimitry Andric assert(Token.is(MIToken::MachineBasicBlockLabel));
9610b57cec5SDimitry Andric MachineBasicBlock *AddFalthroughFrom = nullptr;
9620b57cec5SDimitry Andric do {
9630b57cec5SDimitry Andric MachineBasicBlock *MBB = nullptr;
9640b57cec5SDimitry Andric if (parseMBBReference(MBB))
9650b57cec5SDimitry Andric return true;
9660b57cec5SDimitry Andric if (AddFalthroughFrom) {
9670b57cec5SDimitry Andric if (!AddFalthroughFrom->isSuccessor(MBB))
9680b57cec5SDimitry Andric AddFalthroughFrom->addSuccessor(MBB);
9690b57cec5SDimitry Andric AddFalthroughFrom->normalizeSuccProbs();
9700b57cec5SDimitry Andric AddFalthroughFrom = nullptr;
9710b57cec5SDimitry Andric }
9720b57cec5SDimitry Andric if (parseBasicBlock(*MBB, AddFalthroughFrom))
9730b57cec5SDimitry Andric return true;
9740b57cec5SDimitry Andric // The method 'parseBasicBlock' should parse the whole block until the next
9750b57cec5SDimitry Andric // block or the end of file.
9760b57cec5SDimitry Andric assert(Token.is(MIToken::MachineBasicBlockLabel) || Token.is(MIToken::Eof));
9770b57cec5SDimitry Andric } while (Token.isNot(MIToken::Eof));
9780b57cec5SDimitry Andric return false;
9790b57cec5SDimitry Andric }
9800b57cec5SDimitry Andric
parse(MachineInstr * & MI)9810b57cec5SDimitry Andric bool MIParser::parse(MachineInstr *&MI) {
9820b57cec5SDimitry Andric // Parse any register operands before '='
9830b57cec5SDimitry Andric MachineOperand MO = MachineOperand::CreateImm(0);
9840b57cec5SDimitry Andric SmallVector<ParsedMachineOperand, 8> Operands;
9850b57cec5SDimitry Andric while (Token.isRegister() || Token.isRegisterFlag()) {
9860b57cec5SDimitry Andric auto Loc = Token.location();
9870b57cec5SDimitry Andric Optional<unsigned> TiedDefIdx;
9880b57cec5SDimitry Andric if (parseRegisterOperand(MO, TiedDefIdx, /*IsDef=*/true))
9890b57cec5SDimitry Andric return true;
9900b57cec5SDimitry Andric Operands.push_back(
9910b57cec5SDimitry Andric ParsedMachineOperand(MO, Loc, Token.location(), TiedDefIdx));
9920b57cec5SDimitry Andric if (Token.isNot(MIToken::comma))
9930b57cec5SDimitry Andric break;
9940b57cec5SDimitry Andric lex();
9950b57cec5SDimitry Andric }
9960b57cec5SDimitry Andric if (!Operands.empty() && expectAndConsume(MIToken::equal))
9970b57cec5SDimitry Andric return true;
9980b57cec5SDimitry Andric
9990b57cec5SDimitry Andric unsigned OpCode, Flags = 0;
10000b57cec5SDimitry Andric if (Token.isError() || parseInstruction(OpCode, Flags))
10010b57cec5SDimitry Andric return true;
10020b57cec5SDimitry Andric
10030b57cec5SDimitry Andric // Parse the remaining machine operands.
10040b57cec5SDimitry Andric while (!Token.isNewlineOrEOF() && Token.isNot(MIToken::kw_pre_instr_symbol) &&
10050b57cec5SDimitry Andric Token.isNot(MIToken::kw_post_instr_symbol) &&
1006480093f4SDimitry Andric Token.isNot(MIToken::kw_heap_alloc_marker) &&
10070b57cec5SDimitry Andric Token.isNot(MIToken::kw_debug_location) &&
1008af732203SDimitry Andric Token.isNot(MIToken::kw_debug_instr_number) &&
10090b57cec5SDimitry Andric Token.isNot(MIToken::coloncolon) && Token.isNot(MIToken::lbrace)) {
10100b57cec5SDimitry Andric auto Loc = Token.location();
10110b57cec5SDimitry Andric Optional<unsigned> TiedDefIdx;
1012480093f4SDimitry Andric if (parseMachineOperandAndTargetFlags(OpCode, Operands.size(), MO, TiedDefIdx))
10130b57cec5SDimitry Andric return true;
1014*5f7ddb14SDimitry Andric if ((OpCode == TargetOpcode::DBG_VALUE ||
1015*5f7ddb14SDimitry Andric OpCode == TargetOpcode::DBG_VALUE_LIST) &&
1016*5f7ddb14SDimitry Andric MO.isReg())
10170b57cec5SDimitry Andric MO.setIsDebug();
10180b57cec5SDimitry Andric Operands.push_back(
10190b57cec5SDimitry Andric ParsedMachineOperand(MO, Loc, Token.location(), TiedDefIdx));
10200b57cec5SDimitry Andric if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) ||
10210b57cec5SDimitry Andric Token.is(MIToken::lbrace))
10220b57cec5SDimitry Andric break;
10230b57cec5SDimitry Andric if (Token.isNot(MIToken::comma))
10240b57cec5SDimitry Andric return error("expected ',' before the next machine operand");
10250b57cec5SDimitry Andric lex();
10260b57cec5SDimitry Andric }
10270b57cec5SDimitry Andric
10280b57cec5SDimitry Andric MCSymbol *PreInstrSymbol = nullptr;
10290b57cec5SDimitry Andric if (Token.is(MIToken::kw_pre_instr_symbol))
10300b57cec5SDimitry Andric if (parsePreOrPostInstrSymbol(PreInstrSymbol))
10310b57cec5SDimitry Andric return true;
10320b57cec5SDimitry Andric MCSymbol *PostInstrSymbol = nullptr;
10330b57cec5SDimitry Andric if (Token.is(MIToken::kw_post_instr_symbol))
10340b57cec5SDimitry Andric if (parsePreOrPostInstrSymbol(PostInstrSymbol))
10350b57cec5SDimitry Andric return true;
1036480093f4SDimitry Andric MDNode *HeapAllocMarker = nullptr;
1037480093f4SDimitry Andric if (Token.is(MIToken::kw_heap_alloc_marker))
1038480093f4SDimitry Andric if (parseHeapAllocMarker(HeapAllocMarker))
1039480093f4SDimitry Andric return true;
10400b57cec5SDimitry Andric
1041af732203SDimitry Andric unsigned InstrNum = 0;
1042af732203SDimitry Andric if (Token.is(MIToken::kw_debug_instr_number)) {
1043af732203SDimitry Andric lex();
1044af732203SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral))
1045af732203SDimitry Andric return error("expected an integer literal after 'debug-instr-number'");
1046af732203SDimitry Andric if (getUnsigned(InstrNum))
1047af732203SDimitry Andric return true;
1048af732203SDimitry Andric lex();
1049af732203SDimitry Andric // Lex past trailing comma if present.
1050af732203SDimitry Andric if (Token.is(MIToken::comma))
1051af732203SDimitry Andric lex();
1052af732203SDimitry Andric }
1053af732203SDimitry Andric
10540b57cec5SDimitry Andric DebugLoc DebugLocation;
10550b57cec5SDimitry Andric if (Token.is(MIToken::kw_debug_location)) {
10560b57cec5SDimitry Andric lex();
10570b57cec5SDimitry Andric MDNode *Node = nullptr;
10580b57cec5SDimitry Andric if (Token.is(MIToken::exclaim)) {
10590b57cec5SDimitry Andric if (parseMDNode(Node))
10600b57cec5SDimitry Andric return true;
10610b57cec5SDimitry Andric } else if (Token.is(MIToken::md_dilocation)) {
10620b57cec5SDimitry Andric if (parseDILocation(Node))
10630b57cec5SDimitry Andric return true;
10640b57cec5SDimitry Andric } else
10650b57cec5SDimitry Andric return error("expected a metadata node after 'debug-location'");
10660b57cec5SDimitry Andric if (!isa<DILocation>(Node))
10670b57cec5SDimitry Andric return error("referenced metadata is not a DILocation");
10680b57cec5SDimitry Andric DebugLocation = DebugLoc(Node);
10690b57cec5SDimitry Andric }
10700b57cec5SDimitry Andric
10710b57cec5SDimitry Andric // Parse the machine memory operands.
10720b57cec5SDimitry Andric SmallVector<MachineMemOperand *, 2> MemOperands;
10730b57cec5SDimitry Andric if (Token.is(MIToken::coloncolon)) {
10740b57cec5SDimitry Andric lex();
10750b57cec5SDimitry Andric while (!Token.isNewlineOrEOF()) {
10760b57cec5SDimitry Andric MachineMemOperand *MemOp = nullptr;
10770b57cec5SDimitry Andric if (parseMachineMemoryOperand(MemOp))
10780b57cec5SDimitry Andric return true;
10790b57cec5SDimitry Andric MemOperands.push_back(MemOp);
10800b57cec5SDimitry Andric if (Token.isNewlineOrEOF())
10810b57cec5SDimitry Andric break;
10820b57cec5SDimitry Andric if (Token.isNot(MIToken::comma))
10830b57cec5SDimitry Andric return error("expected ',' before the next machine memory operand");
10840b57cec5SDimitry Andric lex();
10850b57cec5SDimitry Andric }
10860b57cec5SDimitry Andric }
10870b57cec5SDimitry Andric
10880b57cec5SDimitry Andric const auto &MCID = MF.getSubtarget().getInstrInfo()->get(OpCode);
10890b57cec5SDimitry Andric if (!MCID.isVariadic()) {
10900b57cec5SDimitry Andric // FIXME: Move the implicit operand verification to the machine verifier.
10910b57cec5SDimitry Andric if (verifyImplicitOperands(Operands, MCID))
10920b57cec5SDimitry Andric return true;
10930b57cec5SDimitry Andric }
10940b57cec5SDimitry Andric
10950b57cec5SDimitry Andric // TODO: Check for extraneous machine operands.
10960b57cec5SDimitry Andric MI = MF.CreateMachineInstr(MCID, DebugLocation, /*NoImplicit=*/true);
10970b57cec5SDimitry Andric MI->setFlags(Flags);
10980b57cec5SDimitry Andric for (const auto &Operand : Operands)
10990b57cec5SDimitry Andric MI->addOperand(MF, Operand.Operand);
11000b57cec5SDimitry Andric if (assignRegisterTies(*MI, Operands))
11010b57cec5SDimitry Andric return true;
11020b57cec5SDimitry Andric if (PreInstrSymbol)
11030b57cec5SDimitry Andric MI->setPreInstrSymbol(MF, PreInstrSymbol);
11040b57cec5SDimitry Andric if (PostInstrSymbol)
11050b57cec5SDimitry Andric MI->setPostInstrSymbol(MF, PostInstrSymbol);
1106480093f4SDimitry Andric if (HeapAllocMarker)
1107480093f4SDimitry Andric MI->setHeapAllocMarker(MF, HeapAllocMarker);
11080b57cec5SDimitry Andric if (!MemOperands.empty())
11090b57cec5SDimitry Andric MI->setMemRefs(MF, MemOperands);
1110af732203SDimitry Andric if (InstrNum)
1111af732203SDimitry Andric MI->setDebugInstrNum(InstrNum);
11120b57cec5SDimitry Andric return false;
11130b57cec5SDimitry Andric }
11140b57cec5SDimitry Andric
parseStandaloneMBB(MachineBasicBlock * & MBB)11150b57cec5SDimitry Andric bool MIParser::parseStandaloneMBB(MachineBasicBlock *&MBB) {
11160b57cec5SDimitry Andric lex();
11170b57cec5SDimitry Andric if (Token.isNot(MIToken::MachineBasicBlock))
11180b57cec5SDimitry Andric return error("expected a machine basic block reference");
11190b57cec5SDimitry Andric if (parseMBBReference(MBB))
11200b57cec5SDimitry Andric return true;
11210b57cec5SDimitry Andric lex();
11220b57cec5SDimitry Andric if (Token.isNot(MIToken::Eof))
11230b57cec5SDimitry Andric return error(
11240b57cec5SDimitry Andric "expected end of string after the machine basic block reference");
11250b57cec5SDimitry Andric return false;
11260b57cec5SDimitry Andric }
11270b57cec5SDimitry Andric
parseStandaloneNamedRegister(Register & Reg)11285ffd83dbSDimitry Andric bool MIParser::parseStandaloneNamedRegister(Register &Reg) {
11290b57cec5SDimitry Andric lex();
11300b57cec5SDimitry Andric if (Token.isNot(MIToken::NamedRegister))
11310b57cec5SDimitry Andric return error("expected a named register");
11320b57cec5SDimitry Andric if (parseNamedRegister(Reg))
11330b57cec5SDimitry Andric return true;
11340b57cec5SDimitry Andric lex();
11350b57cec5SDimitry Andric if (Token.isNot(MIToken::Eof))
11360b57cec5SDimitry Andric return error("expected end of string after the register reference");
11370b57cec5SDimitry Andric return false;
11380b57cec5SDimitry Andric }
11390b57cec5SDimitry Andric
parseStandaloneVirtualRegister(VRegInfo * & Info)11400b57cec5SDimitry Andric bool MIParser::parseStandaloneVirtualRegister(VRegInfo *&Info) {
11410b57cec5SDimitry Andric lex();
11420b57cec5SDimitry Andric if (Token.isNot(MIToken::VirtualRegister))
11430b57cec5SDimitry Andric return error("expected a virtual register");
11440b57cec5SDimitry Andric if (parseVirtualRegister(Info))
11450b57cec5SDimitry Andric return true;
11460b57cec5SDimitry Andric lex();
11470b57cec5SDimitry Andric if (Token.isNot(MIToken::Eof))
11480b57cec5SDimitry Andric return error("expected end of string after the register reference");
11490b57cec5SDimitry Andric return false;
11500b57cec5SDimitry Andric }
11510b57cec5SDimitry Andric
parseStandaloneRegister(Register & Reg)11525ffd83dbSDimitry Andric bool MIParser::parseStandaloneRegister(Register &Reg) {
11530b57cec5SDimitry Andric lex();
11540b57cec5SDimitry Andric if (Token.isNot(MIToken::NamedRegister) &&
11550b57cec5SDimitry Andric Token.isNot(MIToken::VirtualRegister))
11560b57cec5SDimitry Andric return error("expected either a named or virtual register");
11570b57cec5SDimitry Andric
11580b57cec5SDimitry Andric VRegInfo *Info;
11590b57cec5SDimitry Andric if (parseRegister(Reg, Info))
11600b57cec5SDimitry Andric return true;
11610b57cec5SDimitry Andric
11620b57cec5SDimitry Andric lex();
11630b57cec5SDimitry Andric if (Token.isNot(MIToken::Eof))
11640b57cec5SDimitry Andric return error("expected end of string after the register reference");
11650b57cec5SDimitry Andric return false;
11660b57cec5SDimitry Andric }
11670b57cec5SDimitry Andric
parseStandaloneStackObject(int & FI)11680b57cec5SDimitry Andric bool MIParser::parseStandaloneStackObject(int &FI) {
11690b57cec5SDimitry Andric lex();
11700b57cec5SDimitry Andric if (Token.isNot(MIToken::StackObject))
11710b57cec5SDimitry Andric return error("expected a stack object");
11720b57cec5SDimitry Andric if (parseStackFrameIndex(FI))
11730b57cec5SDimitry Andric return true;
11740b57cec5SDimitry Andric if (Token.isNot(MIToken::Eof))
11750b57cec5SDimitry Andric return error("expected end of string after the stack object reference");
11760b57cec5SDimitry Andric return false;
11770b57cec5SDimitry Andric }
11780b57cec5SDimitry Andric
parseStandaloneMDNode(MDNode * & Node)11790b57cec5SDimitry Andric bool MIParser::parseStandaloneMDNode(MDNode *&Node) {
11800b57cec5SDimitry Andric lex();
11810b57cec5SDimitry Andric if (Token.is(MIToken::exclaim)) {
11820b57cec5SDimitry Andric if (parseMDNode(Node))
11830b57cec5SDimitry Andric return true;
11840b57cec5SDimitry Andric } else if (Token.is(MIToken::md_diexpr)) {
11850b57cec5SDimitry Andric if (parseDIExpression(Node))
11860b57cec5SDimitry Andric return true;
11870b57cec5SDimitry Andric } else if (Token.is(MIToken::md_dilocation)) {
11880b57cec5SDimitry Andric if (parseDILocation(Node))
11890b57cec5SDimitry Andric return true;
11900b57cec5SDimitry Andric } else
11910b57cec5SDimitry Andric return error("expected a metadata node");
11920b57cec5SDimitry Andric if (Token.isNot(MIToken::Eof))
11930b57cec5SDimitry Andric return error("expected end of string after the metadata node");
11940b57cec5SDimitry Andric return false;
11950b57cec5SDimitry Andric }
11960b57cec5SDimitry Andric
parseMachineMetadata()1197*5f7ddb14SDimitry Andric bool MIParser::parseMachineMetadata() {
1198*5f7ddb14SDimitry Andric lex();
1199*5f7ddb14SDimitry Andric if (Token.isNot(MIToken::exclaim))
1200*5f7ddb14SDimitry Andric return error("expected a metadata node");
1201*5f7ddb14SDimitry Andric
1202*5f7ddb14SDimitry Andric lex();
1203*5f7ddb14SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned())
1204*5f7ddb14SDimitry Andric return error("expected metadata id after '!'");
1205*5f7ddb14SDimitry Andric unsigned ID = 0;
1206*5f7ddb14SDimitry Andric if (getUnsigned(ID))
1207*5f7ddb14SDimitry Andric return true;
1208*5f7ddb14SDimitry Andric lex();
1209*5f7ddb14SDimitry Andric if (expectAndConsume(MIToken::equal))
1210*5f7ddb14SDimitry Andric return true;
1211*5f7ddb14SDimitry Andric bool IsDistinct = Token.is(MIToken::kw_distinct);
1212*5f7ddb14SDimitry Andric if (IsDistinct)
1213*5f7ddb14SDimitry Andric lex();
1214*5f7ddb14SDimitry Andric if (Token.isNot(MIToken::exclaim))
1215*5f7ddb14SDimitry Andric return error("expected a metadata node");
1216*5f7ddb14SDimitry Andric lex();
1217*5f7ddb14SDimitry Andric
1218*5f7ddb14SDimitry Andric MDNode *MD;
1219*5f7ddb14SDimitry Andric if (parseMDTuple(MD, IsDistinct))
1220*5f7ddb14SDimitry Andric return true;
1221*5f7ddb14SDimitry Andric
1222*5f7ddb14SDimitry Andric auto FI = PFS.MachineForwardRefMDNodes.find(ID);
1223*5f7ddb14SDimitry Andric if (FI != PFS.MachineForwardRefMDNodes.end()) {
1224*5f7ddb14SDimitry Andric FI->second.first->replaceAllUsesWith(MD);
1225*5f7ddb14SDimitry Andric PFS.MachineForwardRefMDNodes.erase(FI);
1226*5f7ddb14SDimitry Andric
1227*5f7ddb14SDimitry Andric assert(PFS.MachineMetadataNodes[ID] == MD && "Tracking VH didn't work");
1228*5f7ddb14SDimitry Andric } else {
1229*5f7ddb14SDimitry Andric if (PFS.MachineMetadataNodes.count(ID))
1230*5f7ddb14SDimitry Andric return error("Metadata id is already used");
1231*5f7ddb14SDimitry Andric PFS.MachineMetadataNodes[ID].reset(MD);
1232*5f7ddb14SDimitry Andric }
1233*5f7ddb14SDimitry Andric
1234*5f7ddb14SDimitry Andric return false;
1235*5f7ddb14SDimitry Andric }
1236*5f7ddb14SDimitry Andric
parseMDTuple(MDNode * & MD,bool IsDistinct)1237*5f7ddb14SDimitry Andric bool MIParser::parseMDTuple(MDNode *&MD, bool IsDistinct) {
1238*5f7ddb14SDimitry Andric SmallVector<Metadata *, 16> Elts;
1239*5f7ddb14SDimitry Andric if (parseMDNodeVector(Elts))
1240*5f7ddb14SDimitry Andric return true;
1241*5f7ddb14SDimitry Andric MD = (IsDistinct ? MDTuple::getDistinct
1242*5f7ddb14SDimitry Andric : MDTuple::get)(MF.getFunction().getContext(), Elts);
1243*5f7ddb14SDimitry Andric return false;
1244*5f7ddb14SDimitry Andric }
1245*5f7ddb14SDimitry Andric
parseMDNodeVector(SmallVectorImpl<Metadata * > & Elts)1246*5f7ddb14SDimitry Andric bool MIParser::parseMDNodeVector(SmallVectorImpl<Metadata *> &Elts) {
1247*5f7ddb14SDimitry Andric if (Token.isNot(MIToken::lbrace))
1248*5f7ddb14SDimitry Andric return error("expected '{' here");
1249*5f7ddb14SDimitry Andric lex();
1250*5f7ddb14SDimitry Andric
1251*5f7ddb14SDimitry Andric if (Token.is(MIToken::rbrace)) {
1252*5f7ddb14SDimitry Andric lex();
1253*5f7ddb14SDimitry Andric return false;
1254*5f7ddb14SDimitry Andric }
1255*5f7ddb14SDimitry Andric
1256*5f7ddb14SDimitry Andric do {
1257*5f7ddb14SDimitry Andric Metadata *MD;
1258*5f7ddb14SDimitry Andric if (parseMetadata(MD))
1259*5f7ddb14SDimitry Andric return true;
1260*5f7ddb14SDimitry Andric
1261*5f7ddb14SDimitry Andric Elts.push_back(MD);
1262*5f7ddb14SDimitry Andric
1263*5f7ddb14SDimitry Andric if (Token.isNot(MIToken::comma))
1264*5f7ddb14SDimitry Andric break;
1265*5f7ddb14SDimitry Andric lex();
1266*5f7ddb14SDimitry Andric } while (true);
1267*5f7ddb14SDimitry Andric
1268*5f7ddb14SDimitry Andric if (Token.isNot(MIToken::rbrace))
1269*5f7ddb14SDimitry Andric return error("expected end of metadata node");
1270*5f7ddb14SDimitry Andric lex();
1271*5f7ddb14SDimitry Andric
1272*5f7ddb14SDimitry Andric return false;
1273*5f7ddb14SDimitry Andric }
1274*5f7ddb14SDimitry Andric
1275*5f7ddb14SDimitry Andric // ::= !42
1276*5f7ddb14SDimitry Andric // ::= !"string"
parseMetadata(Metadata * & MD)1277*5f7ddb14SDimitry Andric bool MIParser::parseMetadata(Metadata *&MD) {
1278*5f7ddb14SDimitry Andric if (Token.isNot(MIToken::exclaim))
1279*5f7ddb14SDimitry Andric return error("expected '!' here");
1280*5f7ddb14SDimitry Andric lex();
1281*5f7ddb14SDimitry Andric
1282*5f7ddb14SDimitry Andric if (Token.is(MIToken::StringConstant)) {
1283*5f7ddb14SDimitry Andric std::string Str;
1284*5f7ddb14SDimitry Andric if (parseStringConstant(Str))
1285*5f7ddb14SDimitry Andric return true;
1286*5f7ddb14SDimitry Andric MD = MDString::get(MF.getFunction().getContext(), Str);
1287*5f7ddb14SDimitry Andric return false;
1288*5f7ddb14SDimitry Andric }
1289*5f7ddb14SDimitry Andric
1290*5f7ddb14SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned())
1291*5f7ddb14SDimitry Andric return error("expected metadata id after '!'");
1292*5f7ddb14SDimitry Andric
1293*5f7ddb14SDimitry Andric SMLoc Loc = mapSMLoc(Token.location());
1294*5f7ddb14SDimitry Andric
1295*5f7ddb14SDimitry Andric unsigned ID = 0;
1296*5f7ddb14SDimitry Andric if (getUnsigned(ID))
1297*5f7ddb14SDimitry Andric return true;
1298*5f7ddb14SDimitry Andric lex();
1299*5f7ddb14SDimitry Andric
1300*5f7ddb14SDimitry Andric auto NodeInfo = PFS.IRSlots.MetadataNodes.find(ID);
1301*5f7ddb14SDimitry Andric if (NodeInfo != PFS.IRSlots.MetadataNodes.end()) {
1302*5f7ddb14SDimitry Andric MD = NodeInfo->second.get();
1303*5f7ddb14SDimitry Andric return false;
1304*5f7ddb14SDimitry Andric }
1305*5f7ddb14SDimitry Andric // Check machine metadata.
1306*5f7ddb14SDimitry Andric NodeInfo = PFS.MachineMetadataNodes.find(ID);
1307*5f7ddb14SDimitry Andric if (NodeInfo != PFS.MachineMetadataNodes.end()) {
1308*5f7ddb14SDimitry Andric MD = NodeInfo->second.get();
1309*5f7ddb14SDimitry Andric return false;
1310*5f7ddb14SDimitry Andric }
1311*5f7ddb14SDimitry Andric // Forward reference.
1312*5f7ddb14SDimitry Andric auto &FwdRef = PFS.MachineForwardRefMDNodes[ID];
1313*5f7ddb14SDimitry Andric FwdRef = std::make_pair(
1314*5f7ddb14SDimitry Andric MDTuple::getTemporary(MF.getFunction().getContext(), None), Loc);
1315*5f7ddb14SDimitry Andric PFS.MachineMetadataNodes[ID].reset(FwdRef.first.get());
1316*5f7ddb14SDimitry Andric MD = FwdRef.first.get();
1317*5f7ddb14SDimitry Andric
1318*5f7ddb14SDimitry Andric return false;
1319*5f7ddb14SDimitry Andric }
1320*5f7ddb14SDimitry Andric
printImplicitRegisterFlag(const MachineOperand & MO)13210b57cec5SDimitry Andric static const char *printImplicitRegisterFlag(const MachineOperand &MO) {
13220b57cec5SDimitry Andric assert(MO.isImplicit());
13230b57cec5SDimitry Andric return MO.isDef() ? "implicit-def" : "implicit";
13240b57cec5SDimitry Andric }
13250b57cec5SDimitry Andric
getRegisterName(const TargetRegisterInfo * TRI,Register Reg)13260b57cec5SDimitry Andric static std::string getRegisterName(const TargetRegisterInfo *TRI,
13275ffd83dbSDimitry Andric Register Reg) {
13288bcb0991SDimitry Andric assert(Register::isPhysicalRegister(Reg) && "expected phys reg");
13290b57cec5SDimitry Andric return StringRef(TRI->getName(Reg)).lower();
13300b57cec5SDimitry Andric }
13310b57cec5SDimitry Andric
13320b57cec5SDimitry Andric /// Return true if the parsed machine operands contain a given machine operand.
isImplicitOperandIn(const MachineOperand & ImplicitOperand,ArrayRef<ParsedMachineOperand> Operands)13330b57cec5SDimitry Andric static bool isImplicitOperandIn(const MachineOperand &ImplicitOperand,
13340b57cec5SDimitry Andric ArrayRef<ParsedMachineOperand> Operands) {
13350b57cec5SDimitry Andric for (const auto &I : Operands) {
13360b57cec5SDimitry Andric if (ImplicitOperand.isIdenticalTo(I.Operand))
13370b57cec5SDimitry Andric return true;
13380b57cec5SDimitry Andric }
13390b57cec5SDimitry Andric return false;
13400b57cec5SDimitry Andric }
13410b57cec5SDimitry Andric
verifyImplicitOperands(ArrayRef<ParsedMachineOperand> Operands,const MCInstrDesc & MCID)13420b57cec5SDimitry Andric bool MIParser::verifyImplicitOperands(ArrayRef<ParsedMachineOperand> Operands,
13430b57cec5SDimitry Andric const MCInstrDesc &MCID) {
13440b57cec5SDimitry Andric if (MCID.isCall())
13450b57cec5SDimitry Andric // We can't verify call instructions as they can contain arbitrary implicit
13460b57cec5SDimitry Andric // register and register mask operands.
13470b57cec5SDimitry Andric return false;
13480b57cec5SDimitry Andric
13490b57cec5SDimitry Andric // Gather all the expected implicit operands.
13500b57cec5SDimitry Andric SmallVector<MachineOperand, 4> ImplicitOperands;
13510b57cec5SDimitry Andric if (MCID.ImplicitDefs)
13520b57cec5SDimitry Andric for (const MCPhysReg *ImpDefs = MCID.getImplicitDefs(); *ImpDefs; ++ImpDefs)
13530b57cec5SDimitry Andric ImplicitOperands.push_back(
13540b57cec5SDimitry Andric MachineOperand::CreateReg(*ImpDefs, true, true));
13550b57cec5SDimitry Andric if (MCID.ImplicitUses)
13560b57cec5SDimitry Andric for (const MCPhysReg *ImpUses = MCID.getImplicitUses(); *ImpUses; ++ImpUses)
13570b57cec5SDimitry Andric ImplicitOperands.push_back(
13580b57cec5SDimitry Andric MachineOperand::CreateReg(*ImpUses, false, true));
13590b57cec5SDimitry Andric
13600b57cec5SDimitry Andric const auto *TRI = MF.getSubtarget().getRegisterInfo();
13610b57cec5SDimitry Andric assert(TRI && "Expected target register info");
13620b57cec5SDimitry Andric for (const auto &I : ImplicitOperands) {
13630b57cec5SDimitry Andric if (isImplicitOperandIn(I, Operands))
13640b57cec5SDimitry Andric continue;
13650b57cec5SDimitry Andric return error(Operands.empty() ? Token.location() : Operands.back().End,
13660b57cec5SDimitry Andric Twine("missing implicit register operand '") +
13670b57cec5SDimitry Andric printImplicitRegisterFlag(I) + " $" +
13680b57cec5SDimitry Andric getRegisterName(TRI, I.getReg()) + "'");
13690b57cec5SDimitry Andric }
13700b57cec5SDimitry Andric return false;
13710b57cec5SDimitry Andric }
13720b57cec5SDimitry Andric
parseInstruction(unsigned & OpCode,unsigned & Flags)13730b57cec5SDimitry Andric bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) {
13740b57cec5SDimitry Andric // Allow frame and fast math flags for OPCODE
13750b57cec5SDimitry Andric while (Token.is(MIToken::kw_frame_setup) ||
13760b57cec5SDimitry Andric Token.is(MIToken::kw_frame_destroy) ||
13770b57cec5SDimitry Andric Token.is(MIToken::kw_nnan) ||
13780b57cec5SDimitry Andric Token.is(MIToken::kw_ninf) ||
13790b57cec5SDimitry Andric Token.is(MIToken::kw_nsz) ||
13800b57cec5SDimitry Andric Token.is(MIToken::kw_arcp) ||
13810b57cec5SDimitry Andric Token.is(MIToken::kw_contract) ||
13820b57cec5SDimitry Andric Token.is(MIToken::kw_afn) ||
13830b57cec5SDimitry Andric Token.is(MIToken::kw_reassoc) ||
13840b57cec5SDimitry Andric Token.is(MIToken::kw_nuw) ||
13850b57cec5SDimitry Andric Token.is(MIToken::kw_nsw) ||
13860b57cec5SDimitry Andric Token.is(MIToken::kw_exact) ||
1387480093f4SDimitry Andric Token.is(MIToken::kw_nofpexcept)) {
13880b57cec5SDimitry Andric // Mine frame and fast math flags
13890b57cec5SDimitry Andric if (Token.is(MIToken::kw_frame_setup))
13900b57cec5SDimitry Andric Flags |= MachineInstr::FrameSetup;
13910b57cec5SDimitry Andric if (Token.is(MIToken::kw_frame_destroy))
13920b57cec5SDimitry Andric Flags |= MachineInstr::FrameDestroy;
13930b57cec5SDimitry Andric if (Token.is(MIToken::kw_nnan))
13940b57cec5SDimitry Andric Flags |= MachineInstr::FmNoNans;
13950b57cec5SDimitry Andric if (Token.is(MIToken::kw_ninf))
13960b57cec5SDimitry Andric Flags |= MachineInstr::FmNoInfs;
13970b57cec5SDimitry Andric if (Token.is(MIToken::kw_nsz))
13980b57cec5SDimitry Andric Flags |= MachineInstr::FmNsz;
13990b57cec5SDimitry Andric if (Token.is(MIToken::kw_arcp))
14000b57cec5SDimitry Andric Flags |= MachineInstr::FmArcp;
14010b57cec5SDimitry Andric if (Token.is(MIToken::kw_contract))
14020b57cec5SDimitry Andric Flags |= MachineInstr::FmContract;
14030b57cec5SDimitry Andric if (Token.is(MIToken::kw_afn))
14040b57cec5SDimitry Andric Flags |= MachineInstr::FmAfn;
14050b57cec5SDimitry Andric if (Token.is(MIToken::kw_reassoc))
14060b57cec5SDimitry Andric Flags |= MachineInstr::FmReassoc;
14070b57cec5SDimitry Andric if (Token.is(MIToken::kw_nuw))
14080b57cec5SDimitry Andric Flags |= MachineInstr::NoUWrap;
14090b57cec5SDimitry Andric if (Token.is(MIToken::kw_nsw))
14100b57cec5SDimitry Andric Flags |= MachineInstr::NoSWrap;
14110b57cec5SDimitry Andric if (Token.is(MIToken::kw_exact))
14120b57cec5SDimitry Andric Flags |= MachineInstr::IsExact;
1413480093f4SDimitry Andric if (Token.is(MIToken::kw_nofpexcept))
1414480093f4SDimitry Andric Flags |= MachineInstr::NoFPExcept;
14150b57cec5SDimitry Andric
14160b57cec5SDimitry Andric lex();
14170b57cec5SDimitry Andric }
14180b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier))
14190b57cec5SDimitry Andric return error("expected a machine instruction");
14200b57cec5SDimitry Andric StringRef InstrName = Token.stringValue();
14210b57cec5SDimitry Andric if (PFS.Target.parseInstrName(InstrName, OpCode))
14220b57cec5SDimitry Andric return error(Twine("unknown machine instruction name '") + InstrName + "'");
14230b57cec5SDimitry Andric lex();
14240b57cec5SDimitry Andric return false;
14250b57cec5SDimitry Andric }
14260b57cec5SDimitry Andric
parseNamedRegister(Register & Reg)14275ffd83dbSDimitry Andric bool MIParser::parseNamedRegister(Register &Reg) {
14280b57cec5SDimitry Andric assert(Token.is(MIToken::NamedRegister) && "Needs NamedRegister token");
14290b57cec5SDimitry Andric StringRef Name = Token.stringValue();
14300b57cec5SDimitry Andric if (PFS.Target.getRegisterByName(Name, Reg))
14310b57cec5SDimitry Andric return error(Twine("unknown register name '") + Name + "'");
14320b57cec5SDimitry Andric return false;
14330b57cec5SDimitry Andric }
14340b57cec5SDimitry Andric
parseNamedVirtualRegister(VRegInfo * & Info)14350b57cec5SDimitry Andric bool MIParser::parseNamedVirtualRegister(VRegInfo *&Info) {
14360b57cec5SDimitry Andric assert(Token.is(MIToken::NamedVirtualRegister) && "Expected NamedVReg token");
14370b57cec5SDimitry Andric StringRef Name = Token.stringValue();
14380b57cec5SDimitry Andric // TODO: Check that the VReg name is not the same as a physical register name.
14390b57cec5SDimitry Andric // If it is, then print a warning (when warnings are implemented).
14400b57cec5SDimitry Andric Info = &PFS.getVRegInfoNamed(Name);
14410b57cec5SDimitry Andric return false;
14420b57cec5SDimitry Andric }
14430b57cec5SDimitry Andric
parseVirtualRegister(VRegInfo * & Info)14440b57cec5SDimitry Andric bool MIParser::parseVirtualRegister(VRegInfo *&Info) {
14450b57cec5SDimitry Andric if (Token.is(MIToken::NamedVirtualRegister))
14460b57cec5SDimitry Andric return parseNamedVirtualRegister(Info);
14470b57cec5SDimitry Andric assert(Token.is(MIToken::VirtualRegister) && "Needs VirtualRegister token");
14480b57cec5SDimitry Andric unsigned ID;
14490b57cec5SDimitry Andric if (getUnsigned(ID))
14500b57cec5SDimitry Andric return true;
14510b57cec5SDimitry Andric Info = &PFS.getVRegInfo(ID);
14520b57cec5SDimitry Andric return false;
14530b57cec5SDimitry Andric }
14540b57cec5SDimitry Andric
parseRegister(Register & Reg,VRegInfo * & Info)14555ffd83dbSDimitry Andric bool MIParser::parseRegister(Register &Reg, VRegInfo *&Info) {
14560b57cec5SDimitry Andric switch (Token.kind()) {
14570b57cec5SDimitry Andric case MIToken::underscore:
14580b57cec5SDimitry Andric Reg = 0;
14590b57cec5SDimitry Andric return false;
14600b57cec5SDimitry Andric case MIToken::NamedRegister:
14610b57cec5SDimitry Andric return parseNamedRegister(Reg);
14620b57cec5SDimitry Andric case MIToken::NamedVirtualRegister:
14630b57cec5SDimitry Andric case MIToken::VirtualRegister:
14640b57cec5SDimitry Andric if (parseVirtualRegister(Info))
14650b57cec5SDimitry Andric return true;
14660b57cec5SDimitry Andric Reg = Info->VReg;
14670b57cec5SDimitry Andric return false;
14680b57cec5SDimitry Andric // TODO: Parse other register kinds.
14690b57cec5SDimitry Andric default:
14700b57cec5SDimitry Andric llvm_unreachable("The current token should be a register");
14710b57cec5SDimitry Andric }
14720b57cec5SDimitry Andric }
14730b57cec5SDimitry Andric
parseRegisterClassOrBank(VRegInfo & RegInfo)14740b57cec5SDimitry Andric bool MIParser::parseRegisterClassOrBank(VRegInfo &RegInfo) {
14750b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier) && Token.isNot(MIToken::underscore))
14760b57cec5SDimitry Andric return error("expected '_', register class, or register bank name");
14770b57cec5SDimitry Andric StringRef::iterator Loc = Token.location();
14780b57cec5SDimitry Andric StringRef Name = Token.stringValue();
14790b57cec5SDimitry Andric
14800b57cec5SDimitry Andric // Was it a register class?
14810b57cec5SDimitry Andric const TargetRegisterClass *RC = PFS.Target.getRegClass(Name);
14820b57cec5SDimitry Andric if (RC) {
14830b57cec5SDimitry Andric lex();
14840b57cec5SDimitry Andric
14850b57cec5SDimitry Andric switch (RegInfo.Kind) {
14860b57cec5SDimitry Andric case VRegInfo::UNKNOWN:
14870b57cec5SDimitry Andric case VRegInfo::NORMAL:
14880b57cec5SDimitry Andric RegInfo.Kind = VRegInfo::NORMAL;
14890b57cec5SDimitry Andric if (RegInfo.Explicit && RegInfo.D.RC != RC) {
14900b57cec5SDimitry Andric const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
14910b57cec5SDimitry Andric return error(Loc, Twine("conflicting register classes, previously: ") +
14920b57cec5SDimitry Andric Twine(TRI.getRegClassName(RegInfo.D.RC)));
14930b57cec5SDimitry Andric }
14940b57cec5SDimitry Andric RegInfo.D.RC = RC;
14950b57cec5SDimitry Andric RegInfo.Explicit = true;
14960b57cec5SDimitry Andric return false;
14970b57cec5SDimitry Andric
14980b57cec5SDimitry Andric case VRegInfo::GENERIC:
14990b57cec5SDimitry Andric case VRegInfo::REGBANK:
15000b57cec5SDimitry Andric return error(Loc, "register class specification on generic register");
15010b57cec5SDimitry Andric }
15020b57cec5SDimitry Andric llvm_unreachable("Unexpected register kind");
15030b57cec5SDimitry Andric }
15040b57cec5SDimitry Andric
15050b57cec5SDimitry Andric // Should be a register bank or a generic register.
15060b57cec5SDimitry Andric const RegisterBank *RegBank = nullptr;
15070b57cec5SDimitry Andric if (Name != "_") {
15080b57cec5SDimitry Andric RegBank = PFS.Target.getRegBank(Name);
15090b57cec5SDimitry Andric if (!RegBank)
15100b57cec5SDimitry Andric return error(Loc, "expected '_', register class, or register bank name");
15110b57cec5SDimitry Andric }
15120b57cec5SDimitry Andric
15130b57cec5SDimitry Andric lex();
15140b57cec5SDimitry Andric
15150b57cec5SDimitry Andric switch (RegInfo.Kind) {
15160b57cec5SDimitry Andric case VRegInfo::UNKNOWN:
15170b57cec5SDimitry Andric case VRegInfo::GENERIC:
15180b57cec5SDimitry Andric case VRegInfo::REGBANK:
15190b57cec5SDimitry Andric RegInfo.Kind = RegBank ? VRegInfo::REGBANK : VRegInfo::GENERIC;
15200b57cec5SDimitry Andric if (RegInfo.Explicit && RegInfo.D.RegBank != RegBank)
15210b57cec5SDimitry Andric return error(Loc, "conflicting generic register banks");
15220b57cec5SDimitry Andric RegInfo.D.RegBank = RegBank;
15230b57cec5SDimitry Andric RegInfo.Explicit = true;
15240b57cec5SDimitry Andric return false;
15250b57cec5SDimitry Andric
15260b57cec5SDimitry Andric case VRegInfo::NORMAL:
15270b57cec5SDimitry Andric return error(Loc, "register bank specification on normal register");
15280b57cec5SDimitry Andric }
15290b57cec5SDimitry Andric llvm_unreachable("Unexpected register kind");
15300b57cec5SDimitry Andric }
15310b57cec5SDimitry Andric
parseRegisterFlag(unsigned & Flags)15320b57cec5SDimitry Andric bool MIParser::parseRegisterFlag(unsigned &Flags) {
15330b57cec5SDimitry Andric const unsigned OldFlags = Flags;
15340b57cec5SDimitry Andric switch (Token.kind()) {
15350b57cec5SDimitry Andric case MIToken::kw_implicit:
15360b57cec5SDimitry Andric Flags |= RegState::Implicit;
15370b57cec5SDimitry Andric break;
15380b57cec5SDimitry Andric case MIToken::kw_implicit_define:
15390b57cec5SDimitry Andric Flags |= RegState::ImplicitDefine;
15400b57cec5SDimitry Andric break;
15410b57cec5SDimitry Andric case MIToken::kw_def:
15420b57cec5SDimitry Andric Flags |= RegState::Define;
15430b57cec5SDimitry Andric break;
15440b57cec5SDimitry Andric case MIToken::kw_dead:
15450b57cec5SDimitry Andric Flags |= RegState::Dead;
15460b57cec5SDimitry Andric break;
15470b57cec5SDimitry Andric case MIToken::kw_killed:
15480b57cec5SDimitry Andric Flags |= RegState::Kill;
15490b57cec5SDimitry Andric break;
15500b57cec5SDimitry Andric case MIToken::kw_undef:
15510b57cec5SDimitry Andric Flags |= RegState::Undef;
15520b57cec5SDimitry Andric break;
15530b57cec5SDimitry Andric case MIToken::kw_internal:
15540b57cec5SDimitry Andric Flags |= RegState::InternalRead;
15550b57cec5SDimitry Andric break;
15560b57cec5SDimitry Andric case MIToken::kw_early_clobber:
15570b57cec5SDimitry Andric Flags |= RegState::EarlyClobber;
15580b57cec5SDimitry Andric break;
15590b57cec5SDimitry Andric case MIToken::kw_debug_use:
15600b57cec5SDimitry Andric Flags |= RegState::Debug;
15610b57cec5SDimitry Andric break;
15620b57cec5SDimitry Andric case MIToken::kw_renamable:
15630b57cec5SDimitry Andric Flags |= RegState::Renamable;
15640b57cec5SDimitry Andric break;
15650b57cec5SDimitry Andric default:
15660b57cec5SDimitry Andric llvm_unreachable("The current token should be a register flag");
15670b57cec5SDimitry Andric }
15680b57cec5SDimitry Andric if (OldFlags == Flags)
15690b57cec5SDimitry Andric // We know that the same flag is specified more than once when the flags
15700b57cec5SDimitry Andric // weren't modified.
15710b57cec5SDimitry Andric return error("duplicate '" + Token.stringValue() + "' register flag");
15720b57cec5SDimitry Andric lex();
15730b57cec5SDimitry Andric return false;
15740b57cec5SDimitry Andric }
15750b57cec5SDimitry Andric
parseSubRegisterIndex(unsigned & SubReg)15760b57cec5SDimitry Andric bool MIParser::parseSubRegisterIndex(unsigned &SubReg) {
15770b57cec5SDimitry Andric assert(Token.is(MIToken::dot));
15780b57cec5SDimitry Andric lex();
15790b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier))
15800b57cec5SDimitry Andric return error("expected a subregister index after '.'");
15810b57cec5SDimitry Andric auto Name = Token.stringValue();
15820b57cec5SDimitry Andric SubReg = PFS.Target.getSubRegIndex(Name);
15830b57cec5SDimitry Andric if (!SubReg)
15840b57cec5SDimitry Andric return error(Twine("use of unknown subregister index '") + Name + "'");
15850b57cec5SDimitry Andric lex();
15860b57cec5SDimitry Andric return false;
15870b57cec5SDimitry Andric }
15880b57cec5SDimitry Andric
parseRegisterTiedDefIndex(unsigned & TiedDefIdx)15890b57cec5SDimitry Andric bool MIParser::parseRegisterTiedDefIndex(unsigned &TiedDefIdx) {
15900b57cec5SDimitry Andric if (!consumeIfPresent(MIToken::kw_tied_def))
15910b57cec5SDimitry Andric return true;
15920b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral))
15930b57cec5SDimitry Andric return error("expected an integer literal after 'tied-def'");
15940b57cec5SDimitry Andric if (getUnsigned(TiedDefIdx))
15950b57cec5SDimitry Andric return true;
15960b57cec5SDimitry Andric lex();
15970b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
15980b57cec5SDimitry Andric return true;
15990b57cec5SDimitry Andric return false;
16000b57cec5SDimitry Andric }
16010b57cec5SDimitry Andric
assignRegisterTies(MachineInstr & MI,ArrayRef<ParsedMachineOperand> Operands)16020b57cec5SDimitry Andric bool MIParser::assignRegisterTies(MachineInstr &MI,
16030b57cec5SDimitry Andric ArrayRef<ParsedMachineOperand> Operands) {
16040b57cec5SDimitry Andric SmallVector<std::pair<unsigned, unsigned>, 4> TiedRegisterPairs;
16050b57cec5SDimitry Andric for (unsigned I = 0, E = Operands.size(); I != E; ++I) {
16060b57cec5SDimitry Andric if (!Operands[I].TiedDefIdx)
16070b57cec5SDimitry Andric continue;
16080b57cec5SDimitry Andric // The parser ensures that this operand is a register use, so we just have
16090b57cec5SDimitry Andric // to check the tied-def operand.
16100b57cec5SDimitry Andric unsigned DefIdx = Operands[I].TiedDefIdx.getValue();
16110b57cec5SDimitry Andric if (DefIdx >= E)
16120b57cec5SDimitry Andric return error(Operands[I].Begin,
16130b57cec5SDimitry Andric Twine("use of invalid tied-def operand index '" +
16140b57cec5SDimitry Andric Twine(DefIdx) + "'; instruction has only ") +
16150b57cec5SDimitry Andric Twine(E) + " operands");
16160b57cec5SDimitry Andric const auto &DefOperand = Operands[DefIdx].Operand;
16170b57cec5SDimitry Andric if (!DefOperand.isReg() || !DefOperand.isDef())
16180b57cec5SDimitry Andric // FIXME: add note with the def operand.
16190b57cec5SDimitry Andric return error(Operands[I].Begin,
16200b57cec5SDimitry Andric Twine("use of invalid tied-def operand index '") +
16210b57cec5SDimitry Andric Twine(DefIdx) + "'; the operand #" + Twine(DefIdx) +
16220b57cec5SDimitry Andric " isn't a defined register");
16230b57cec5SDimitry Andric // Check that the tied-def operand wasn't tied elsewhere.
16240b57cec5SDimitry Andric for (const auto &TiedPair : TiedRegisterPairs) {
16250b57cec5SDimitry Andric if (TiedPair.first == DefIdx)
16260b57cec5SDimitry Andric return error(Operands[I].Begin,
16270b57cec5SDimitry Andric Twine("the tied-def operand #") + Twine(DefIdx) +
16280b57cec5SDimitry Andric " is already tied with another register operand");
16290b57cec5SDimitry Andric }
16300b57cec5SDimitry Andric TiedRegisterPairs.push_back(std::make_pair(DefIdx, I));
16310b57cec5SDimitry Andric }
16320b57cec5SDimitry Andric // FIXME: Verify that for non INLINEASM instructions, the def and use tied
16330b57cec5SDimitry Andric // indices must be less than tied max.
16340b57cec5SDimitry Andric for (const auto &TiedPair : TiedRegisterPairs)
16350b57cec5SDimitry Andric MI.tieOperands(TiedPair.first, TiedPair.second);
16360b57cec5SDimitry Andric return false;
16370b57cec5SDimitry Andric }
16380b57cec5SDimitry Andric
parseRegisterOperand(MachineOperand & Dest,Optional<unsigned> & TiedDefIdx,bool IsDef)16390b57cec5SDimitry Andric bool MIParser::parseRegisterOperand(MachineOperand &Dest,
16400b57cec5SDimitry Andric Optional<unsigned> &TiedDefIdx,
16410b57cec5SDimitry Andric bool IsDef) {
16420b57cec5SDimitry Andric unsigned Flags = IsDef ? RegState::Define : 0;
16430b57cec5SDimitry Andric while (Token.isRegisterFlag()) {
16440b57cec5SDimitry Andric if (parseRegisterFlag(Flags))
16450b57cec5SDimitry Andric return true;
16460b57cec5SDimitry Andric }
16470b57cec5SDimitry Andric if (!Token.isRegister())
16480b57cec5SDimitry Andric return error("expected a register after register flags");
16495ffd83dbSDimitry Andric Register Reg;
16500b57cec5SDimitry Andric VRegInfo *RegInfo;
16510b57cec5SDimitry Andric if (parseRegister(Reg, RegInfo))
16520b57cec5SDimitry Andric return true;
16530b57cec5SDimitry Andric lex();
16540b57cec5SDimitry Andric unsigned SubReg = 0;
16550b57cec5SDimitry Andric if (Token.is(MIToken::dot)) {
16560b57cec5SDimitry Andric if (parseSubRegisterIndex(SubReg))
16570b57cec5SDimitry Andric return true;
16588bcb0991SDimitry Andric if (!Register::isVirtualRegister(Reg))
16590b57cec5SDimitry Andric return error("subregister index expects a virtual register");
16600b57cec5SDimitry Andric }
16610b57cec5SDimitry Andric if (Token.is(MIToken::colon)) {
16628bcb0991SDimitry Andric if (!Register::isVirtualRegister(Reg))
16630b57cec5SDimitry Andric return error("register class specification expects a virtual register");
16640b57cec5SDimitry Andric lex();
16650b57cec5SDimitry Andric if (parseRegisterClassOrBank(*RegInfo))
16660b57cec5SDimitry Andric return true;
16670b57cec5SDimitry Andric }
16680b57cec5SDimitry Andric MachineRegisterInfo &MRI = MF.getRegInfo();
16690b57cec5SDimitry Andric if ((Flags & RegState::Define) == 0) {
16700b57cec5SDimitry Andric if (consumeIfPresent(MIToken::lparen)) {
16710b57cec5SDimitry Andric unsigned Idx;
16720b57cec5SDimitry Andric if (!parseRegisterTiedDefIndex(Idx))
16730b57cec5SDimitry Andric TiedDefIdx = Idx;
16740b57cec5SDimitry Andric else {
16750b57cec5SDimitry Andric // Try a redundant low-level type.
16760b57cec5SDimitry Andric LLT Ty;
16770b57cec5SDimitry Andric if (parseLowLevelType(Token.location(), Ty))
16780b57cec5SDimitry Andric return error("expected tied-def or low-level type after '('");
16790b57cec5SDimitry Andric
16800b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
16810b57cec5SDimitry Andric return true;
16820b57cec5SDimitry Andric
16830b57cec5SDimitry Andric if (MRI.getType(Reg).isValid() && MRI.getType(Reg) != Ty)
16840b57cec5SDimitry Andric return error("inconsistent type for generic virtual register");
16850b57cec5SDimitry Andric
16868bcb0991SDimitry Andric MRI.setRegClassOrRegBank(Reg, static_cast<RegisterBank *>(nullptr));
16870b57cec5SDimitry Andric MRI.setType(Reg, Ty);
16880b57cec5SDimitry Andric }
16890b57cec5SDimitry Andric }
16900b57cec5SDimitry Andric } else if (consumeIfPresent(MIToken::lparen)) {
16910b57cec5SDimitry Andric // Virtual registers may have a tpe with GlobalISel.
16928bcb0991SDimitry Andric if (!Register::isVirtualRegister(Reg))
16930b57cec5SDimitry Andric return error("unexpected type on physical register");
16940b57cec5SDimitry Andric
16950b57cec5SDimitry Andric LLT Ty;
16960b57cec5SDimitry Andric if (parseLowLevelType(Token.location(), Ty))
16970b57cec5SDimitry Andric return true;
16980b57cec5SDimitry Andric
16990b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
17000b57cec5SDimitry Andric return true;
17010b57cec5SDimitry Andric
17020b57cec5SDimitry Andric if (MRI.getType(Reg).isValid() && MRI.getType(Reg) != Ty)
17030b57cec5SDimitry Andric return error("inconsistent type for generic virtual register");
17040b57cec5SDimitry Andric
17058bcb0991SDimitry Andric MRI.setRegClassOrRegBank(Reg, static_cast<RegisterBank *>(nullptr));
17060b57cec5SDimitry Andric MRI.setType(Reg, Ty);
17078bcb0991SDimitry Andric } else if (Register::isVirtualRegister(Reg)) {
17080b57cec5SDimitry Andric // Generic virtual registers must have a type.
17090b57cec5SDimitry Andric // If we end up here this means the type hasn't been specified and
17100b57cec5SDimitry Andric // this is bad!
17110b57cec5SDimitry Andric if (RegInfo->Kind == VRegInfo::GENERIC ||
17120b57cec5SDimitry Andric RegInfo->Kind == VRegInfo::REGBANK)
17130b57cec5SDimitry Andric return error("generic virtual registers must have a type");
17140b57cec5SDimitry Andric }
17150b57cec5SDimitry Andric Dest = MachineOperand::CreateReg(
17160b57cec5SDimitry Andric Reg, Flags & RegState::Define, Flags & RegState::Implicit,
17170b57cec5SDimitry Andric Flags & RegState::Kill, Flags & RegState::Dead, Flags & RegState::Undef,
17180b57cec5SDimitry Andric Flags & RegState::EarlyClobber, SubReg, Flags & RegState::Debug,
17190b57cec5SDimitry Andric Flags & RegState::InternalRead, Flags & RegState::Renamable);
17200b57cec5SDimitry Andric
17210b57cec5SDimitry Andric return false;
17220b57cec5SDimitry Andric }
17230b57cec5SDimitry Andric
parseImmediateOperand(MachineOperand & Dest)17240b57cec5SDimitry Andric bool MIParser::parseImmediateOperand(MachineOperand &Dest) {
17250b57cec5SDimitry Andric assert(Token.is(MIToken::IntegerLiteral));
17260b57cec5SDimitry Andric const APSInt &Int = Token.integerValue();
17270b57cec5SDimitry Andric if (Int.getMinSignedBits() > 64)
17280b57cec5SDimitry Andric return error("integer literal is too large to be an immediate operand");
17290b57cec5SDimitry Andric Dest = MachineOperand::CreateImm(Int.getExtValue());
17300b57cec5SDimitry Andric lex();
17310b57cec5SDimitry Andric return false;
17320b57cec5SDimitry Andric }
17330b57cec5SDimitry Andric
parseTargetImmMnemonic(const unsigned OpCode,const unsigned OpIdx,MachineOperand & Dest,const MIRFormatter & MF)1734480093f4SDimitry Andric bool MIParser::parseTargetImmMnemonic(const unsigned OpCode,
1735480093f4SDimitry Andric const unsigned OpIdx,
1736480093f4SDimitry Andric MachineOperand &Dest,
1737480093f4SDimitry Andric const MIRFormatter &MF) {
1738480093f4SDimitry Andric assert(Token.is(MIToken::dot));
1739480093f4SDimitry Andric auto Loc = Token.location(); // record start position
1740480093f4SDimitry Andric size_t Len = 1; // for "."
1741480093f4SDimitry Andric lex();
1742480093f4SDimitry Andric
1743480093f4SDimitry Andric // Handle the case that mnemonic starts with number.
1744480093f4SDimitry Andric if (Token.is(MIToken::IntegerLiteral)) {
1745480093f4SDimitry Andric Len += Token.range().size();
1746480093f4SDimitry Andric lex();
1747480093f4SDimitry Andric }
1748480093f4SDimitry Andric
1749480093f4SDimitry Andric StringRef Src;
1750480093f4SDimitry Andric if (Token.is(MIToken::comma))
1751480093f4SDimitry Andric Src = StringRef(Loc, Len);
1752480093f4SDimitry Andric else {
1753480093f4SDimitry Andric assert(Token.is(MIToken::Identifier));
1754480093f4SDimitry Andric Src = StringRef(Loc, Len + Token.stringValue().size());
1755480093f4SDimitry Andric }
1756480093f4SDimitry Andric int64_t Val;
1757480093f4SDimitry Andric if (MF.parseImmMnemonic(OpCode, OpIdx, Src, Val,
1758480093f4SDimitry Andric [this](StringRef::iterator Loc, const Twine &Msg)
1759480093f4SDimitry Andric -> bool { return error(Loc, Msg); }))
1760480093f4SDimitry Andric return true;
1761480093f4SDimitry Andric
1762480093f4SDimitry Andric Dest = MachineOperand::CreateImm(Val);
1763480093f4SDimitry Andric if (!Token.is(MIToken::comma))
1764480093f4SDimitry Andric lex();
1765480093f4SDimitry Andric return false;
1766480093f4SDimitry Andric }
1767480093f4SDimitry Andric
parseIRConstant(StringRef::iterator Loc,StringRef StringValue,PerFunctionMIParsingState & PFS,const Constant * & C,ErrorCallbackType ErrCB)1768480093f4SDimitry Andric static bool parseIRConstant(StringRef::iterator Loc, StringRef StringValue,
1769480093f4SDimitry Andric PerFunctionMIParsingState &PFS, const Constant *&C,
1770480093f4SDimitry Andric ErrorCallbackType ErrCB) {
17710b57cec5SDimitry Andric auto Source = StringValue.str(); // The source has to be null terminated.
17720b57cec5SDimitry Andric SMDiagnostic Err;
1773480093f4SDimitry Andric C = parseConstantValue(Source, Err, *PFS.MF.getFunction().getParent(),
17740b57cec5SDimitry Andric &PFS.IRSlots);
17750b57cec5SDimitry Andric if (!C)
1776480093f4SDimitry Andric return ErrCB(Loc + Err.getColumnNo(), Err.getMessage());
17770b57cec5SDimitry Andric return false;
17780b57cec5SDimitry Andric }
17790b57cec5SDimitry Andric
parseIRConstant(StringRef::iterator Loc,StringRef StringValue,const Constant * & C)1780480093f4SDimitry Andric bool MIParser::parseIRConstant(StringRef::iterator Loc, StringRef StringValue,
1781480093f4SDimitry Andric const Constant *&C) {
1782480093f4SDimitry Andric return ::parseIRConstant(
1783480093f4SDimitry Andric Loc, StringValue, PFS, C,
1784480093f4SDimitry Andric [this](StringRef::iterator Loc, const Twine &Msg) -> bool {
1785480093f4SDimitry Andric return error(Loc, Msg);
1786480093f4SDimitry Andric });
1787480093f4SDimitry Andric }
1788480093f4SDimitry Andric
parseIRConstant(StringRef::iterator Loc,const Constant * & C)17890b57cec5SDimitry Andric bool MIParser::parseIRConstant(StringRef::iterator Loc, const Constant *&C) {
17900b57cec5SDimitry Andric if (parseIRConstant(Loc, StringRef(Loc, Token.range().end() - Loc), C))
17910b57cec5SDimitry Andric return true;
17920b57cec5SDimitry Andric lex();
17930b57cec5SDimitry Andric return false;
17940b57cec5SDimitry Andric }
17950b57cec5SDimitry Andric
17960b57cec5SDimitry Andric // See LLT implemntation for bit size limits.
verifyScalarSize(uint64_t Size)17970b57cec5SDimitry Andric static bool verifyScalarSize(uint64_t Size) {
17980b57cec5SDimitry Andric return Size != 0 && isUInt<16>(Size);
17990b57cec5SDimitry Andric }
18000b57cec5SDimitry Andric
verifyVectorElementCount(uint64_t NumElts)18010b57cec5SDimitry Andric static bool verifyVectorElementCount(uint64_t NumElts) {
18020b57cec5SDimitry Andric return NumElts != 0 && isUInt<16>(NumElts);
18030b57cec5SDimitry Andric }
18040b57cec5SDimitry Andric
verifyAddrSpace(uint64_t AddrSpace)18050b57cec5SDimitry Andric static bool verifyAddrSpace(uint64_t AddrSpace) {
18060b57cec5SDimitry Andric return isUInt<24>(AddrSpace);
18070b57cec5SDimitry Andric }
18080b57cec5SDimitry Andric
parseLowLevelType(StringRef::iterator Loc,LLT & Ty)18090b57cec5SDimitry Andric bool MIParser::parseLowLevelType(StringRef::iterator Loc, LLT &Ty) {
18100b57cec5SDimitry Andric if (Token.range().front() == 's' || Token.range().front() == 'p') {
18110b57cec5SDimitry Andric StringRef SizeStr = Token.range().drop_front();
18120b57cec5SDimitry Andric if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit))
18130b57cec5SDimitry Andric return error("expected integers after 's'/'p' type character");
18140b57cec5SDimitry Andric }
18150b57cec5SDimitry Andric
18160b57cec5SDimitry Andric if (Token.range().front() == 's') {
18170b57cec5SDimitry Andric auto ScalarSize = APSInt(Token.range().drop_front()).getZExtValue();
18180b57cec5SDimitry Andric if (!verifyScalarSize(ScalarSize))
18190b57cec5SDimitry Andric return error("invalid size for scalar type");
18200b57cec5SDimitry Andric
18210b57cec5SDimitry Andric Ty = LLT::scalar(ScalarSize);
18220b57cec5SDimitry Andric lex();
18230b57cec5SDimitry Andric return false;
18240b57cec5SDimitry Andric } else if (Token.range().front() == 'p') {
18250b57cec5SDimitry Andric const DataLayout &DL = MF.getDataLayout();
18260b57cec5SDimitry Andric uint64_t AS = APSInt(Token.range().drop_front()).getZExtValue();
18270b57cec5SDimitry Andric if (!verifyAddrSpace(AS))
18280b57cec5SDimitry Andric return error("invalid address space number");
18290b57cec5SDimitry Andric
18300b57cec5SDimitry Andric Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS));
18310b57cec5SDimitry Andric lex();
18320b57cec5SDimitry Andric return false;
18330b57cec5SDimitry Andric }
18340b57cec5SDimitry Andric
18350b57cec5SDimitry Andric // Now we're looking for a vector.
18360b57cec5SDimitry Andric if (Token.isNot(MIToken::less))
18370b57cec5SDimitry Andric return error(Loc,
18380b57cec5SDimitry Andric "expected sN, pA, <M x sN>, or <M x pA> for GlobalISel type");
18390b57cec5SDimitry Andric lex();
18400b57cec5SDimitry Andric
18410b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral))
18420b57cec5SDimitry Andric return error(Loc, "expected <M x sN> or <M x pA> for vector type");
18430b57cec5SDimitry Andric uint64_t NumElements = Token.integerValue().getZExtValue();
18440b57cec5SDimitry Andric if (!verifyVectorElementCount(NumElements))
18450b57cec5SDimitry Andric return error("invalid number of vector elements");
18460b57cec5SDimitry Andric
18470b57cec5SDimitry Andric lex();
18480b57cec5SDimitry Andric
18490b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier) || Token.stringValue() != "x")
18500b57cec5SDimitry Andric return error(Loc, "expected <M x sN> or <M x pA> for vector type");
18510b57cec5SDimitry Andric lex();
18520b57cec5SDimitry Andric
18530b57cec5SDimitry Andric if (Token.range().front() != 's' && Token.range().front() != 'p')
18540b57cec5SDimitry Andric return error(Loc, "expected <M x sN> or <M x pA> for vector type");
18550b57cec5SDimitry Andric StringRef SizeStr = Token.range().drop_front();
18560b57cec5SDimitry Andric if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit))
18570b57cec5SDimitry Andric return error("expected integers after 's'/'p' type character");
18580b57cec5SDimitry Andric
18590b57cec5SDimitry Andric if (Token.range().front() == 's') {
18600b57cec5SDimitry Andric auto ScalarSize = APSInt(Token.range().drop_front()).getZExtValue();
18610b57cec5SDimitry Andric if (!verifyScalarSize(ScalarSize))
18620b57cec5SDimitry Andric return error("invalid size for scalar type");
18630b57cec5SDimitry Andric Ty = LLT::scalar(ScalarSize);
18640b57cec5SDimitry Andric } else if (Token.range().front() == 'p') {
18650b57cec5SDimitry Andric const DataLayout &DL = MF.getDataLayout();
18660b57cec5SDimitry Andric uint64_t AS = APSInt(Token.range().drop_front()).getZExtValue();
18670b57cec5SDimitry Andric if (!verifyAddrSpace(AS))
18680b57cec5SDimitry Andric return error("invalid address space number");
18690b57cec5SDimitry Andric
18700b57cec5SDimitry Andric Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS));
18710b57cec5SDimitry Andric } else
18720b57cec5SDimitry Andric return error(Loc, "expected <M x sN> or <M x pA> for vector type");
18730b57cec5SDimitry Andric lex();
18740b57cec5SDimitry Andric
18750b57cec5SDimitry Andric if (Token.isNot(MIToken::greater))
18760b57cec5SDimitry Andric return error(Loc, "expected <M x sN> or <M x pA> for vector type");
18770b57cec5SDimitry Andric lex();
18780b57cec5SDimitry Andric
1879*5f7ddb14SDimitry Andric Ty = LLT::fixed_vector(NumElements, Ty);
18800b57cec5SDimitry Andric return false;
18810b57cec5SDimitry Andric }
18820b57cec5SDimitry Andric
parseTypedImmediateOperand(MachineOperand & Dest)18830b57cec5SDimitry Andric bool MIParser::parseTypedImmediateOperand(MachineOperand &Dest) {
18840b57cec5SDimitry Andric assert(Token.is(MIToken::Identifier));
18850b57cec5SDimitry Andric StringRef TypeStr = Token.range();
18860b57cec5SDimitry Andric if (TypeStr.front() != 'i' && TypeStr.front() != 's' &&
18870b57cec5SDimitry Andric TypeStr.front() != 'p')
18880b57cec5SDimitry Andric return error(
18890b57cec5SDimitry Andric "a typed immediate operand should start with one of 'i', 's', or 'p'");
18900b57cec5SDimitry Andric StringRef SizeStr = Token.range().drop_front();
18910b57cec5SDimitry Andric if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit))
18920b57cec5SDimitry Andric return error("expected integers after 'i'/'s'/'p' type character");
18930b57cec5SDimitry Andric
18940b57cec5SDimitry Andric auto Loc = Token.location();
18950b57cec5SDimitry Andric lex();
18960b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral)) {
18970b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier) ||
18980b57cec5SDimitry Andric !(Token.range() == "true" || Token.range() == "false"))
18990b57cec5SDimitry Andric return error("expected an integer literal");
19000b57cec5SDimitry Andric }
19010b57cec5SDimitry Andric const Constant *C = nullptr;
19020b57cec5SDimitry Andric if (parseIRConstant(Loc, C))
19030b57cec5SDimitry Andric return true;
19040b57cec5SDimitry Andric Dest = MachineOperand::CreateCImm(cast<ConstantInt>(C));
19050b57cec5SDimitry Andric return false;
19060b57cec5SDimitry Andric }
19070b57cec5SDimitry Andric
parseFPImmediateOperand(MachineOperand & Dest)19080b57cec5SDimitry Andric bool MIParser::parseFPImmediateOperand(MachineOperand &Dest) {
19090b57cec5SDimitry Andric auto Loc = Token.location();
19100b57cec5SDimitry Andric lex();
19110b57cec5SDimitry Andric if (Token.isNot(MIToken::FloatingPointLiteral) &&
19120b57cec5SDimitry Andric Token.isNot(MIToken::HexLiteral))
19130b57cec5SDimitry Andric return error("expected a floating point literal");
19140b57cec5SDimitry Andric const Constant *C = nullptr;
19150b57cec5SDimitry Andric if (parseIRConstant(Loc, C))
19160b57cec5SDimitry Andric return true;
19170b57cec5SDimitry Andric Dest = MachineOperand::CreateFPImm(cast<ConstantFP>(C));
19180b57cec5SDimitry Andric return false;
19190b57cec5SDimitry Andric }
19200b57cec5SDimitry Andric
getHexUint(const MIToken & Token,APInt & Result)1921480093f4SDimitry Andric static bool getHexUint(const MIToken &Token, APInt &Result) {
1922480093f4SDimitry Andric assert(Token.is(MIToken::HexLiteral));
1923480093f4SDimitry Andric StringRef S = Token.range();
1924480093f4SDimitry Andric assert(S[0] == '0' && tolower(S[1]) == 'x');
1925480093f4SDimitry Andric // This could be a floating point literal with a special prefix.
1926480093f4SDimitry Andric if (!isxdigit(S[2]))
1927480093f4SDimitry Andric return true;
1928480093f4SDimitry Andric StringRef V = S.substr(2);
1929480093f4SDimitry Andric APInt A(V.size()*4, V, 16);
1930480093f4SDimitry Andric
1931480093f4SDimitry Andric // If A is 0, then A.getActiveBits() is 0. This isn't a valid bitwidth. Make
1932480093f4SDimitry Andric // sure it isn't the case before constructing result.
1933480093f4SDimitry Andric unsigned NumBits = (A == 0) ? 32 : A.getActiveBits();
1934480093f4SDimitry Andric Result = APInt(NumBits, ArrayRef<uint64_t>(A.getRawData(), A.getNumWords()));
1935480093f4SDimitry Andric return false;
1936480093f4SDimitry Andric }
1937480093f4SDimitry Andric
getUnsigned(const MIToken & Token,unsigned & Result,ErrorCallbackType ErrCB)1938480093f4SDimitry Andric static bool getUnsigned(const MIToken &Token, unsigned &Result,
1939480093f4SDimitry Andric ErrorCallbackType ErrCB) {
19400b57cec5SDimitry Andric if (Token.hasIntegerValue()) {
19410b57cec5SDimitry Andric const uint64_t Limit = uint64_t(std::numeric_limits<unsigned>::max()) + 1;
19420b57cec5SDimitry Andric uint64_t Val64 = Token.integerValue().getLimitedValue(Limit);
19430b57cec5SDimitry Andric if (Val64 == Limit)
1944480093f4SDimitry Andric return ErrCB(Token.location(), "expected 32-bit integer (too large)");
19450b57cec5SDimitry Andric Result = Val64;
19460b57cec5SDimitry Andric return false;
19470b57cec5SDimitry Andric }
19480b57cec5SDimitry Andric if (Token.is(MIToken::HexLiteral)) {
19490b57cec5SDimitry Andric APInt A;
1950480093f4SDimitry Andric if (getHexUint(Token, A))
19510b57cec5SDimitry Andric return true;
19520b57cec5SDimitry Andric if (A.getBitWidth() > 32)
1953480093f4SDimitry Andric return ErrCB(Token.location(), "expected 32-bit integer (too large)");
19540b57cec5SDimitry Andric Result = A.getZExtValue();
19550b57cec5SDimitry Andric return false;
19560b57cec5SDimitry Andric }
19570b57cec5SDimitry Andric return true;
19580b57cec5SDimitry Andric }
19590b57cec5SDimitry Andric
getUnsigned(unsigned & Result)1960480093f4SDimitry Andric bool MIParser::getUnsigned(unsigned &Result) {
1961480093f4SDimitry Andric return ::getUnsigned(
1962480093f4SDimitry Andric Token, Result, [this](StringRef::iterator Loc, const Twine &Msg) -> bool {
1963480093f4SDimitry Andric return error(Loc, Msg);
1964480093f4SDimitry Andric });
1965480093f4SDimitry Andric }
1966480093f4SDimitry Andric
parseMBBReference(MachineBasicBlock * & MBB)19670b57cec5SDimitry Andric bool MIParser::parseMBBReference(MachineBasicBlock *&MBB) {
19680b57cec5SDimitry Andric assert(Token.is(MIToken::MachineBasicBlock) ||
19690b57cec5SDimitry Andric Token.is(MIToken::MachineBasicBlockLabel));
19700b57cec5SDimitry Andric unsigned Number;
19710b57cec5SDimitry Andric if (getUnsigned(Number))
19720b57cec5SDimitry Andric return true;
19730b57cec5SDimitry Andric auto MBBInfo = PFS.MBBSlots.find(Number);
19740b57cec5SDimitry Andric if (MBBInfo == PFS.MBBSlots.end())
19750b57cec5SDimitry Andric return error(Twine("use of undefined machine basic block #") +
19760b57cec5SDimitry Andric Twine(Number));
19770b57cec5SDimitry Andric MBB = MBBInfo->second;
19780b57cec5SDimitry Andric // TODO: Only parse the name if it's a MachineBasicBlockLabel. Deprecate once
19790b57cec5SDimitry Andric // we drop the <irname> from the bb.<id>.<irname> format.
19800b57cec5SDimitry Andric if (!Token.stringValue().empty() && Token.stringValue() != MBB->getName())
19810b57cec5SDimitry Andric return error(Twine("the name of machine basic block #") + Twine(Number) +
19820b57cec5SDimitry Andric " isn't '" + Token.stringValue() + "'");
19830b57cec5SDimitry Andric return false;
19840b57cec5SDimitry Andric }
19850b57cec5SDimitry Andric
parseMBBOperand(MachineOperand & Dest)19860b57cec5SDimitry Andric bool MIParser::parseMBBOperand(MachineOperand &Dest) {
19870b57cec5SDimitry Andric MachineBasicBlock *MBB;
19880b57cec5SDimitry Andric if (parseMBBReference(MBB))
19890b57cec5SDimitry Andric return true;
19900b57cec5SDimitry Andric Dest = MachineOperand::CreateMBB(MBB);
19910b57cec5SDimitry Andric lex();
19920b57cec5SDimitry Andric return false;
19930b57cec5SDimitry Andric }
19940b57cec5SDimitry Andric
parseStackFrameIndex(int & FI)19950b57cec5SDimitry Andric bool MIParser::parseStackFrameIndex(int &FI) {
19960b57cec5SDimitry Andric assert(Token.is(MIToken::StackObject));
19970b57cec5SDimitry Andric unsigned ID;
19980b57cec5SDimitry Andric if (getUnsigned(ID))
19990b57cec5SDimitry Andric return true;
20000b57cec5SDimitry Andric auto ObjectInfo = PFS.StackObjectSlots.find(ID);
20010b57cec5SDimitry Andric if (ObjectInfo == PFS.StackObjectSlots.end())
20020b57cec5SDimitry Andric return error(Twine("use of undefined stack object '%stack.") + Twine(ID) +
20030b57cec5SDimitry Andric "'");
20040b57cec5SDimitry Andric StringRef Name;
20050b57cec5SDimitry Andric if (const auto *Alloca =
20060b57cec5SDimitry Andric MF.getFrameInfo().getObjectAllocation(ObjectInfo->second))
20070b57cec5SDimitry Andric Name = Alloca->getName();
20080b57cec5SDimitry Andric if (!Token.stringValue().empty() && Token.stringValue() != Name)
20090b57cec5SDimitry Andric return error(Twine("the name of the stack object '%stack.") + Twine(ID) +
20100b57cec5SDimitry Andric "' isn't '" + Token.stringValue() + "'");
20110b57cec5SDimitry Andric lex();
20120b57cec5SDimitry Andric FI = ObjectInfo->second;
20130b57cec5SDimitry Andric return false;
20140b57cec5SDimitry Andric }
20150b57cec5SDimitry Andric
parseStackObjectOperand(MachineOperand & Dest)20160b57cec5SDimitry Andric bool MIParser::parseStackObjectOperand(MachineOperand &Dest) {
20170b57cec5SDimitry Andric int FI;
20180b57cec5SDimitry Andric if (parseStackFrameIndex(FI))
20190b57cec5SDimitry Andric return true;
20200b57cec5SDimitry Andric Dest = MachineOperand::CreateFI(FI);
20210b57cec5SDimitry Andric return false;
20220b57cec5SDimitry Andric }
20230b57cec5SDimitry Andric
parseFixedStackFrameIndex(int & FI)20240b57cec5SDimitry Andric bool MIParser::parseFixedStackFrameIndex(int &FI) {
20250b57cec5SDimitry Andric assert(Token.is(MIToken::FixedStackObject));
20260b57cec5SDimitry Andric unsigned ID;
20270b57cec5SDimitry Andric if (getUnsigned(ID))
20280b57cec5SDimitry Andric return true;
20290b57cec5SDimitry Andric auto ObjectInfo = PFS.FixedStackObjectSlots.find(ID);
20300b57cec5SDimitry Andric if (ObjectInfo == PFS.FixedStackObjectSlots.end())
20310b57cec5SDimitry Andric return error(Twine("use of undefined fixed stack object '%fixed-stack.") +
20320b57cec5SDimitry Andric Twine(ID) + "'");
20330b57cec5SDimitry Andric lex();
20340b57cec5SDimitry Andric FI = ObjectInfo->second;
20350b57cec5SDimitry Andric return false;
20360b57cec5SDimitry Andric }
20370b57cec5SDimitry Andric
parseFixedStackObjectOperand(MachineOperand & Dest)20380b57cec5SDimitry Andric bool MIParser::parseFixedStackObjectOperand(MachineOperand &Dest) {
20390b57cec5SDimitry Andric int FI;
20400b57cec5SDimitry Andric if (parseFixedStackFrameIndex(FI))
20410b57cec5SDimitry Andric return true;
20420b57cec5SDimitry Andric Dest = MachineOperand::CreateFI(FI);
20430b57cec5SDimitry Andric return false;
20440b57cec5SDimitry Andric }
20450b57cec5SDimitry Andric
parseGlobalValue(const MIToken & Token,PerFunctionMIParsingState & PFS,GlobalValue * & GV,ErrorCallbackType ErrCB)2046480093f4SDimitry Andric static bool parseGlobalValue(const MIToken &Token,
2047480093f4SDimitry Andric PerFunctionMIParsingState &PFS, GlobalValue *&GV,
2048480093f4SDimitry Andric ErrorCallbackType ErrCB) {
20490b57cec5SDimitry Andric switch (Token.kind()) {
20500b57cec5SDimitry Andric case MIToken::NamedGlobalValue: {
2051480093f4SDimitry Andric const Module *M = PFS.MF.getFunction().getParent();
20520b57cec5SDimitry Andric GV = M->getNamedValue(Token.stringValue());
20530b57cec5SDimitry Andric if (!GV)
2054480093f4SDimitry Andric return ErrCB(Token.location(), Twine("use of undefined global value '") +
2055480093f4SDimitry Andric Token.range() + "'");
20560b57cec5SDimitry Andric break;
20570b57cec5SDimitry Andric }
20580b57cec5SDimitry Andric case MIToken::GlobalValue: {
20590b57cec5SDimitry Andric unsigned GVIdx;
2060480093f4SDimitry Andric if (getUnsigned(Token, GVIdx, ErrCB))
20610b57cec5SDimitry Andric return true;
20620b57cec5SDimitry Andric if (GVIdx >= PFS.IRSlots.GlobalValues.size())
2063480093f4SDimitry Andric return ErrCB(Token.location(), Twine("use of undefined global value '@") +
2064480093f4SDimitry Andric Twine(GVIdx) + "'");
20650b57cec5SDimitry Andric GV = PFS.IRSlots.GlobalValues[GVIdx];
20660b57cec5SDimitry Andric break;
20670b57cec5SDimitry Andric }
20680b57cec5SDimitry Andric default:
20690b57cec5SDimitry Andric llvm_unreachable("The current token should be a global value");
20700b57cec5SDimitry Andric }
20710b57cec5SDimitry Andric return false;
20720b57cec5SDimitry Andric }
20730b57cec5SDimitry Andric
parseGlobalValue(GlobalValue * & GV)2074480093f4SDimitry Andric bool MIParser::parseGlobalValue(GlobalValue *&GV) {
2075480093f4SDimitry Andric return ::parseGlobalValue(
2076480093f4SDimitry Andric Token, PFS, GV,
2077480093f4SDimitry Andric [this](StringRef::iterator Loc, const Twine &Msg) -> bool {
2078480093f4SDimitry Andric return error(Loc, Msg);
2079480093f4SDimitry Andric });
2080480093f4SDimitry Andric }
2081480093f4SDimitry Andric
parseGlobalAddressOperand(MachineOperand & Dest)20820b57cec5SDimitry Andric bool MIParser::parseGlobalAddressOperand(MachineOperand &Dest) {
20830b57cec5SDimitry Andric GlobalValue *GV = nullptr;
20840b57cec5SDimitry Andric if (parseGlobalValue(GV))
20850b57cec5SDimitry Andric return true;
20860b57cec5SDimitry Andric lex();
20870b57cec5SDimitry Andric Dest = MachineOperand::CreateGA(GV, /*Offset=*/0);
20880b57cec5SDimitry Andric if (parseOperandsOffset(Dest))
20890b57cec5SDimitry Andric return true;
20900b57cec5SDimitry Andric return false;
20910b57cec5SDimitry Andric }
20920b57cec5SDimitry Andric
parseConstantPoolIndexOperand(MachineOperand & Dest)20930b57cec5SDimitry Andric bool MIParser::parseConstantPoolIndexOperand(MachineOperand &Dest) {
20940b57cec5SDimitry Andric assert(Token.is(MIToken::ConstantPoolItem));
20950b57cec5SDimitry Andric unsigned ID;
20960b57cec5SDimitry Andric if (getUnsigned(ID))
20970b57cec5SDimitry Andric return true;
20980b57cec5SDimitry Andric auto ConstantInfo = PFS.ConstantPoolSlots.find(ID);
20990b57cec5SDimitry Andric if (ConstantInfo == PFS.ConstantPoolSlots.end())
21000b57cec5SDimitry Andric return error("use of undefined constant '%const." + Twine(ID) + "'");
21010b57cec5SDimitry Andric lex();
21020b57cec5SDimitry Andric Dest = MachineOperand::CreateCPI(ID, /*Offset=*/0);
21030b57cec5SDimitry Andric if (parseOperandsOffset(Dest))
21040b57cec5SDimitry Andric return true;
21050b57cec5SDimitry Andric return false;
21060b57cec5SDimitry Andric }
21070b57cec5SDimitry Andric
parseJumpTableIndexOperand(MachineOperand & Dest)21080b57cec5SDimitry Andric bool MIParser::parseJumpTableIndexOperand(MachineOperand &Dest) {
21090b57cec5SDimitry Andric assert(Token.is(MIToken::JumpTableIndex));
21100b57cec5SDimitry Andric unsigned ID;
21110b57cec5SDimitry Andric if (getUnsigned(ID))
21120b57cec5SDimitry Andric return true;
21130b57cec5SDimitry Andric auto JumpTableEntryInfo = PFS.JumpTableSlots.find(ID);
21140b57cec5SDimitry Andric if (JumpTableEntryInfo == PFS.JumpTableSlots.end())
21150b57cec5SDimitry Andric return error("use of undefined jump table '%jump-table." + Twine(ID) + "'");
21160b57cec5SDimitry Andric lex();
21170b57cec5SDimitry Andric Dest = MachineOperand::CreateJTI(JumpTableEntryInfo->second);
21180b57cec5SDimitry Andric return false;
21190b57cec5SDimitry Andric }
21200b57cec5SDimitry Andric
parseExternalSymbolOperand(MachineOperand & Dest)21210b57cec5SDimitry Andric bool MIParser::parseExternalSymbolOperand(MachineOperand &Dest) {
21220b57cec5SDimitry Andric assert(Token.is(MIToken::ExternalSymbol));
21230b57cec5SDimitry Andric const char *Symbol = MF.createExternalSymbolName(Token.stringValue());
21240b57cec5SDimitry Andric lex();
21250b57cec5SDimitry Andric Dest = MachineOperand::CreateES(Symbol);
21260b57cec5SDimitry Andric if (parseOperandsOffset(Dest))
21270b57cec5SDimitry Andric return true;
21280b57cec5SDimitry Andric return false;
21290b57cec5SDimitry Andric }
21300b57cec5SDimitry Andric
parseMCSymbolOperand(MachineOperand & Dest)21310b57cec5SDimitry Andric bool MIParser::parseMCSymbolOperand(MachineOperand &Dest) {
21320b57cec5SDimitry Andric assert(Token.is(MIToken::MCSymbol));
21330b57cec5SDimitry Andric MCSymbol *Symbol = getOrCreateMCSymbol(Token.stringValue());
21340b57cec5SDimitry Andric lex();
21350b57cec5SDimitry Andric Dest = MachineOperand::CreateMCSymbol(Symbol);
21360b57cec5SDimitry Andric if (parseOperandsOffset(Dest))
21370b57cec5SDimitry Andric return true;
21380b57cec5SDimitry Andric return false;
21390b57cec5SDimitry Andric }
21400b57cec5SDimitry Andric
parseSubRegisterIndexOperand(MachineOperand & Dest)21410b57cec5SDimitry Andric bool MIParser::parseSubRegisterIndexOperand(MachineOperand &Dest) {
21420b57cec5SDimitry Andric assert(Token.is(MIToken::SubRegisterIndex));
21430b57cec5SDimitry Andric StringRef Name = Token.stringValue();
21440b57cec5SDimitry Andric unsigned SubRegIndex = PFS.Target.getSubRegIndex(Token.stringValue());
21450b57cec5SDimitry Andric if (SubRegIndex == 0)
21460b57cec5SDimitry Andric return error(Twine("unknown subregister index '") + Name + "'");
21470b57cec5SDimitry Andric lex();
21480b57cec5SDimitry Andric Dest = MachineOperand::CreateImm(SubRegIndex);
21490b57cec5SDimitry Andric return false;
21500b57cec5SDimitry Andric }
21510b57cec5SDimitry Andric
parseMDNode(MDNode * & Node)21520b57cec5SDimitry Andric bool MIParser::parseMDNode(MDNode *&Node) {
21530b57cec5SDimitry Andric assert(Token.is(MIToken::exclaim));
21540b57cec5SDimitry Andric
21550b57cec5SDimitry Andric auto Loc = Token.location();
21560b57cec5SDimitry Andric lex();
21570b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned())
21580b57cec5SDimitry Andric return error("expected metadata id after '!'");
21590b57cec5SDimitry Andric unsigned ID;
21600b57cec5SDimitry Andric if (getUnsigned(ID))
21610b57cec5SDimitry Andric return true;
21620b57cec5SDimitry Andric auto NodeInfo = PFS.IRSlots.MetadataNodes.find(ID);
2163*5f7ddb14SDimitry Andric if (NodeInfo == PFS.IRSlots.MetadataNodes.end()) {
2164*5f7ddb14SDimitry Andric NodeInfo = PFS.MachineMetadataNodes.find(ID);
2165*5f7ddb14SDimitry Andric if (NodeInfo == PFS.MachineMetadataNodes.end())
21660b57cec5SDimitry Andric return error(Loc, "use of undefined metadata '!" + Twine(ID) + "'");
2167*5f7ddb14SDimitry Andric }
21680b57cec5SDimitry Andric lex();
21690b57cec5SDimitry Andric Node = NodeInfo->second.get();
21700b57cec5SDimitry Andric return false;
21710b57cec5SDimitry Andric }
21720b57cec5SDimitry Andric
parseDIExpression(MDNode * & Expr)21730b57cec5SDimitry Andric bool MIParser::parseDIExpression(MDNode *&Expr) {
21740b57cec5SDimitry Andric assert(Token.is(MIToken::md_diexpr));
21750b57cec5SDimitry Andric lex();
21760b57cec5SDimitry Andric
21770b57cec5SDimitry Andric // FIXME: Share this parsing with the IL parser.
21780b57cec5SDimitry Andric SmallVector<uint64_t, 8> Elements;
21790b57cec5SDimitry Andric
21800b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen))
21810b57cec5SDimitry Andric return true;
21820b57cec5SDimitry Andric
21830b57cec5SDimitry Andric if (Token.isNot(MIToken::rparen)) {
21840b57cec5SDimitry Andric do {
21850b57cec5SDimitry Andric if (Token.is(MIToken::Identifier)) {
21860b57cec5SDimitry Andric if (unsigned Op = dwarf::getOperationEncoding(Token.stringValue())) {
21870b57cec5SDimitry Andric lex();
21880b57cec5SDimitry Andric Elements.push_back(Op);
21890b57cec5SDimitry Andric continue;
21900b57cec5SDimitry Andric }
21910b57cec5SDimitry Andric if (unsigned Enc = dwarf::getAttributeEncoding(Token.stringValue())) {
21920b57cec5SDimitry Andric lex();
21930b57cec5SDimitry Andric Elements.push_back(Enc);
21940b57cec5SDimitry Andric continue;
21950b57cec5SDimitry Andric }
21960b57cec5SDimitry Andric return error(Twine("invalid DWARF op '") + Token.stringValue() + "'");
21970b57cec5SDimitry Andric }
21980b57cec5SDimitry Andric
21990b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) ||
22000b57cec5SDimitry Andric Token.integerValue().isSigned())
22010b57cec5SDimitry Andric return error("expected unsigned integer");
22020b57cec5SDimitry Andric
22030b57cec5SDimitry Andric auto &U = Token.integerValue();
22040b57cec5SDimitry Andric if (U.ugt(UINT64_MAX))
22050b57cec5SDimitry Andric return error("element too large, limit is " + Twine(UINT64_MAX));
22060b57cec5SDimitry Andric Elements.push_back(U.getZExtValue());
22070b57cec5SDimitry Andric lex();
22080b57cec5SDimitry Andric
22090b57cec5SDimitry Andric } while (consumeIfPresent(MIToken::comma));
22100b57cec5SDimitry Andric }
22110b57cec5SDimitry Andric
22120b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
22130b57cec5SDimitry Andric return true;
22140b57cec5SDimitry Andric
22150b57cec5SDimitry Andric Expr = DIExpression::get(MF.getFunction().getContext(), Elements);
22160b57cec5SDimitry Andric return false;
22170b57cec5SDimitry Andric }
22180b57cec5SDimitry Andric
parseDILocation(MDNode * & Loc)22190b57cec5SDimitry Andric bool MIParser::parseDILocation(MDNode *&Loc) {
22200b57cec5SDimitry Andric assert(Token.is(MIToken::md_dilocation));
22210b57cec5SDimitry Andric lex();
22220b57cec5SDimitry Andric
22230b57cec5SDimitry Andric bool HaveLine = false;
22240b57cec5SDimitry Andric unsigned Line = 0;
22250b57cec5SDimitry Andric unsigned Column = 0;
22260b57cec5SDimitry Andric MDNode *Scope = nullptr;
22270b57cec5SDimitry Andric MDNode *InlinedAt = nullptr;
22280b57cec5SDimitry Andric bool ImplicitCode = false;
22290b57cec5SDimitry Andric
22300b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen))
22310b57cec5SDimitry Andric return true;
22320b57cec5SDimitry Andric
22330b57cec5SDimitry Andric if (Token.isNot(MIToken::rparen)) {
22340b57cec5SDimitry Andric do {
22350b57cec5SDimitry Andric if (Token.is(MIToken::Identifier)) {
22360b57cec5SDimitry Andric if (Token.stringValue() == "line") {
22370b57cec5SDimitry Andric lex();
22380b57cec5SDimitry Andric if (expectAndConsume(MIToken::colon))
22390b57cec5SDimitry Andric return true;
22400b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) ||
22410b57cec5SDimitry Andric Token.integerValue().isSigned())
22420b57cec5SDimitry Andric return error("expected unsigned integer");
22430b57cec5SDimitry Andric Line = Token.integerValue().getZExtValue();
22440b57cec5SDimitry Andric HaveLine = true;
22450b57cec5SDimitry Andric lex();
22460b57cec5SDimitry Andric continue;
22470b57cec5SDimitry Andric }
22480b57cec5SDimitry Andric if (Token.stringValue() == "column") {
22490b57cec5SDimitry Andric lex();
22500b57cec5SDimitry Andric if (expectAndConsume(MIToken::colon))
22510b57cec5SDimitry Andric return true;
22520b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) ||
22530b57cec5SDimitry Andric Token.integerValue().isSigned())
22540b57cec5SDimitry Andric return error("expected unsigned integer");
22550b57cec5SDimitry Andric Column = Token.integerValue().getZExtValue();
22560b57cec5SDimitry Andric lex();
22570b57cec5SDimitry Andric continue;
22580b57cec5SDimitry Andric }
22590b57cec5SDimitry Andric if (Token.stringValue() == "scope") {
22600b57cec5SDimitry Andric lex();
22610b57cec5SDimitry Andric if (expectAndConsume(MIToken::colon))
22620b57cec5SDimitry Andric return true;
22630b57cec5SDimitry Andric if (parseMDNode(Scope))
22640b57cec5SDimitry Andric return error("expected metadata node");
22650b57cec5SDimitry Andric if (!isa<DIScope>(Scope))
22660b57cec5SDimitry Andric return error("expected DIScope node");
22670b57cec5SDimitry Andric continue;
22680b57cec5SDimitry Andric }
22690b57cec5SDimitry Andric if (Token.stringValue() == "inlinedAt") {
22700b57cec5SDimitry Andric lex();
22710b57cec5SDimitry Andric if (expectAndConsume(MIToken::colon))
22720b57cec5SDimitry Andric return true;
22730b57cec5SDimitry Andric if (Token.is(MIToken::exclaim)) {
22740b57cec5SDimitry Andric if (parseMDNode(InlinedAt))
22750b57cec5SDimitry Andric return true;
22760b57cec5SDimitry Andric } else if (Token.is(MIToken::md_dilocation)) {
22770b57cec5SDimitry Andric if (parseDILocation(InlinedAt))
22780b57cec5SDimitry Andric return true;
22790b57cec5SDimitry Andric } else
22800b57cec5SDimitry Andric return error("expected metadata node");
22810b57cec5SDimitry Andric if (!isa<DILocation>(InlinedAt))
22820b57cec5SDimitry Andric return error("expected DILocation node");
22830b57cec5SDimitry Andric continue;
22840b57cec5SDimitry Andric }
22850b57cec5SDimitry Andric if (Token.stringValue() == "isImplicitCode") {
22860b57cec5SDimitry Andric lex();
22870b57cec5SDimitry Andric if (expectAndConsume(MIToken::colon))
22880b57cec5SDimitry Andric return true;
22890b57cec5SDimitry Andric if (!Token.is(MIToken::Identifier))
22900b57cec5SDimitry Andric return error("expected true/false");
22910b57cec5SDimitry Andric // As far as I can see, we don't have any existing need for parsing
22920b57cec5SDimitry Andric // true/false in MIR yet. Do it ad-hoc until there's something else
22930b57cec5SDimitry Andric // that needs it.
22940b57cec5SDimitry Andric if (Token.stringValue() == "true")
22950b57cec5SDimitry Andric ImplicitCode = true;
22960b57cec5SDimitry Andric else if (Token.stringValue() == "false")
22970b57cec5SDimitry Andric ImplicitCode = false;
22980b57cec5SDimitry Andric else
22990b57cec5SDimitry Andric return error("expected true/false");
23000b57cec5SDimitry Andric lex();
23010b57cec5SDimitry Andric continue;
23020b57cec5SDimitry Andric }
23030b57cec5SDimitry Andric }
23040b57cec5SDimitry Andric return error(Twine("invalid DILocation argument '") +
23050b57cec5SDimitry Andric Token.stringValue() + "'");
23060b57cec5SDimitry Andric } while (consumeIfPresent(MIToken::comma));
23070b57cec5SDimitry Andric }
23080b57cec5SDimitry Andric
23090b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
23100b57cec5SDimitry Andric return true;
23110b57cec5SDimitry Andric
23120b57cec5SDimitry Andric if (!HaveLine)
23130b57cec5SDimitry Andric return error("DILocation requires line number");
23140b57cec5SDimitry Andric if (!Scope)
23150b57cec5SDimitry Andric return error("DILocation requires a scope");
23160b57cec5SDimitry Andric
23170b57cec5SDimitry Andric Loc = DILocation::get(MF.getFunction().getContext(), Line, Column, Scope,
23180b57cec5SDimitry Andric InlinedAt, ImplicitCode);
23190b57cec5SDimitry Andric return false;
23200b57cec5SDimitry Andric }
23210b57cec5SDimitry Andric
parseMetadataOperand(MachineOperand & Dest)23220b57cec5SDimitry Andric bool MIParser::parseMetadataOperand(MachineOperand &Dest) {
23230b57cec5SDimitry Andric MDNode *Node = nullptr;
23240b57cec5SDimitry Andric if (Token.is(MIToken::exclaim)) {
23250b57cec5SDimitry Andric if (parseMDNode(Node))
23260b57cec5SDimitry Andric return true;
23270b57cec5SDimitry Andric } else if (Token.is(MIToken::md_diexpr)) {
23280b57cec5SDimitry Andric if (parseDIExpression(Node))
23290b57cec5SDimitry Andric return true;
23300b57cec5SDimitry Andric }
23310b57cec5SDimitry Andric Dest = MachineOperand::CreateMetadata(Node);
23320b57cec5SDimitry Andric return false;
23330b57cec5SDimitry Andric }
23340b57cec5SDimitry Andric
parseCFIOffset(int & Offset)23350b57cec5SDimitry Andric bool MIParser::parseCFIOffset(int &Offset) {
23360b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral))
23370b57cec5SDimitry Andric return error("expected a cfi offset");
23380b57cec5SDimitry Andric if (Token.integerValue().getMinSignedBits() > 32)
23390b57cec5SDimitry Andric return error("expected a 32 bit integer (the cfi offset is too large)");
23400b57cec5SDimitry Andric Offset = (int)Token.integerValue().getExtValue();
23410b57cec5SDimitry Andric lex();
23420b57cec5SDimitry Andric return false;
23430b57cec5SDimitry Andric }
23440b57cec5SDimitry Andric
parseCFIRegister(Register & Reg)23455ffd83dbSDimitry Andric bool MIParser::parseCFIRegister(Register &Reg) {
23460b57cec5SDimitry Andric if (Token.isNot(MIToken::NamedRegister))
23470b57cec5SDimitry Andric return error("expected a cfi register");
23485ffd83dbSDimitry Andric Register LLVMReg;
23490b57cec5SDimitry Andric if (parseNamedRegister(LLVMReg))
23500b57cec5SDimitry Andric return true;
23510b57cec5SDimitry Andric const auto *TRI = MF.getSubtarget().getRegisterInfo();
23520b57cec5SDimitry Andric assert(TRI && "Expected target register info");
23530b57cec5SDimitry Andric int DwarfReg = TRI->getDwarfRegNum(LLVMReg, true);
23540b57cec5SDimitry Andric if (DwarfReg < 0)
23550b57cec5SDimitry Andric return error("invalid DWARF register");
23560b57cec5SDimitry Andric Reg = (unsigned)DwarfReg;
23570b57cec5SDimitry Andric lex();
23580b57cec5SDimitry Andric return false;
23590b57cec5SDimitry Andric }
23600b57cec5SDimitry Andric
parseCFIAddressSpace(unsigned & AddressSpace)2361*5f7ddb14SDimitry Andric bool MIParser::parseCFIAddressSpace(unsigned &AddressSpace) {
2362*5f7ddb14SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral))
2363*5f7ddb14SDimitry Andric return error("expected a cfi address space literal");
2364*5f7ddb14SDimitry Andric if (Token.integerValue().isSigned())
2365*5f7ddb14SDimitry Andric return error("expected an unsigned integer (cfi address space)");
2366*5f7ddb14SDimitry Andric AddressSpace = Token.integerValue().getZExtValue();
2367*5f7ddb14SDimitry Andric lex();
2368*5f7ddb14SDimitry Andric return false;
2369*5f7ddb14SDimitry Andric }
2370*5f7ddb14SDimitry Andric
parseCFIEscapeValues(std::string & Values)23710b57cec5SDimitry Andric bool MIParser::parseCFIEscapeValues(std::string &Values) {
23720b57cec5SDimitry Andric do {
23730b57cec5SDimitry Andric if (Token.isNot(MIToken::HexLiteral))
23740b57cec5SDimitry Andric return error("expected a hexadecimal literal");
23750b57cec5SDimitry Andric unsigned Value;
23760b57cec5SDimitry Andric if (getUnsigned(Value))
23770b57cec5SDimitry Andric return true;
23780b57cec5SDimitry Andric if (Value > UINT8_MAX)
23790b57cec5SDimitry Andric return error("expected a 8-bit integer (too large)");
23800b57cec5SDimitry Andric Values.push_back(static_cast<uint8_t>(Value));
23810b57cec5SDimitry Andric lex();
23820b57cec5SDimitry Andric } while (consumeIfPresent(MIToken::comma));
23830b57cec5SDimitry Andric return false;
23840b57cec5SDimitry Andric }
23850b57cec5SDimitry Andric
parseCFIOperand(MachineOperand & Dest)23860b57cec5SDimitry Andric bool MIParser::parseCFIOperand(MachineOperand &Dest) {
23870b57cec5SDimitry Andric auto Kind = Token.kind();
23880b57cec5SDimitry Andric lex();
23890b57cec5SDimitry Andric int Offset;
23905ffd83dbSDimitry Andric Register Reg;
2391*5f7ddb14SDimitry Andric unsigned AddressSpace;
23920b57cec5SDimitry Andric unsigned CFIIndex;
23930b57cec5SDimitry Andric switch (Kind) {
23940b57cec5SDimitry Andric case MIToken::kw_cfi_same_value:
23950b57cec5SDimitry Andric if (parseCFIRegister(Reg))
23960b57cec5SDimitry Andric return true;
23970b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createSameValue(nullptr, Reg));
23980b57cec5SDimitry Andric break;
23990b57cec5SDimitry Andric case MIToken::kw_cfi_offset:
24000b57cec5SDimitry Andric if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
24010b57cec5SDimitry Andric parseCFIOffset(Offset))
24020b57cec5SDimitry Andric return true;
24030b57cec5SDimitry Andric CFIIndex =
24040b57cec5SDimitry Andric MF.addFrameInst(MCCFIInstruction::createOffset(nullptr, Reg, Offset));
24050b57cec5SDimitry Andric break;
24060b57cec5SDimitry Andric case MIToken::kw_cfi_rel_offset:
24070b57cec5SDimitry Andric if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
24080b57cec5SDimitry Andric parseCFIOffset(Offset))
24090b57cec5SDimitry Andric return true;
24100b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(
24110b57cec5SDimitry Andric MCCFIInstruction::createRelOffset(nullptr, Reg, Offset));
24120b57cec5SDimitry Andric break;
24130b57cec5SDimitry Andric case MIToken::kw_cfi_def_cfa_register:
24140b57cec5SDimitry Andric if (parseCFIRegister(Reg))
24150b57cec5SDimitry Andric return true;
24160b57cec5SDimitry Andric CFIIndex =
24170b57cec5SDimitry Andric MF.addFrameInst(MCCFIInstruction::createDefCfaRegister(nullptr, Reg));
24180b57cec5SDimitry Andric break;
24190b57cec5SDimitry Andric case MIToken::kw_cfi_def_cfa_offset:
24200b57cec5SDimitry Andric if (parseCFIOffset(Offset))
24210b57cec5SDimitry Andric return true;
24225ffd83dbSDimitry Andric CFIIndex =
24235ffd83dbSDimitry Andric MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, Offset));
24240b57cec5SDimitry Andric break;
24250b57cec5SDimitry Andric case MIToken::kw_cfi_adjust_cfa_offset:
24260b57cec5SDimitry Andric if (parseCFIOffset(Offset))
24270b57cec5SDimitry Andric return true;
24280b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(
24290b57cec5SDimitry Andric MCCFIInstruction::createAdjustCfaOffset(nullptr, Offset));
24300b57cec5SDimitry Andric break;
24310b57cec5SDimitry Andric case MIToken::kw_cfi_def_cfa:
24320b57cec5SDimitry Andric if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
24330b57cec5SDimitry Andric parseCFIOffset(Offset))
24340b57cec5SDimitry Andric return true;
24350b57cec5SDimitry Andric CFIIndex =
24365ffd83dbSDimitry Andric MF.addFrameInst(MCCFIInstruction::cfiDefCfa(nullptr, Reg, Offset));
24370b57cec5SDimitry Andric break;
2438*5f7ddb14SDimitry Andric case MIToken::kw_cfi_llvm_def_aspace_cfa:
2439*5f7ddb14SDimitry Andric if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
2440*5f7ddb14SDimitry Andric parseCFIOffset(Offset) || expectAndConsume(MIToken::comma) ||
2441*5f7ddb14SDimitry Andric parseCFIAddressSpace(AddressSpace))
2442*5f7ddb14SDimitry Andric return true;
2443*5f7ddb14SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createLLVMDefAspaceCfa(
2444*5f7ddb14SDimitry Andric nullptr, Reg, Offset, AddressSpace));
2445*5f7ddb14SDimitry Andric break;
24460b57cec5SDimitry Andric case MIToken::kw_cfi_remember_state:
24470b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createRememberState(nullptr));
24480b57cec5SDimitry Andric break;
24490b57cec5SDimitry Andric case MIToken::kw_cfi_restore:
24500b57cec5SDimitry Andric if (parseCFIRegister(Reg))
24510b57cec5SDimitry Andric return true;
24520b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(nullptr, Reg));
24530b57cec5SDimitry Andric break;
24540b57cec5SDimitry Andric case MIToken::kw_cfi_restore_state:
24550b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestoreState(nullptr));
24560b57cec5SDimitry Andric break;
24570b57cec5SDimitry Andric case MIToken::kw_cfi_undefined:
24580b57cec5SDimitry Andric if (parseCFIRegister(Reg))
24590b57cec5SDimitry Andric return true;
24600b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createUndefined(nullptr, Reg));
24610b57cec5SDimitry Andric break;
24620b57cec5SDimitry Andric case MIToken::kw_cfi_register: {
24635ffd83dbSDimitry Andric Register Reg2;
24640b57cec5SDimitry Andric if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
24650b57cec5SDimitry Andric parseCFIRegister(Reg2))
24660b57cec5SDimitry Andric return true;
24670b57cec5SDimitry Andric
24680b57cec5SDimitry Andric CFIIndex =
24690b57cec5SDimitry Andric MF.addFrameInst(MCCFIInstruction::createRegister(nullptr, Reg, Reg2));
24700b57cec5SDimitry Andric break;
24710b57cec5SDimitry Andric }
24720b57cec5SDimitry Andric case MIToken::kw_cfi_window_save:
24730b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createWindowSave(nullptr));
24740b57cec5SDimitry Andric break;
24750b57cec5SDimitry Andric case MIToken::kw_cfi_aarch64_negate_ra_sign_state:
24760b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr));
24770b57cec5SDimitry Andric break;
24780b57cec5SDimitry Andric case MIToken::kw_cfi_escape: {
24790b57cec5SDimitry Andric std::string Values;
24800b57cec5SDimitry Andric if (parseCFIEscapeValues(Values))
24810b57cec5SDimitry Andric return true;
24820b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createEscape(nullptr, Values));
24830b57cec5SDimitry Andric break;
24840b57cec5SDimitry Andric }
24850b57cec5SDimitry Andric default:
24860b57cec5SDimitry Andric // TODO: Parse the other CFI operands.
24870b57cec5SDimitry Andric llvm_unreachable("The current token should be a cfi operand");
24880b57cec5SDimitry Andric }
24890b57cec5SDimitry Andric Dest = MachineOperand::CreateCFIIndex(CFIIndex);
24900b57cec5SDimitry Andric return false;
24910b57cec5SDimitry Andric }
24920b57cec5SDimitry Andric
parseIRBlock(BasicBlock * & BB,const Function & F)24930b57cec5SDimitry Andric bool MIParser::parseIRBlock(BasicBlock *&BB, const Function &F) {
24940b57cec5SDimitry Andric switch (Token.kind()) {
24950b57cec5SDimitry Andric case MIToken::NamedIRBlock: {
24960b57cec5SDimitry Andric BB = dyn_cast_or_null<BasicBlock>(
24970b57cec5SDimitry Andric F.getValueSymbolTable()->lookup(Token.stringValue()));
24980b57cec5SDimitry Andric if (!BB)
24990b57cec5SDimitry Andric return error(Twine("use of undefined IR block '") + Token.range() + "'");
25000b57cec5SDimitry Andric break;
25010b57cec5SDimitry Andric }
25020b57cec5SDimitry Andric case MIToken::IRBlock: {
25030b57cec5SDimitry Andric unsigned SlotNumber = 0;
25040b57cec5SDimitry Andric if (getUnsigned(SlotNumber))
25050b57cec5SDimitry Andric return true;
25060b57cec5SDimitry Andric BB = const_cast<BasicBlock *>(getIRBlock(SlotNumber, F));
25070b57cec5SDimitry Andric if (!BB)
25080b57cec5SDimitry Andric return error(Twine("use of undefined IR block '%ir-block.") +
25090b57cec5SDimitry Andric Twine(SlotNumber) + "'");
25100b57cec5SDimitry Andric break;
25110b57cec5SDimitry Andric }
25120b57cec5SDimitry Andric default:
25130b57cec5SDimitry Andric llvm_unreachable("The current token should be an IR block reference");
25140b57cec5SDimitry Andric }
25150b57cec5SDimitry Andric return false;
25160b57cec5SDimitry Andric }
25170b57cec5SDimitry Andric
parseBlockAddressOperand(MachineOperand & Dest)25180b57cec5SDimitry Andric bool MIParser::parseBlockAddressOperand(MachineOperand &Dest) {
25190b57cec5SDimitry Andric assert(Token.is(MIToken::kw_blockaddress));
25200b57cec5SDimitry Andric lex();
25210b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen))
25220b57cec5SDimitry Andric return true;
25230b57cec5SDimitry Andric if (Token.isNot(MIToken::GlobalValue) &&
25240b57cec5SDimitry Andric Token.isNot(MIToken::NamedGlobalValue))
25250b57cec5SDimitry Andric return error("expected a global value");
25260b57cec5SDimitry Andric GlobalValue *GV = nullptr;
25270b57cec5SDimitry Andric if (parseGlobalValue(GV))
25280b57cec5SDimitry Andric return true;
25290b57cec5SDimitry Andric auto *F = dyn_cast<Function>(GV);
25300b57cec5SDimitry Andric if (!F)
25310b57cec5SDimitry Andric return error("expected an IR function reference");
25320b57cec5SDimitry Andric lex();
25330b57cec5SDimitry Andric if (expectAndConsume(MIToken::comma))
25340b57cec5SDimitry Andric return true;
25350b57cec5SDimitry Andric BasicBlock *BB = nullptr;
25360b57cec5SDimitry Andric if (Token.isNot(MIToken::IRBlock) && Token.isNot(MIToken::NamedIRBlock))
25370b57cec5SDimitry Andric return error("expected an IR block reference");
25380b57cec5SDimitry Andric if (parseIRBlock(BB, *F))
25390b57cec5SDimitry Andric return true;
25400b57cec5SDimitry Andric lex();
25410b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
25420b57cec5SDimitry Andric return true;
25430b57cec5SDimitry Andric Dest = MachineOperand::CreateBA(BlockAddress::get(F, BB), /*Offset=*/0);
25440b57cec5SDimitry Andric if (parseOperandsOffset(Dest))
25450b57cec5SDimitry Andric return true;
25460b57cec5SDimitry Andric return false;
25470b57cec5SDimitry Andric }
25480b57cec5SDimitry Andric
parseIntrinsicOperand(MachineOperand & Dest)25490b57cec5SDimitry Andric bool MIParser::parseIntrinsicOperand(MachineOperand &Dest) {
25500b57cec5SDimitry Andric assert(Token.is(MIToken::kw_intrinsic));
25510b57cec5SDimitry Andric lex();
25520b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen))
25530b57cec5SDimitry Andric return error("expected syntax intrinsic(@llvm.whatever)");
25540b57cec5SDimitry Andric
25550b57cec5SDimitry Andric if (Token.isNot(MIToken::NamedGlobalValue))
25560b57cec5SDimitry Andric return error("expected syntax intrinsic(@llvm.whatever)");
25570b57cec5SDimitry Andric
25585ffd83dbSDimitry Andric std::string Name = std::string(Token.stringValue());
25590b57cec5SDimitry Andric lex();
25600b57cec5SDimitry Andric
25610b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
25620b57cec5SDimitry Andric return error("expected ')' to terminate intrinsic name");
25630b57cec5SDimitry Andric
25640b57cec5SDimitry Andric // Find out what intrinsic we're dealing with, first try the global namespace
25650b57cec5SDimitry Andric // and then the target's private intrinsics if that fails.
25660b57cec5SDimitry Andric const TargetIntrinsicInfo *TII = MF.getTarget().getIntrinsicInfo();
25670b57cec5SDimitry Andric Intrinsic::ID ID = Function::lookupIntrinsicID(Name);
25680b57cec5SDimitry Andric if (ID == Intrinsic::not_intrinsic && TII)
25690b57cec5SDimitry Andric ID = static_cast<Intrinsic::ID>(TII->lookupName(Name));
25700b57cec5SDimitry Andric
25710b57cec5SDimitry Andric if (ID == Intrinsic::not_intrinsic)
25720b57cec5SDimitry Andric return error("unknown intrinsic name");
25730b57cec5SDimitry Andric Dest = MachineOperand::CreateIntrinsicID(ID);
25740b57cec5SDimitry Andric
25750b57cec5SDimitry Andric return false;
25760b57cec5SDimitry Andric }
25770b57cec5SDimitry Andric
parsePredicateOperand(MachineOperand & Dest)25780b57cec5SDimitry Andric bool MIParser::parsePredicateOperand(MachineOperand &Dest) {
25790b57cec5SDimitry Andric assert(Token.is(MIToken::kw_intpred) || Token.is(MIToken::kw_floatpred));
25800b57cec5SDimitry Andric bool IsFloat = Token.is(MIToken::kw_floatpred);
25810b57cec5SDimitry Andric lex();
25820b57cec5SDimitry Andric
25830b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen))
25840b57cec5SDimitry Andric return error("expected syntax intpred(whatever) or floatpred(whatever");
25850b57cec5SDimitry Andric
25860b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier))
25870b57cec5SDimitry Andric return error("whatever");
25880b57cec5SDimitry Andric
25890b57cec5SDimitry Andric CmpInst::Predicate Pred;
25900b57cec5SDimitry Andric if (IsFloat) {
25910b57cec5SDimitry Andric Pred = StringSwitch<CmpInst::Predicate>(Token.stringValue())
25920b57cec5SDimitry Andric .Case("false", CmpInst::FCMP_FALSE)
25930b57cec5SDimitry Andric .Case("oeq", CmpInst::FCMP_OEQ)
25940b57cec5SDimitry Andric .Case("ogt", CmpInst::FCMP_OGT)
25950b57cec5SDimitry Andric .Case("oge", CmpInst::FCMP_OGE)
25960b57cec5SDimitry Andric .Case("olt", CmpInst::FCMP_OLT)
25970b57cec5SDimitry Andric .Case("ole", CmpInst::FCMP_OLE)
25980b57cec5SDimitry Andric .Case("one", CmpInst::FCMP_ONE)
25990b57cec5SDimitry Andric .Case("ord", CmpInst::FCMP_ORD)
26000b57cec5SDimitry Andric .Case("uno", CmpInst::FCMP_UNO)
26010b57cec5SDimitry Andric .Case("ueq", CmpInst::FCMP_UEQ)
26020b57cec5SDimitry Andric .Case("ugt", CmpInst::FCMP_UGT)
26030b57cec5SDimitry Andric .Case("uge", CmpInst::FCMP_UGE)
26040b57cec5SDimitry Andric .Case("ult", CmpInst::FCMP_ULT)
26050b57cec5SDimitry Andric .Case("ule", CmpInst::FCMP_ULE)
26060b57cec5SDimitry Andric .Case("une", CmpInst::FCMP_UNE)
26070b57cec5SDimitry Andric .Case("true", CmpInst::FCMP_TRUE)
26080b57cec5SDimitry Andric .Default(CmpInst::BAD_FCMP_PREDICATE);
26090b57cec5SDimitry Andric if (!CmpInst::isFPPredicate(Pred))
26100b57cec5SDimitry Andric return error("invalid floating-point predicate");
26110b57cec5SDimitry Andric } else {
26120b57cec5SDimitry Andric Pred = StringSwitch<CmpInst::Predicate>(Token.stringValue())
26130b57cec5SDimitry Andric .Case("eq", CmpInst::ICMP_EQ)
26140b57cec5SDimitry Andric .Case("ne", CmpInst::ICMP_NE)
26150b57cec5SDimitry Andric .Case("sgt", CmpInst::ICMP_SGT)
26160b57cec5SDimitry Andric .Case("sge", CmpInst::ICMP_SGE)
26170b57cec5SDimitry Andric .Case("slt", CmpInst::ICMP_SLT)
26180b57cec5SDimitry Andric .Case("sle", CmpInst::ICMP_SLE)
26190b57cec5SDimitry Andric .Case("ugt", CmpInst::ICMP_UGT)
26200b57cec5SDimitry Andric .Case("uge", CmpInst::ICMP_UGE)
26210b57cec5SDimitry Andric .Case("ult", CmpInst::ICMP_ULT)
26220b57cec5SDimitry Andric .Case("ule", CmpInst::ICMP_ULE)
26230b57cec5SDimitry Andric .Default(CmpInst::BAD_ICMP_PREDICATE);
26240b57cec5SDimitry Andric if (!CmpInst::isIntPredicate(Pred))
26250b57cec5SDimitry Andric return error("invalid integer predicate");
26260b57cec5SDimitry Andric }
26270b57cec5SDimitry Andric
26280b57cec5SDimitry Andric lex();
26290b57cec5SDimitry Andric Dest = MachineOperand::CreatePredicate(Pred);
26300b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
26310b57cec5SDimitry Andric return error("predicate should be terminated by ')'.");
26320b57cec5SDimitry Andric
26330b57cec5SDimitry Andric return false;
26340b57cec5SDimitry Andric }
26350b57cec5SDimitry Andric
parseShuffleMaskOperand(MachineOperand & Dest)26368bcb0991SDimitry Andric bool MIParser::parseShuffleMaskOperand(MachineOperand &Dest) {
26378bcb0991SDimitry Andric assert(Token.is(MIToken::kw_shufflemask));
26388bcb0991SDimitry Andric
26398bcb0991SDimitry Andric lex();
26408bcb0991SDimitry Andric if (expectAndConsume(MIToken::lparen))
26418bcb0991SDimitry Andric return error("expected syntax shufflemask(<integer or undef>, ...)");
26428bcb0991SDimitry Andric
2643480093f4SDimitry Andric SmallVector<int, 32> ShufMask;
26448bcb0991SDimitry Andric do {
26458bcb0991SDimitry Andric if (Token.is(MIToken::kw_undef)) {
2646480093f4SDimitry Andric ShufMask.push_back(-1);
26478bcb0991SDimitry Andric } else if (Token.is(MIToken::IntegerLiteral)) {
26488bcb0991SDimitry Andric const APSInt &Int = Token.integerValue();
2649480093f4SDimitry Andric ShufMask.push_back(Int.getExtValue());
26508bcb0991SDimitry Andric } else
26518bcb0991SDimitry Andric return error("expected integer constant");
26528bcb0991SDimitry Andric
26538bcb0991SDimitry Andric lex();
26548bcb0991SDimitry Andric } while (consumeIfPresent(MIToken::comma));
26558bcb0991SDimitry Andric
26568bcb0991SDimitry Andric if (expectAndConsume(MIToken::rparen))
26578bcb0991SDimitry Andric return error("shufflemask should be terminated by ')'.");
26588bcb0991SDimitry Andric
2659480093f4SDimitry Andric ArrayRef<int> MaskAlloc = MF.allocateShuffleMask(ShufMask);
2660480093f4SDimitry Andric Dest = MachineOperand::CreateShuffleMask(MaskAlloc);
26618bcb0991SDimitry Andric return false;
26628bcb0991SDimitry Andric }
26638bcb0991SDimitry Andric
parseTargetIndexOperand(MachineOperand & Dest)26640b57cec5SDimitry Andric bool MIParser::parseTargetIndexOperand(MachineOperand &Dest) {
26650b57cec5SDimitry Andric assert(Token.is(MIToken::kw_target_index));
26660b57cec5SDimitry Andric lex();
26670b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen))
26680b57cec5SDimitry Andric return true;
26690b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier))
26700b57cec5SDimitry Andric return error("expected the name of the target index");
26710b57cec5SDimitry Andric int Index = 0;
26720b57cec5SDimitry Andric if (PFS.Target.getTargetIndex(Token.stringValue(), Index))
26730b57cec5SDimitry Andric return error("use of undefined target index '" + Token.stringValue() + "'");
26740b57cec5SDimitry Andric lex();
26750b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
26760b57cec5SDimitry Andric return true;
26770b57cec5SDimitry Andric Dest = MachineOperand::CreateTargetIndex(unsigned(Index), /*Offset=*/0);
26780b57cec5SDimitry Andric if (parseOperandsOffset(Dest))
26790b57cec5SDimitry Andric return true;
26800b57cec5SDimitry Andric return false;
26810b57cec5SDimitry Andric }
26820b57cec5SDimitry Andric
parseCustomRegisterMaskOperand(MachineOperand & Dest)26830b57cec5SDimitry Andric bool MIParser::parseCustomRegisterMaskOperand(MachineOperand &Dest) {
26840b57cec5SDimitry Andric assert(Token.stringValue() == "CustomRegMask" && "Expected a custom RegMask");
26850b57cec5SDimitry Andric lex();
26860b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen))
26870b57cec5SDimitry Andric return true;
26880b57cec5SDimitry Andric
26890b57cec5SDimitry Andric uint32_t *Mask = MF.allocateRegMask();
26900b57cec5SDimitry Andric while (true) {
26910b57cec5SDimitry Andric if (Token.isNot(MIToken::NamedRegister))
26920b57cec5SDimitry Andric return error("expected a named register");
26935ffd83dbSDimitry Andric Register Reg;
26940b57cec5SDimitry Andric if (parseNamedRegister(Reg))
26950b57cec5SDimitry Andric return true;
26960b57cec5SDimitry Andric lex();
26970b57cec5SDimitry Andric Mask[Reg / 32] |= 1U << (Reg % 32);
26980b57cec5SDimitry Andric // TODO: Report an error if the same register is used more than once.
26990b57cec5SDimitry Andric if (Token.isNot(MIToken::comma))
27000b57cec5SDimitry Andric break;
27010b57cec5SDimitry Andric lex();
27020b57cec5SDimitry Andric }
27030b57cec5SDimitry Andric
27040b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
27050b57cec5SDimitry Andric return true;
27060b57cec5SDimitry Andric Dest = MachineOperand::CreateRegMask(Mask);
27070b57cec5SDimitry Andric return false;
27080b57cec5SDimitry Andric }
27090b57cec5SDimitry Andric
parseLiveoutRegisterMaskOperand(MachineOperand & Dest)27100b57cec5SDimitry Andric bool MIParser::parseLiveoutRegisterMaskOperand(MachineOperand &Dest) {
27110b57cec5SDimitry Andric assert(Token.is(MIToken::kw_liveout));
27120b57cec5SDimitry Andric uint32_t *Mask = MF.allocateRegMask();
27130b57cec5SDimitry Andric lex();
27140b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen))
27150b57cec5SDimitry Andric return true;
27160b57cec5SDimitry Andric while (true) {
27170b57cec5SDimitry Andric if (Token.isNot(MIToken::NamedRegister))
27180b57cec5SDimitry Andric return error("expected a named register");
27195ffd83dbSDimitry Andric Register Reg;
27200b57cec5SDimitry Andric if (parseNamedRegister(Reg))
27210b57cec5SDimitry Andric return true;
27220b57cec5SDimitry Andric lex();
27230b57cec5SDimitry Andric Mask[Reg / 32] |= 1U << (Reg % 32);
27240b57cec5SDimitry Andric // TODO: Report an error if the same register is used more than once.
27250b57cec5SDimitry Andric if (Token.isNot(MIToken::comma))
27260b57cec5SDimitry Andric break;
27270b57cec5SDimitry Andric lex();
27280b57cec5SDimitry Andric }
27290b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
27300b57cec5SDimitry Andric return true;
27310b57cec5SDimitry Andric Dest = MachineOperand::CreateRegLiveOut(Mask);
27320b57cec5SDimitry Andric return false;
27330b57cec5SDimitry Andric }
27340b57cec5SDimitry Andric
parseMachineOperand(const unsigned OpCode,const unsigned OpIdx,MachineOperand & Dest,Optional<unsigned> & TiedDefIdx)2735480093f4SDimitry Andric bool MIParser::parseMachineOperand(const unsigned OpCode, const unsigned OpIdx,
2736480093f4SDimitry Andric MachineOperand &Dest,
27370b57cec5SDimitry Andric Optional<unsigned> &TiedDefIdx) {
27380b57cec5SDimitry Andric switch (Token.kind()) {
27390b57cec5SDimitry Andric case MIToken::kw_implicit:
27400b57cec5SDimitry Andric case MIToken::kw_implicit_define:
27410b57cec5SDimitry Andric case MIToken::kw_def:
27420b57cec5SDimitry Andric case MIToken::kw_dead:
27430b57cec5SDimitry Andric case MIToken::kw_killed:
27440b57cec5SDimitry Andric case MIToken::kw_undef:
27450b57cec5SDimitry Andric case MIToken::kw_internal:
27460b57cec5SDimitry Andric case MIToken::kw_early_clobber:
27470b57cec5SDimitry Andric case MIToken::kw_debug_use:
27480b57cec5SDimitry Andric case MIToken::kw_renamable:
27490b57cec5SDimitry Andric case MIToken::underscore:
27500b57cec5SDimitry Andric case MIToken::NamedRegister:
27510b57cec5SDimitry Andric case MIToken::VirtualRegister:
27520b57cec5SDimitry Andric case MIToken::NamedVirtualRegister:
27530b57cec5SDimitry Andric return parseRegisterOperand(Dest, TiedDefIdx);
27540b57cec5SDimitry Andric case MIToken::IntegerLiteral:
27550b57cec5SDimitry Andric return parseImmediateOperand(Dest);
27560b57cec5SDimitry Andric case MIToken::kw_half:
27570b57cec5SDimitry Andric case MIToken::kw_float:
27580b57cec5SDimitry Andric case MIToken::kw_double:
27590b57cec5SDimitry Andric case MIToken::kw_x86_fp80:
27600b57cec5SDimitry Andric case MIToken::kw_fp128:
27610b57cec5SDimitry Andric case MIToken::kw_ppc_fp128:
27620b57cec5SDimitry Andric return parseFPImmediateOperand(Dest);
27630b57cec5SDimitry Andric case MIToken::MachineBasicBlock:
27640b57cec5SDimitry Andric return parseMBBOperand(Dest);
27650b57cec5SDimitry Andric case MIToken::StackObject:
27660b57cec5SDimitry Andric return parseStackObjectOperand(Dest);
27670b57cec5SDimitry Andric case MIToken::FixedStackObject:
27680b57cec5SDimitry Andric return parseFixedStackObjectOperand(Dest);
27690b57cec5SDimitry Andric case MIToken::GlobalValue:
27700b57cec5SDimitry Andric case MIToken::NamedGlobalValue:
27710b57cec5SDimitry Andric return parseGlobalAddressOperand(Dest);
27720b57cec5SDimitry Andric case MIToken::ConstantPoolItem:
27730b57cec5SDimitry Andric return parseConstantPoolIndexOperand(Dest);
27740b57cec5SDimitry Andric case MIToken::JumpTableIndex:
27750b57cec5SDimitry Andric return parseJumpTableIndexOperand(Dest);
27760b57cec5SDimitry Andric case MIToken::ExternalSymbol:
27770b57cec5SDimitry Andric return parseExternalSymbolOperand(Dest);
27780b57cec5SDimitry Andric case MIToken::MCSymbol:
27790b57cec5SDimitry Andric return parseMCSymbolOperand(Dest);
27800b57cec5SDimitry Andric case MIToken::SubRegisterIndex:
27810b57cec5SDimitry Andric return parseSubRegisterIndexOperand(Dest);
27820b57cec5SDimitry Andric case MIToken::md_diexpr:
27830b57cec5SDimitry Andric case MIToken::exclaim:
27840b57cec5SDimitry Andric return parseMetadataOperand(Dest);
27850b57cec5SDimitry Andric case MIToken::kw_cfi_same_value:
27860b57cec5SDimitry Andric case MIToken::kw_cfi_offset:
27870b57cec5SDimitry Andric case MIToken::kw_cfi_rel_offset:
27880b57cec5SDimitry Andric case MIToken::kw_cfi_def_cfa_register:
27890b57cec5SDimitry Andric case MIToken::kw_cfi_def_cfa_offset:
27900b57cec5SDimitry Andric case MIToken::kw_cfi_adjust_cfa_offset:
27910b57cec5SDimitry Andric case MIToken::kw_cfi_escape:
27920b57cec5SDimitry Andric case MIToken::kw_cfi_def_cfa:
2793*5f7ddb14SDimitry Andric case MIToken::kw_cfi_llvm_def_aspace_cfa:
27940b57cec5SDimitry Andric case MIToken::kw_cfi_register:
27950b57cec5SDimitry Andric case MIToken::kw_cfi_remember_state:
27960b57cec5SDimitry Andric case MIToken::kw_cfi_restore:
27970b57cec5SDimitry Andric case MIToken::kw_cfi_restore_state:
27980b57cec5SDimitry Andric case MIToken::kw_cfi_undefined:
27990b57cec5SDimitry Andric case MIToken::kw_cfi_window_save:
28000b57cec5SDimitry Andric case MIToken::kw_cfi_aarch64_negate_ra_sign_state:
28010b57cec5SDimitry Andric return parseCFIOperand(Dest);
28020b57cec5SDimitry Andric case MIToken::kw_blockaddress:
28030b57cec5SDimitry Andric return parseBlockAddressOperand(Dest);
28040b57cec5SDimitry Andric case MIToken::kw_intrinsic:
28050b57cec5SDimitry Andric return parseIntrinsicOperand(Dest);
28060b57cec5SDimitry Andric case MIToken::kw_target_index:
28070b57cec5SDimitry Andric return parseTargetIndexOperand(Dest);
28080b57cec5SDimitry Andric case MIToken::kw_liveout:
28090b57cec5SDimitry Andric return parseLiveoutRegisterMaskOperand(Dest);
28100b57cec5SDimitry Andric case MIToken::kw_floatpred:
28110b57cec5SDimitry Andric case MIToken::kw_intpred:
28120b57cec5SDimitry Andric return parsePredicateOperand(Dest);
28138bcb0991SDimitry Andric case MIToken::kw_shufflemask:
28148bcb0991SDimitry Andric return parseShuffleMaskOperand(Dest);
28150b57cec5SDimitry Andric case MIToken::Error:
28160b57cec5SDimitry Andric return true;
28170b57cec5SDimitry Andric case MIToken::Identifier:
28180b57cec5SDimitry Andric if (const auto *RegMask = PFS.Target.getRegMask(Token.stringValue())) {
28190b57cec5SDimitry Andric Dest = MachineOperand::CreateRegMask(RegMask);
28200b57cec5SDimitry Andric lex();
28210b57cec5SDimitry Andric break;
28220b57cec5SDimitry Andric } else if (Token.stringValue() == "CustomRegMask") {
28230b57cec5SDimitry Andric return parseCustomRegisterMaskOperand(Dest);
28240b57cec5SDimitry Andric } else
28250b57cec5SDimitry Andric return parseTypedImmediateOperand(Dest);
2826480093f4SDimitry Andric case MIToken::dot: {
2827480093f4SDimitry Andric const auto *TII = MF.getSubtarget().getInstrInfo();
2828480093f4SDimitry Andric if (const auto *Formatter = TII->getMIRFormatter()) {
2829480093f4SDimitry Andric return parseTargetImmMnemonic(OpCode, OpIdx, Dest, *Formatter);
2830480093f4SDimitry Andric }
2831480093f4SDimitry Andric LLVM_FALLTHROUGH;
2832480093f4SDimitry Andric }
28330b57cec5SDimitry Andric default:
28340b57cec5SDimitry Andric // FIXME: Parse the MCSymbol machine operand.
28350b57cec5SDimitry Andric return error("expected a machine operand");
28360b57cec5SDimitry Andric }
28370b57cec5SDimitry Andric return false;
28380b57cec5SDimitry Andric }
28390b57cec5SDimitry Andric
parseMachineOperandAndTargetFlags(const unsigned OpCode,const unsigned OpIdx,MachineOperand & Dest,Optional<unsigned> & TiedDefIdx)28400b57cec5SDimitry Andric bool MIParser::parseMachineOperandAndTargetFlags(
2841480093f4SDimitry Andric const unsigned OpCode, const unsigned OpIdx, MachineOperand &Dest,
2842480093f4SDimitry Andric Optional<unsigned> &TiedDefIdx) {
28430b57cec5SDimitry Andric unsigned TF = 0;
28440b57cec5SDimitry Andric bool HasTargetFlags = false;
28450b57cec5SDimitry Andric if (Token.is(MIToken::kw_target_flags)) {
28460b57cec5SDimitry Andric HasTargetFlags = true;
28470b57cec5SDimitry Andric lex();
28480b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen))
28490b57cec5SDimitry Andric return true;
28500b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier))
28510b57cec5SDimitry Andric return error("expected the name of the target flag");
28520b57cec5SDimitry Andric if (PFS.Target.getDirectTargetFlag(Token.stringValue(), TF)) {
28530b57cec5SDimitry Andric if (PFS.Target.getBitmaskTargetFlag(Token.stringValue(), TF))
28540b57cec5SDimitry Andric return error("use of undefined target flag '" + Token.stringValue() +
28550b57cec5SDimitry Andric "'");
28560b57cec5SDimitry Andric }
28570b57cec5SDimitry Andric lex();
28580b57cec5SDimitry Andric while (Token.is(MIToken::comma)) {
28590b57cec5SDimitry Andric lex();
28600b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier))
28610b57cec5SDimitry Andric return error("expected the name of the target flag");
28620b57cec5SDimitry Andric unsigned BitFlag = 0;
28630b57cec5SDimitry Andric if (PFS.Target.getBitmaskTargetFlag(Token.stringValue(), BitFlag))
28640b57cec5SDimitry Andric return error("use of undefined target flag '" + Token.stringValue() +
28650b57cec5SDimitry Andric "'");
28660b57cec5SDimitry Andric // TODO: Report an error when using a duplicate bit target flag.
28670b57cec5SDimitry Andric TF |= BitFlag;
28680b57cec5SDimitry Andric lex();
28690b57cec5SDimitry Andric }
28700b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
28710b57cec5SDimitry Andric return true;
28720b57cec5SDimitry Andric }
28730b57cec5SDimitry Andric auto Loc = Token.location();
2874480093f4SDimitry Andric if (parseMachineOperand(OpCode, OpIdx, Dest, TiedDefIdx))
28750b57cec5SDimitry Andric return true;
28760b57cec5SDimitry Andric if (!HasTargetFlags)
28770b57cec5SDimitry Andric return false;
28780b57cec5SDimitry Andric if (Dest.isReg())
28790b57cec5SDimitry Andric return error(Loc, "register operands can't have target flags");
28800b57cec5SDimitry Andric Dest.setTargetFlags(TF);
28810b57cec5SDimitry Andric return false;
28820b57cec5SDimitry Andric }
28830b57cec5SDimitry Andric
parseOffset(int64_t & Offset)28840b57cec5SDimitry Andric bool MIParser::parseOffset(int64_t &Offset) {
28850b57cec5SDimitry Andric if (Token.isNot(MIToken::plus) && Token.isNot(MIToken::minus))
28860b57cec5SDimitry Andric return false;
28870b57cec5SDimitry Andric StringRef Sign = Token.range();
28880b57cec5SDimitry Andric bool IsNegative = Token.is(MIToken::minus);
28890b57cec5SDimitry Andric lex();
28900b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral))
28910b57cec5SDimitry Andric return error("expected an integer literal after '" + Sign + "'");
28920b57cec5SDimitry Andric if (Token.integerValue().getMinSignedBits() > 64)
28930b57cec5SDimitry Andric return error("expected 64-bit integer (too large)");
28940b57cec5SDimitry Andric Offset = Token.integerValue().getExtValue();
28950b57cec5SDimitry Andric if (IsNegative)
28960b57cec5SDimitry Andric Offset = -Offset;
28970b57cec5SDimitry Andric lex();
28980b57cec5SDimitry Andric return false;
28990b57cec5SDimitry Andric }
29000b57cec5SDimitry Andric
parseAlignment(unsigned & Alignment)29010b57cec5SDimitry Andric bool MIParser::parseAlignment(unsigned &Alignment) {
2902af732203SDimitry Andric assert(Token.is(MIToken::kw_align) || Token.is(MIToken::kw_basealign));
29030b57cec5SDimitry Andric lex();
29040b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned())
29050b57cec5SDimitry Andric return error("expected an integer literal after 'align'");
29060b57cec5SDimitry Andric if (getUnsigned(Alignment))
29070b57cec5SDimitry Andric return true;
29080b57cec5SDimitry Andric lex();
29090b57cec5SDimitry Andric
29100b57cec5SDimitry Andric if (!isPowerOf2_32(Alignment))
29110b57cec5SDimitry Andric return error("expected a power-of-2 literal after 'align'");
29120b57cec5SDimitry Andric
29130b57cec5SDimitry Andric return false;
29140b57cec5SDimitry Andric }
29150b57cec5SDimitry Andric
parseAddrspace(unsigned & Addrspace)29160b57cec5SDimitry Andric bool MIParser::parseAddrspace(unsigned &Addrspace) {
29170b57cec5SDimitry Andric assert(Token.is(MIToken::kw_addrspace));
29180b57cec5SDimitry Andric lex();
29190b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned())
29200b57cec5SDimitry Andric return error("expected an integer literal after 'addrspace'");
29210b57cec5SDimitry Andric if (getUnsigned(Addrspace))
29220b57cec5SDimitry Andric return true;
29230b57cec5SDimitry Andric lex();
29240b57cec5SDimitry Andric return false;
29250b57cec5SDimitry Andric }
29260b57cec5SDimitry Andric
parseOperandsOffset(MachineOperand & Op)29270b57cec5SDimitry Andric bool MIParser::parseOperandsOffset(MachineOperand &Op) {
29280b57cec5SDimitry Andric int64_t Offset = 0;
29290b57cec5SDimitry Andric if (parseOffset(Offset))
29300b57cec5SDimitry Andric return true;
29310b57cec5SDimitry Andric Op.setOffset(Offset);
29320b57cec5SDimitry Andric return false;
29330b57cec5SDimitry Andric }
29340b57cec5SDimitry Andric
parseIRValue(const MIToken & Token,PerFunctionMIParsingState & PFS,const Value * & V,ErrorCallbackType ErrCB)2935480093f4SDimitry Andric static bool parseIRValue(const MIToken &Token, PerFunctionMIParsingState &PFS,
2936480093f4SDimitry Andric const Value *&V, ErrorCallbackType ErrCB) {
29370b57cec5SDimitry Andric switch (Token.kind()) {
29380b57cec5SDimitry Andric case MIToken::NamedIRValue: {
2939480093f4SDimitry Andric V = PFS.MF.getFunction().getValueSymbolTable()->lookup(Token.stringValue());
29400b57cec5SDimitry Andric break;
29410b57cec5SDimitry Andric }
29420b57cec5SDimitry Andric case MIToken::IRValue: {
29430b57cec5SDimitry Andric unsigned SlotNumber = 0;
2944480093f4SDimitry Andric if (getUnsigned(Token, SlotNumber, ErrCB))
29450b57cec5SDimitry Andric return true;
2946480093f4SDimitry Andric V = PFS.getIRValue(SlotNumber);
29470b57cec5SDimitry Andric break;
29480b57cec5SDimitry Andric }
29490b57cec5SDimitry Andric case MIToken::NamedGlobalValue:
29500b57cec5SDimitry Andric case MIToken::GlobalValue: {
29510b57cec5SDimitry Andric GlobalValue *GV = nullptr;
2952480093f4SDimitry Andric if (parseGlobalValue(Token, PFS, GV, ErrCB))
29530b57cec5SDimitry Andric return true;
29540b57cec5SDimitry Andric V = GV;
29550b57cec5SDimitry Andric break;
29560b57cec5SDimitry Andric }
29570b57cec5SDimitry Andric case MIToken::QuotedIRValue: {
29580b57cec5SDimitry Andric const Constant *C = nullptr;
2959480093f4SDimitry Andric if (parseIRConstant(Token.location(), Token.stringValue(), PFS, C, ErrCB))
29600b57cec5SDimitry Andric return true;
29610b57cec5SDimitry Andric V = C;
29620b57cec5SDimitry Andric break;
29630b57cec5SDimitry Andric }
2964*5f7ddb14SDimitry Andric case MIToken::kw_unknown_address:
2965*5f7ddb14SDimitry Andric V = nullptr;
2966*5f7ddb14SDimitry Andric return false;
29670b57cec5SDimitry Andric default:
29680b57cec5SDimitry Andric llvm_unreachable("The current token should be an IR block reference");
29690b57cec5SDimitry Andric }
29700b57cec5SDimitry Andric if (!V)
2971480093f4SDimitry Andric return ErrCB(Token.location(), Twine("use of undefined IR value '") + Token.range() + "'");
29720b57cec5SDimitry Andric return false;
29730b57cec5SDimitry Andric }
29740b57cec5SDimitry Andric
parseIRValue(const Value * & V)2975480093f4SDimitry Andric bool MIParser::parseIRValue(const Value *&V) {
2976480093f4SDimitry Andric return ::parseIRValue(
2977480093f4SDimitry Andric Token, PFS, V, [this](StringRef::iterator Loc, const Twine &Msg) -> bool {
2978480093f4SDimitry Andric return error(Loc, Msg);
2979480093f4SDimitry Andric });
2980480093f4SDimitry Andric }
2981480093f4SDimitry Andric
getUint64(uint64_t & Result)29820b57cec5SDimitry Andric bool MIParser::getUint64(uint64_t &Result) {
29830b57cec5SDimitry Andric if (Token.hasIntegerValue()) {
29840b57cec5SDimitry Andric if (Token.integerValue().getActiveBits() > 64)
29850b57cec5SDimitry Andric return error("expected 64-bit integer (too large)");
29860b57cec5SDimitry Andric Result = Token.integerValue().getZExtValue();
29870b57cec5SDimitry Andric return false;
29880b57cec5SDimitry Andric }
29890b57cec5SDimitry Andric if (Token.is(MIToken::HexLiteral)) {
29900b57cec5SDimitry Andric APInt A;
29910b57cec5SDimitry Andric if (getHexUint(A))
29920b57cec5SDimitry Andric return true;
29930b57cec5SDimitry Andric if (A.getBitWidth() > 64)
29940b57cec5SDimitry Andric return error("expected 64-bit integer (too large)");
29950b57cec5SDimitry Andric Result = A.getZExtValue();
29960b57cec5SDimitry Andric return false;
29970b57cec5SDimitry Andric }
29980b57cec5SDimitry Andric return true;
29990b57cec5SDimitry Andric }
30000b57cec5SDimitry Andric
getHexUint(APInt & Result)30010b57cec5SDimitry Andric bool MIParser::getHexUint(APInt &Result) {
3002480093f4SDimitry Andric return ::getHexUint(Token, Result);
30030b57cec5SDimitry Andric }
30040b57cec5SDimitry Andric
parseMemoryOperandFlag(MachineMemOperand::Flags & Flags)30050b57cec5SDimitry Andric bool MIParser::parseMemoryOperandFlag(MachineMemOperand::Flags &Flags) {
30060b57cec5SDimitry Andric const auto OldFlags = Flags;
30070b57cec5SDimitry Andric switch (Token.kind()) {
30080b57cec5SDimitry Andric case MIToken::kw_volatile:
30090b57cec5SDimitry Andric Flags |= MachineMemOperand::MOVolatile;
30100b57cec5SDimitry Andric break;
30110b57cec5SDimitry Andric case MIToken::kw_non_temporal:
30120b57cec5SDimitry Andric Flags |= MachineMemOperand::MONonTemporal;
30130b57cec5SDimitry Andric break;
30140b57cec5SDimitry Andric case MIToken::kw_dereferenceable:
30150b57cec5SDimitry Andric Flags |= MachineMemOperand::MODereferenceable;
30160b57cec5SDimitry Andric break;
30170b57cec5SDimitry Andric case MIToken::kw_invariant:
30180b57cec5SDimitry Andric Flags |= MachineMemOperand::MOInvariant;
30190b57cec5SDimitry Andric break;
30200b57cec5SDimitry Andric case MIToken::StringConstant: {
30210b57cec5SDimitry Andric MachineMemOperand::Flags TF;
30220b57cec5SDimitry Andric if (PFS.Target.getMMOTargetFlag(Token.stringValue(), TF))
30230b57cec5SDimitry Andric return error("use of undefined target MMO flag '" + Token.stringValue() +
30240b57cec5SDimitry Andric "'");
30250b57cec5SDimitry Andric Flags |= TF;
30260b57cec5SDimitry Andric break;
30270b57cec5SDimitry Andric }
30280b57cec5SDimitry Andric default:
30290b57cec5SDimitry Andric llvm_unreachable("The current token should be a memory operand flag");
30300b57cec5SDimitry Andric }
30310b57cec5SDimitry Andric if (OldFlags == Flags)
30320b57cec5SDimitry Andric // We know that the same flag is specified more than once when the flags
30330b57cec5SDimitry Andric // weren't modified.
30340b57cec5SDimitry Andric return error("duplicate '" + Token.stringValue() + "' memory operand flag");
30350b57cec5SDimitry Andric lex();
30360b57cec5SDimitry Andric return false;
30370b57cec5SDimitry Andric }
30380b57cec5SDimitry Andric
parseMemoryPseudoSourceValue(const PseudoSourceValue * & PSV)30390b57cec5SDimitry Andric bool MIParser::parseMemoryPseudoSourceValue(const PseudoSourceValue *&PSV) {
30400b57cec5SDimitry Andric switch (Token.kind()) {
30410b57cec5SDimitry Andric case MIToken::kw_stack:
30420b57cec5SDimitry Andric PSV = MF.getPSVManager().getStack();
30430b57cec5SDimitry Andric break;
30440b57cec5SDimitry Andric case MIToken::kw_got:
30450b57cec5SDimitry Andric PSV = MF.getPSVManager().getGOT();
30460b57cec5SDimitry Andric break;
30470b57cec5SDimitry Andric case MIToken::kw_jump_table:
30480b57cec5SDimitry Andric PSV = MF.getPSVManager().getJumpTable();
30490b57cec5SDimitry Andric break;
30500b57cec5SDimitry Andric case MIToken::kw_constant_pool:
30510b57cec5SDimitry Andric PSV = MF.getPSVManager().getConstantPool();
30520b57cec5SDimitry Andric break;
30530b57cec5SDimitry Andric case MIToken::FixedStackObject: {
30540b57cec5SDimitry Andric int FI;
30550b57cec5SDimitry Andric if (parseFixedStackFrameIndex(FI))
30560b57cec5SDimitry Andric return true;
30570b57cec5SDimitry Andric PSV = MF.getPSVManager().getFixedStack(FI);
30580b57cec5SDimitry Andric // The token was already consumed, so use return here instead of break.
30590b57cec5SDimitry Andric return false;
30600b57cec5SDimitry Andric }
30610b57cec5SDimitry Andric case MIToken::StackObject: {
30620b57cec5SDimitry Andric int FI;
30630b57cec5SDimitry Andric if (parseStackFrameIndex(FI))
30640b57cec5SDimitry Andric return true;
30650b57cec5SDimitry Andric PSV = MF.getPSVManager().getFixedStack(FI);
30660b57cec5SDimitry Andric // The token was already consumed, so use return here instead of break.
30670b57cec5SDimitry Andric return false;
30680b57cec5SDimitry Andric }
30690b57cec5SDimitry Andric case MIToken::kw_call_entry:
30700b57cec5SDimitry Andric lex();
30710b57cec5SDimitry Andric switch (Token.kind()) {
30720b57cec5SDimitry Andric case MIToken::GlobalValue:
30730b57cec5SDimitry Andric case MIToken::NamedGlobalValue: {
30740b57cec5SDimitry Andric GlobalValue *GV = nullptr;
30750b57cec5SDimitry Andric if (parseGlobalValue(GV))
30760b57cec5SDimitry Andric return true;
30770b57cec5SDimitry Andric PSV = MF.getPSVManager().getGlobalValueCallEntry(GV);
30780b57cec5SDimitry Andric break;
30790b57cec5SDimitry Andric }
30800b57cec5SDimitry Andric case MIToken::ExternalSymbol:
30810b57cec5SDimitry Andric PSV = MF.getPSVManager().getExternalSymbolCallEntry(
30820b57cec5SDimitry Andric MF.createExternalSymbolName(Token.stringValue()));
30830b57cec5SDimitry Andric break;
30840b57cec5SDimitry Andric default:
30850b57cec5SDimitry Andric return error(
30860b57cec5SDimitry Andric "expected a global value or an external symbol after 'call-entry'");
30870b57cec5SDimitry Andric }
30880b57cec5SDimitry Andric break;
3089480093f4SDimitry Andric case MIToken::kw_custom: {
3090480093f4SDimitry Andric lex();
3091480093f4SDimitry Andric const auto *TII = MF.getSubtarget().getInstrInfo();
3092480093f4SDimitry Andric if (const auto *Formatter = TII->getMIRFormatter()) {
3093480093f4SDimitry Andric if (Formatter->parseCustomPseudoSourceValue(
3094480093f4SDimitry Andric Token.stringValue(), MF, PFS, PSV,
3095480093f4SDimitry Andric [this](StringRef::iterator Loc, const Twine &Msg) -> bool {
3096480093f4SDimitry Andric return error(Loc, Msg);
3097480093f4SDimitry Andric }))
3098480093f4SDimitry Andric return true;
3099480093f4SDimitry Andric } else
3100480093f4SDimitry Andric return error("unable to parse target custom pseudo source value");
3101480093f4SDimitry Andric break;
3102480093f4SDimitry Andric }
31030b57cec5SDimitry Andric default:
31040b57cec5SDimitry Andric llvm_unreachable("The current token should be pseudo source value");
31050b57cec5SDimitry Andric }
31060b57cec5SDimitry Andric lex();
31070b57cec5SDimitry Andric return false;
31080b57cec5SDimitry Andric }
31090b57cec5SDimitry Andric
parseMachinePointerInfo(MachinePointerInfo & Dest)31100b57cec5SDimitry Andric bool MIParser::parseMachinePointerInfo(MachinePointerInfo &Dest) {
31110b57cec5SDimitry Andric if (Token.is(MIToken::kw_constant_pool) || Token.is(MIToken::kw_stack) ||
31120b57cec5SDimitry Andric Token.is(MIToken::kw_got) || Token.is(MIToken::kw_jump_table) ||
31130b57cec5SDimitry Andric Token.is(MIToken::FixedStackObject) || Token.is(MIToken::StackObject) ||
3114480093f4SDimitry Andric Token.is(MIToken::kw_call_entry) || Token.is(MIToken::kw_custom)) {
31150b57cec5SDimitry Andric const PseudoSourceValue *PSV = nullptr;
31160b57cec5SDimitry Andric if (parseMemoryPseudoSourceValue(PSV))
31170b57cec5SDimitry Andric return true;
31180b57cec5SDimitry Andric int64_t Offset = 0;
31190b57cec5SDimitry Andric if (parseOffset(Offset))
31200b57cec5SDimitry Andric return true;
31210b57cec5SDimitry Andric Dest = MachinePointerInfo(PSV, Offset);
31220b57cec5SDimitry Andric return false;
31230b57cec5SDimitry Andric }
31240b57cec5SDimitry Andric if (Token.isNot(MIToken::NamedIRValue) && Token.isNot(MIToken::IRValue) &&
31250b57cec5SDimitry Andric Token.isNot(MIToken::GlobalValue) &&
31260b57cec5SDimitry Andric Token.isNot(MIToken::NamedGlobalValue) &&
3127*5f7ddb14SDimitry Andric Token.isNot(MIToken::QuotedIRValue) &&
3128*5f7ddb14SDimitry Andric Token.isNot(MIToken::kw_unknown_address))
31290b57cec5SDimitry Andric return error("expected an IR value reference");
31300b57cec5SDimitry Andric const Value *V = nullptr;
31310b57cec5SDimitry Andric if (parseIRValue(V))
31320b57cec5SDimitry Andric return true;
3133*5f7ddb14SDimitry Andric if (V && !V->getType()->isPointerTy())
31340b57cec5SDimitry Andric return error("expected a pointer IR value");
31350b57cec5SDimitry Andric lex();
31360b57cec5SDimitry Andric int64_t Offset = 0;
31370b57cec5SDimitry Andric if (parseOffset(Offset))
31380b57cec5SDimitry Andric return true;
31390b57cec5SDimitry Andric Dest = MachinePointerInfo(V, Offset);
31400b57cec5SDimitry Andric return false;
31410b57cec5SDimitry Andric }
31420b57cec5SDimitry Andric
parseOptionalScope(LLVMContext & Context,SyncScope::ID & SSID)31430b57cec5SDimitry Andric bool MIParser::parseOptionalScope(LLVMContext &Context,
31440b57cec5SDimitry Andric SyncScope::ID &SSID) {
31450b57cec5SDimitry Andric SSID = SyncScope::System;
31460b57cec5SDimitry Andric if (Token.is(MIToken::Identifier) && Token.stringValue() == "syncscope") {
31470b57cec5SDimitry Andric lex();
31480b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen))
31490b57cec5SDimitry Andric return error("expected '(' in syncscope");
31500b57cec5SDimitry Andric
31510b57cec5SDimitry Andric std::string SSN;
31520b57cec5SDimitry Andric if (parseStringConstant(SSN))
31530b57cec5SDimitry Andric return true;
31540b57cec5SDimitry Andric
31550b57cec5SDimitry Andric SSID = Context.getOrInsertSyncScopeID(SSN);
31560b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
31570b57cec5SDimitry Andric return error("expected ')' in syncscope");
31580b57cec5SDimitry Andric }
31590b57cec5SDimitry Andric
31600b57cec5SDimitry Andric return false;
31610b57cec5SDimitry Andric }
31620b57cec5SDimitry Andric
parseOptionalAtomicOrdering(AtomicOrdering & Order)31630b57cec5SDimitry Andric bool MIParser::parseOptionalAtomicOrdering(AtomicOrdering &Order) {
31640b57cec5SDimitry Andric Order = AtomicOrdering::NotAtomic;
31650b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier))
31660b57cec5SDimitry Andric return false;
31670b57cec5SDimitry Andric
31680b57cec5SDimitry Andric Order = StringSwitch<AtomicOrdering>(Token.stringValue())
31690b57cec5SDimitry Andric .Case("unordered", AtomicOrdering::Unordered)
31700b57cec5SDimitry Andric .Case("monotonic", AtomicOrdering::Monotonic)
31710b57cec5SDimitry Andric .Case("acquire", AtomicOrdering::Acquire)
31720b57cec5SDimitry Andric .Case("release", AtomicOrdering::Release)
31730b57cec5SDimitry Andric .Case("acq_rel", AtomicOrdering::AcquireRelease)
31740b57cec5SDimitry Andric .Case("seq_cst", AtomicOrdering::SequentiallyConsistent)
31750b57cec5SDimitry Andric .Default(AtomicOrdering::NotAtomic);
31760b57cec5SDimitry Andric
31770b57cec5SDimitry Andric if (Order != AtomicOrdering::NotAtomic) {
31780b57cec5SDimitry Andric lex();
31790b57cec5SDimitry Andric return false;
31800b57cec5SDimitry Andric }
31810b57cec5SDimitry Andric
31820b57cec5SDimitry Andric return error("expected an atomic scope, ordering or a size specification");
31830b57cec5SDimitry Andric }
31840b57cec5SDimitry Andric
parseMachineMemoryOperand(MachineMemOperand * & Dest)31850b57cec5SDimitry Andric bool MIParser::parseMachineMemoryOperand(MachineMemOperand *&Dest) {
31860b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen))
31870b57cec5SDimitry Andric return true;
31880b57cec5SDimitry Andric MachineMemOperand::Flags Flags = MachineMemOperand::MONone;
31890b57cec5SDimitry Andric while (Token.isMemoryOperandFlag()) {
31900b57cec5SDimitry Andric if (parseMemoryOperandFlag(Flags))
31910b57cec5SDimitry Andric return true;
31920b57cec5SDimitry Andric }
31930b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier) ||
31940b57cec5SDimitry Andric (Token.stringValue() != "load" && Token.stringValue() != "store"))
31950b57cec5SDimitry Andric return error("expected 'load' or 'store' memory operation");
31960b57cec5SDimitry Andric if (Token.stringValue() == "load")
31970b57cec5SDimitry Andric Flags |= MachineMemOperand::MOLoad;
31980b57cec5SDimitry Andric else
31990b57cec5SDimitry Andric Flags |= MachineMemOperand::MOStore;
32000b57cec5SDimitry Andric lex();
32010b57cec5SDimitry Andric
32020b57cec5SDimitry Andric // Optional 'store' for operands that both load and store.
32030b57cec5SDimitry Andric if (Token.is(MIToken::Identifier) && Token.stringValue() == "store") {
32040b57cec5SDimitry Andric Flags |= MachineMemOperand::MOStore;
32050b57cec5SDimitry Andric lex();
32060b57cec5SDimitry Andric }
32070b57cec5SDimitry Andric
32080b57cec5SDimitry Andric // Optional synchronization scope.
32090b57cec5SDimitry Andric SyncScope::ID SSID;
32100b57cec5SDimitry Andric if (parseOptionalScope(MF.getFunction().getContext(), SSID))
32110b57cec5SDimitry Andric return true;
32120b57cec5SDimitry Andric
32130b57cec5SDimitry Andric // Up to two atomic orderings (cmpxchg provides guarantees on failure).
32140b57cec5SDimitry Andric AtomicOrdering Order, FailureOrder;
32150b57cec5SDimitry Andric if (parseOptionalAtomicOrdering(Order))
32160b57cec5SDimitry Andric return true;
32170b57cec5SDimitry Andric
32180b57cec5SDimitry Andric if (parseOptionalAtomicOrdering(FailureOrder))
32190b57cec5SDimitry Andric return true;
32200b57cec5SDimitry Andric
3221*5f7ddb14SDimitry Andric LLT MemoryType;
32220b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) &&
3223*5f7ddb14SDimitry Andric Token.isNot(MIToken::kw_unknown_size) &&
3224*5f7ddb14SDimitry Andric Token.isNot(MIToken::lparen))
3225*5f7ddb14SDimitry Andric return error("expected memory LLT, the size integer literal or 'unknown-size' after "
32260b57cec5SDimitry Andric "memory operation");
3227*5f7ddb14SDimitry Andric
3228*5f7ddb14SDimitry Andric uint64_t Size = MemoryLocation::UnknownSize;
32290b57cec5SDimitry Andric if (Token.is(MIToken::IntegerLiteral)) {
32300b57cec5SDimitry Andric if (getUint64(Size))
32310b57cec5SDimitry Andric return true;
3232*5f7ddb14SDimitry Andric
3233*5f7ddb14SDimitry Andric // Convert from bytes to bits for storage.
3234*5f7ddb14SDimitry Andric MemoryType = LLT::scalar(8 * Size);
3235*5f7ddb14SDimitry Andric lex();
32360b57cec5SDimitry Andric } else if (Token.is(MIToken::kw_unknown_size)) {
32370b57cec5SDimitry Andric Size = MemoryLocation::UnknownSize;
32380b57cec5SDimitry Andric lex();
3239*5f7ddb14SDimitry Andric } else {
3240*5f7ddb14SDimitry Andric if (expectAndConsume(MIToken::lparen))
3241*5f7ddb14SDimitry Andric return true;
3242*5f7ddb14SDimitry Andric if (parseLowLevelType(Token.location(), MemoryType))
3243*5f7ddb14SDimitry Andric return true;
3244*5f7ddb14SDimitry Andric if (expectAndConsume(MIToken::rparen))
3245*5f7ddb14SDimitry Andric return true;
3246*5f7ddb14SDimitry Andric
3247*5f7ddb14SDimitry Andric Size = MemoryType.getSizeInBytes();
3248*5f7ddb14SDimitry Andric }
32490b57cec5SDimitry Andric
32500b57cec5SDimitry Andric MachinePointerInfo Ptr = MachinePointerInfo();
32510b57cec5SDimitry Andric if (Token.is(MIToken::Identifier)) {
32520b57cec5SDimitry Andric const char *Word =
32530b57cec5SDimitry Andric ((Flags & MachineMemOperand::MOLoad) &&
32540b57cec5SDimitry Andric (Flags & MachineMemOperand::MOStore))
32550b57cec5SDimitry Andric ? "on"
32560b57cec5SDimitry Andric : Flags & MachineMemOperand::MOLoad ? "from" : "into";
32570b57cec5SDimitry Andric if (Token.stringValue() != Word)
32580b57cec5SDimitry Andric return error(Twine("expected '") + Word + "'");
32590b57cec5SDimitry Andric lex();
32600b57cec5SDimitry Andric
32610b57cec5SDimitry Andric if (parseMachinePointerInfo(Ptr))
32620b57cec5SDimitry Andric return true;
32630b57cec5SDimitry Andric }
3264*5f7ddb14SDimitry Andric unsigned BaseAlignment =
3265*5f7ddb14SDimitry Andric (Size != MemoryLocation::UnknownSize ? PowerOf2Ceil(Size) : 1);
32660b57cec5SDimitry Andric AAMDNodes AAInfo;
32670b57cec5SDimitry Andric MDNode *Range = nullptr;
32680b57cec5SDimitry Andric while (consumeIfPresent(MIToken::comma)) {
32690b57cec5SDimitry Andric switch (Token.kind()) {
32700b57cec5SDimitry Andric case MIToken::kw_align:
3271af732203SDimitry Andric // align is printed if it is different than size.
3272af732203SDimitry Andric if (parseAlignment(BaseAlignment))
3273af732203SDimitry Andric return true;
3274af732203SDimitry Andric break;
3275af732203SDimitry Andric case MIToken::kw_basealign:
3276af732203SDimitry Andric // basealign is printed if it is different than align.
32770b57cec5SDimitry Andric if (parseAlignment(BaseAlignment))
32780b57cec5SDimitry Andric return true;
32790b57cec5SDimitry Andric break;
32800b57cec5SDimitry Andric case MIToken::kw_addrspace:
32810b57cec5SDimitry Andric if (parseAddrspace(Ptr.AddrSpace))
32820b57cec5SDimitry Andric return true;
32830b57cec5SDimitry Andric break;
32840b57cec5SDimitry Andric case MIToken::md_tbaa:
32850b57cec5SDimitry Andric lex();
32860b57cec5SDimitry Andric if (parseMDNode(AAInfo.TBAA))
32870b57cec5SDimitry Andric return true;
32880b57cec5SDimitry Andric break;
32890b57cec5SDimitry Andric case MIToken::md_alias_scope:
32900b57cec5SDimitry Andric lex();
32910b57cec5SDimitry Andric if (parseMDNode(AAInfo.Scope))
32920b57cec5SDimitry Andric return true;
32930b57cec5SDimitry Andric break;
32940b57cec5SDimitry Andric case MIToken::md_noalias:
32950b57cec5SDimitry Andric lex();
32960b57cec5SDimitry Andric if (parseMDNode(AAInfo.NoAlias))
32970b57cec5SDimitry Andric return true;
32980b57cec5SDimitry Andric break;
32990b57cec5SDimitry Andric case MIToken::md_range:
33000b57cec5SDimitry Andric lex();
33010b57cec5SDimitry Andric if (parseMDNode(Range))
33020b57cec5SDimitry Andric return true;
33030b57cec5SDimitry Andric break;
33040b57cec5SDimitry Andric // TODO: Report an error on duplicate metadata nodes.
33050b57cec5SDimitry Andric default:
33060b57cec5SDimitry Andric return error("expected 'align' or '!tbaa' or '!alias.scope' or "
33070b57cec5SDimitry Andric "'!noalias' or '!range'");
33080b57cec5SDimitry Andric }
33090b57cec5SDimitry Andric }
33100b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
33110b57cec5SDimitry Andric return true;
3312*5f7ddb14SDimitry Andric Dest = MF.getMachineMemOperand(Ptr, Flags, MemoryType, Align(BaseAlignment),
3313*5f7ddb14SDimitry Andric AAInfo, Range, SSID, Order, FailureOrder);
33140b57cec5SDimitry Andric return false;
33150b57cec5SDimitry Andric }
33160b57cec5SDimitry Andric
parsePreOrPostInstrSymbol(MCSymbol * & Symbol)33170b57cec5SDimitry Andric bool MIParser::parsePreOrPostInstrSymbol(MCSymbol *&Symbol) {
33180b57cec5SDimitry Andric assert((Token.is(MIToken::kw_pre_instr_symbol) ||
33190b57cec5SDimitry Andric Token.is(MIToken::kw_post_instr_symbol)) &&
33200b57cec5SDimitry Andric "Invalid token for a pre- post-instruction symbol!");
33210b57cec5SDimitry Andric lex();
33220b57cec5SDimitry Andric if (Token.isNot(MIToken::MCSymbol))
33230b57cec5SDimitry Andric return error("expected a symbol after 'pre-instr-symbol'");
33240b57cec5SDimitry Andric Symbol = getOrCreateMCSymbol(Token.stringValue());
33250b57cec5SDimitry Andric lex();
33260b57cec5SDimitry Andric if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) ||
33270b57cec5SDimitry Andric Token.is(MIToken::lbrace))
33280b57cec5SDimitry Andric return false;
33290b57cec5SDimitry Andric if (Token.isNot(MIToken::comma))
33300b57cec5SDimitry Andric return error("expected ',' before the next machine operand");
33310b57cec5SDimitry Andric lex();
33320b57cec5SDimitry Andric return false;
33330b57cec5SDimitry Andric }
33340b57cec5SDimitry Andric
parseHeapAllocMarker(MDNode * & Node)3335480093f4SDimitry Andric bool MIParser::parseHeapAllocMarker(MDNode *&Node) {
3336480093f4SDimitry Andric assert(Token.is(MIToken::kw_heap_alloc_marker) &&
3337480093f4SDimitry Andric "Invalid token for a heap alloc marker!");
3338480093f4SDimitry Andric lex();
3339480093f4SDimitry Andric parseMDNode(Node);
3340480093f4SDimitry Andric if (!Node)
3341480093f4SDimitry Andric return error("expected a MDNode after 'heap-alloc-marker'");
3342480093f4SDimitry Andric if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) ||
3343480093f4SDimitry Andric Token.is(MIToken::lbrace))
3344480093f4SDimitry Andric return false;
3345480093f4SDimitry Andric if (Token.isNot(MIToken::comma))
3346480093f4SDimitry Andric return error("expected ',' before the next machine operand");
3347480093f4SDimitry Andric lex();
3348480093f4SDimitry Andric return false;
3349480093f4SDimitry Andric }
3350480093f4SDimitry Andric
initSlots2BasicBlocks(const Function & F,DenseMap<unsigned,const BasicBlock * > & Slots2BasicBlocks)33510b57cec5SDimitry Andric static void initSlots2BasicBlocks(
33520b57cec5SDimitry Andric const Function &F,
33530b57cec5SDimitry Andric DenseMap<unsigned, const BasicBlock *> &Slots2BasicBlocks) {
33540b57cec5SDimitry Andric ModuleSlotTracker MST(F.getParent(), /*ShouldInitializeAllMetadata=*/false);
33550b57cec5SDimitry Andric MST.incorporateFunction(F);
33560b57cec5SDimitry Andric for (auto &BB : F) {
33570b57cec5SDimitry Andric if (BB.hasName())
33580b57cec5SDimitry Andric continue;
33590b57cec5SDimitry Andric int Slot = MST.getLocalSlot(&BB);
33600b57cec5SDimitry Andric if (Slot == -1)
33610b57cec5SDimitry Andric continue;
33620b57cec5SDimitry Andric Slots2BasicBlocks.insert(std::make_pair(unsigned(Slot), &BB));
33630b57cec5SDimitry Andric }
33640b57cec5SDimitry Andric }
33650b57cec5SDimitry Andric
getIRBlockFromSlot(unsigned Slot,const DenseMap<unsigned,const BasicBlock * > & Slots2BasicBlocks)33660b57cec5SDimitry Andric static const BasicBlock *getIRBlockFromSlot(
33670b57cec5SDimitry Andric unsigned Slot,
33680b57cec5SDimitry Andric const DenseMap<unsigned, const BasicBlock *> &Slots2BasicBlocks) {
3369af732203SDimitry Andric return Slots2BasicBlocks.lookup(Slot);
33700b57cec5SDimitry Andric }
33710b57cec5SDimitry Andric
getIRBlock(unsigned Slot)33720b57cec5SDimitry Andric const BasicBlock *MIParser::getIRBlock(unsigned Slot) {
33730b57cec5SDimitry Andric if (Slots2BasicBlocks.empty())
33740b57cec5SDimitry Andric initSlots2BasicBlocks(MF.getFunction(), Slots2BasicBlocks);
33750b57cec5SDimitry Andric return getIRBlockFromSlot(Slot, Slots2BasicBlocks);
33760b57cec5SDimitry Andric }
33770b57cec5SDimitry Andric
getIRBlock(unsigned Slot,const Function & F)33780b57cec5SDimitry Andric const BasicBlock *MIParser::getIRBlock(unsigned Slot, const Function &F) {
33790b57cec5SDimitry Andric if (&F == &MF.getFunction())
33800b57cec5SDimitry Andric return getIRBlock(Slot);
33810b57cec5SDimitry Andric DenseMap<unsigned, const BasicBlock *> CustomSlots2BasicBlocks;
33820b57cec5SDimitry Andric initSlots2BasicBlocks(F, CustomSlots2BasicBlocks);
33830b57cec5SDimitry Andric return getIRBlockFromSlot(Slot, CustomSlots2BasicBlocks);
33840b57cec5SDimitry Andric }
33850b57cec5SDimitry Andric
getOrCreateMCSymbol(StringRef Name)33860b57cec5SDimitry Andric MCSymbol *MIParser::getOrCreateMCSymbol(StringRef Name) {
33870b57cec5SDimitry Andric // FIXME: Currently we can't recognize temporary or local symbols and call all
33880b57cec5SDimitry Andric // of the appropriate forms to create them. However, this handles basic cases
33890b57cec5SDimitry Andric // well as most of the special aspects are recognized by a prefix on their
33900b57cec5SDimitry Andric // name, and the input names should already be unique. For test cases, keeping
33910b57cec5SDimitry Andric // the symbol name out of the symbol table isn't terribly important.
33920b57cec5SDimitry Andric return MF.getContext().getOrCreateSymbol(Name);
33930b57cec5SDimitry Andric }
33940b57cec5SDimitry Andric
parseStringConstant(std::string & Result)33950b57cec5SDimitry Andric bool MIParser::parseStringConstant(std::string &Result) {
33960b57cec5SDimitry Andric if (Token.isNot(MIToken::StringConstant))
33970b57cec5SDimitry Andric return error("expected string constant");
33985ffd83dbSDimitry Andric Result = std::string(Token.stringValue());
33990b57cec5SDimitry Andric lex();
34000b57cec5SDimitry Andric return false;
34010b57cec5SDimitry Andric }
34020b57cec5SDimitry Andric
parseMachineBasicBlockDefinitions(PerFunctionMIParsingState & PFS,StringRef Src,SMDiagnostic & Error)34030b57cec5SDimitry Andric bool llvm::parseMachineBasicBlockDefinitions(PerFunctionMIParsingState &PFS,
34040b57cec5SDimitry Andric StringRef Src,
34050b57cec5SDimitry Andric SMDiagnostic &Error) {
34060b57cec5SDimitry Andric return MIParser(PFS, Error, Src).parseBasicBlockDefinitions(PFS.MBBSlots);
34070b57cec5SDimitry Andric }
34080b57cec5SDimitry Andric
parseMachineInstructions(PerFunctionMIParsingState & PFS,StringRef Src,SMDiagnostic & Error)34090b57cec5SDimitry Andric bool llvm::parseMachineInstructions(PerFunctionMIParsingState &PFS,
34100b57cec5SDimitry Andric StringRef Src, SMDiagnostic &Error) {
34110b57cec5SDimitry Andric return MIParser(PFS, Error, Src).parseBasicBlocks();
34120b57cec5SDimitry Andric }
34130b57cec5SDimitry Andric
parseMBBReference(PerFunctionMIParsingState & PFS,MachineBasicBlock * & MBB,StringRef Src,SMDiagnostic & Error)34140b57cec5SDimitry Andric bool llvm::parseMBBReference(PerFunctionMIParsingState &PFS,
34150b57cec5SDimitry Andric MachineBasicBlock *&MBB, StringRef Src,
34160b57cec5SDimitry Andric SMDiagnostic &Error) {
34170b57cec5SDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneMBB(MBB);
34180b57cec5SDimitry Andric }
34190b57cec5SDimitry Andric
parseRegisterReference(PerFunctionMIParsingState & PFS,Register & Reg,StringRef Src,SMDiagnostic & Error)34200b57cec5SDimitry Andric bool llvm::parseRegisterReference(PerFunctionMIParsingState &PFS,
34215ffd83dbSDimitry Andric Register &Reg, StringRef Src,
34220b57cec5SDimitry Andric SMDiagnostic &Error) {
34230b57cec5SDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneRegister(Reg);
34240b57cec5SDimitry Andric }
34250b57cec5SDimitry Andric
parseNamedRegisterReference(PerFunctionMIParsingState & PFS,Register & Reg,StringRef Src,SMDiagnostic & Error)34260b57cec5SDimitry Andric bool llvm::parseNamedRegisterReference(PerFunctionMIParsingState &PFS,
34275ffd83dbSDimitry Andric Register &Reg, StringRef Src,
34280b57cec5SDimitry Andric SMDiagnostic &Error) {
34290b57cec5SDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneNamedRegister(Reg);
34300b57cec5SDimitry Andric }
34310b57cec5SDimitry Andric
parseVirtualRegisterReference(PerFunctionMIParsingState & PFS,VRegInfo * & Info,StringRef Src,SMDiagnostic & Error)34320b57cec5SDimitry Andric bool llvm::parseVirtualRegisterReference(PerFunctionMIParsingState &PFS,
34330b57cec5SDimitry Andric VRegInfo *&Info, StringRef Src,
34340b57cec5SDimitry Andric SMDiagnostic &Error) {
34350b57cec5SDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneVirtualRegister(Info);
34360b57cec5SDimitry Andric }
34370b57cec5SDimitry Andric
parseStackObjectReference(PerFunctionMIParsingState & PFS,int & FI,StringRef Src,SMDiagnostic & Error)34380b57cec5SDimitry Andric bool llvm::parseStackObjectReference(PerFunctionMIParsingState &PFS,
34390b57cec5SDimitry Andric int &FI, StringRef Src,
34400b57cec5SDimitry Andric SMDiagnostic &Error) {
34410b57cec5SDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneStackObject(FI);
34420b57cec5SDimitry Andric }
34430b57cec5SDimitry Andric
parseMDNode(PerFunctionMIParsingState & PFS,MDNode * & Node,StringRef Src,SMDiagnostic & Error)34440b57cec5SDimitry Andric bool llvm::parseMDNode(PerFunctionMIParsingState &PFS,
34450b57cec5SDimitry Andric MDNode *&Node, StringRef Src, SMDiagnostic &Error) {
34460b57cec5SDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneMDNode(Node);
34470b57cec5SDimitry Andric }
3448480093f4SDimitry Andric
parseMachineMetadata(PerFunctionMIParsingState & PFS,StringRef Src,SMRange SrcRange,SMDiagnostic & Error)3449*5f7ddb14SDimitry Andric bool llvm::parseMachineMetadata(PerFunctionMIParsingState &PFS, StringRef Src,
3450*5f7ddb14SDimitry Andric SMRange SrcRange, SMDiagnostic &Error) {
3451*5f7ddb14SDimitry Andric return MIParser(PFS, Error, Src, SrcRange).parseMachineMetadata();
3452*5f7ddb14SDimitry Andric }
3453*5f7ddb14SDimitry Andric
parseIRValue(StringRef Src,MachineFunction & MF,PerFunctionMIParsingState & PFS,const Value * & V,ErrorCallbackType ErrorCallback)3454480093f4SDimitry Andric bool MIRFormatter::parseIRValue(StringRef Src, MachineFunction &MF,
3455480093f4SDimitry Andric PerFunctionMIParsingState &PFS, const Value *&V,
3456480093f4SDimitry Andric ErrorCallbackType ErrorCallback) {
3457480093f4SDimitry Andric MIToken Token;
3458480093f4SDimitry Andric Src = lexMIToken(Src, Token, [&](StringRef::iterator Loc, const Twine &Msg) {
3459480093f4SDimitry Andric ErrorCallback(Loc, Msg);
3460480093f4SDimitry Andric });
3461480093f4SDimitry Andric V = nullptr;
3462480093f4SDimitry Andric
3463480093f4SDimitry Andric return ::parseIRValue(Token, PFS, V, ErrorCallback);
3464480093f4SDimitry Andric }
3465