brintos

brintos / llvm-project-archived public Read only

0
0
Text · 38.1 KiB · c055449 Raw
1024 lines · cpp
1//===- MIRPrinter.cpp - MIR serialization format printer ------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the class that prints out the LLVM IR and machine10// functions using the MIR serialization format.11//12//===----------------------------------------------------------------------===//13 14#include "llvm/CodeGen/MIRPrinter.h"15#include "llvm/ADT/DenseMap.h"16#include "llvm/ADT/STLExtras.h"17#include "llvm/ADT/SmallBitVector.h"18#include "llvm/ADT/SmallPtrSet.h"19#include "llvm/ADT/SmallVector.h"20#include "llvm/ADT/StringExtras.h"21#include "llvm/ADT/StringRef.h"22#include "llvm/CodeGen/MIRFormatter.h"23#include "llvm/CodeGen/MIRYamlMapping.h"24#include "llvm/CodeGen/MachineBasicBlock.h"25#include "llvm/CodeGen/MachineConstantPool.h"26#include "llvm/CodeGen/MachineFrameInfo.h"27#include "llvm/CodeGen/MachineFunction.h"28#include "llvm/CodeGen/MachineInstr.h"29#include "llvm/CodeGen/MachineJumpTableInfo.h"30#include "llvm/CodeGen/MachineMemOperand.h"31#include "llvm/CodeGen/MachineModuleSlotTracker.h"32#include "llvm/CodeGen/MachineOperand.h"33#include "llvm/CodeGen/MachineRegisterInfo.h"34#include "llvm/CodeGen/TargetFrameLowering.h"35#include "llvm/CodeGen/TargetInstrInfo.h"36#include "llvm/CodeGen/TargetRegisterInfo.h"37#include "llvm/CodeGen/TargetSubtargetInfo.h"38#include "llvm/CodeGenTypes/LowLevelType.h"39#include "llvm/IR/DebugInfoMetadata.h"40#include "llvm/IR/DebugLoc.h"41#include "llvm/IR/Function.h"42#include "llvm/IR/IRPrintingPasses.h"43#include "llvm/IR/Instructions.h"44#include "llvm/IR/Module.h"45#include "llvm/IR/ModuleSlotTracker.h"46#include "llvm/IR/Value.h"47#include "llvm/MC/LaneBitmask.h"48#include "llvm/Support/BranchProbability.h"49#include "llvm/Support/Casting.h"50#include "llvm/Support/CommandLine.h"51#include "llvm/Support/ErrorHandling.h"52#include "llvm/Support/Format.h"53#include "llvm/Support/YAMLTraits.h"54#include "llvm/Support/raw_ostream.h"55#include "llvm/Target/TargetMachine.h"56#include <algorithm>57#include <cassert>58#include <cinttypes>59#include <cstdint>60#include <iterator>61#include <string>62#include <utility>63#include <vector>64 65using namespace llvm;66 67static cl::opt<bool> SimplifyMIR(68    "simplify-mir", cl::Hidden,69    cl::desc("Leave out unnecessary information when printing MIR"));70 71static cl::opt<bool> PrintLocations("mir-debug-loc", cl::Hidden, cl::init(true),72                                    cl::desc("Print MIR debug-locations"));73 74namespace {75 76/// This structure describes how to print out stack object references.77struct FrameIndexOperand {78  std::string Name;79  unsigned ID;80  bool IsFixed;81 82  FrameIndexOperand(StringRef Name, unsigned ID, bool IsFixed)83      : Name(Name.str()), ID(ID), IsFixed(IsFixed) {}84 85  /// Return an ordinary stack object reference.86  static FrameIndexOperand create(StringRef Name, unsigned ID) {87    return FrameIndexOperand(Name, ID, /*IsFixed=*/false);88  }89 90  /// Return a fixed stack object reference.91  static FrameIndexOperand createFixed(unsigned ID) {92    return FrameIndexOperand("", ID, /*IsFixed=*/true);93  }94};95 96struct MFPrintState {97  MachineModuleSlotTracker MST;98  DenseMap<const uint32_t *, unsigned> RegisterMaskIds;99  /// Maps from stack object indices to operand indices which will be used when100  /// printing frame index machine operands.101  DenseMap<int, FrameIndexOperand> StackObjectOperandMapping;102  /// Synchronization scope names registered with LLVMContext.103  SmallVector<StringRef, 8> SSNs;104 105  MFPrintState(const MachineModuleInfo &MMI, const MachineFunction &MF)106      : MST(MMI, &MF) {}107};108 109} // end anonymous namespace110 111/// This struct serializes the LLVM IR module.112template <> struct yaml::BlockScalarTraits<Module> {113  static void output(const Module &Mod, void *Ctxt, raw_ostream &OS) {114    Mod.print(OS, nullptr);115  }116 117  static StringRef input(StringRef Str, void *Ctxt, Module &Mod) {118    llvm_unreachable("LLVM Module is supposed to be parsed separately");119    return "";120  }121};122 123static void printRegMIR(Register Reg, yaml::StringValue &Dest,124                        const TargetRegisterInfo *TRI) {125  raw_string_ostream OS(Dest.Value);126  OS << printReg(Reg, TRI);127}128 129static DenseMap<const uint32_t *, unsigned>130initRegisterMaskIds(const MachineFunction &MF) {131  DenseMap<const uint32_t *, unsigned> RegisterMaskIds;132  const auto *TRI = MF.getSubtarget().getRegisterInfo();133  unsigned I = 0;134  for (const uint32_t *Mask : TRI->getRegMasks())135    RegisterMaskIds.insert(std::make_pair(Mask, I++));136  return RegisterMaskIds;137}138 139static void printMBB(raw_ostream &OS, MFPrintState &State,140                     const MachineBasicBlock &MBB);141static void convertMRI(yaml::MachineFunction &YamlMF, const MachineFunction &MF,142                       const MachineRegisterInfo &RegInfo,143                       const TargetRegisterInfo *TRI);144static void convertMCP(yaml::MachineFunction &MF,145                       const MachineConstantPool &ConstantPool);146static void convertMJTI(ModuleSlotTracker &MST, yaml::MachineJumpTable &YamlJTI,147                        const MachineJumpTableInfo &JTI);148static void convertMFI(ModuleSlotTracker &MST, yaml::MachineFrameInfo &YamlMFI,149                       const MachineFrameInfo &MFI,150                       const TargetRegisterInfo *TRI);151static void152convertSRPoints(ModuleSlotTracker &MST,153                std::vector<yaml::SaveRestorePointEntry> &YamlSRPoints,154                const llvm::SaveRestorePoints &SRPoints,155                const TargetRegisterInfo *TRI);156static void convertStackObjects(yaml::MachineFunction &YMF,157                                const MachineFunction &MF,158                                ModuleSlotTracker &MST, MFPrintState &State);159static void convertEntryValueObjects(yaml::MachineFunction &YMF,160                                     const MachineFunction &MF,161                                     ModuleSlotTracker &MST);162static void convertCallSiteObjects(yaml::MachineFunction &YMF,163                                   const MachineFunction &MF,164                                   ModuleSlotTracker &MST);165static void convertMachineMetadataNodes(yaml::MachineFunction &YMF,166                                        const MachineFunction &MF,167                                        MachineModuleSlotTracker &MST);168static void convertCalledGlobals(yaml::MachineFunction &YMF,169                                 const MachineFunction &MF,170                                 MachineModuleSlotTracker &MST);171 172static void printMF(raw_ostream &OS, const MachineModuleInfo &MMI,173                    const MachineFunction &MF) {174  MFPrintState State(MMI, MF);175  State.RegisterMaskIds = initRegisterMaskIds(MF);176 177  yaml::MachineFunction YamlMF;178  YamlMF.Name = MF.getName();179  YamlMF.Alignment = MF.getAlignment();180  YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice();181  YamlMF.HasWinCFI = MF.hasWinCFI();182 183  YamlMF.CallsEHReturn = MF.callsEHReturn();184  YamlMF.CallsUnwindInit = MF.callsUnwindInit();185  YamlMF.HasEHContTarget = MF.hasEHContTarget();186  YamlMF.HasEHScopes = MF.hasEHScopes();187  YamlMF.HasEHFunclets = MF.hasEHFunclets();188  YamlMF.HasFakeUses = MF.hasFakeUses();189  YamlMF.IsOutlined = MF.isOutlined();190  YamlMF.UseDebugInstrRef = MF.useDebugInstrRef();191 192  const MachineFunctionProperties &Props = MF.getProperties();193  YamlMF.Legalized = Props.hasLegalized();194  YamlMF.RegBankSelected = Props.hasRegBankSelected();195  YamlMF.Selected = Props.hasSelected();196  YamlMF.FailedISel = Props.hasFailedISel();197  YamlMF.FailsVerification = Props.hasFailsVerification();198  YamlMF.TracksDebugUserValues = Props.hasTracksDebugUserValues();199  YamlMF.NoPHIs = Props.hasNoPHIs();200  YamlMF.IsSSA = Props.hasIsSSA();201  YamlMF.NoVRegs = Props.hasNoVRegs();202 203  convertMRI(YamlMF, MF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo());204  MachineModuleSlotTracker &MST = State.MST;205  MST.incorporateFunction(MF.getFunction());206  convertMFI(MST, YamlMF.FrameInfo, MF.getFrameInfo(),207             MF.getSubtarget().getRegisterInfo());208  convertStackObjects(YamlMF, MF, MST, State);209  convertEntryValueObjects(YamlMF, MF, MST);210  convertCallSiteObjects(YamlMF, MF, MST);211  for (const auto &Sub : MF.DebugValueSubstitutions) {212    const auto &SubSrc = Sub.Src;213    const auto &SubDest = Sub.Dest;214    YamlMF.DebugValueSubstitutions.push_back({SubSrc.first, SubSrc.second,215                                              SubDest.first,216                                              SubDest.second,217                                              Sub.Subreg});218  }219  if (const auto *ConstantPool = MF.getConstantPool())220    convertMCP(YamlMF, *ConstantPool);221  if (const auto *JumpTableInfo = MF.getJumpTableInfo())222    convertMJTI(MST, YamlMF.JumpTableInfo, *JumpTableInfo);223 224  const TargetMachine &TM = MF.getTarget();225  YamlMF.MachineFuncInfo =226      std::unique_ptr<yaml::MachineFunctionInfo>(TM.convertFuncInfoToYAML(MF));227 228  raw_string_ostream StrOS(YamlMF.Body.Value.Value);229  bool IsNewlineNeeded = false;230  for (const auto &MBB : MF) {231    if (IsNewlineNeeded)232      StrOS << "\n";233    printMBB(StrOS, State, MBB);234    IsNewlineNeeded = true;235  }236  // Convert machine metadata collected during the print of the machine237  // function.238  convertMachineMetadataNodes(YamlMF, MF, MST);239 240  convertCalledGlobals(YamlMF, MF, MST);241 242  yaml::Output Out(OS);243  if (!SimplifyMIR)244      Out.setWriteDefaultValues(true);245  Out << YamlMF;246}247 248static void printCustomRegMask(const uint32_t *RegMask, raw_ostream &OS,249                               const TargetRegisterInfo *TRI) {250  assert(RegMask && "Can't print an empty register mask");251  OS << StringRef("CustomRegMask(");252 253  bool IsRegInRegMaskFound = false;254  for (int I = 0, E = TRI->getNumRegs(); I < E; I++) {255    // Check whether the register is asserted in regmask.256    if (RegMask[I / 32] & (1u << (I % 32))) {257      if (IsRegInRegMaskFound)258        OS << ',';259      OS << printReg(I, TRI);260      IsRegInRegMaskFound = true;261    }262  }263 264  OS << ')';265}266 267static void printRegClassOrBank(Register Reg, yaml::StringValue &Dest,268                                const MachineRegisterInfo &RegInfo,269                                const TargetRegisterInfo *TRI) {270  raw_string_ostream OS(Dest.Value);271  OS << printRegClassOrBank(Reg, RegInfo, TRI);272}273 274template <typename T>275static void276printStackObjectDbgInfo(const MachineFunction::VariableDbgInfo &DebugVar,277                        T &Object, ModuleSlotTracker &MST) {278  std::array<std::string *, 3> Outputs{{&Object.DebugVar.Value,279                                        &Object.DebugExpr.Value,280                                        &Object.DebugLoc.Value}};281  std::array<const Metadata *, 3> Metas{{DebugVar.Var,282                                        DebugVar.Expr,283                                        DebugVar.Loc}};284  for (unsigned i = 0; i < 3; ++i) {285    raw_string_ostream StrOS(*Outputs[i]);286    Metas[i]->printAsOperand(StrOS, MST);287  }288}289 290static void printRegFlags(Register Reg,291                          std::vector<yaml::FlowStringValue> &RegisterFlags,292                          const MachineFunction &MF,293                          const TargetRegisterInfo *TRI) {294  auto FlagValues = TRI->getVRegFlagsOfReg(Reg, MF);295  for (auto &Flag : FlagValues)296    RegisterFlags.push_back(yaml::FlowStringValue(Flag.str()));297}298 299static void convertMRI(yaml::MachineFunction &YamlMF, const MachineFunction &MF,300                       const MachineRegisterInfo &RegInfo,301                       const TargetRegisterInfo *TRI) {302  YamlMF.TracksRegLiveness = RegInfo.tracksLiveness();303 304  // Print the virtual register definitions.305  for (unsigned I = 0, E = RegInfo.getNumVirtRegs(); I < E; ++I) {306    Register Reg = Register::index2VirtReg(I);307    yaml::VirtualRegisterDefinition VReg;308    VReg.ID = I;309    if (RegInfo.getVRegName(Reg) != "")310      continue;311    ::printRegClassOrBank(Reg, VReg.Class, RegInfo, TRI);312    Register PreferredReg = RegInfo.getSimpleHint(Reg);313    if (PreferredReg)314      printRegMIR(PreferredReg, VReg.PreferredRegister, TRI);315    printRegFlags(Reg, VReg.RegisterFlags, MF, TRI);316    YamlMF.VirtualRegisters.push_back(std::move(VReg));317  }318 319  // Print the live ins.320  for (std::pair<MCRegister, Register> LI : RegInfo.liveins()) {321    yaml::MachineFunctionLiveIn LiveIn;322    printRegMIR(LI.first, LiveIn.Register, TRI);323    if (LI.second)324      printRegMIR(LI.second, LiveIn.VirtualRegister, TRI);325    YamlMF.LiveIns.push_back(std::move(LiveIn));326  }327 328  // Prints the callee saved registers.329  if (RegInfo.isUpdatedCSRsInitialized()) {330    const MCPhysReg *CalleeSavedRegs = RegInfo.getCalleeSavedRegs();331    std::vector<yaml::FlowStringValue> CalleeSavedRegisters;332    for (const MCPhysReg *I = CalleeSavedRegs; *I; ++I) {333      yaml::FlowStringValue Reg;334      printRegMIR(*I, Reg, TRI);335      CalleeSavedRegisters.push_back(std::move(Reg));336    }337    YamlMF.CalleeSavedRegisters = std::move(CalleeSavedRegisters);338  }339}340 341static void convertMFI(ModuleSlotTracker &MST, yaml::MachineFrameInfo &YamlMFI,342                       const MachineFrameInfo &MFI,343                       const TargetRegisterInfo *TRI) {344  YamlMFI.IsFrameAddressTaken = MFI.isFrameAddressTaken();345  YamlMFI.IsReturnAddressTaken = MFI.isReturnAddressTaken();346  YamlMFI.HasStackMap = MFI.hasStackMap();347  YamlMFI.HasPatchPoint = MFI.hasPatchPoint();348  YamlMFI.StackSize = MFI.getStackSize();349  YamlMFI.OffsetAdjustment = MFI.getOffsetAdjustment();350  YamlMFI.MaxAlignment = MFI.getMaxAlign().value();351  YamlMFI.AdjustsStack = MFI.adjustsStack();352  YamlMFI.HasCalls = MFI.hasCalls();353  YamlMFI.MaxCallFrameSize = MFI.isMaxCallFrameSizeComputed()354    ? MFI.getMaxCallFrameSize() : ~0u;355  YamlMFI.CVBytesOfCalleeSavedRegisters =356      MFI.getCVBytesOfCalleeSavedRegisters();357  YamlMFI.HasOpaqueSPAdjustment = MFI.hasOpaqueSPAdjustment();358  YamlMFI.HasVAStart = MFI.hasVAStart();359  YamlMFI.HasMustTailInVarArgFunc = MFI.hasMustTailInVarArgFunc();360  YamlMFI.HasTailCall = MFI.hasTailCall();361  YamlMFI.IsCalleeSavedInfoValid = MFI.isCalleeSavedInfoValid();362  YamlMFI.LocalFrameSize = MFI.getLocalFrameSize();363  if (!MFI.getSavePoints().empty())364    convertSRPoints(MST, YamlMFI.SavePoints, MFI.getSavePoints(), TRI);365  if (!MFI.getRestorePoints().empty())366    convertSRPoints(MST, YamlMFI.RestorePoints, MFI.getRestorePoints(), TRI);367}368 369static void convertEntryValueObjects(yaml::MachineFunction &YMF,370                                     const MachineFunction &MF,371                                     ModuleSlotTracker &MST) {372  const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();373  for (const MachineFunction::VariableDbgInfo &DebugVar :374       MF.getEntryValueVariableDbgInfo()) {375    yaml::EntryValueObject &Obj = YMF.EntryValueObjects.emplace_back();376    printStackObjectDbgInfo(DebugVar, Obj, MST);377    MCRegister EntryValReg = DebugVar.getEntryValueRegister();378    printRegMIR(EntryValReg, Obj.EntryValueRegister, TRI);379  }380}381 382static void printStackObjectReference(raw_ostream &OS,383                                      const MFPrintState &State,384                                      int FrameIndex) {385  auto ObjectInfo = State.StackObjectOperandMapping.find(FrameIndex);386  assert(ObjectInfo != State.StackObjectOperandMapping.end() &&387         "Invalid frame index");388  const FrameIndexOperand &Operand = ObjectInfo->second;389  MachineOperand::printStackObjectReference(OS, Operand.ID, Operand.IsFixed,390                                            Operand.Name);391}392 393static void convertStackObjects(yaml::MachineFunction &YMF,394                                const MachineFunction &MF,395                                ModuleSlotTracker &MST, MFPrintState &State) {396  const MachineFrameInfo &MFI = MF.getFrameInfo();397  const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();398 399  // Process fixed stack objects.400  assert(YMF.FixedStackObjects.empty());401  SmallVector<int, 32> FixedStackObjectsIdx;402  const int BeginIdx = MFI.getObjectIndexBegin();403  if (BeginIdx < 0)404    FixedStackObjectsIdx.reserve(-BeginIdx);405 406  unsigned ID = 0;407  for (int I = BeginIdx; I < 0; ++I, ++ID) {408    FixedStackObjectsIdx.push_back(-1); // Fill index for possible dead.409    if (MFI.isDeadObjectIndex(I))410      continue;411 412    yaml::FixedMachineStackObject YamlObject;413    YamlObject.ID = ID;414    YamlObject.Type = MFI.isSpillSlotObjectIndex(I)415                          ? yaml::FixedMachineStackObject::SpillSlot416                          : yaml::FixedMachineStackObject::DefaultType;417    YamlObject.Offset = MFI.getObjectOffset(I);418    YamlObject.Size = MFI.getObjectSize(I);419    YamlObject.Alignment = MFI.getObjectAlign(I);420    YamlObject.StackID = (TargetStackID::Value)MFI.getStackID(I);421    YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I);422    YamlObject.IsAliased = MFI.isAliasedObjectIndex(I);423    // Save the ID' position in FixedStackObjects storage vector.424    FixedStackObjectsIdx[ID] = YMF.FixedStackObjects.size();425    YMF.FixedStackObjects.push_back(std::move(YamlObject));426    State.StackObjectOperandMapping.insert(427        std::make_pair(I, FrameIndexOperand::createFixed(ID)));428  }429 430  // Process ordinary stack objects.431  assert(YMF.StackObjects.empty());432  SmallVector<unsigned, 32> StackObjectsIdx;433  const int EndIdx = MFI.getObjectIndexEnd();434  if (EndIdx > 0)435    StackObjectsIdx.reserve(EndIdx);436  ID = 0;437  for (int I = 0; I < EndIdx; ++I, ++ID) {438    StackObjectsIdx.push_back(-1); // Fill index for possible dead.439    if (MFI.isDeadObjectIndex(I))440      continue;441 442    yaml::MachineStackObject YamlObject;443    YamlObject.ID = ID;444    if (const auto *Alloca = MFI.getObjectAllocation(I))445      YamlObject.Name.Value = std::string(446          Alloca->hasName() ? Alloca->getName() : "");447    YamlObject.Type = MFI.isSpillSlotObjectIndex(I)448                          ? yaml::MachineStackObject::SpillSlot449                          : MFI.isVariableSizedObjectIndex(I)450                                ? yaml::MachineStackObject::VariableSized451                                : yaml::MachineStackObject::DefaultType;452    YamlObject.Offset = MFI.getObjectOffset(I);453    YamlObject.Size = MFI.getObjectSize(I);454    YamlObject.Alignment = MFI.getObjectAlign(I);455    YamlObject.StackID = (TargetStackID::Value)MFI.getStackID(I);456 457    // Save the ID' position in StackObjects storage vector.458    StackObjectsIdx[ID] = YMF.StackObjects.size();459    YMF.StackObjects.push_back(YamlObject);460    State.StackObjectOperandMapping.insert(std::make_pair(461        I, FrameIndexOperand::create(YamlObject.Name.Value, ID)));462  }463 464  for (const auto &CSInfo : MFI.getCalleeSavedInfo()) {465    const int FrameIdx = CSInfo.getFrameIdx();466    if (!CSInfo.isSpilledToReg() && MFI.isDeadObjectIndex(FrameIdx))467      continue;468 469    yaml::StringValue Reg;470    printRegMIR(CSInfo.getReg(), Reg, TRI);471    if (!CSInfo.isSpilledToReg()) {472      assert(FrameIdx >= MFI.getObjectIndexBegin() &&473             FrameIdx < MFI.getObjectIndexEnd() &&474             "Invalid stack object index");475      if (FrameIdx < 0) { // Negative index means fixed objects.476        auto &Object =477            YMF.FixedStackObjects478                [FixedStackObjectsIdx[FrameIdx + MFI.getNumFixedObjects()]];479        Object.CalleeSavedRegister = std::move(Reg);480        Object.CalleeSavedRestored = CSInfo.isRestored();481      } else {482        auto &Object = YMF.StackObjects[StackObjectsIdx[FrameIdx]];483        Object.CalleeSavedRegister = std::move(Reg);484        Object.CalleeSavedRestored = CSInfo.isRestored();485      }486    }487  }488  for (unsigned I = 0, E = MFI.getLocalFrameObjectCount(); I < E; ++I) {489    auto LocalObject = MFI.getLocalFrameObjectMap(I);490    assert(LocalObject.first >= 0 && "Expected a locally mapped stack object");491    YMF.StackObjects[StackObjectsIdx[LocalObject.first]].LocalOffset =492        LocalObject.second;493  }494 495  // Print the stack object references in the frame information class after496  // converting the stack objects.497  if (MFI.hasStackProtectorIndex()) {498    raw_string_ostream StrOS(YMF.FrameInfo.StackProtector.Value);499    printStackObjectReference(StrOS, State, MFI.getStackProtectorIndex());500  }501 502  if (MFI.hasFunctionContextIndex()) {503    raw_string_ostream StrOS(YMF.FrameInfo.FunctionContext.Value);504    printStackObjectReference(StrOS, State, MFI.getFunctionContextIndex());505  }506 507  // Print the debug variable information.508  for (const MachineFunction::VariableDbgInfo &DebugVar :509       MF.getInStackSlotVariableDbgInfo()) {510    int Idx = DebugVar.getStackSlot();511    assert(Idx >= MFI.getObjectIndexBegin() && Idx < MFI.getObjectIndexEnd() &&512           "Invalid stack object index");513    if (Idx < 0) { // Negative index means fixed objects.514      auto &Object =515          YMF.FixedStackObjects[FixedStackObjectsIdx[Idx +516                                                     MFI.getNumFixedObjects()]];517      printStackObjectDbgInfo(DebugVar, Object, MST);518    } else {519      auto &Object = YMF.StackObjects[StackObjectsIdx[Idx]];520      printStackObjectDbgInfo(DebugVar, Object, MST);521    }522  }523}524 525static void convertCallSiteObjects(yaml::MachineFunction &YMF,526                                   const MachineFunction &MF,527                                   ModuleSlotTracker &MST) {528  const auto *TRI = MF.getSubtarget().getRegisterInfo();529  for (auto [MI, CallSiteInfo] : MF.getCallSitesInfo()) {530    yaml::CallSiteInfo YmlCS;531    yaml::MachineInstrLoc CallLocation;532 533    // Prepare instruction position.534    MachineBasicBlock::const_instr_iterator CallI = MI->getIterator();535    CallLocation.BlockNum = CallI->getParent()->getNumber();536    // Get call instruction offset from the beginning of block.537    CallLocation.Offset =538        std::distance(CallI->getParent()->instr_begin(), CallI);539    YmlCS.CallLocation = CallLocation;540 541    auto [ArgRegPairs, CalleeTypeIds] = CallSiteInfo;542    // Construct call arguments and theirs forwarding register info.543    for (auto ArgReg : ArgRegPairs) {544      yaml::CallSiteInfo::ArgRegPair YmlArgReg;545      YmlArgReg.ArgNo = ArgReg.ArgNo;546      printRegMIR(ArgReg.Reg, YmlArgReg.Reg, TRI);547      YmlCS.ArgForwardingRegs.emplace_back(YmlArgReg);548    }549    // Get type ids.550    for (auto *CalleeTypeId : CalleeTypeIds) {551      YmlCS.CalleeTypeIds.push_back(CalleeTypeId->getZExtValue());552    }553    YMF.CallSitesInfo.push_back(std::move(YmlCS));554  }555 556  // Sort call info by position of call instructions.557  llvm::sort(YMF.CallSitesInfo.begin(), YMF.CallSitesInfo.end(),558             [](yaml::CallSiteInfo A, yaml::CallSiteInfo B) {559               return std::tie(A.CallLocation.BlockNum, A.CallLocation.Offset) <560                      std::tie(B.CallLocation.BlockNum, B.CallLocation.Offset);561             });562}563 564static void convertMachineMetadataNodes(yaml::MachineFunction &YMF,565                                        const MachineFunction &MF,566                                        MachineModuleSlotTracker &MST) {567  MachineModuleSlotTracker::MachineMDNodeListType MDList;568  MST.collectMachineMDNodes(MDList);569  for (auto &MD : MDList) {570    std::string NS;571    raw_string_ostream StrOS(NS);572    MD.second->print(StrOS, MST, MF.getFunction().getParent());573    YMF.MachineMetadataNodes.push_back(std::move(NS));574  }575}576 577static void convertCalledGlobals(yaml::MachineFunction &YMF,578                                 const MachineFunction &MF,579                                 MachineModuleSlotTracker &MST) {580  for (const auto &[CallInst, CG] : MF.getCalledGlobals()) {581    yaml::MachineInstrLoc CallSite;582    CallSite.BlockNum = CallInst->getParent()->getNumber();583    CallSite.Offset = std::distance(CallInst->getParent()->instr_begin(),584                                    CallInst->getIterator());585 586    yaml::CalledGlobal YamlCG{CallSite, CG.Callee->getName().str(),587                              CG.TargetFlags};588    YMF.CalledGlobals.push_back(std::move(YamlCG));589  }590 591  // Sort by position of call instructions.592  llvm::sort(YMF.CalledGlobals.begin(), YMF.CalledGlobals.end(),593             [](yaml::CalledGlobal A, yaml::CalledGlobal B) {594               return std::tie(A.CallSite.BlockNum, A.CallSite.Offset) <595                      std::tie(B.CallSite.BlockNum, B.CallSite.Offset);596             });597}598 599static void convertMCP(yaml::MachineFunction &MF,600                       const MachineConstantPool &ConstantPool) {601  unsigned ID = 0;602  for (const MachineConstantPoolEntry &Constant : ConstantPool.getConstants()) {603    std::string Str;604    raw_string_ostream StrOS(Str);605    if (Constant.isMachineConstantPoolEntry())606      Constant.Val.MachineCPVal->print(StrOS);607    else608      Constant.Val.ConstVal->printAsOperand(StrOS);609 610    yaml::MachineConstantPoolValue YamlConstant;611    YamlConstant.ID = ID++;612    YamlConstant.Value = std::move(Str);613    YamlConstant.Alignment = Constant.getAlign();614    YamlConstant.IsTargetSpecific = Constant.isMachineConstantPoolEntry();615 616    MF.Constants.push_back(std::move(YamlConstant));617  }618}619 620static void621convertSRPoints(ModuleSlotTracker &MST,622                std::vector<yaml::SaveRestorePointEntry> &YamlSRPoints,623                const llvm::SaveRestorePoints &SRPoints,624                const TargetRegisterInfo *TRI) {625  for (const auto &[MBB, CSInfos] : SRPoints) {626    SmallString<16> Str;627    yaml::SaveRestorePointEntry Entry;628    raw_svector_ostream StrOS(Str);629    StrOS << printMBBReference(*MBB);630    Entry.Point = StrOS.str().str();631    Str.clear();632    for (const CalleeSavedInfo &Info : CSInfos) {633      if (Info.getReg()) {634        StrOS << printReg(Info.getReg(), TRI);635        Entry.Registers.push_back(StrOS.str().str());636        Str.clear();637      }638    }639    // Sort here needed for stable output for lit tests640    std::sort(Entry.Registers.begin(), Entry.Registers.end(),641              [](const yaml::StringValue &Lhs, const yaml::StringValue &Rhs) {642                return Lhs.Value < Rhs.Value;643              });644    YamlSRPoints.push_back(std::move(Entry));645  }646  // Sort here needed for stable output for lit tests647  std::sort(YamlSRPoints.begin(), YamlSRPoints.end(),648            [](const yaml::SaveRestorePointEntry &Lhs,649               const yaml::SaveRestorePointEntry &Rhs) {650              return Lhs.Point.Value < Rhs.Point.Value;651            });652}653 654static void convertMJTI(ModuleSlotTracker &MST, yaml::MachineJumpTable &YamlJTI,655                        const MachineJumpTableInfo &JTI) {656  YamlJTI.Kind = JTI.getEntryKind();657  unsigned ID = 0;658  for (const auto &Table : JTI.getJumpTables()) {659    std::string Str;660    yaml::MachineJumpTable::Entry Entry;661    Entry.ID = ID++;662    for (const auto *MBB : Table.MBBs) {663      raw_string_ostream StrOS(Str);664      StrOS << printMBBReference(*MBB);665      Entry.Blocks.push_back(Str);666      Str.clear();667    }668    YamlJTI.Entries.push_back(std::move(Entry));669  }670}671 672void llvm::guessSuccessors(const MachineBasicBlock &MBB,673                           SmallVectorImpl<MachineBasicBlock*> &Result,674                           bool &IsFallthrough) {675  SmallPtrSet<MachineBasicBlock*,8> Seen;676 677  for (const MachineInstr &MI : MBB) {678    if (MI.isPHI())679      continue;680    for (const MachineOperand &MO : MI.operands()) {681      if (!MO.isMBB())682        continue;683      MachineBasicBlock *Succ = MO.getMBB();684      auto RP = Seen.insert(Succ);685      if (RP.second)686        Result.push_back(Succ);687    }688  }689  MachineBasicBlock::const_iterator I = MBB.getLastNonDebugInstr();690  IsFallthrough = I == MBB.end() || !I->isBarrier();691}692 693static bool canPredictSuccessors(const MachineBasicBlock &MBB) {694  SmallVector<MachineBasicBlock*,8> GuessedSuccs;695  bool GuessedFallthrough;696  guessSuccessors(MBB, GuessedSuccs, GuessedFallthrough);697  if (GuessedFallthrough) {698    const MachineFunction &MF = *MBB.getParent();699    MachineFunction::const_iterator NextI = std::next(MBB.getIterator());700    if (NextI != MF.end()) {701      MachineBasicBlock *Next = const_cast<MachineBasicBlock*>(&*NextI);702      if (!is_contained(GuessedSuccs, Next))703        GuessedSuccs.push_back(Next);704    }705  }706  if (GuessedSuccs.size() != MBB.succ_size())707    return false;708  return std::equal(MBB.succ_begin(), MBB.succ_end(), GuessedSuccs.begin());709}710 711static void printMI(raw_ostream &OS, MFPrintState &State,712                    const MachineInstr &MI);713 714static void printMIOperand(raw_ostream &OS, MFPrintState &State,715                           const MachineInstr &MI, unsigned OpIdx,716                           const TargetRegisterInfo *TRI,717                           const TargetInstrInfo *TII,718                           bool ShouldPrintRegisterTies,719                           SmallBitVector &PrintedTypes,720                           const MachineRegisterInfo &MRI, bool PrintDef);721 722void printMBB(raw_ostream &OS, MFPrintState &State,723              const MachineBasicBlock &MBB) {724  assert(MBB.getNumber() >= 0 && "Invalid MBB number");725  MBB.printName(OS,726                MachineBasicBlock::PrintNameIr |727                    MachineBasicBlock::PrintNameAttributes,728                &State.MST);729  OS << ":\n";730 731  bool HasLineAttributes = false;732  // Print the successors733  bool canPredictProbs = MBB.canPredictBranchProbabilities();734  // Even if the list of successors is empty, if we cannot guess it,735  // we need to print it to tell the parser that the list is empty.736  // This is needed, because MI model unreachable as empty blocks737  // with an empty successor list. If the parser would see that738  // without the successor list, it would guess the code would739  // fallthrough.740  if ((!MBB.succ_empty() && !SimplifyMIR) || !canPredictProbs ||741      !canPredictSuccessors(MBB)) {742    OS.indent(2) << "successors:";743    if (!MBB.succ_empty())744      OS << " ";745    ListSeparator LS;746    for (auto I = MBB.succ_begin(), E = MBB.succ_end(); I != E; ++I) {747      OS << LS << printMBBReference(**I);748      if (!SimplifyMIR || !canPredictProbs)749        OS << format("(0x%08" PRIx32 ")",750                     MBB.getSuccProbability(I).getNumerator());751    }752    OS << "\n";753    HasLineAttributes = true;754  }755 756  // Print the live in registers.757  const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();758  if (!MBB.livein_empty()) {759    const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();760    OS.indent(2) << "liveins: ";761    ListSeparator LS;762    for (const auto &LI : MBB.liveins_dbg()) {763      OS << LS << printReg(LI.PhysReg, &TRI);764      if (!LI.LaneMask.all())765        OS << ":0x" << PrintLaneMask(LI.LaneMask);766    }767    OS << "\n";768    HasLineAttributes = true;769  }770 771  if (HasLineAttributes && !MBB.empty())772    OS << "\n";773  bool IsInBundle = false;774  for (const MachineInstr &MI : MBB.instrs()) {775    if (IsInBundle && !MI.isInsideBundle()) {776      OS.indent(2) << "}\n";777      IsInBundle = false;778    }779    OS.indent(IsInBundle ? 4 : 2);780    printMI(OS, State, MI);781    if (!IsInBundle && MI.getFlag(MachineInstr::BundledSucc)) {782      OS << " {";783      IsInBundle = true;784    }785    OS << "\n";786  }787  if (IsInBundle)788    OS.indent(2) << "}\n";789}790 791static void printMI(raw_ostream &OS, MFPrintState &State,792                    const MachineInstr &MI) {793  const auto *MF = MI.getMF();794  const auto &MRI = MF->getRegInfo();795  const auto &SubTarget = MF->getSubtarget();796  const auto *TRI = SubTarget.getRegisterInfo();797  assert(TRI && "Expected target register info");798  const auto *TII = SubTarget.getInstrInfo();799  assert(TII && "Expected target instruction info");800  if (MI.isCFIInstruction())801    assert(MI.getNumOperands() == 1 && "Expected 1 operand in CFI instruction");802 803  SmallBitVector PrintedTypes(8);804  bool ShouldPrintRegisterTies = MI.hasComplexRegisterTies();805  ListSeparator LS;806  unsigned I = 0, E = MI.getNumOperands();807  for (; I < E; ++I) {808    const MachineOperand MO = MI.getOperand(I);809    if (!MO.isReg() || !MO.isDef() || MO.isImplicit())810      break;811    OS << LS;812    printMIOperand(OS, State, MI, I, TRI, TII, ShouldPrintRegisterTies,813                   PrintedTypes, MRI, /*PrintDef=*/false);814  }815 816  if (I)817    OS << " = ";818  if (MI.getFlag(MachineInstr::FrameSetup))819    OS << "frame-setup ";820  if (MI.getFlag(MachineInstr::FrameDestroy))821    OS << "frame-destroy ";822  if (MI.getFlag(MachineInstr::FmNoNans))823    OS << "nnan ";824  if (MI.getFlag(MachineInstr::FmNoInfs))825    OS << "ninf ";826  if (MI.getFlag(MachineInstr::FmNsz))827    OS << "nsz ";828  if (MI.getFlag(MachineInstr::FmArcp))829    OS << "arcp ";830  if (MI.getFlag(MachineInstr::FmContract))831    OS << "contract ";832  if (MI.getFlag(MachineInstr::FmAfn))833    OS << "afn ";834  if (MI.getFlag(MachineInstr::FmReassoc))835    OS << "reassoc ";836  if (MI.getFlag(MachineInstr::NoUWrap))837    OS << "nuw ";838  if (MI.getFlag(MachineInstr::NoSWrap))839    OS << "nsw ";840  if (MI.getFlag(MachineInstr::IsExact))841    OS << "exact ";842  if (MI.getFlag(MachineInstr::NoFPExcept))843    OS << "nofpexcept ";844  if (MI.getFlag(MachineInstr::NoMerge))845    OS << "nomerge ";846  if (MI.getFlag(MachineInstr::Unpredictable))847    OS << "unpredictable ";848  if (MI.getFlag(MachineInstr::NoConvergent))849    OS << "noconvergent ";850  if (MI.getFlag(MachineInstr::NonNeg))851    OS << "nneg ";852  if (MI.getFlag(MachineInstr::Disjoint))853    OS << "disjoint ";854  if (MI.getFlag(MachineInstr::NoUSWrap))855    OS << "nusw ";856  if (MI.getFlag(MachineInstr::SameSign))857    OS << "samesign ";858  if (MI.getFlag(MachineInstr::InBounds))859    OS << "inbounds ";860 861  // NOTE: Please add new MIFlags also to the MI_FLAGS_STR in862  // llvm/utils/update_mir_test_checks.py.863 864  OS << TII->getName(MI.getOpcode());865 866  // Print a space after the opcode if any additional tokens are printed.867  LS = ListSeparator(", ", " ");868 869  for (; I < E; ++I) {870    OS << LS;871    printMIOperand(OS, State, MI, I, TRI, TII, ShouldPrintRegisterTies,872                   PrintedTypes, MRI, /*PrintDef=*/true);873  }874 875  // Print any optional symbols attached to this instruction as-if they were876  // operands.877  if (MCSymbol *PreInstrSymbol = MI.getPreInstrSymbol()) {878    OS << LS << "pre-instr-symbol ";879    MachineOperand::printSymbol(OS, *PreInstrSymbol);880  }881  if (MCSymbol *PostInstrSymbol = MI.getPostInstrSymbol()) {882    OS << LS << "post-instr-symbol ";883    MachineOperand::printSymbol(OS, *PostInstrSymbol);884  }885  if (MDNode *HeapAllocMarker = MI.getHeapAllocMarker()) {886    OS << LS << "heap-alloc-marker ";887    HeapAllocMarker->printAsOperand(OS, State.MST);888  }889  if (MDNode *PCSections = MI.getPCSections()) {890    OS << LS << "pcsections ";891    PCSections->printAsOperand(OS, State.MST);892  }893  if (MDNode *MMRA = MI.getMMRAMetadata()) {894    OS << LS << "mmra ";895    MMRA->printAsOperand(OS, State.MST);896  }897  if (uint32_t CFIType = MI.getCFIType())898    OS << LS << "cfi-type " << CFIType;899  if (Value *DS = MI.getDeactivationSymbol()) {900    OS << LS << "deactivation-symbol ";901    MIRFormatter::printIRValue(OS, *DS, State.MST);902  }903 904  if (auto Num = MI.peekDebugInstrNum())905    OS << LS << "debug-instr-number " << Num;906 907  if (PrintLocations) {908    if (const DebugLoc &DL = MI.getDebugLoc()) {909      OS << LS << "debug-location ";910      DL->printAsOperand(OS, State.MST);911    }912  }913 914  if (!MI.memoperands_empty()) {915    OS << " :: ";916    const LLVMContext &Context = MF->getFunction().getContext();917    const MachineFrameInfo &MFI = MF->getFrameInfo();918    LS = ListSeparator();919    for (const auto *Op : MI.memoperands()) {920      OS << LS;921      Op->print(OS, State.MST, State.SSNs, Context, &MFI, TII);922    }923  }924}925 926static std::string formatOperandComment(std::string Comment) {927  if (Comment.empty())928    return Comment;929  return std::string(" /* " + Comment + " */");930}931 932static void printMIOperand(raw_ostream &OS, MFPrintState &State,933                           const MachineInstr &MI, unsigned OpIdx,934                           const TargetRegisterInfo *TRI,935                           const TargetInstrInfo *TII,936                           bool ShouldPrintRegisterTies,937                           SmallBitVector &PrintedTypes,938                           const MachineRegisterInfo &MRI, bool PrintDef) {939  LLT TypeToPrint = MI.getTypeToPrint(OpIdx, PrintedTypes, MRI);940  const MachineOperand &Op = MI.getOperand(OpIdx);941  std::string MOComment = TII->createMIROperandComment(MI, Op, OpIdx, TRI);942 943  switch (Op.getType()) {944  case MachineOperand::MO_Immediate:945    if (MI.isOperandSubregIdx(OpIdx)) {946      MachineOperand::printTargetFlags(OS, Op);947      MachineOperand::printSubRegIdx(OS, Op.getImm(), TRI);948      break;949    }950    [[fallthrough]];951  case MachineOperand::MO_Register:952  case MachineOperand::MO_CImmediate:953  case MachineOperand::MO_FPImmediate:954  case MachineOperand::MO_MachineBasicBlock:955  case MachineOperand::MO_ConstantPoolIndex:956  case MachineOperand::MO_TargetIndex:957  case MachineOperand::MO_JumpTableIndex:958  case MachineOperand::MO_ExternalSymbol:959  case MachineOperand::MO_GlobalAddress:960  case MachineOperand::MO_RegisterLiveOut:961  case MachineOperand::MO_Metadata:962  case MachineOperand::MO_MCSymbol:963  case MachineOperand::MO_CFIIndex:964  case MachineOperand::MO_IntrinsicID:965  case MachineOperand::MO_Predicate:966  case MachineOperand::MO_BlockAddress:967  case MachineOperand::MO_DbgInstrRef:968  case MachineOperand::MO_ShuffleMask: {969    unsigned TiedOperandIdx = 0;970    if (ShouldPrintRegisterTies && Op.isReg() && Op.isTied() && !Op.isDef())971      TiedOperandIdx = Op.getParent()->findTiedOperandIdx(OpIdx);972    Op.print(OS, State.MST, TypeToPrint, OpIdx, PrintDef,973             /*IsStandalone=*/false, ShouldPrintRegisterTies, TiedOperandIdx,974             TRI);975    OS << formatOperandComment(MOComment);976    break;977  }978  case MachineOperand::MO_FrameIndex:979    printStackObjectReference(OS, State, Op.getIndex());980    break;981  case MachineOperand::MO_RegisterMask: {982    const auto &RegisterMaskIds = State.RegisterMaskIds;983    auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask());984    if (RegMaskInfo != RegisterMaskIds.end())985      OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower();986    else987      printCustomRegMask(Op.getRegMask(), OS, TRI);988    break;989  }990  }991}992 993void MIRFormatter::printIRValue(raw_ostream &OS, const Value &V,994                                ModuleSlotTracker &MST) {995  if (isa<GlobalValue>(V)) {996    V.printAsOperand(OS, /*PrintType=*/false, MST);997    return;998  }999  if (isa<Constant>(V)) {1000    // Machine memory operands can load/store to/from constant value pointers.1001    OS << '`';1002    V.printAsOperand(OS, /*PrintType=*/true, MST);1003    OS << '`';1004    return;1005  }1006  OS << "%ir.";1007  if (V.hasName()) {1008    printLLVMNameWithoutPrefix(OS, V.getName());1009    return;1010  }1011  int Slot = MST.getCurrentFunction() ? MST.getLocalSlot(&V) : -1;1012  MachineOperand::printIRSlotNumber(OS, Slot);1013}1014 1015void llvm::printMIR(raw_ostream &OS, const Module &M) {1016  yaml::Output Out(OS);1017  Out << const_cast<Module &>(M);1018}1019 1020void llvm::printMIR(raw_ostream &OS, const MachineModuleInfo &MMI,1021                    const MachineFunction &MF) {1022  printMF(OS, MMI, MF);1023}1024