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