1 //===- llvm/CodeGen/GlobalISel/GenericMachineInstrs.h -----------*- C++ -*-===// 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// Declares convenience wrapper classes for interpreting MachineInstr instances 10 /// as specific generic operations. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CODEGEN_GLOBALISEL_GENERICMACHINEINSTRS_H 15 #define LLVM_CODEGEN_GLOBALISEL_GENERICMACHINEINSTRS_H 16 17 #include "llvm/CodeGen/MachineInstr.h" 18 #include "llvm/CodeGen/MachineMemOperand.h" 19 #include "llvm/CodeGen/TargetOpcodes.h" 20 #include "llvm/Support/Casting.h" 21 22 namespace llvm { 23 24 /// A base class for all GenericMachineInstrs. 25 class GenericMachineInstr : public MachineInstr { 26 public: 27 GenericMachineInstr() = delete; 28 29 /// Access the Idx'th operand as a register and return it. 30 /// This assumes that the Idx'th operand is a Register type. getReg(unsigned Idx)31 Register getReg(unsigned Idx) const { return getOperand(Idx).getReg(); } 32 classof(const MachineInstr * MI)33 static bool classof(const MachineInstr *MI) { 34 return isPreISelGenericOpcode(MI->getOpcode()); 35 } 36 }; 37 38 /// Represents any type of generic load or store. 39 /// G_LOAD, G_STORE, G_ZEXTLOAD, G_SEXTLOAD. 40 class GLoadStore : public GenericMachineInstr { 41 public: 42 /// Get the source register of the pointer value. getPointerReg()43 Register getPointerReg() const { return getOperand(1).getReg(); } 44 45 /// Get the MachineMemOperand on this instruction. getMMO()46 MachineMemOperand &getMMO() const { return **memoperands_begin(); } 47 48 /// Returns true if the attached MachineMemOperand has the atomic flag set. isAtomic()49 bool isAtomic() const { return getMMO().isAtomic(); } 50 /// Returns true if the attached MachineMemOpeand as the volatile flag set. isVolatile()51 bool isVolatile() const { return getMMO().isVolatile(); } 52 /// Returns true if the memory operation is neither atomic or volatile. isSimple()53 bool isSimple() const { return !isAtomic() && !isVolatile(); } 54 /// Returns true if this memory operation doesn't have any ordering 55 /// constraints other than normal aliasing. Volatile and (ordered) atomic 56 /// memory operations can't be reordered. isUnordered()57 bool isUnordered() const { return getMMO().isUnordered(); } 58 59 /// Returns the size in bytes of the memory access. getMemSize()60 uint64_t getMemSize() { return getMMO().getSize(); 61 } /// Returns the size in bits of the memory access. getMemSizeInBits()62 uint64_t getMemSizeInBits() { return getMMO().getSizeInBits(); } 63 classof(const MachineInstr * MI)64 static bool classof(const MachineInstr *MI) { 65 switch (MI->getOpcode()) { 66 case TargetOpcode::G_LOAD: 67 case TargetOpcode::G_STORE: 68 case TargetOpcode::G_ZEXTLOAD: 69 case TargetOpcode::G_SEXTLOAD: 70 return true; 71 default: 72 return false; 73 } 74 } 75 }; 76 77 /// Represents any generic load, including sign/zero extending variants. 78 class GAnyLoad : public GLoadStore { 79 public: 80 /// Get the definition register of the loaded value. getDstReg()81 Register getDstReg() const { return getOperand(0).getReg(); } 82 classof(const MachineInstr * MI)83 static bool classof(const MachineInstr *MI) { 84 switch (MI->getOpcode()) { 85 case TargetOpcode::G_LOAD: 86 case TargetOpcode::G_ZEXTLOAD: 87 case TargetOpcode::G_SEXTLOAD: 88 return true; 89 default: 90 return false; 91 } 92 } 93 }; 94 95 /// Represents a G_LOAD. 96 class GLoad : public GAnyLoad { 97 public: classof(const MachineInstr * MI)98 static bool classof(const MachineInstr *MI) { 99 return MI->getOpcode() == TargetOpcode::G_LOAD; 100 } 101 }; 102 103 /// Represents either a G_SEXTLOAD or G_ZEXTLOAD. 104 class GExtLoad : public GAnyLoad { 105 public: classof(const MachineInstr * MI)106 static bool classof(const MachineInstr *MI) { 107 return MI->getOpcode() == TargetOpcode::G_SEXTLOAD || 108 MI->getOpcode() == TargetOpcode::G_ZEXTLOAD; 109 } 110 }; 111 112 /// Represents a G_SEXTLOAD. 113 class GSExtLoad : public GExtLoad { 114 public: classof(const MachineInstr * MI)115 static bool classof(const MachineInstr *MI) { 116 return MI->getOpcode() == TargetOpcode::G_SEXTLOAD; 117 } 118 }; 119 120 /// Represents a G_ZEXTLOAD. 121 class GZExtLoad : public GExtLoad { 122 public: classof(const MachineInstr * MI)123 static bool classof(const MachineInstr *MI) { 124 return MI->getOpcode() == TargetOpcode::G_ZEXTLOAD; 125 } 126 }; 127 128 /// Represents a G_STORE. 129 class GStore : public GLoadStore { 130 public: 131 /// Get the stored value register. getValueReg()132 Register getValueReg() const { return getOperand(0).getReg(); } 133 classof(const MachineInstr * MI)134 static bool classof(const MachineInstr *MI) { 135 return MI->getOpcode() == TargetOpcode::G_STORE; 136 } 137 }; 138 139 /// Represents a G_UNMERGE_VALUES. 140 class GUnmerge : public GenericMachineInstr { 141 public: 142 /// Returns the number of def registers. getNumDefs()143 unsigned getNumDefs() const { return getNumOperands() - 1; } 144 /// Get the unmerge source register. getSourceReg()145 Register getSourceReg() const { return getOperand(getNumDefs()).getReg(); } 146 classof(const MachineInstr * MI)147 static bool classof(const MachineInstr *MI) { 148 return MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES; 149 } 150 }; 151 152 /// Represents G_BUILD_VECTOR, G_CONCAT_VECTORS or G_MERGE_VALUES. 153 /// All these have the common property of generating a single value from 154 /// multiple sources. 155 class GMergeLikeOp : public GenericMachineInstr { 156 public: 157 /// Returns the number of source registers. getNumSources()158 unsigned getNumSources() const { return getNumOperands() - 1; } 159 /// Returns the I'th source register. getSourceReg(unsigned I)160 Register getSourceReg(unsigned I) const { return getReg(I + 1); } 161 classof(const MachineInstr * MI)162 static bool classof(const MachineInstr *MI) { 163 switch (MI->getOpcode()) { 164 case TargetOpcode::G_MERGE_VALUES: 165 case TargetOpcode::G_CONCAT_VECTORS: 166 case TargetOpcode::G_BUILD_VECTOR: 167 return true; 168 default: 169 return false; 170 } 171 } 172 }; 173 174 /// Represents a G_MERGE_VALUES. 175 class GMerge : public GMergeLikeOp { 176 public: classof(const MachineInstr * MI)177 static bool classof(const MachineInstr *MI) { 178 return MI->getOpcode() == TargetOpcode::G_MERGE_VALUES; 179 } 180 }; 181 182 /// Represents a G_CONCAT_VECTORS. 183 class GConcatVectors : public GMergeLikeOp { 184 public: classof(const MachineInstr * MI)185 static bool classof(const MachineInstr *MI) { 186 return MI->getOpcode() == TargetOpcode::G_CONCAT_VECTORS; 187 } 188 }; 189 190 /// Represents a G_BUILD_VECTOR. 191 class GBuildVector : public GMergeLikeOp { 192 public: classof(const MachineInstr * MI)193 static bool classof(const MachineInstr *MI) { 194 return MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR; 195 } 196 }; 197 198 } // namespace llvm 199 200 #endif // LLVM_CODEGEN_GLOBALISEL_GENERICMACHINEINSTRS_H