1321369Sdim//===- llvm/CodeGen/MachineInstr.h - MachineInstr class ---------*- C++ -*-===// 2193323Sed// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6193323Sed// 7193323Sed//===----------------------------------------------------------------------===// 8193323Sed// 9193323Sed// This file contains the declaration of the MachineInstr class, which is the 10193323Sed// basic representation for all target dependent machine instructions used by 11193323Sed// the back end. 12193323Sed// 13193323Sed//===----------------------------------------------------------------------===// 14193323Sed 15193323Sed#ifndef LLVM_CODEGEN_MACHINEINSTR_H 16193323Sed#define LLVM_CODEGEN_MACHINEINSTR_H 17193323Sed 18249423Sdim#include "llvm/ADT/DenseMapInfo.h" 19344779Sdim#include "llvm/ADT/PointerSumType.h" 20193323Sed#include "llvm/ADT/ilist.h" 21193323Sed#include "llvm/ADT/ilist_node.h" 22276479Sdim#include "llvm/ADT/iterator_range.h" 23344779Sdim#include "llvm/CodeGen/MachineMemOperand.h" 24249423Sdim#include "llvm/CodeGen/MachineOperand.h" 25327952Sdim#include "llvm/CodeGen/TargetOpcodes.h" 26276479Sdim#include "llvm/IR/DebugLoc.h" 27249423Sdim#include "llvm/IR/InlineAsm.h" 28249423Sdim#include "llvm/MC/MCInstrDesc.h" 29344779Sdim#include "llvm/MC/MCSymbol.h" 30249423Sdim#include "llvm/Support/ArrayRecycler.h" 31344779Sdim#include "llvm/Support/TrailingObjects.h" 32321369Sdim#include <algorithm> 33321369Sdim#include <cassert> 34321369Sdim#include <cstdint> 35321369Sdim#include <utility> 36193323Sed 37193323Sednamespace llvm { 38193323Sed 39360784Sdimclass AAResults; 40309124Sdimtemplate <typename T> class ArrayRef; 41321369Sdimclass DIExpression; 42321369Sdimclass DILocalVariable; 43321369Sdimclass MachineBasicBlock; 44321369Sdimclass MachineFunction; 45321369Sdimclass MachineMemOperand; 46321369Sdimclass MachineRegisterInfo; 47321369Sdimclass ModuleSlotTracker; 48321369Sdimclass raw_ostream; 49208599Srdivackytemplate <typename T> class SmallVectorImpl; 50327952Sdimclass SmallBitVector; 51321369Sdimclass StringRef; 52193323Sedclass TargetInstrInfo; 53226633Sdimclass TargetRegisterClass; 54193323Sedclass TargetRegisterInfo; 55193323Sed 56193323Sed//===----------------------------------------------------------------------===// 57288943Sdim/// Representation of each machine instruction. 58193323Sed/// 59249423Sdim/// This class isn't a POD type, but it must have a trivial destructor. When a 60249423Sdim/// MachineFunction is deleted, all the contained MachineInstrs are deallocated 61249423Sdim/// without having their destructor called. 62249423Sdim/// 63296417Sdimclass MachineInstr 64314564Sdim : public ilist_node_with_parent<MachineInstr, MachineBasicBlock, 65314564Sdim ilist_sentinel_tracking<true>> { 66198090Srdivackypublic: 67344779Sdim using mmo_iterator = ArrayRef<MachineMemOperand *>::iterator; 68198090Srdivacky 69203954Srdivacky /// Flags to specify different kinds of comments to output in 70203954Srdivacky /// assembly code. These flags carry semantic information not 71203954Srdivacky /// otherwise easily derivable from the IR text. 72203954Srdivacky /// 73203954Srdivacky enum CommentFlag { 74327952Sdim ReloadReuse = 0x1, // higher bits are reserved for target dep comments. 75327952Sdim NoSchedComment = 0x2, 76327952Sdim TAsmComments = 0x4 // Target Asm comments should start from this value. 77203954Srdivacky }; 78221345Sdim 79221345Sdim enum MIFlag { 80234353Sdim NoFlags = 0, 81234353Sdim FrameSetup = 1 << 0, // Instruction is used as a part of 82221345Sdim // function frame setup code. 83296417Sdim FrameDestroy = 1 << 1, // Instruction is used as a part of 84296417Sdim // function frame destruction code. 85296417Sdim BundledPred = 1 << 2, // Instruction has bundled predecessors. 86341825Sdim BundledSucc = 1 << 3, // Instruction has bundled successors. 87341825Sdim FmNoNans = 1 << 4, // Instruction does not support Fast 88341825Sdim // math nan values. 89341825Sdim FmNoInfs = 1 << 5, // Instruction does not support Fast 90341825Sdim // math infinity values. 91341825Sdim FmNsz = 1 << 6, // Instruction is not required to retain 92341825Sdim // signed zero values. 93341825Sdim FmArcp = 1 << 7, // Instruction supports Fast math 94341825Sdim // reciprocal approximations. 95341825Sdim FmContract = 1 << 8, // Instruction supports Fast math 96341825Sdim // contraction operations like fma. 97341825Sdim FmAfn = 1 << 9, // Instruction may map to Fast math 98341825Sdim // instrinsic approximation. 99344779Sdim FmReassoc = 1 << 10, // Instruction supports Fast math 100341825Sdim // reassociation of operand order. 101344779Sdim NoUWrap = 1 << 11, // Instruction supports binary operator 102344779Sdim // no unsigned wrap. 103344779Sdim NoSWrap = 1 << 12, // Instruction supports binary operator 104344779Sdim // no signed wrap. 105353358Sdim IsExact = 1 << 13, // Instruction supports division is 106344779Sdim // known to be exact. 107360784Sdim NoFPExcept = 1 << 14, // Instruction does not raise 108360784Sdim // floatint-point exceptions. 109221345Sdim }; 110321369Sdim 111198090Srdivackyprivate: 112224145Sdim const MCInstrDesc *MCID; // Instruction descriptor. 113321369Sdim MachineBasicBlock *Parent = nullptr; // Pointer to the owning basic block. 114193323Sed 115249423Sdim // Operands are allocated by an ArrayRecycler. 116321369Sdim MachineOperand *Operands = nullptr; // Pointer to the first operand. 117321369Sdim unsigned NumOperands = 0; // Number of operands on instruction. 118321369Sdim using OperandCapacity = ArrayRecycler<MachineOperand>::Capacity; 119249423Sdim OperandCapacity CapOperands; // Capacity of the Operands array. 120249423Sdim 121341825Sdim uint16_t Flags = 0; // Various bits of additional 122221345Sdim // information about machine 123221345Sdim // instruction. 124221345Sdim 125321369Sdim uint8_t AsmPrinterFlags = 0; // Various bits of information used by 126199481Srdivacky // the AsmPrinter to emit helpful 127199481Srdivacky // comments. This is *not* semantic 128199481Srdivacky // information. Do not use this for 129199481Srdivacky // anything other than to convey comment 130199481Srdivacky // information to AsmPrinter. 131199481Srdivacky 132344779Sdim /// Internal implementation detail class that provides out-of-line storage for 133344779Sdim /// extra info used by the machine instruction when this info cannot be stored 134344779Sdim /// in-line within the instruction itself. 135344779Sdim /// 136344779Sdim /// This has to be defined eagerly due to the implementation constraints of 137344779Sdim /// `PointerSumType` where it is used. 138344779Sdim class ExtraInfo final 139360661Sdim : TrailingObjects<ExtraInfo, MachineMemOperand *, MCSymbol *, MDNode *> { 140344779Sdim public: 141344779Sdim static ExtraInfo *create(BumpPtrAllocator &Allocator, 142344779Sdim ArrayRef<MachineMemOperand *> MMOs, 143344779Sdim MCSymbol *PreInstrSymbol = nullptr, 144360661Sdim MCSymbol *PostInstrSymbol = nullptr, 145360661Sdim MDNode *HeapAllocMarker = nullptr) { 146344779Sdim bool HasPreInstrSymbol = PreInstrSymbol != nullptr; 147344779Sdim bool HasPostInstrSymbol = PostInstrSymbol != nullptr; 148360661Sdim bool HasHeapAllocMarker = HeapAllocMarker != nullptr; 149344779Sdim auto *Result = new (Allocator.Allocate( 150360661Sdim totalSizeToAlloc<MachineMemOperand *, MCSymbol *, MDNode *>( 151360661Sdim MMOs.size(), HasPreInstrSymbol + HasPostInstrSymbol, 152360661Sdim HasHeapAllocMarker), 153344779Sdim alignof(ExtraInfo))) 154360661Sdim ExtraInfo(MMOs.size(), HasPreInstrSymbol, HasPostInstrSymbol, 155360661Sdim HasHeapAllocMarker); 156234353Sdim 157344779Sdim // Copy the actual data into the trailing objects. 158344779Sdim std::copy(MMOs.begin(), MMOs.end(), 159344779Sdim Result->getTrailingObjects<MachineMemOperand *>()); 160344779Sdim 161344779Sdim if (HasPreInstrSymbol) 162344779Sdim Result->getTrailingObjects<MCSymbol *>()[0] = PreInstrSymbol; 163344779Sdim if (HasPostInstrSymbol) 164344779Sdim Result->getTrailingObjects<MCSymbol *>()[HasPreInstrSymbol] = 165344779Sdim PostInstrSymbol; 166360661Sdim if (HasHeapAllocMarker) 167360661Sdim Result->getTrailingObjects<MDNode *>()[0] = HeapAllocMarker; 168344779Sdim 169344779Sdim return Result; 170344779Sdim } 171344779Sdim 172344779Sdim ArrayRef<MachineMemOperand *> getMMOs() const { 173344779Sdim return makeArrayRef(getTrailingObjects<MachineMemOperand *>(), NumMMOs); 174344779Sdim } 175344779Sdim 176344779Sdim MCSymbol *getPreInstrSymbol() const { 177344779Sdim return HasPreInstrSymbol ? getTrailingObjects<MCSymbol *>()[0] : nullptr; 178344779Sdim } 179344779Sdim 180344779Sdim MCSymbol *getPostInstrSymbol() const { 181344779Sdim return HasPostInstrSymbol 182344779Sdim ? getTrailingObjects<MCSymbol *>()[HasPreInstrSymbol] 183344779Sdim : nullptr; 184344779Sdim } 185344779Sdim 186360661Sdim MDNode *getHeapAllocMarker() const { 187360661Sdim return HasHeapAllocMarker ? getTrailingObjects<MDNode *>()[0] : nullptr; 188360661Sdim } 189360661Sdim 190344779Sdim private: 191344779Sdim friend TrailingObjects; 192344779Sdim 193344779Sdim // Description of the extra info, used to interpret the actual optional 194344779Sdim // data appended. 195344779Sdim // 196344779Sdim // Note that this is not terribly space optimized. This leaves a great deal 197344779Sdim // of flexibility to fit more in here later. 198344779Sdim const int NumMMOs; 199344779Sdim const bool HasPreInstrSymbol; 200344779Sdim const bool HasPostInstrSymbol; 201360661Sdim const bool HasHeapAllocMarker; 202344779Sdim 203344779Sdim // Implement the `TrailingObjects` internal API. 204344779Sdim size_t numTrailingObjects(OverloadToken<MachineMemOperand *>) const { 205344779Sdim return NumMMOs; 206344779Sdim } 207344779Sdim size_t numTrailingObjects(OverloadToken<MCSymbol *>) const { 208344779Sdim return HasPreInstrSymbol + HasPostInstrSymbol; 209344779Sdim } 210360661Sdim size_t numTrailingObjects(OverloadToken<MDNode *>) const { 211360661Sdim return HasHeapAllocMarker; 212360661Sdim } 213344779Sdim 214344779Sdim // Just a boring constructor to allow us to initialize the sizes. Always use 215344779Sdim // the `create` routine above. 216360661Sdim ExtraInfo(int NumMMOs, bool HasPreInstrSymbol, bool HasPostInstrSymbol, 217360661Sdim bool HasHeapAllocMarker) 218344779Sdim : NumMMOs(NumMMOs), HasPreInstrSymbol(HasPreInstrSymbol), 219360661Sdim HasPostInstrSymbol(HasPostInstrSymbol), 220360661Sdim HasHeapAllocMarker(HasHeapAllocMarker) {} 221344779Sdim }; 222344779Sdim 223344779Sdim /// Enumeration of the kinds of inline extra info available. It is important 224344779Sdim /// that the `MachineMemOperand` inline kind has a tag value of zero to make 225344779Sdim /// it accessible as an `ArrayRef`. 226344779Sdim enum ExtraInfoInlineKinds { 227344779Sdim EIIK_MMO = 0, 228344779Sdim EIIK_PreInstrSymbol, 229344779Sdim EIIK_PostInstrSymbol, 230344779Sdim EIIK_OutOfLine 231344779Sdim }; 232344779Sdim 233344779Sdim // We store extra information about the instruction here. The common case is 234344779Sdim // expected to be nothing or a single pointer (typically a MMO or a symbol). 235344779Sdim // We work to optimize this common case by storing it inline here rather than 236344779Sdim // requiring a separate allocation, but we fall back to an allocation when 237344779Sdim // multiple pointers are needed. 238344779Sdim PointerSumType<ExtraInfoInlineKinds, 239344779Sdim PointerSumTypeMember<EIIK_MMO, MachineMemOperand *>, 240344779Sdim PointerSumTypeMember<EIIK_PreInstrSymbol, MCSymbol *>, 241344779Sdim PointerSumTypeMember<EIIK_PostInstrSymbol, MCSymbol *>, 242344779Sdim PointerSumTypeMember<EIIK_OutOfLine, ExtraInfo *>> 243344779Sdim Info; 244344779Sdim 245193323Sed DebugLoc debugLoc; // Source line information. 246193323Sed 247193323Sed // Intrusive list support 248193323Sed friend struct ilist_traits<MachineInstr>; 249314564Sdim friend struct ilist_callback_traits<MachineBasicBlock>; 250193323Sed void setParent(MachineBasicBlock *P) { Parent = P; } 251193323Sed 252288943Sdim /// This constructor creates a copy of the given 253193323Sed /// MachineInstr in the given MachineFunction. 254193323Sed MachineInstr(MachineFunction &, const MachineInstr &); 255193323Sed 256288943Sdim /// This constructor create a MachineInstr and add the implicit operands. 257288943Sdim /// It reserves space for number of operands specified by 258224145Sdim /// MCInstrDesc. An explicit DebugLoc is supplied. 259341825Sdim MachineInstr(MachineFunction &, const MCInstrDesc &tid, DebugLoc dl, 260288943Sdim bool NoImp = false); 261193323Sed 262193323Sed // MachineInstrs are pool-allocated and owned by MachineFunction. 263193323Sed friend class MachineFunction; 264193323Sed 265193323Sedpublic: 266321369Sdim MachineInstr(const MachineInstr &) = delete; 267321369Sdim MachineInstr &operator=(const MachineInstr &) = delete; 268321369Sdim // Use MachineFunction::DeleteMachineInstr() instead. 269321369Sdim ~MachineInstr() = delete; 270321369Sdim 271193323Sed const MachineBasicBlock* getParent() const { return Parent; } 272193323Sed MachineBasicBlock* getParent() { return Parent; } 273193323Sed 274327952Sdim /// Return the function that contains the basic block that this instruction 275327952Sdim /// belongs to. 276327952Sdim /// 277327952Sdim /// Note: this is undefined behaviour if the instruction does not have a 278327952Sdim /// parent. 279327952Sdim const MachineFunction *getMF() const; 280327952Sdim MachineFunction *getMF() { 281327952Sdim return const_cast<MachineFunction *>( 282327952Sdim static_cast<const MachineInstr *>(this)->getMF()); 283327952Sdim } 284327952Sdim 285288943Sdim /// Return the asm printer flags bitvector. 286221345Sdim uint8_t getAsmPrinterFlags() const { return AsmPrinterFlags; } 287199481Srdivacky 288288943Sdim /// Clear the AsmPrinter bitvector. 289218893Sdim void clearAsmPrinterFlags() { AsmPrinterFlags = 0; } 290221345Sdim 291288943Sdim /// Return whether an AsmPrinter flag is set. 292203954Srdivacky bool getAsmPrinterFlag(CommentFlag Flag) const { 293199481Srdivacky return AsmPrinterFlags & Flag; 294199481Srdivacky } 295199481Srdivacky 296288943Sdim /// Set a flag for the AsmPrinter. 297314564Sdim void setAsmPrinterFlag(uint8_t Flag) { 298314564Sdim AsmPrinterFlags |= Flag; 299199481Srdivacky } 300221345Sdim 301288943Sdim /// Clear specific AsmPrinter flags. 302234353Sdim void clearAsmPrinterFlag(CommentFlag Flag) { 303234353Sdim AsmPrinterFlags &= ~Flag; 304234353Sdim } 305234353Sdim 306288943Sdim /// Return the MI flags bitvector. 307341825Sdim uint16_t getFlags() const { 308221345Sdim return Flags; 309221345Sdim } 310221345Sdim 311288943Sdim /// Return whether an MI flag is set. 312221345Sdim bool getFlag(MIFlag Flag) const { 313221345Sdim return Flags & Flag; 314221345Sdim } 315221345Sdim 316288943Sdim /// Set a MI flag. 317221345Sdim void setFlag(MIFlag Flag) { 318341825Sdim Flags |= (uint16_t)Flag; 319221345Sdim } 320221345Sdim 321221345Sdim void setFlags(unsigned flags) { 322249423Sdim // Filter out the automatically maintained flags. 323249423Sdim unsigned Mask = BundledPred | BundledSucc; 324249423Sdim Flags = (Flags & Mask) | (flags & ~Mask); 325221345Sdim } 326221345Sdim 327234353Sdim /// clearFlag - Clear a MI flag. 328234353Sdim void clearFlag(MIFlag Flag) { 329341825Sdim Flags &= ~((uint16_t)Flag); 330234353Sdim } 331234353Sdim 332288943Sdim /// Return true if MI is in a bundle (but not the first MI in a bundle). 333218893Sdim /// 334234353Sdim /// A bundle looks like this before it's finalized: 335234353Sdim /// ---------------- 336234353Sdim /// | MI | 337234353Sdim /// ---------------- 338234353Sdim /// | 339234353Sdim /// ---------------- 340234353Sdim /// | MI * | 341234353Sdim /// ---------------- 342234353Sdim /// | 343234353Sdim /// ---------------- 344234353Sdim /// | MI * | 345234353Sdim /// ---------------- 346234353Sdim /// In this case, the first MI starts a bundle but is not inside a bundle, the 347234353Sdim /// next 2 MIs are considered "inside" the bundle. 348234353Sdim /// 349234353Sdim /// After a bundle is finalized, it looks like this: 350234353Sdim /// ---------------- 351234353Sdim /// | Bundle | 352234353Sdim /// ---------------- 353234353Sdim /// | 354234353Sdim /// ---------------- 355234353Sdim /// | MI * | 356234353Sdim /// ---------------- 357234353Sdim /// | 358234353Sdim /// ---------------- 359234353Sdim /// | MI * | 360234353Sdim /// ---------------- 361234353Sdim /// | 362234353Sdim /// ---------------- 363234353Sdim /// | MI * | 364234353Sdim /// ---------------- 365234353Sdim /// The first instruction has the special opcode "BUNDLE". It's not "inside" 366234353Sdim /// a bundle, but the next three MIs are. 367234353Sdim bool isInsideBundle() const { 368249423Sdim return getFlag(BundledPred); 369218893Sdim } 370199481Srdivacky 371288943Sdim /// Return true if this instruction part of a bundle. This is true 372234353Sdim /// if either itself or its following instruction is marked "InsideBundle". 373249423Sdim bool isBundled() const { 374249423Sdim return isBundledWithPred() || isBundledWithSucc(); 375249423Sdim } 376234353Sdim 377249423Sdim /// Return true if this instruction is part of a bundle, and it is not the 378249423Sdim /// first instruction in the bundle. 379249423Sdim bool isBundledWithPred() const { return getFlag(BundledPred); } 380249423Sdim 381249423Sdim /// Return true if this instruction is part of a bundle, and it is not the 382249423Sdim /// last instruction in the bundle. 383249423Sdim bool isBundledWithSucc() const { return getFlag(BundledSucc); } 384249423Sdim 385249423Sdim /// Bundle this instruction with its predecessor. This can be an unbundled 386249423Sdim /// instruction, or it can be the first instruction in a bundle. 387249423Sdim void bundleWithPred(); 388249423Sdim 389249423Sdim /// Bundle this instruction with its successor. This can be an unbundled 390249423Sdim /// instruction, or it can be the last instruction in a bundle. 391249423Sdim void bundleWithSucc(); 392249423Sdim 393249423Sdim /// Break bundle above this instruction. 394249423Sdim void unbundleFromPred(); 395249423Sdim 396249423Sdim /// Break bundle below this instruction. 397249423Sdim void unbundleFromSucc(); 398249423Sdim 399288943Sdim /// Returns the debug location id of this MachineInstr. 400288943Sdim const DebugLoc &getDebugLoc() const { return debugLoc; } 401221345Sdim 402288943Sdim /// Return the debug variable referenced by 403276479Sdim /// this DBG_VALUE instruction. 404309124Sdim const DILocalVariable *getDebugVariable() const; 405276479Sdim 406288943Sdim /// Return the complex address expression referenced by 407280031Sdim /// this DBG_VALUE instruction. 408309124Sdim const DIExpression *getDebugExpression() const; 409280031Sdim 410341825Sdim /// Return the debug label referenced by 411341825Sdim /// this DBG_LABEL instruction. 412341825Sdim const DILabel *getDebugLabel() const; 413341825Sdim 414288943Sdim /// Emit an error referring to the source location of this instruction. 415288943Sdim /// This should only be used for inline assembly that is somehow 416224145Sdim /// impossible to compile. Other errors should have been handled much 417224145Sdim /// earlier. 418224145Sdim /// 419224145Sdim /// If this method returns, the caller should try to recover from the error. 420224145Sdim void emitError(StringRef Msg) const; 421224145Sdim 422288943Sdim /// Returns the target instruction descriptor of this MachineInstr. 423224145Sdim const MCInstrDesc &getDesc() const { return *MCID; } 424193323Sed 425288943Sdim /// Returns the opcode of this MachineInstr. 426288943Sdim unsigned getOpcode() const { return MCID->Opcode; } 427193323Sed 428344779Sdim /// Retuns the total number of operands. 429249423Sdim unsigned getNumOperands() const { return NumOperands; } 430193323Sed 431193323Sed const MachineOperand& getOperand(unsigned i) const { 432193323Sed assert(i < getNumOperands() && "getOperand() out of range!"); 433193323Sed return Operands[i]; 434193323Sed } 435193323Sed MachineOperand& getOperand(unsigned i) { 436193323Sed assert(i < getNumOperands() && "getOperand() out of range!"); 437193323Sed return Operands[i]; 438193323Sed } 439193323Sed 440341825Sdim /// Returns the total number of definitions. 441341825Sdim unsigned getNumDefs() const { 442341825Sdim return getNumExplicitDefs() + MCID->getNumImplicitDefs(); 443341825Sdim } 444341825Sdim 445360784Sdim /// Returns true if the instruction has implicit definition. 446360784Sdim bool hasImplicitDef() const { 447360784Sdim for (unsigned I = getNumExplicitOperands(), E = getNumOperands(); 448360784Sdim I != E; ++I) { 449360784Sdim const MachineOperand &MO = getOperand(I); 450360784Sdim if (MO.isDef() && MO.isImplicit()) 451360784Sdim return true; 452360784Sdim } 453360784Sdim return false; 454360784Sdim } 455360784Sdim 456360784Sdim /// Returns the implicit operands number. 457360784Sdim unsigned getNumImplicitOperands() const { 458360784Sdim return getNumOperands() - getNumExplicitOperands(); 459360784Sdim } 460360784Sdim 461327952Sdim /// Return true if operand \p OpIdx is a subregister index. 462327952Sdim bool isOperandSubregIdx(unsigned OpIdx) const { 463327952Sdim assert(getOperand(OpIdx).getType() == MachineOperand::MO_Immediate && 464327952Sdim "Expected MO_Immediate operand type."); 465327952Sdim if (isExtractSubreg() && OpIdx == 2) 466327952Sdim return true; 467327952Sdim if (isInsertSubreg() && OpIdx == 3) 468327952Sdim return true; 469327952Sdim if (isRegSequence() && OpIdx > 1 && (OpIdx % 2) == 0) 470327952Sdim return true; 471327952Sdim if (isSubregToReg() && OpIdx == 3) 472327952Sdim return true; 473327952Sdim return false; 474327952Sdim } 475327952Sdim 476288943Sdim /// Returns the number of non-implicit operands. 477193323Sed unsigned getNumExplicitOperands() const; 478218893Sdim 479341825Sdim /// Returns the number of non-implicit definitions. 480341825Sdim unsigned getNumExplicitDefs() const; 481341825Sdim 482218893Sdim /// iterator/begin/end - Iterate over all operands of a machine instruction. 483321369Sdim using mop_iterator = MachineOperand *; 484321369Sdim using const_mop_iterator = const MachineOperand *; 485218893Sdim 486249423Sdim mop_iterator operands_begin() { return Operands; } 487249423Sdim mop_iterator operands_end() { return Operands + NumOperands; } 488218893Sdim 489249423Sdim const_mop_iterator operands_begin() const { return Operands; } 490249423Sdim const_mop_iterator operands_end() const { return Operands + NumOperands; } 491218893Sdim 492276479Sdim iterator_range<mop_iterator> operands() { 493296417Sdim return make_range(operands_begin(), operands_end()); 494276479Sdim } 495276479Sdim iterator_range<const_mop_iterator> operands() const { 496296417Sdim return make_range(operands_begin(), operands_end()); 497276479Sdim } 498276479Sdim iterator_range<mop_iterator> explicit_operands() { 499296417Sdim return make_range(operands_begin(), 500296417Sdim operands_begin() + getNumExplicitOperands()); 501276479Sdim } 502276479Sdim iterator_range<const_mop_iterator> explicit_operands() const { 503296417Sdim return make_range(operands_begin(), 504296417Sdim operands_begin() + getNumExplicitOperands()); 505276479Sdim } 506276479Sdim iterator_range<mop_iterator> implicit_operands() { 507296417Sdim return make_range(explicit_operands().end(), operands_end()); 508276479Sdim } 509276479Sdim iterator_range<const_mop_iterator> implicit_operands() const { 510296417Sdim return make_range(explicit_operands().end(), operands_end()); 511276479Sdim } 512296417Sdim /// Returns a range over all explicit operands that are register definitions. 513296417Sdim /// Implicit definition are not included! 514276479Sdim iterator_range<mop_iterator> defs() { 515296417Sdim return make_range(operands_begin(), 516341825Sdim operands_begin() + getNumExplicitDefs()); 517276479Sdim } 518296417Sdim /// \copydoc defs() 519276479Sdim iterator_range<const_mop_iterator> defs() const { 520296417Sdim return make_range(operands_begin(), 521341825Sdim operands_begin() + getNumExplicitDefs()); 522276479Sdim } 523296417Sdim /// Returns a range that includes all operands that are register uses. 524296417Sdim /// This may include unrelated operands which are not register uses. 525276479Sdim iterator_range<mop_iterator> uses() { 526341825Sdim return make_range(operands_begin() + getNumExplicitDefs(), operands_end()); 527276479Sdim } 528296417Sdim /// \copydoc uses() 529276479Sdim iterator_range<const_mop_iterator> uses() const { 530341825Sdim return make_range(operands_begin() + getNumExplicitDefs(), operands_end()); 531276479Sdim } 532309124Sdim iterator_range<mop_iterator> explicit_uses() { 533341825Sdim return make_range(operands_begin() + getNumExplicitDefs(), 534341825Sdim operands_begin() + getNumExplicitOperands()); 535309124Sdim } 536309124Sdim iterator_range<const_mop_iterator> explicit_uses() const { 537341825Sdim return make_range(operands_begin() + getNumExplicitDefs(), 538341825Sdim operands_begin() + getNumExplicitOperands()); 539309124Sdim } 540276479Sdim 541288943Sdim /// Returns the number of the operand iterator \p I points to. 542288943Sdim unsigned getOperandNo(const_mop_iterator I) const { 543288943Sdim return I - operands_begin(); 544288943Sdim } 545288943Sdim 546344779Sdim /// Access to memory operands of the instruction. If there are none, that does 547344779Sdim /// not imply anything about whether the function accesses memory. Instead, 548344779Sdim /// the caller must behave conservatively. 549344779Sdim ArrayRef<MachineMemOperand *> memoperands() const { 550344779Sdim if (!Info) 551344779Sdim return {}; 552344779Sdim 553344779Sdim if (Info.is<EIIK_MMO>()) 554344779Sdim return makeArrayRef(Info.getAddrOfZeroTagPointer(), 1); 555344779Sdim 556344779Sdim if (ExtraInfo *EI = Info.get<EIIK_OutOfLine>()) 557344779Sdim return EI->getMMOs(); 558344779Sdim 559344779Sdim return {}; 560344779Sdim } 561344779Sdim 562344779Sdim /// Access to memory operands of the instruction. 563344779Sdim /// 564344779Sdim /// If `memoperands_begin() == memoperands_end()`, that does not imply 565344779Sdim /// anything about whether the function accesses memory. Instead, the caller 566344779Sdim /// must behave conservatively. 567344779Sdim mmo_iterator memoperands_begin() const { return memoperands().begin(); } 568344779Sdim 569344779Sdim /// Access to memory operands of the instruction. 570344779Sdim /// 571344779Sdim /// If `memoperands_begin() == memoperands_end()`, that does not imply 572344779Sdim /// anything about whether the function accesses memory. Instead, the caller 573344779Sdim /// must behave conservatively. 574344779Sdim mmo_iterator memoperands_end() const { return memoperands().end(); } 575344779Sdim 576341825Sdim /// Return true if we don't have any memory operands which described the 577296417Sdim /// memory access done by this instruction. If this is true, calling code 578296417Sdim /// must be conservative. 579344779Sdim bool memoperands_empty() const { return memoperands().empty(); } 580193323Sed 581344779Sdim /// Return true if this instruction has exactly one MachineMemOperand. 582344779Sdim bool hasOneMemOperand() const { return memoperands().size() == 1; } 583344779Sdim 584344779Sdim /// Return the number of memory operands. 585344779Sdim unsigned getNumMemOperands() const { return memoperands().size(); } 586344779Sdim 587344779Sdim /// Helper to extract a pre-instruction symbol if one has been added. 588344779Sdim MCSymbol *getPreInstrSymbol() const { 589344779Sdim if (!Info) 590344779Sdim return nullptr; 591344779Sdim if (MCSymbol *S = Info.get<EIIK_PreInstrSymbol>()) 592344779Sdim return S; 593344779Sdim if (ExtraInfo *EI = Info.get<EIIK_OutOfLine>()) 594344779Sdim return EI->getPreInstrSymbol(); 595344779Sdim 596344779Sdim return nullptr; 597276479Sdim } 598276479Sdim 599344779Sdim /// Helper to extract a post-instruction symbol if one has been added. 600344779Sdim MCSymbol *getPostInstrSymbol() const { 601344779Sdim if (!Info) 602344779Sdim return nullptr; 603344779Sdim if (MCSymbol *S = Info.get<EIIK_PostInstrSymbol>()) 604344779Sdim return S; 605344779Sdim if (ExtraInfo *EI = Info.get<EIIK_OutOfLine>()) 606344779Sdim return EI->getPostInstrSymbol(); 607344779Sdim 608344779Sdim return nullptr; 609193323Sed } 610193323Sed 611360661Sdim /// Helper to extract a heap alloc marker if one has been added. 612360661Sdim MDNode *getHeapAllocMarker() const { 613360661Sdim if (!Info) 614360661Sdim return nullptr; 615360661Sdim if (ExtraInfo *EI = Info.get<EIIK_OutOfLine>()) 616360661Sdim return EI->getHeapAllocMarker(); 617360661Sdim 618360661Sdim return nullptr; 619360661Sdim } 620360661Sdim 621234353Sdim /// API for querying MachineInstr properties. They are the same as MCInstrDesc 622234353Sdim /// queries but they are bundle aware. 623234353Sdim 624234353Sdim enum QueryType { 625234353Sdim IgnoreBundle, // Ignore bundles 626234353Sdim AnyInBundle, // Return true if any instruction in bundle has property 627234353Sdim AllInBundle // Return true if all instructions in bundle have property 628234353Sdim }; 629234353Sdim 630288943Sdim /// Return true if the instruction (or in the case of a bundle, 631234353Sdim /// the instructions inside the bundle) has the specified property. 632234353Sdim /// The first argument is the property being queried. 633234353Sdim /// The second argument indicates whether the query should look inside 634234353Sdim /// instruction bundles. 635234353Sdim bool hasProperty(unsigned MCFlag, QueryType Type = AnyInBundle) const { 636344779Sdim assert(MCFlag < 64 && 637344779Sdim "MCFlag out of range for bit mask in getFlags/hasPropertyInBundle."); 638249423Sdim // Inline the fast path for unbundled or bundle-internal instructions. 639249423Sdim if (Type == IgnoreBundle || !isBundled() || isBundledWithPred()) 640314564Sdim return getDesc().getFlags() & (1ULL << MCFlag); 641234353Sdim 642249423Sdim // If this is the first instruction in a bundle, take the slow path. 643314564Sdim return hasPropertyInBundle(1ULL << MCFlag, Type); 644234353Sdim } 645234353Sdim 646360784Sdim /// Return true if this is an instruction that should go through the usual 647360784Sdim /// legalization steps. 648360784Sdim bool isPreISelOpcode(QueryType Type = IgnoreBundle) const { 649360784Sdim return hasProperty(MCID::PreISelOpcode, Type); 650360784Sdim } 651360784Sdim 652288943Sdim /// Return true if this instruction can have a variable number of operands. 653288943Sdim /// In this case, the variable operands will be after the normal 654234353Sdim /// operands but before the implicit definitions and uses (if any are 655234353Sdim /// present). 656234353Sdim bool isVariadic(QueryType Type = IgnoreBundle) const { 657234353Sdim return hasProperty(MCID::Variadic, Type); 658234353Sdim } 659234353Sdim 660288943Sdim /// Set if this instruction has an optional definition, e.g. 661234353Sdim /// ARM instructions which can set condition code if 's' bit is set. 662234353Sdim bool hasOptionalDef(QueryType Type = IgnoreBundle) const { 663234353Sdim return hasProperty(MCID::HasOptionalDef, Type); 664234353Sdim } 665234353Sdim 666288943Sdim /// Return true if this is a pseudo instruction that doesn't 667234353Sdim /// correspond to a real machine instruction. 668234353Sdim bool isPseudo(QueryType Type = IgnoreBundle) const { 669234353Sdim return hasProperty(MCID::Pseudo, Type); 670234353Sdim } 671234353Sdim 672234353Sdim bool isReturn(QueryType Type = AnyInBundle) const { 673234353Sdim return hasProperty(MCID::Return, Type); 674234353Sdim } 675234353Sdim 676344779Sdim /// Return true if this is an instruction that marks the end of an EH scope, 677344779Sdim /// i.e., a catchpad or a cleanuppad instruction. 678344779Sdim bool isEHScopeReturn(QueryType Type = AnyInBundle) const { 679344779Sdim return hasProperty(MCID::EHScopeReturn, Type); 680344779Sdim } 681344779Sdim 682234353Sdim bool isCall(QueryType Type = AnyInBundle) const { 683234353Sdim return hasProperty(MCID::Call, Type); 684234353Sdim } 685234353Sdim 686288943Sdim /// Returns true if the specified instruction stops control flow 687234353Sdim /// from executing the instruction immediately following it. Examples include 688234353Sdim /// unconditional branches and return instructions. 689234353Sdim bool isBarrier(QueryType Type = AnyInBundle) const { 690234353Sdim return hasProperty(MCID::Barrier, Type); 691234353Sdim } 692234353Sdim 693288943Sdim /// Returns true if this instruction part of the terminator for a basic block. 694288943Sdim /// Typically this is things like return and branch instructions. 695234353Sdim /// 696234353Sdim /// Various passes use this to insert code into the bottom of a basic block, 697234353Sdim /// but before control flow occurs. 698234353Sdim bool isTerminator(QueryType Type = AnyInBundle) const { 699234353Sdim return hasProperty(MCID::Terminator, Type); 700234353Sdim } 701234353Sdim 702288943Sdim /// Returns true if this is a conditional, unconditional, or indirect branch. 703288943Sdim /// Predicates below can be used to discriminate between 704234353Sdim /// these cases, and the TargetInstrInfo::AnalyzeBranch method can be used to 705234353Sdim /// get more information. 706234353Sdim bool isBranch(QueryType Type = AnyInBundle) const { 707234353Sdim return hasProperty(MCID::Branch, Type); 708234353Sdim } 709234353Sdim 710288943Sdim /// Return true if this is an indirect branch, such as a 711234353Sdim /// branch through a register. 712234353Sdim bool isIndirectBranch(QueryType Type = AnyInBundle) const { 713234353Sdim return hasProperty(MCID::IndirectBranch, Type); 714234353Sdim } 715234353Sdim 716288943Sdim /// Return true if this is a branch which may fall 717234353Sdim /// through to the next instruction or may transfer control flow to some other 718234353Sdim /// block. The TargetInstrInfo::AnalyzeBranch method can be used to get more 719234353Sdim /// information about this branch. 720234353Sdim bool isConditionalBranch(QueryType Type = AnyInBundle) const { 721360784Sdim return isBranch(Type) && !isBarrier(Type) && !isIndirectBranch(Type); 722234353Sdim } 723234353Sdim 724288943Sdim /// Return true if this is a branch which always 725234353Sdim /// transfers control flow to some other block. The 726234353Sdim /// TargetInstrInfo::AnalyzeBranch method can be used to get more information 727234353Sdim /// about this branch. 728234353Sdim bool isUnconditionalBranch(QueryType Type = AnyInBundle) const { 729360784Sdim return isBranch(Type) && isBarrier(Type) && !isIndirectBranch(Type); 730234353Sdim } 731234353Sdim 732261991Sdim /// Return true if this instruction has a predicate operand that 733261991Sdim /// controls execution. It may be set to 'always', or may be set to other 734234353Sdim /// values. There are various methods in TargetInstrInfo that can be used to 735234353Sdim /// control and modify the predicate in this instruction. 736234353Sdim bool isPredicable(QueryType Type = AllInBundle) const { 737234353Sdim // If it's a bundle than all bundled instructions must be predicable for this 738234353Sdim // to return true. 739234353Sdim return hasProperty(MCID::Predicable, Type); 740234353Sdim } 741234353Sdim 742288943Sdim /// Return true if this instruction is a comparison. 743234353Sdim bool isCompare(QueryType Type = IgnoreBundle) const { 744234353Sdim return hasProperty(MCID::Compare, Type); 745234353Sdim } 746234353Sdim 747288943Sdim /// Return true if this instruction is a move immediate 748234353Sdim /// (including conditional moves) instruction. 749234353Sdim bool isMoveImmediate(QueryType Type = IgnoreBundle) const { 750234353Sdim return hasProperty(MCID::MoveImm, Type); 751234353Sdim } 752234353Sdim 753341825Sdim /// Return true if this instruction is a register move. 754341825Sdim /// (including moving values from subreg to reg) 755341825Sdim bool isMoveReg(QueryType Type = IgnoreBundle) const { 756341825Sdim return hasProperty(MCID::MoveReg, Type); 757341825Sdim } 758341825Sdim 759288943Sdim /// Return true if this instruction is a bitcast instruction. 760234353Sdim bool isBitcast(QueryType Type = IgnoreBundle) const { 761234353Sdim return hasProperty(MCID::Bitcast, Type); 762234353Sdim } 763234353Sdim 764288943Sdim /// Return true if this instruction is a select instruction. 765239462Sdim bool isSelect(QueryType Type = IgnoreBundle) const { 766239462Sdim return hasProperty(MCID::Select, Type); 767239462Sdim } 768239462Sdim 769288943Sdim /// Return true if this instruction cannot be safely duplicated. 770288943Sdim /// For example, if the instruction has a unique labels attached 771234353Sdim /// to it, duplicating it would cause multiple definition errors. 772234353Sdim bool isNotDuplicable(QueryType Type = AnyInBundle) const { 773234353Sdim return hasProperty(MCID::NotDuplicable, Type); 774234353Sdim } 775234353Sdim 776288943Sdim /// Return true if this instruction is convergent. 777296417Sdim /// Convergent instructions can not be made control-dependent on any 778296417Sdim /// additional values. 779288943Sdim bool isConvergent(QueryType Type = AnyInBundle) const { 780309124Sdim if (isInlineAsm()) { 781309124Sdim unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 782309124Sdim if (ExtraInfo & InlineAsm::Extra_IsConvergent) 783309124Sdim return true; 784309124Sdim } 785288943Sdim return hasProperty(MCID::Convergent, Type); 786288943Sdim } 787288943Sdim 788288943Sdim /// Returns true if the specified instruction has a delay slot 789234353Sdim /// which must be filled by the code generator. 790234353Sdim bool hasDelaySlot(QueryType Type = AnyInBundle) const { 791234353Sdim return hasProperty(MCID::DelaySlot, Type); 792234353Sdim } 793234353Sdim 794288943Sdim /// Return true for instructions that can be folded as 795234353Sdim /// memory operands in other instructions. The most common use for this 796234353Sdim /// is instructions that are simple loads from memory that don't modify 797234353Sdim /// the loaded value in any way, but it can also be used for instructions 798234353Sdim /// that can be expressed as constant-pool loads, such as V_SETALLONES 799234353Sdim /// on x86, to allow them to be folded when it is beneficial. 800234353Sdim /// This should only be set on instructions that return a value in their 801234353Sdim /// only virtual register definition. 802234353Sdim bool canFoldAsLoad(QueryType Type = IgnoreBundle) const { 803234353Sdim return hasProperty(MCID::FoldableAsLoad, Type); 804234353Sdim } 805234353Sdim 806341825Sdim /// Return true if this instruction behaves 807280031Sdim /// the same way as the generic REG_SEQUENCE instructions. 808280031Sdim /// E.g., on ARM, 809280031Sdim /// dX VMOVDRR rY, rZ 810280031Sdim /// is equivalent to 811280031Sdim /// dX = REG_SEQUENCE rY, ssub_0, rZ, ssub_1. 812280031Sdim /// 813280031Sdim /// Note that for the optimizers to be able to take advantage of 814280031Sdim /// this property, TargetInstrInfo::getRegSequenceLikeInputs has to be 815280031Sdim /// override accordingly. 816280031Sdim bool isRegSequenceLike(QueryType Type = IgnoreBundle) const { 817280031Sdim return hasProperty(MCID::RegSequence, Type); 818280031Sdim } 819280031Sdim 820341825Sdim /// Return true if this instruction behaves 821280031Sdim /// the same way as the generic EXTRACT_SUBREG instructions. 822280031Sdim /// E.g., on ARM, 823280031Sdim /// rX, rY VMOVRRD dZ 824280031Sdim /// is equivalent to two EXTRACT_SUBREG: 825280031Sdim /// rX = EXTRACT_SUBREG dZ, ssub_0 826280031Sdim /// rY = EXTRACT_SUBREG dZ, ssub_1 827280031Sdim /// 828280031Sdim /// Note that for the optimizers to be able to take advantage of 829280031Sdim /// this property, TargetInstrInfo::getExtractSubregLikeInputs has to be 830280031Sdim /// override accordingly. 831280031Sdim bool isExtractSubregLike(QueryType Type = IgnoreBundle) const { 832280031Sdim return hasProperty(MCID::ExtractSubreg, Type); 833280031Sdim } 834280031Sdim 835341825Sdim /// Return true if this instruction behaves 836280031Sdim /// the same way as the generic INSERT_SUBREG instructions. 837280031Sdim /// E.g., on ARM, 838280031Sdim /// dX = VSETLNi32 dY, rZ, Imm 839280031Sdim /// is equivalent to a INSERT_SUBREG: 840280031Sdim /// dX = INSERT_SUBREG dY, rZ, translateImmToSubIdx(Imm) 841280031Sdim /// 842280031Sdim /// Note that for the optimizers to be able to take advantage of 843280031Sdim /// this property, TargetInstrInfo::getInsertSubregLikeInputs has to be 844280031Sdim /// override accordingly. 845280031Sdim bool isInsertSubregLike(QueryType Type = IgnoreBundle) const { 846280031Sdim return hasProperty(MCID::InsertSubreg, Type); 847280031Sdim } 848280031Sdim 849234353Sdim //===--------------------------------------------------------------------===// 850234353Sdim // Side Effect Analysis 851234353Sdim //===--------------------------------------------------------------------===// 852234353Sdim 853288943Sdim /// Return true if this instruction could possibly read memory. 854234353Sdim /// Instructions with this flag set are not necessarily simple load 855234353Sdim /// instructions, they may load a value and modify it, for example. 856234353Sdim bool mayLoad(QueryType Type = AnyInBundle) const { 857243830Sdim if (isInlineAsm()) { 858243830Sdim unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 859243830Sdim if (ExtraInfo & InlineAsm::Extra_MayLoad) 860243830Sdim return true; 861243830Sdim } 862234353Sdim return hasProperty(MCID::MayLoad, Type); 863234353Sdim } 864234353Sdim 865288943Sdim /// Return true if this instruction could possibly modify memory. 866234353Sdim /// Instructions with this flag set are not necessarily simple store 867234353Sdim /// instructions, they may store a modified value based on their operands, or 868234353Sdim /// may not actually modify anything, for example. 869234353Sdim bool mayStore(QueryType Type = AnyInBundle) const { 870243830Sdim if (isInlineAsm()) { 871243830Sdim unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 872243830Sdim if (ExtraInfo & InlineAsm::Extra_MayStore) 873243830Sdim return true; 874243830Sdim } 875234353Sdim return hasProperty(MCID::MayStore, Type); 876234353Sdim } 877234353Sdim 878288943Sdim /// Return true if this instruction could possibly read or modify memory. 879288943Sdim bool mayLoadOrStore(QueryType Type = AnyInBundle) const { 880288943Sdim return mayLoad(Type) || mayStore(Type); 881288943Sdim } 882288943Sdim 883353358Sdim /// Return true if this instruction could possibly raise a floating-point 884353358Sdim /// exception. This is the case if the instruction is a floating-point 885353358Sdim /// instruction that can in principle raise an exception, as indicated 886353358Sdim /// by the MCID::MayRaiseFPException property, *and* at the same time, 887353358Sdim /// the instruction is used in a context where we expect floating-point 888360784Sdim /// exceptions are not disabled, as indicated by the NoFPExcept MI flag. 889353358Sdim bool mayRaiseFPException() const { 890353358Sdim return hasProperty(MCID::MayRaiseFPException) && 891360784Sdim !getFlag(MachineInstr::MIFlag::NoFPExcept); 892353358Sdim } 893353358Sdim 894234353Sdim //===--------------------------------------------------------------------===// 895234353Sdim // Flags that indicate whether an instruction can be modified by a method. 896234353Sdim //===--------------------------------------------------------------------===// 897234353Sdim 898288943Sdim /// Return true if this may be a 2- or 3-address 899234353Sdim /// instruction (of the form "X = op Y, Z, ..."), which produces the same 900234353Sdim /// result if Y and Z are exchanged. If this flag is set, then the 901234353Sdim /// TargetInstrInfo::commuteInstruction method may be used to hack on the 902234353Sdim /// instruction. 903234353Sdim /// 904234353Sdim /// Note that this flag may be set on instructions that are only commutable 905234353Sdim /// sometimes. In these cases, the call to commuteInstruction will fail. 906234353Sdim /// Also note that some instructions require non-trivial modification to 907234353Sdim /// commute them. 908234353Sdim bool isCommutable(QueryType Type = IgnoreBundle) const { 909234353Sdim return hasProperty(MCID::Commutable, Type); 910234353Sdim } 911234353Sdim 912288943Sdim /// Return true if this is a 2-address instruction 913234353Sdim /// which can be changed into a 3-address instruction if needed. Doing this 914234353Sdim /// transformation can be profitable in the register allocator, because it 915234353Sdim /// means that the instruction can use a 2-address form if possible, but 916234353Sdim /// degrade into a less efficient form if the source and dest register cannot 917234353Sdim /// be assigned to the same register. For example, this allows the x86 918234353Sdim /// backend to turn a "shl reg, 3" instruction into an LEA instruction, which 919234353Sdim /// is the same speed as the shift but has bigger code size. 920234353Sdim /// 921234353Sdim /// If this returns true, then the target must implement the 922234353Sdim /// TargetInstrInfo::convertToThreeAddress method for this instruction, which 923234353Sdim /// is allowed to fail if the transformation isn't valid for this specific 924234353Sdim /// instruction (e.g. shl reg, 4 on x86). 925234353Sdim /// 926234353Sdim bool isConvertibleTo3Addr(QueryType Type = IgnoreBundle) const { 927234353Sdim return hasProperty(MCID::ConvertibleTo3Addr, Type); 928234353Sdim } 929234353Sdim 930288943Sdim /// Return true if this instruction requires 931234353Sdim /// custom insertion support when the DAG scheduler is inserting it into a 932234353Sdim /// machine basic block. If this is true for the instruction, it basically 933234353Sdim /// means that it is a pseudo instruction used at SelectionDAG time that is 934234353Sdim /// expanded out into magic code by the target when MachineInstrs are formed. 935234353Sdim /// 936234353Sdim /// If this is true, the TargetLoweringInfo::InsertAtEndOfBasicBlock method 937234353Sdim /// is used to insert this into the MachineBasicBlock. 938234353Sdim bool usesCustomInsertionHook(QueryType Type = IgnoreBundle) const { 939234353Sdim return hasProperty(MCID::UsesCustomInserter, Type); 940234353Sdim } 941234353Sdim 942288943Sdim /// Return true if this instruction requires *adjustment* 943234353Sdim /// after instruction selection by calling a target hook. For example, this 944234353Sdim /// can be used to fill in ARM 's' optional operand depending on whether 945234353Sdim /// the conditional flag register is used. 946234353Sdim bool hasPostISelHook(QueryType Type = IgnoreBundle) const { 947234353Sdim return hasProperty(MCID::HasPostISelHook, Type); 948234353Sdim } 949234353Sdim 950288943Sdim /// Returns true if this instruction is a candidate for remat. 951288943Sdim /// This flag is deprecated, please don't use it anymore. If this 952234353Sdim /// flag is set, the isReallyTriviallyReMaterializable() method is called to 953234353Sdim /// verify the instruction is really rematable. 954234353Sdim bool isRematerializable(QueryType Type = AllInBundle) const { 955234353Sdim // It's only possible to re-mat a bundle if all bundled instructions are 956234353Sdim // re-materializable. 957234353Sdim return hasProperty(MCID::Rematerializable, Type); 958234353Sdim } 959234353Sdim 960288943Sdim /// Returns true if this instruction has the same cost (or less) than a move 961288943Sdim /// instruction. This is useful during certain types of optimizations 962288943Sdim /// (e.g., remat during two-address conversion or machine licm) 963234353Sdim /// where we would like to remat or hoist the instruction, but not if it costs 964234353Sdim /// more than moving the instruction into the appropriate register. Note, we 965234353Sdim /// are not marking copies from and to the same register class with this flag. 966234353Sdim bool isAsCheapAsAMove(QueryType Type = AllInBundle) const { 967234353Sdim // Only returns true for a bundle if all bundled instructions are cheap. 968234353Sdim return hasProperty(MCID::CheapAsAMove, Type); 969234353Sdim } 970234353Sdim 971288943Sdim /// Returns true if this instruction source operands 972234353Sdim /// have special register allocation requirements that are not captured by the 973234353Sdim /// operand register classes. e.g. ARM::STRD's two source registers must be an 974234353Sdim /// even / odd pair, ARM::STM registers have to be in ascending order. 975234353Sdim /// Post-register allocation passes should not attempt to change allocations 976234353Sdim /// for sources of instructions with this flag. 977234353Sdim bool hasExtraSrcRegAllocReq(QueryType Type = AnyInBundle) const { 978234353Sdim return hasProperty(MCID::ExtraSrcRegAllocReq, Type); 979234353Sdim } 980234353Sdim 981288943Sdim /// Returns true if this instruction def operands 982234353Sdim /// have special register allocation requirements that are not captured by the 983234353Sdim /// operand register classes. e.g. ARM::LDRD's two def registers must be an 984234353Sdim /// even / odd pair, ARM::LDM registers have to be in ascending order. 985234353Sdim /// Post-register allocation passes should not attempt to change allocations 986234353Sdim /// for definitions of instructions with this flag. 987234353Sdim bool hasExtraDefRegAllocReq(QueryType Type = AnyInBundle) const { 988234353Sdim return hasProperty(MCID::ExtraDefRegAllocReq, Type); 989234353Sdim } 990234353Sdim 991204642Srdivacky enum MICheckType { 992204642Srdivacky CheckDefs, // Check all operands for equality 993223017Sdim CheckKillDead, // Check all operands including kill / dead markers 994204642Srdivacky IgnoreDefs, // Ignore all definitions 995204642Srdivacky IgnoreVRegDefs // Ignore virtual register definitions 996204642Srdivacky }; 997204642Srdivacky 998314564Sdim /// Return true if this instruction is identical to \p Other. 999314564Sdim /// Two instructions are identical if they have the same opcode and all their 1000314564Sdim /// operands are identical (with respect to MachineOperand::isIdenticalTo()). 1001314564Sdim /// Note that this means liveness related flags (dead, undef, kill) do not 1002314564Sdim /// affect the notion of identical. 1003309124Sdim bool isIdenticalTo(const MachineInstr &Other, 1004204642Srdivacky MICheckType Check = CheckDefs) const; 1005193323Sed 1006249423Sdim /// Unlink 'this' from the containing basic block, and return it without 1007249423Sdim /// deleting it. 1008249423Sdim /// 1009249423Sdim /// This function can not be used on bundled instructions, use 1010249423Sdim /// removeFromBundle() to remove individual instructions from a bundle. 1011193323Sed MachineInstr *removeFromParent(); 1012221345Sdim 1013249423Sdim /// Unlink this instruction from its basic block and return it without 1014249423Sdim /// deleting it. 1015249423Sdim /// 1016249423Sdim /// If the instruction is part of a bundle, the other instructions in the 1017249423Sdim /// bundle remain bundled. 1018249423Sdim MachineInstr *removeFromBundle(); 1019249423Sdim 1020249423Sdim /// Unlink 'this' from the containing basic block and delete it. 1021249423Sdim /// 1022249423Sdim /// If this instruction is the header of a bundle, the whole bundle is erased. 1023249423Sdim /// This function can not be used for instructions inside a bundle, use 1024249423Sdim /// eraseFromBundle() to erase individual bundled instructions. 1025193323Sed void eraseFromParent(); 1026193323Sed 1027280031Sdim /// Unlink 'this' from the containing basic block and delete it. 1028280031Sdim /// 1029280031Sdim /// For all definitions mark their uses in DBG_VALUE nodes 1030280031Sdim /// as undefined. Otherwise like eraseFromParent(). 1031280031Sdim void eraseFromParentAndMarkDBGValuesForRemoval(); 1032280031Sdim 1033249423Sdim /// Unlink 'this' form its basic block and delete it. 1034249423Sdim /// 1035249423Sdim /// If the instruction is part of a bundle, the other instructions in the 1036249423Sdim /// bundle remain bundled. 1037249423Sdim void eraseFromBundle(); 1038249423Sdim 1039276479Sdim bool isEHLabel() const { return getOpcode() == TargetOpcode::EH_LABEL; } 1040276479Sdim bool isGCLabel() const { return getOpcode() == TargetOpcode::GC_LABEL; } 1041327952Sdim bool isAnnotationLabel() const { 1042327952Sdim return getOpcode() == TargetOpcode::ANNOTATION_LABEL; 1043327952Sdim } 1044276479Sdim 1045288943Sdim /// Returns true if the MachineInstr represents a label. 1046327952Sdim bool isLabel() const { 1047327952Sdim return isEHLabel() || isGCLabel() || isAnnotationLabel(); 1048327952Sdim } 1049321369Sdim 1050276479Sdim bool isCFIInstruction() const { 1051276479Sdim return getOpcode() == TargetOpcode::CFI_INSTRUCTION; 1052203954Srdivacky } 1053221345Sdim 1054276479Sdim // True if the instruction represents a position in the function. 1055276479Sdim bool isPosition() const { return isLabel() || isCFIInstruction(); } 1056276479Sdim 1057203954Srdivacky bool isDebugValue() const { return getOpcode() == TargetOpcode::DBG_VALUE; } 1058341825Sdim bool isDebugLabel() const { return getOpcode() == TargetOpcode::DBG_LABEL; } 1059341825Sdim bool isDebugInstr() const { return isDebugValue() || isDebugLabel(); } 1060321369Sdim 1061261991Sdim /// A DBG_VALUE is indirect iff the first operand is a register and 1062261991Sdim /// the second operand is an immediate. 1063261991Sdim bool isIndirectDebugValue() const { 1064261991Sdim return isDebugValue() 1065261991Sdim && getOperand(0).isReg() 1066261991Sdim && getOperand(1).isImm(); 1067261991Sdim } 1068221345Sdim 1069353358Sdim /// A DBG_VALUE is an entry value iff its debug expression contains the 1070360784Sdim /// DW_OP_LLVM_entry_value operation. 1071360784Sdim bool isDebugEntryValue() const; 1072353358Sdim 1073353358Sdim /// Return true if the instruction is a debug value which describes a part of 1074353358Sdim /// a variable as unavailable. 1075353358Sdim bool isUndefDebugValue() const { 1076360784Sdim return isDebugValue() && getOperand(0).isReg() && !getOperand(0).getReg().isValid(); 1077353358Sdim } 1078353358Sdim 1079327952Sdim bool isPHI() const { 1080327952Sdim return getOpcode() == TargetOpcode::PHI || 1081327952Sdim getOpcode() == TargetOpcode::G_PHI; 1082327952Sdim } 1083203954Srdivacky bool isKill() const { return getOpcode() == TargetOpcode::KILL; } 1084203954Srdivacky bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; } 1085353358Sdim bool isInlineAsm() const { 1086353358Sdim return getOpcode() == TargetOpcode::INLINEASM || 1087353358Sdim getOpcode() == TargetOpcode::INLINEASM_BR; 1088353358Sdim } 1089321369Sdim 1090353358Sdim /// FIXME: Seems like a layering violation that the AsmDialect, which is X86 1091353358Sdim /// specific, be attached to a generic MachineInstr. 1092296417Sdim bool isMSInlineAsm() const { 1093353358Sdim return isInlineAsm() && getInlineAsmDialect() == InlineAsm::AD_Intel; 1094249423Sdim } 1095321369Sdim 1096218893Sdim bool isStackAligningInlineAsm() const; 1097243830Sdim InlineAsm::AsmDialect getInlineAsmDialect() const; 1098321369Sdim 1099203954Srdivacky bool isInsertSubreg() const { 1100203954Srdivacky return getOpcode() == TargetOpcode::INSERT_SUBREG; 1101203954Srdivacky } 1102321369Sdim 1103203954Srdivacky bool isSubregToReg() const { 1104203954Srdivacky return getOpcode() == TargetOpcode::SUBREG_TO_REG; 1105203954Srdivacky } 1106321369Sdim 1107208599Srdivacky bool isRegSequence() const { 1108208599Srdivacky return getOpcode() == TargetOpcode::REG_SEQUENCE; 1109208599Srdivacky } 1110321369Sdim 1111234353Sdim bool isBundle() const { 1112234353Sdim return getOpcode() == TargetOpcode::BUNDLE; 1113234353Sdim } 1114321369Sdim 1115210299Sed bool isCopy() const { 1116210299Sed return getOpcode() == TargetOpcode::COPY; 1117210299Sed } 1118321369Sdim 1119224145Sdim bool isFullCopy() const { 1120224145Sdim return isCopy() && !getOperand(0).getSubReg() && !getOperand(1).getSubReg(); 1121224145Sdim } 1122321369Sdim 1123276479Sdim bool isExtractSubreg() const { 1124276479Sdim return getOpcode() == TargetOpcode::EXTRACT_SUBREG; 1125276479Sdim } 1126210299Sed 1127288943Sdim /// Return true if the instruction behaves like a copy. 1128210299Sed /// This does not include native copy instructions. 1129210299Sed bool isCopyLike() const { 1130210299Sed return isCopy() || isSubregToReg(); 1131210299Sed } 1132210299Sed 1133288943Sdim /// Return true is the instruction is an identity copy. 1134210299Sed bool isIdentityCopy() const { 1135210299Sed return isCopy() && getOperand(0).getReg() == getOperand(1).getReg() && 1136210299Sed getOperand(0).getSubReg() == getOperand(1).getSubReg(); 1137210299Sed } 1138210299Sed 1139321369Sdim /// Return true if this instruction doesn't produce any output in the form of 1140321369Sdim /// executable instructions. 1141321369Sdim bool isMetaInstruction() const { 1142321369Sdim switch (getOpcode()) { 1143321369Sdim default: 1144321369Sdim return false; 1145321369Sdim case TargetOpcode::IMPLICIT_DEF: 1146321369Sdim case TargetOpcode::KILL: 1147321369Sdim case TargetOpcode::CFI_INSTRUCTION: 1148321369Sdim case TargetOpcode::EH_LABEL: 1149321369Sdim case TargetOpcode::GC_LABEL: 1150321369Sdim case TargetOpcode::DBG_VALUE: 1151341825Sdim case TargetOpcode::DBG_LABEL: 1152341825Sdim case TargetOpcode::LIFETIME_START: 1153341825Sdim case TargetOpcode::LIFETIME_END: 1154321369Sdim return true; 1155321369Sdim } 1156321369Sdim } 1157321369Sdim 1158321369Sdim /// Return true if this is a transient instruction that is either very likely 1159321369Sdim /// to be eliminated during register allocation (such as copy-like 1160321369Sdim /// instructions), or if this instruction doesn't have an execution-time cost. 1161239462Sdim bool isTransient() const { 1162321369Sdim switch (getOpcode()) { 1163321369Sdim default: 1164321369Sdim return isMetaInstruction(); 1165239462Sdim // Copy-like instructions are usually eliminated during register allocation. 1166239462Sdim case TargetOpcode::PHI: 1167327952Sdim case TargetOpcode::G_PHI: 1168239462Sdim case TargetOpcode::COPY: 1169239462Sdim case TargetOpcode::INSERT_SUBREG: 1170239462Sdim case TargetOpcode::SUBREG_TO_REG: 1171239462Sdim case TargetOpcode::REG_SEQUENCE: 1172239462Sdim return true; 1173239462Sdim } 1174239462Sdim } 1175239462Sdim 1176249423Sdim /// Return the number of instructions inside the MI bundle, excluding the 1177249423Sdim /// bundle header. 1178249423Sdim /// 1179249423Sdim /// This is the number of instructions that MachineBasicBlock::iterator 1180249423Sdim /// skips, 0 for unbundled instructions. 1181234353Sdim unsigned getBundleSize() const; 1182234353Sdim 1183288943Sdim /// Return true if the MachineInstr reads the specified register. 1184288943Sdim /// If TargetRegisterInfo is passed, then it also checks if there 1185193323Sed /// is a read of a super-register. 1186208599Srdivacky /// This does not count partial redefines of virtual registers as reads: 1187208599Srdivacky /// %reg1024:6 = OP. 1188360784Sdim bool readsRegister(Register Reg, 1189276479Sdim const TargetRegisterInfo *TRI = nullptr) const { 1190193323Sed return findRegisterUseOperandIdx(Reg, false, TRI) != -1; 1191193323Sed } 1192193323Sed 1193288943Sdim /// Return true if the MachineInstr reads the specified virtual register. 1194288943Sdim /// Take into account that a partial define is a 1195208599Srdivacky /// read-modify-write operation. 1196360784Sdim bool readsVirtualRegister(Register Reg) const { 1197208599Srdivacky return readsWritesVirtualRegister(Reg).first; 1198208599Srdivacky } 1199208599Srdivacky 1200288943Sdim /// Return a pair of bools (reads, writes) indicating if this instruction 1201288943Sdim /// reads or writes Reg. This also considers partial defines. 1202208599Srdivacky /// If Ops is not null, all operand indices for Reg are added. 1203360784Sdim std::pair<bool,bool> readsWritesVirtualRegister(Register Reg, 1204276479Sdim SmallVectorImpl<unsigned> *Ops = nullptr) const; 1205208599Srdivacky 1206288943Sdim /// Return true if the MachineInstr kills the specified register. 1207288943Sdim /// If TargetRegisterInfo is passed, then it also checks if there is 1208193323Sed /// a kill of a super-register. 1209360784Sdim bool killsRegister(Register Reg, 1210276479Sdim const TargetRegisterInfo *TRI = nullptr) const { 1211193323Sed return findRegisterUseOperandIdx(Reg, true, TRI) != -1; 1212193323Sed } 1213193323Sed 1214288943Sdim /// Return true if the MachineInstr fully defines the specified register. 1215288943Sdim /// If TargetRegisterInfo is passed, then it also checks 1216193323Sed /// if there is a def of a super-register. 1217208599Srdivacky /// NOTE: It's ignoring subreg indices on virtual registers. 1218360784Sdim bool definesRegister(Register Reg, 1219276479Sdim const TargetRegisterInfo *TRI = nullptr) const { 1220208599Srdivacky return findRegisterDefOperandIdx(Reg, false, false, TRI) != -1; 1221193323Sed } 1222193323Sed 1223288943Sdim /// Return true if the MachineInstr modifies (fully define or partially 1224288943Sdim /// define) the specified register. 1225208599Srdivacky /// NOTE: It's ignoring subreg indices on virtual registers. 1226360784Sdim bool modifiesRegister(Register Reg, const TargetRegisterInfo *TRI) const { 1227208599Srdivacky return findRegisterDefOperandIdx(Reg, false, true, TRI) != -1; 1228208599Srdivacky } 1229208599Srdivacky 1230288943Sdim /// Returns true if the register is dead in this machine instruction. 1231288943Sdim /// If TargetRegisterInfo is passed, then it also checks 1232193323Sed /// if there is a dead def of a super-register. 1233360784Sdim bool registerDefIsDead(Register Reg, 1234276479Sdim const TargetRegisterInfo *TRI = nullptr) const { 1235208599Srdivacky return findRegisterDefOperandIdx(Reg, true, false, TRI) != -1; 1236193323Sed } 1237193323Sed 1238309124Sdim /// Returns true if the MachineInstr has an implicit-use operand of exactly 1239309124Sdim /// the given register (not considering sub/super-registers). 1240360784Sdim bool hasRegisterImplicitUseOperand(Register Reg) const; 1241309124Sdim 1242288943Sdim /// Returns the operand index that is a use of the specific register or -1 1243288943Sdim /// if it is not found. It further tightens the search criteria to a use 1244288943Sdim /// that kills the register if isKill is true. 1245360784Sdim int findRegisterUseOperandIdx(Register Reg, bool isKill = false, 1246276479Sdim const TargetRegisterInfo *TRI = nullptr) const; 1247193323Sed 1248288943Sdim /// Wrapper for findRegisterUseOperandIdx, it returns 1249193323Sed /// a pointer to the MachineOperand rather than an index. 1250360784Sdim MachineOperand *findRegisterUseOperand(Register Reg, bool isKill = false, 1251276479Sdim const TargetRegisterInfo *TRI = nullptr) { 1252193323Sed int Idx = findRegisterUseOperandIdx(Reg, isKill, TRI); 1253276479Sdim return (Idx == -1) ? nullptr : &getOperand(Idx); 1254193323Sed } 1255221345Sdim 1256296417Sdim const MachineOperand *findRegisterUseOperand( 1257360784Sdim Register Reg, bool isKill = false, 1258296417Sdim const TargetRegisterInfo *TRI = nullptr) const { 1259296417Sdim return const_cast<MachineInstr *>(this)-> 1260296417Sdim findRegisterUseOperand(Reg, isKill, TRI); 1261296417Sdim } 1262296417Sdim 1263288943Sdim /// Returns the operand index that is a def of the specified register or 1264288943Sdim /// -1 if it is not found. If isDead is true, defs that are not dead are 1265288943Sdim /// skipped. If Overlap is true, then it also looks for defs that merely 1266288943Sdim /// overlap the specified register. If TargetRegisterInfo is non-null, 1267288943Sdim /// then it also checks if there is a def of a super-register. 1268234353Sdim /// This may also return a register mask operand when Overlap is true. 1269360784Sdim int findRegisterDefOperandIdx(Register Reg, 1270208599Srdivacky bool isDead = false, bool Overlap = false, 1271276479Sdim const TargetRegisterInfo *TRI = nullptr) const; 1272193323Sed 1273288943Sdim /// Wrapper for findRegisterDefOperandIdx, it returns 1274193323Sed /// a pointer to the MachineOperand rather than an index. 1275353358Sdim MachineOperand * 1276360784Sdim findRegisterDefOperand(Register Reg, bool isDead = false, 1277353358Sdim bool Overlap = false, 1278353358Sdim const TargetRegisterInfo *TRI = nullptr) { 1279353358Sdim int Idx = findRegisterDefOperandIdx(Reg, isDead, Overlap, TRI); 1280276479Sdim return (Idx == -1) ? nullptr : &getOperand(Idx); 1281193323Sed } 1282193323Sed 1283353358Sdim const MachineOperand * 1284360784Sdim findRegisterDefOperand(Register Reg, bool isDead = false, 1285353358Sdim bool Overlap = false, 1286353358Sdim const TargetRegisterInfo *TRI = nullptr) const { 1287353358Sdim return const_cast<MachineInstr *>(this)->findRegisterDefOperand( 1288353358Sdim Reg, isDead, Overlap, TRI); 1289353358Sdim } 1290353358Sdim 1291288943Sdim /// Find the index of the first operand in the 1292193323Sed /// operand list that is used to represent the predicate. It returns -1 if 1293193323Sed /// none is found. 1294193323Sed int findFirstPredOperandIdx() const; 1295221345Sdim 1296288943Sdim /// Find the index of the flag word operand that 1297226633Sdim /// corresponds to operand OpIdx on an inline asm instruction. Returns -1 if 1298226633Sdim /// getOperand(OpIdx) does not belong to an inline asm operand group. 1299226633Sdim /// 1300226633Sdim /// If GroupNo is not NULL, it will receive the number of the operand group 1301226633Sdim /// containing OpIdx. 1302226633Sdim /// 1303226633Sdim /// The flag operand is an immediate that can be decoded with methods like 1304226633Sdim /// InlineAsm::hasRegClassConstraint(). 1305276479Sdim int findInlineAsmFlagIdx(unsigned OpIdx, unsigned *GroupNo = nullptr) const; 1306226633Sdim 1307288943Sdim /// Compute the static register class constraint for operand OpIdx. 1308288943Sdim /// For normal instructions, this is derived from the MCInstrDesc. 1309288943Sdim /// For inline assembly it is derived from the flag words. 1310226633Sdim /// 1311288943Sdim /// Returns NULL if the static register class constraint cannot be 1312226633Sdim /// determined. 1313226633Sdim const TargetRegisterClass* 1314226633Sdim getRegClassConstraint(unsigned OpIdx, 1315226633Sdim const TargetInstrInfo *TII, 1316226633Sdim const TargetRegisterInfo *TRI) const; 1317226633Sdim 1318341825Sdim /// Applies the constraints (def/use) implied by this MI on \p Reg to 1319276479Sdim /// the given \p CurRC. 1320276479Sdim /// If \p ExploreBundle is set and MI is part of a bundle, all the 1321276479Sdim /// instructions inside the bundle will be taken into account. In other words, 1322288943Sdim /// this method accumulates all the constraints of the operand of this MI and 1323276479Sdim /// the related bundle if MI is a bundle or inside a bundle. 1324276479Sdim /// 1325288943Sdim /// Returns the register class that satisfies both \p CurRC and the 1326276479Sdim /// constraints set by MI. Returns NULL if such a register class does not 1327276479Sdim /// exist. 1328276479Sdim /// 1329276479Sdim /// \pre CurRC must not be NULL. 1330276479Sdim const TargetRegisterClass *getRegClassConstraintEffectForVReg( 1331360784Sdim Register Reg, const TargetRegisterClass *CurRC, 1332276479Sdim const TargetInstrInfo *TII, const TargetRegisterInfo *TRI, 1333276479Sdim bool ExploreBundle = false) const; 1334276479Sdim 1335341825Sdim /// Applies the constraints (def/use) implied by the \p OpIdx operand 1336276479Sdim /// to the given \p CurRC. 1337276479Sdim /// 1338288943Sdim /// Returns the register class that satisfies both \p CurRC and the 1339276479Sdim /// constraints set by \p OpIdx MI. Returns NULL if such a register class 1340276479Sdim /// does not exist. 1341276479Sdim /// 1342276479Sdim /// \pre CurRC must not be NULL. 1343276479Sdim /// \pre The operand at \p OpIdx must be a register. 1344276479Sdim const TargetRegisterClass * 1345276479Sdim getRegClassConstraintEffect(unsigned OpIdx, const TargetRegisterClass *CurRC, 1346276479Sdim const TargetInstrInfo *TII, 1347276479Sdim const TargetRegisterInfo *TRI) const; 1348276479Sdim 1349288943Sdim /// Add a tie between the register operands at DefIdx and UseIdx. 1350288943Sdim /// The tie will cause the register allocator to ensure that the two 1351243830Sdim /// operands are assigned the same physical register. 1352243830Sdim /// 1353243830Sdim /// Tied operands are managed automatically for explicit operands in the 1354243830Sdim /// MCInstrDesc. This method is for exceptional cases like inline asm. 1355243830Sdim void tieOperands(unsigned DefIdx, unsigned UseIdx); 1356243830Sdim 1357288943Sdim /// Given the index of a tied register operand, find the 1358243830Sdim /// operand it is tied to. Defs are tied to uses and vice versa. Returns the 1359243830Sdim /// index of the tied operand which must exist. 1360243830Sdim unsigned findTiedOperandIdx(unsigned OpIdx) const; 1361243830Sdim 1362288943Sdim /// Given the index of a register def operand, 1363193323Sed /// check if the register def is tied to a source operand, due to either 1364193323Sed /// two-address elimination or inline assembly constraints. Returns the 1365234353Sdim /// first tied use operand index by reference if UseOpIdx is not null. 1366276479Sdim bool isRegTiedToUseOperand(unsigned DefOpIdx, 1367276479Sdim unsigned *UseOpIdx = nullptr) const { 1368243830Sdim const MachineOperand &MO = getOperand(DefOpIdx); 1369243830Sdim if (!MO.isReg() || !MO.isDef() || !MO.isTied()) 1370243830Sdim return false; 1371243830Sdim if (UseOpIdx) 1372243830Sdim *UseOpIdx = findTiedOperandIdx(DefOpIdx); 1373243830Sdim return true; 1374243830Sdim } 1375193323Sed 1376288943Sdim /// Return true if the use operand of the specified index is tied to a def 1377288943Sdim /// operand. It also returns the def operand index by reference if DefOpIdx 1378288943Sdim /// is not null. 1379276479Sdim bool isRegTiedToDefOperand(unsigned UseOpIdx, 1380276479Sdim unsigned *DefOpIdx = nullptr) const { 1381243830Sdim const MachineOperand &MO = getOperand(UseOpIdx); 1382243830Sdim if (!MO.isReg() || !MO.isUse() || !MO.isTied()) 1383243830Sdim return false; 1384243830Sdim if (DefOpIdx) 1385243830Sdim *DefOpIdx = findTiedOperandIdx(UseOpIdx); 1386243830Sdim return true; 1387243830Sdim } 1388193323Sed 1389288943Sdim /// Clears kill flags on all operands. 1390208599Srdivacky void clearKillInfo(); 1391208599Srdivacky 1392288943Sdim /// Replace all occurrences of FromReg with ToReg:SubIdx, 1393210299Sed /// properly composing subreg indices where necessary. 1394360784Sdim void substituteRegister(Register FromReg, Register ToReg, unsigned SubIdx, 1395210299Sed const TargetRegisterInfo &RegInfo); 1396210299Sed 1397288943Sdim /// We have determined MI kills a register. Look for the 1398193323Sed /// operand that uses it and mark it as IsKill. If AddIfNotFound is true, 1399193323Sed /// add a implicit operand if it's not found. Returns true if the operand 1400193323Sed /// exists / is added. 1401360784Sdim bool addRegisterKilled(Register IncomingReg, 1402193323Sed const TargetRegisterInfo *RegInfo, 1403193323Sed bool AddIfNotFound = false); 1404202375Srdivacky 1405309124Sdim /// Clear all kill flags affecting Reg. If RegInfo is provided, this includes 1406309124Sdim /// all aliasing registers. 1407360784Sdim void clearRegisterKills(Register Reg, const TargetRegisterInfo *RegInfo); 1408234353Sdim 1409288943Sdim /// We have determined MI defined a register without a use. 1410193323Sed /// Look for the operand that defines it and mark it as IsDead. If 1411193323Sed /// AddIfNotFound is true, add a implicit operand if it's not found. Returns 1412193323Sed /// true if the operand exists / is added. 1413360784Sdim bool addRegisterDead(Register Reg, const TargetRegisterInfo *RegInfo, 1414193323Sed bool AddIfNotFound = false); 1415193323Sed 1416288943Sdim /// Clear all dead flags on operands defining register @p Reg. 1417360784Sdim void clearRegisterDeads(Register Reg); 1418288943Sdim 1419288943Sdim /// Mark all subregister defs of register @p Reg with the undef flag. 1420288943Sdim /// This function is used when we determined to have a subregister def in an 1421288943Sdim /// otherwise undefined super register. 1422360784Sdim void setRegisterDefReadUndef(Register Reg, bool IsUndef = true); 1423288943Sdim 1424288943Sdim /// We have determined MI defines a register. Make sure there is an operand 1425288943Sdim /// defining Reg. 1426360784Sdim void addRegisterDefined(Register Reg, 1427276479Sdim const TargetRegisterInfo *RegInfo = nullptr); 1428202375Srdivacky 1429288943Sdim /// Mark every physreg used by this instruction as 1430221345Sdim /// dead except those in the UsedRegs list. 1431234353Sdim /// 1432234353Sdim /// On instructions with register mask operands, also add implicit-def 1433234353Sdim /// operands for all registers in UsedRegs. 1434360784Sdim void setPhysRegsDeadExcept(ArrayRef<Register> UsedRegs, 1435210299Sed const TargetRegisterInfo &TRI); 1436210299Sed 1437288943Sdim /// Return true if it is safe to move this instruction. If 1438193323Sed /// SawStore is set to true, it means that there is a store (or call) between 1439193323Sed /// the instruction's location and its intended destination. 1440360784Sdim bool isSafeToMove(AAResults *AA, bool &SawStore) const; 1441193323Sed 1442321369Sdim /// Returns true if this instruction's memory access aliases the memory 1443321369Sdim /// access of Other. 1444321369Sdim // 1445321369Sdim /// Assumes any physical registers used to compute addresses 1446321369Sdim /// have the same value for both instructions. Returns false if neither 1447321369Sdim /// instruction writes to memory. 1448321369Sdim /// 1449321369Sdim /// @param AA Optional alias analysis, used to compare memory operands. 1450321369Sdim /// @param Other MachineInstr to check aliasing against. 1451321369Sdim /// @param UseTBAA Whether to pass TBAA information to alias analysis. 1452360784Sdim bool mayAlias(AAResults *AA, const MachineInstr &Other, bool UseTBAA) const; 1453321369Sdim 1454288943Sdim /// Return true if this instruction may have an ordered 1455243830Sdim /// or volatile memory reference, or if the information describing the memory 1456243830Sdim /// reference is not available. Return false if it is known to have no 1457243830Sdim /// ordered or volatile memory references. 1458243830Sdim bool hasOrderedMemoryRef() const; 1459193323Sed 1460314564Sdim /// Return true if this load instruction never traps and points to a memory 1461314564Sdim /// location whose value doesn't change during the execution of this function. 1462314564Sdim /// 1463314564Sdim /// Examples include loading a value from the constant pool or from the 1464314564Sdim /// argument area of a function (if it does not change). If the instruction 1465314564Sdim /// does multiple loads, this returns true only if all of the loads are 1466314564Sdim /// dereferenceable and invariant. 1467360784Sdim bool isDereferenceableInvariantLoad(AAResults *AA) const; 1468198090Srdivacky 1469288943Sdim /// If the specified instruction is a PHI that always merges together the 1470288943Sdim /// same virtual register, return the register, otherwise return 0. 1471200581Srdivacky unsigned isConstantValuePHI() const; 1472200581Srdivacky 1473288943Sdim /// Return true if this instruction has side effects that are not modeled 1474288943Sdim /// by mayLoad / mayStore, etc. 1475224145Sdim /// For all instructions, the property is encoded in MCInstrDesc::Flags 1476224145Sdim /// (see MCInstrDesc::hasUnmodeledSideEffects(). The only exception is 1477218893Sdim /// INLINEASM instruction, in which case the side effect property is encoded 1478218893Sdim /// in one of its operands (see InlineAsm::Extra_HasSideEffect). 1479218893Sdim /// 1480218893Sdim bool hasUnmodeledSideEffects() const; 1481218893Sdim 1482296417Sdim /// Returns true if it is illegal to fold a load across this instruction. 1483296417Sdim bool isLoadFoldBarrier() const; 1484296417Sdim 1485288943Sdim /// Return true if all the defs of this instruction are dead. 1486207618Srdivacky bool allDefsAreDead() const; 1487207618Srdivacky 1488353358Sdim /// Return a valid size if the instruction is a spill instruction. 1489353358Sdim Optional<unsigned> getSpillSize(const TargetInstrInfo *TII) const; 1490353358Sdim 1491353358Sdim /// Return a valid size if the instruction is a folded spill instruction. 1492353358Sdim Optional<unsigned> getFoldedSpillSize(const TargetInstrInfo *TII) const; 1493353358Sdim 1494353358Sdim /// Return a valid size if the instruction is a restore instruction. 1495353358Sdim Optional<unsigned> getRestoreSize(const TargetInstrInfo *TII) const; 1496353358Sdim 1497353358Sdim /// Return a valid size if the instruction is a folded restore instruction. 1498353358Sdim Optional<unsigned> 1499353358Sdim getFoldedRestoreSize(const TargetInstrInfo *TII) const; 1500353358Sdim 1501288943Sdim /// Copy implicit register operands from specified 1502218893Sdim /// instruction to this instruction. 1503309124Sdim void copyImplicitOps(MachineFunction &MF, const MachineInstr &MI); 1504218893Sdim 1505321369Sdim /// Debugging support 1506321369Sdim /// @{ 1507327952Sdim /// Determine the generic type to be printed (if needed) on uses and defs. 1508327952Sdim LLT getTypeToPrint(unsigned OpIdx, SmallBitVector &PrintedTypes, 1509327952Sdim const MachineRegisterInfo &MRI) const; 1510327952Sdim 1511327952Sdim /// Return true when an instruction has tied register that can't be determined 1512327952Sdim /// by the instruction's descriptor. This is useful for MIR printing, to 1513327952Sdim /// determine whether we need to print the ties or not. 1514327952Sdim bool hasComplexRegisterTies() const; 1515327952Sdim 1516321369Sdim /// Print this MI to \p OS. 1517341825Sdim /// Don't print information that can be inferred from other instructions if 1518341825Sdim /// \p IsStandalone is false. It is usually true when only a fragment of the 1519341825Sdim /// function is printed. 1520321369Sdim /// Only print the defs and the opcode if \p SkipOpers is true. 1521321369Sdim /// Otherwise, also print operands if \p SkipDebugLoc is true. 1522321369Sdim /// Otherwise, also print the debug loc, with a terminating newline. 1523321369Sdim /// \p TII is used to print the opcode name. If it's not present, but the 1524321369Sdim /// MI is in a function, the opcode will be printed using the function's TII. 1525341825Sdim void print(raw_ostream &OS, bool IsStandalone = true, bool SkipOpers = false, 1526341825Sdim bool SkipDebugLoc = false, bool AddNewLine = true, 1527314564Sdim const TargetInstrInfo *TII = nullptr) const; 1528341825Sdim void print(raw_ostream &OS, ModuleSlotTracker &MST, bool IsStandalone = true, 1529341825Sdim bool SkipOpers = false, bool SkipDebugLoc = false, 1530341825Sdim bool AddNewLine = true, 1531314564Sdim const TargetInstrInfo *TII = nullptr) const; 1532321369Sdim void dump() const; 1533321369Sdim /// @} 1534193323Sed 1535193323Sed //===--------------------------------------------------------------------===// 1536193323Sed // Accessors used to build up machine instructions. 1537193323Sed 1538249423Sdim /// Add the specified operand to the instruction. If it is an implicit 1539249423Sdim /// operand, it is added to the end of the operand list. If it is an 1540249423Sdim /// explicit operand it is added at the end of the explicit operand list 1541221345Sdim /// (before the first implicit operand). 1542249423Sdim /// 1543249423Sdim /// MF must be the machine function that was used to allocate this 1544249423Sdim /// instruction. 1545249423Sdim /// 1546249423Sdim /// MachineInstrBuilder provides a more convenient interface for creating 1547249423Sdim /// instructions and adding operands. 1548249423Sdim void addOperand(MachineFunction &MF, const MachineOperand &Op); 1549249423Sdim 1550249423Sdim /// Add an operand without providing an MF reference. This only works for 1551249423Sdim /// instructions that are inserted in a basic block. 1552249423Sdim /// 1553249423Sdim /// MachineInstrBuilder and the two-argument addOperand(MF, MO) should be 1554249423Sdim /// preferred. 1555193323Sed void addOperand(const MachineOperand &Op); 1556221345Sdim 1557288943Sdim /// Replace the instruction descriptor (thus opcode) of 1558193323Sed /// the current instruction with a new one. 1559224145Sdim void setDesc(const MCInstrDesc &tid) { MCID = &tid; } 1560193323Sed 1561288943Sdim /// Replace current source information with new such. 1562193323Sed /// Avoid using this, the constructor argument is preferable. 1563288943Sdim void setDebugLoc(DebugLoc dl) { 1564288943Sdim debugLoc = std::move(dl); 1565280031Sdim assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor"); 1566280031Sdim } 1567193323Sed 1568309124Sdim /// Erase an operand from an instruction, leaving it with one 1569193323Sed /// fewer operand than it started with. 1570341825Sdim void RemoveOperand(unsigned OpNo); 1571193323Sed 1572344779Sdim /// Clear this MachineInstr's memory reference descriptor list. This resets 1573344779Sdim /// the memrefs to their most conservative state. This should be used only 1574344779Sdim /// as a last resort since it greatly pessimizes our knowledge of the memory 1575344779Sdim /// access performed by the instruction. 1576344779Sdim void dropMemRefs(MachineFunction &MF); 1577344779Sdim 1578344779Sdim /// Assign this MachineInstr's memory reference descriptor list. 1579344779Sdim /// 1580344779Sdim /// Unlike other methods, this *will* allocate them into a new array 1581344779Sdim /// associated with the provided `MachineFunction`. 1582344779Sdim void setMemRefs(MachineFunction &MF, ArrayRef<MachineMemOperand *> MemRefs); 1583344779Sdim 1584288943Sdim /// Add a MachineMemOperand to the machine instruction. 1585198090Srdivacky /// This function should be used only occasionally. The setMemRefs function 1586198090Srdivacky /// is the primary method for setting up a MachineInstr's MemRefs list. 1587198090Srdivacky void addMemOperand(MachineFunction &MF, MachineMemOperand *MO); 1588193323Sed 1589344779Sdim /// Clone another MachineInstr's memory reference descriptor list and replace 1590344779Sdim /// ours with it. 1591344779Sdim /// 1592344779Sdim /// Note that `*this` may be the incoming MI! 1593344779Sdim /// 1594344779Sdim /// Prefer this API whenever possible as it can avoid allocations in common 1595344779Sdim /// cases. 1596344779Sdim void cloneMemRefs(MachineFunction &MF, const MachineInstr &MI); 1597193323Sed 1598344779Sdim /// Clone the merge of multiple MachineInstrs' memory reference descriptors 1599344779Sdim /// list and replace ours with it. 1600344779Sdim /// 1601344779Sdim /// Note that `*this` may be one of the incoming MIs! 1602344779Sdim /// 1603344779Sdim /// Prefer this API whenever possible as it can avoid allocations in common 1604344779Sdim /// cases. 1605344779Sdim void cloneMergedMemRefs(MachineFunction &MF, 1606344779Sdim ArrayRef<const MachineInstr *> MIs); 1607296417Sdim 1608344779Sdim /// Set a symbol that will be emitted just prior to the instruction itself. 1609344779Sdim /// 1610344779Sdim /// Setting this to a null pointer will remove any such symbol. 1611344779Sdim /// 1612344779Sdim /// FIXME: This is not fully implemented yet. 1613344779Sdim void setPreInstrSymbol(MachineFunction &MF, MCSymbol *Symbol); 1614296417Sdim 1615344779Sdim /// Set a symbol that will be emitted just after the instruction itself. 1616344779Sdim /// 1617344779Sdim /// Setting this to a null pointer will remove any such symbol. 1618344779Sdim /// 1619344779Sdim /// FIXME: This is not fully implemented yet. 1620344779Sdim void setPostInstrSymbol(MachineFunction &MF, MCSymbol *Symbol); 1621344779Sdim 1622353358Sdim /// Clone another MachineInstr's pre- and post- instruction symbols and 1623353358Sdim /// replace ours with it. 1624353358Sdim void cloneInstrSymbols(MachineFunction &MF, const MachineInstr &MI); 1625353358Sdim 1626360661Sdim /// Set a marker on instructions that denotes where we should create and emit 1627360661Sdim /// heap alloc site labels. This waits until after instruction selection and 1628360661Sdim /// optimizations to create the label, so it should still work if the 1629360661Sdim /// instruction is removed or duplicated. 1630360661Sdim void setHeapAllocMarker(MachineFunction &MF, MDNode *MD); 1631360661Sdim 1632341825Sdim /// Return the MIFlags which represent both MachineInstrs. This 1633341825Sdim /// should be used when merging two MachineInstrs into one. This routine does 1634341825Sdim /// not modify the MIFlags of this MachineInstr. 1635341825Sdim uint16_t mergeFlagsWith(const MachineInstr& Other) const; 1636341825Sdim 1637353358Sdim static uint16_t copyFlagsFromInstruction(const Instruction &I); 1638353358Sdim 1639344779Sdim /// Copy all flags to MachineInst MIFlags 1640344779Sdim void copyIRFlags(const Instruction &I); 1641193323Sed 1642288943Sdim /// Break any tie involving OpIdx. 1643243830Sdim void untieRegOperand(unsigned OpIdx) { 1644243830Sdim MachineOperand &MO = getOperand(OpIdx); 1645243830Sdim if (MO.isReg() && MO.isTied()) { 1646243830Sdim getOperand(findTiedOperandIdx(OpIdx)).TiedTo = 0; 1647243830Sdim MO.TiedTo = 0; 1648243830Sdim } 1649243830Sdim } 1650243830Sdim 1651296417Sdim /// Add all implicit def and use operands to this instruction. 1652296417Sdim void addImplicitDefUseOperands(MachineFunction &MF); 1653288943Sdim 1654360784Sdim /// Scan instructions immediately following MI and collect any matching 1655360784Sdim /// DBG_VALUEs. 1656344779Sdim void collectDebugValues(SmallVectorImpl<MachineInstr *> &DbgValues); 1657344779Sdim 1658360784Sdim /// Find all DBG_VALUEs that point to the register def in this instruction 1659360784Sdim /// and point them to \p Reg instead. 1660360784Sdim void changeDebugValuesDefReg(Register Reg); 1661344779Sdim 1662360784Sdim /// Returns the Intrinsic::ID for this instruction. 1663360784Sdim /// \pre Must have an intrinsic ID operand. 1664360784Sdim unsigned getIntrinsicID() const { 1665360784Sdim return getOperand(getNumExplicitDefs()).getIntrinsicID(); 1666360784Sdim } 1667360784Sdim 1668288943Sdimprivate: 1669288943Sdim /// If this instruction is embedded into a MachineFunction, return the 1670288943Sdim /// MachineRegisterInfo object for the current function, otherwise 1671288943Sdim /// return null. 1672288943Sdim MachineRegisterInfo *getRegInfo(); 1673288943Sdim 1674288943Sdim /// Unlink all of the register operands in this instruction from their 1675288943Sdim /// respective use lists. This requires that the operands already be on their 1676288943Sdim /// use lists. 1677239462Sdim void RemoveRegOperandsFromUseLists(MachineRegisterInfo&); 1678221345Sdim 1679288943Sdim /// Add all of the register operands in this instruction from their 1680288943Sdim /// respective use lists. This requires that the operands not be on their 1681288943Sdim /// use lists yet. 1682239462Sdim void AddRegOperandsToUseLists(MachineRegisterInfo&); 1683234353Sdim 1684288943Sdim /// Slow path for hasProperty when we're dealing with a bundle. 1685344779Sdim bool hasPropertyInBundle(uint64_t Mask, QueryType Type) const; 1686276479Sdim 1687341825Sdim /// Implements the logic of getRegClassConstraintEffectForVReg for the 1688276479Sdim /// this MI and the given operand index \p OpIdx. 1689276479Sdim /// If the related operand does not constrained Reg, this returns CurRC. 1690276479Sdim const TargetRegisterClass *getRegClassConstraintEffectForVRegImpl( 1691360784Sdim unsigned OpIdx, Register Reg, const TargetRegisterClass *CurRC, 1692276479Sdim const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const; 1693360661Sdim 1694360661Sdim /// Stores extra instruction information inline or allocates as ExtraInfo 1695360661Sdim /// based on the number of pointers. 1696360661Sdim void setExtraInfo(MachineFunction &MF, ArrayRef<MachineMemOperand *> MMOs, 1697360661Sdim MCSymbol *PreInstrSymbol, MCSymbol *PostInstrSymbol, 1698360661Sdim MDNode *HeapAllocMarker); 1699193323Sed}; 1700193323Sed 1701288943Sdim/// Special DenseMapInfo traits to compare MachineInstr* by *value* of the 1702288943Sdim/// instruction rather than by pointer value. 1703204792Srdivacky/// The hashing and equality testing functions ignore definitions so this is 1704204792Srdivacky/// useful for CSE, etc. 1705204792Srdivackystruct MachineInstrExpressionTrait : DenseMapInfo<MachineInstr*> { 1706204792Srdivacky static inline MachineInstr *getEmptyKey() { 1707276479Sdim return nullptr; 1708204792Srdivacky } 1709204792Srdivacky 1710204792Srdivacky static inline MachineInstr *getTombstoneKey() { 1711204792Srdivacky return reinterpret_cast<MachineInstr*>(-1); 1712204792Srdivacky } 1713204792Srdivacky 1714204792Srdivacky static unsigned getHashValue(const MachineInstr* const &MI); 1715204792Srdivacky 1716204792Srdivacky static bool isEqual(const MachineInstr* const &LHS, 1717204792Srdivacky const MachineInstr* const &RHS) { 1718204792Srdivacky if (RHS == getEmptyKey() || RHS == getTombstoneKey() || 1719204792Srdivacky LHS == getEmptyKey() || LHS == getTombstoneKey()) 1720204792Srdivacky return LHS == RHS; 1721309124Sdim return LHS->isIdenticalTo(*RHS, MachineInstr::IgnoreVRegDefs); 1722204792Srdivacky } 1723204792Srdivacky}; 1724204792Srdivacky 1725193323Sed//===----------------------------------------------------------------------===// 1726193323Sed// Debugging Support 1727193323Sed 1728193323Sedinline raw_ostream& operator<<(raw_ostream &OS, const MachineInstr &MI) { 1729193323Sed MI.print(OS); 1730193323Sed return OS; 1731193323Sed} 1732193323Sed 1733321369Sdim} // end namespace llvm 1734193323Sed 1735321369Sdim#endif // LLVM_CODEGEN_MACHINEINSTR_H 1736