1 //===-- llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.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 // This file contains some helper functions which try to cleanup artifacts 9 // such as G_TRUNCs/G_[ZSA]EXTENDS that were created during legalization to make 10 // the types match. This file also contains some combines of merges that happens 11 // at the end of the legalization. 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CODEGEN_GLOBALISEL_LEGALIZATIONARTIFACTCOMBINER_H 15 #define LLVM_CODEGEN_GLOBALISEL_LEGALIZATIONARTIFACTCOMBINER_H 16 17 #include "llvm/CodeGen/GlobalISel/Legalizer.h" 18 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" 19 #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" 20 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 21 #include "llvm/CodeGen/GlobalISel/Utils.h" 22 #include "llvm/CodeGen/MachineRegisterInfo.h" 23 #include "llvm/Support/Debug.h" 24 25 #define DEBUG_TYPE "legalizer" 26 using namespace llvm::MIPatternMatch; 27 28 namespace llvm { 29 class LegalizationArtifactCombiner { 30 MachineIRBuilder &Builder; 31 MachineRegisterInfo &MRI; 32 const LegalizerInfo &LI; 33 isArtifactCast(unsigned Opc)34 static bool isArtifactCast(unsigned Opc) { 35 switch (Opc) { 36 case TargetOpcode::G_TRUNC: 37 case TargetOpcode::G_SEXT: 38 case TargetOpcode::G_ZEXT: 39 case TargetOpcode::G_ANYEXT: 40 return true; 41 default: 42 return false; 43 } 44 } 45 46 public: LegalizationArtifactCombiner(MachineIRBuilder & B,MachineRegisterInfo & MRI,const LegalizerInfo & LI)47 LegalizationArtifactCombiner(MachineIRBuilder &B, MachineRegisterInfo &MRI, 48 const LegalizerInfo &LI) 49 : Builder(B), MRI(MRI), LI(LI) {} 50 tryCombineAnyExt(MachineInstr & MI,SmallVectorImpl<MachineInstr * > & DeadInsts,SmallVectorImpl<Register> & UpdatedDefs)51 bool tryCombineAnyExt(MachineInstr &MI, 52 SmallVectorImpl<MachineInstr *> &DeadInsts, 53 SmallVectorImpl<Register> &UpdatedDefs) { 54 assert(MI.getOpcode() == TargetOpcode::G_ANYEXT); 55 56 Builder.setInstrAndDebugLoc(MI); 57 Register DstReg = MI.getOperand(0).getReg(); 58 Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg()); 59 60 // aext(trunc x) - > aext/copy/trunc x 61 Register TruncSrc; 62 if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc)))) { 63 LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI;); 64 Builder.buildAnyExtOrTrunc(DstReg, TruncSrc); 65 UpdatedDefs.push_back(DstReg); 66 markInstAndDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts); 67 return true; 68 } 69 70 // aext([asz]ext x) -> [asz]ext x 71 Register ExtSrc; 72 MachineInstr *ExtMI; 73 if (mi_match(SrcReg, MRI, 74 m_all_of(m_MInstr(ExtMI), m_any_of(m_GAnyExt(m_Reg(ExtSrc)), 75 m_GSExt(m_Reg(ExtSrc)), 76 m_GZExt(m_Reg(ExtSrc)))))) { 77 Builder.buildInstr(ExtMI->getOpcode(), {DstReg}, {ExtSrc}); 78 UpdatedDefs.push_back(DstReg); 79 markInstAndDefDead(MI, *ExtMI, DeadInsts); 80 return true; 81 } 82 83 // Try to fold aext(g_constant) when the larger constant type is legal. 84 auto *SrcMI = MRI.getVRegDef(SrcReg); 85 if (SrcMI->getOpcode() == TargetOpcode::G_CONSTANT) { 86 const LLT DstTy = MRI.getType(DstReg); 87 if (isInstLegal({TargetOpcode::G_CONSTANT, {DstTy}})) { 88 auto &CstVal = SrcMI->getOperand(1); 89 Builder.buildConstant( 90 DstReg, CstVal.getCImm()->getValue().sext(DstTy.getSizeInBits())); 91 UpdatedDefs.push_back(DstReg); 92 markInstAndDefDead(MI, *SrcMI, DeadInsts); 93 return true; 94 } 95 } 96 return tryFoldImplicitDef(MI, DeadInsts, UpdatedDefs); 97 } 98 tryCombineZExt(MachineInstr & MI,SmallVectorImpl<MachineInstr * > & DeadInsts,SmallVectorImpl<Register> & UpdatedDefs,GISelObserverWrapper & Observer)99 bool tryCombineZExt(MachineInstr &MI, 100 SmallVectorImpl<MachineInstr *> &DeadInsts, 101 SmallVectorImpl<Register> &UpdatedDefs, 102 GISelObserverWrapper &Observer) { 103 assert(MI.getOpcode() == TargetOpcode::G_ZEXT); 104 105 Builder.setInstrAndDebugLoc(MI); 106 Register DstReg = MI.getOperand(0).getReg(); 107 Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg()); 108 109 // zext(trunc x) - > and (aext/copy/trunc x), mask 110 // zext(sext x) -> and (sext x), mask 111 Register TruncSrc; 112 Register SextSrc; 113 if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc))) || 114 mi_match(SrcReg, MRI, m_GSExt(m_Reg(SextSrc)))) { 115 LLT DstTy = MRI.getType(DstReg); 116 if (isInstUnsupported({TargetOpcode::G_AND, {DstTy}}) || 117 isConstantUnsupported(DstTy)) 118 return false; 119 LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI;); 120 LLT SrcTy = MRI.getType(SrcReg); 121 APInt MaskVal = APInt::getAllOnesValue(SrcTy.getScalarSizeInBits()); 122 auto Mask = Builder.buildConstant( 123 DstTy, MaskVal.zext(DstTy.getScalarSizeInBits())); 124 auto Extended = SextSrc ? Builder.buildSExtOrTrunc(DstTy, SextSrc) : 125 Builder.buildAnyExtOrTrunc(DstTy, TruncSrc); 126 Builder.buildAnd(DstReg, Extended, Mask); 127 markInstAndDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts); 128 return true; 129 } 130 131 // zext(zext x) -> (zext x) 132 Register ZextSrc; 133 if (mi_match(SrcReg, MRI, m_GZExt(m_Reg(ZextSrc)))) { 134 LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI); 135 Observer.changingInstr(MI); 136 MI.getOperand(1).setReg(ZextSrc); 137 Observer.changedInstr(MI); 138 UpdatedDefs.push_back(DstReg); 139 markDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts); 140 return true; 141 } 142 143 // Try to fold zext(g_constant) when the larger constant type is legal. 144 auto *SrcMI = MRI.getVRegDef(SrcReg); 145 if (SrcMI->getOpcode() == TargetOpcode::G_CONSTANT) { 146 const LLT DstTy = MRI.getType(DstReg); 147 if (isInstLegal({TargetOpcode::G_CONSTANT, {DstTy}})) { 148 auto &CstVal = SrcMI->getOperand(1); 149 Builder.buildConstant( 150 DstReg, CstVal.getCImm()->getValue().zext(DstTy.getSizeInBits())); 151 UpdatedDefs.push_back(DstReg); 152 markInstAndDefDead(MI, *SrcMI, DeadInsts); 153 return true; 154 } 155 } 156 return tryFoldImplicitDef(MI, DeadInsts, UpdatedDefs); 157 } 158 tryCombineSExt(MachineInstr & MI,SmallVectorImpl<MachineInstr * > & DeadInsts,SmallVectorImpl<Register> & UpdatedDefs)159 bool tryCombineSExt(MachineInstr &MI, 160 SmallVectorImpl<MachineInstr *> &DeadInsts, 161 SmallVectorImpl<Register> &UpdatedDefs) { 162 assert(MI.getOpcode() == TargetOpcode::G_SEXT); 163 164 Builder.setInstrAndDebugLoc(MI); 165 Register DstReg = MI.getOperand(0).getReg(); 166 Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg()); 167 168 // sext(trunc x) - > (sext_inreg (aext/copy/trunc x), c) 169 Register TruncSrc; 170 if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc)))) { 171 LLT DstTy = MRI.getType(DstReg); 172 if (isInstUnsupported({TargetOpcode::G_SEXT_INREG, {DstTy}})) 173 return false; 174 LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI;); 175 LLT SrcTy = MRI.getType(SrcReg); 176 uint64_t SizeInBits = SrcTy.getScalarSizeInBits(); 177 Builder.buildInstr( 178 TargetOpcode::G_SEXT_INREG, {DstReg}, 179 {Builder.buildAnyExtOrTrunc(DstTy, TruncSrc), SizeInBits}); 180 markInstAndDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts); 181 return true; 182 } 183 184 // sext(zext x) -> (zext x) 185 // sext(sext x) -> (sext x) 186 Register ExtSrc; 187 MachineInstr *ExtMI; 188 if (mi_match(SrcReg, MRI, 189 m_all_of(m_MInstr(ExtMI), m_any_of(m_GZExt(m_Reg(ExtSrc)), 190 m_GSExt(m_Reg(ExtSrc)))))) { 191 LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI); 192 Builder.buildInstr(ExtMI->getOpcode(), {DstReg}, {ExtSrc}); 193 UpdatedDefs.push_back(DstReg); 194 markInstAndDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts); 195 return true; 196 } 197 198 // Try to fold sext(g_constant) when the larger constant type is legal. 199 auto *SrcMI = MRI.getVRegDef(SrcReg); 200 if (SrcMI->getOpcode() == TargetOpcode::G_CONSTANT) { 201 const LLT DstTy = MRI.getType(DstReg); 202 if (isInstLegal({TargetOpcode::G_CONSTANT, {DstTy}})) { 203 auto &CstVal = SrcMI->getOperand(1); 204 Builder.buildConstant( 205 DstReg, CstVal.getCImm()->getValue().sext(DstTy.getSizeInBits())); 206 UpdatedDefs.push_back(DstReg); 207 markInstAndDefDead(MI, *SrcMI, DeadInsts); 208 return true; 209 } 210 } 211 212 return tryFoldImplicitDef(MI, DeadInsts, UpdatedDefs); 213 } 214 tryCombineTrunc(MachineInstr & MI,SmallVectorImpl<MachineInstr * > & DeadInsts,SmallVectorImpl<Register> & UpdatedDefs,GISelObserverWrapper & Observer)215 bool tryCombineTrunc(MachineInstr &MI, 216 SmallVectorImpl<MachineInstr *> &DeadInsts, 217 SmallVectorImpl<Register> &UpdatedDefs, 218 GISelObserverWrapper &Observer) { 219 assert(MI.getOpcode() == TargetOpcode::G_TRUNC); 220 221 Builder.setInstr(MI); 222 Register DstReg = MI.getOperand(0).getReg(); 223 Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg()); 224 225 // Try to fold trunc(g_constant) when the smaller constant type is legal. 226 auto *SrcMI = MRI.getVRegDef(SrcReg); 227 if (SrcMI->getOpcode() == TargetOpcode::G_CONSTANT) { 228 const LLT DstTy = MRI.getType(DstReg); 229 if (isInstLegal({TargetOpcode::G_CONSTANT, {DstTy}})) { 230 auto &CstVal = SrcMI->getOperand(1); 231 Builder.buildConstant( 232 DstReg, CstVal.getCImm()->getValue().trunc(DstTy.getSizeInBits())); 233 UpdatedDefs.push_back(DstReg); 234 markInstAndDefDead(MI, *SrcMI, DeadInsts); 235 return true; 236 } 237 } 238 239 // Try to fold trunc(merge) to directly use the source of the merge. 240 // This gets rid of large, difficult to legalize, merges 241 if (SrcMI->getOpcode() == TargetOpcode::G_MERGE_VALUES) { 242 const Register MergeSrcReg = SrcMI->getOperand(1).getReg(); 243 const LLT MergeSrcTy = MRI.getType(MergeSrcReg); 244 const LLT DstTy = MRI.getType(DstReg); 245 246 // We can only fold if the types are scalar 247 const unsigned DstSize = DstTy.getSizeInBits(); 248 const unsigned MergeSrcSize = MergeSrcTy.getSizeInBits(); 249 if (!DstTy.isScalar() || !MergeSrcTy.isScalar()) 250 return false; 251 252 if (DstSize < MergeSrcSize) { 253 // When the merge source is larger than the destination, we can just 254 // truncate the merge source directly 255 if (isInstUnsupported({TargetOpcode::G_TRUNC, {DstTy, MergeSrcTy}})) 256 return false; 257 258 LLVM_DEBUG(dbgs() << "Combining G_TRUNC(G_MERGE_VALUES) to G_TRUNC: " 259 << MI); 260 261 Builder.buildTrunc(DstReg, MergeSrcReg); 262 UpdatedDefs.push_back(DstReg); 263 } else if (DstSize == MergeSrcSize) { 264 // If the sizes match we can simply try to replace the register 265 LLVM_DEBUG( 266 dbgs() << "Replacing G_TRUNC(G_MERGE_VALUES) with merge input: " 267 << MI); 268 replaceRegOrBuildCopy(DstReg, MergeSrcReg, MRI, Builder, UpdatedDefs, 269 Observer); 270 } else if (DstSize % MergeSrcSize == 0) { 271 // If the trunc size is a multiple of the merge source size we can use 272 // a smaller merge instead 273 if (isInstUnsupported( 274 {TargetOpcode::G_MERGE_VALUES, {DstTy, MergeSrcTy}})) 275 return false; 276 277 LLVM_DEBUG( 278 dbgs() << "Combining G_TRUNC(G_MERGE_VALUES) to G_MERGE_VALUES: " 279 << MI); 280 281 const unsigned NumSrcs = DstSize / MergeSrcSize; 282 assert(NumSrcs < SrcMI->getNumOperands() - 1 && 283 "trunc(merge) should require less inputs than merge"); 284 SmallVector<Register, 8> SrcRegs(NumSrcs); 285 for (unsigned i = 0; i < NumSrcs; ++i) 286 SrcRegs[i] = SrcMI->getOperand(i + 1).getReg(); 287 288 Builder.buildMerge(DstReg, SrcRegs); 289 UpdatedDefs.push_back(DstReg); 290 } else { 291 // Unable to combine 292 return false; 293 } 294 295 markInstAndDefDead(MI, *SrcMI, DeadInsts); 296 return true; 297 } 298 299 // trunc(trunc) -> trunc 300 Register TruncSrc; 301 if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc)))) { 302 // Always combine trunc(trunc) since the eventual resulting trunc must be 303 // legal anyway as it must be legal for all outputs of the consumer type 304 // set. 305 LLVM_DEBUG(dbgs() << ".. Combine G_TRUNC(G_TRUNC): " << MI); 306 307 Builder.buildTrunc(DstReg, TruncSrc); 308 UpdatedDefs.push_back(DstReg); 309 markInstAndDefDead(MI, *MRI.getVRegDef(TruncSrc), DeadInsts); 310 return true; 311 } 312 313 return false; 314 } 315 316 /// Try to fold G_[ASZ]EXT (G_IMPLICIT_DEF). tryFoldImplicitDef(MachineInstr & MI,SmallVectorImpl<MachineInstr * > & DeadInsts,SmallVectorImpl<Register> & UpdatedDefs)317 bool tryFoldImplicitDef(MachineInstr &MI, 318 SmallVectorImpl<MachineInstr *> &DeadInsts, 319 SmallVectorImpl<Register> &UpdatedDefs) { 320 unsigned Opcode = MI.getOpcode(); 321 assert(Opcode == TargetOpcode::G_ANYEXT || Opcode == TargetOpcode::G_ZEXT || 322 Opcode == TargetOpcode::G_SEXT); 323 324 if (MachineInstr *DefMI = getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, 325 MI.getOperand(1).getReg(), MRI)) { 326 Builder.setInstr(MI); 327 Register DstReg = MI.getOperand(0).getReg(); 328 LLT DstTy = MRI.getType(DstReg); 329 330 if (Opcode == TargetOpcode::G_ANYEXT) { 331 // G_ANYEXT (G_IMPLICIT_DEF) -> G_IMPLICIT_DEF 332 if (!isInstLegal({TargetOpcode::G_IMPLICIT_DEF, {DstTy}})) 333 return false; 334 LLVM_DEBUG(dbgs() << ".. Combine G_ANYEXT(G_IMPLICIT_DEF): " << MI;); 335 Builder.buildInstr(TargetOpcode::G_IMPLICIT_DEF, {DstReg}, {}); 336 UpdatedDefs.push_back(DstReg); 337 } else { 338 // G_[SZ]EXT (G_IMPLICIT_DEF) -> G_CONSTANT 0 because the top 339 // bits will be 0 for G_ZEXT and 0/1 for the G_SEXT. 340 if (isConstantUnsupported(DstTy)) 341 return false; 342 LLVM_DEBUG(dbgs() << ".. Combine G_[SZ]EXT(G_IMPLICIT_DEF): " << MI;); 343 Builder.buildConstant(DstReg, 0); 344 UpdatedDefs.push_back(DstReg); 345 } 346 347 markInstAndDefDead(MI, *DefMI, DeadInsts); 348 return true; 349 } 350 return false; 351 } 352 tryFoldUnmergeCast(MachineInstr & MI,MachineInstr & CastMI,SmallVectorImpl<MachineInstr * > & DeadInsts,SmallVectorImpl<Register> & UpdatedDefs)353 bool tryFoldUnmergeCast(MachineInstr &MI, MachineInstr &CastMI, 354 SmallVectorImpl<MachineInstr *> &DeadInsts, 355 SmallVectorImpl<Register> &UpdatedDefs) { 356 357 assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES); 358 359 const unsigned CastOpc = CastMI.getOpcode(); 360 361 if (!isArtifactCast(CastOpc)) 362 return false; 363 364 const unsigned NumDefs = MI.getNumOperands() - 1; 365 366 const Register CastSrcReg = CastMI.getOperand(1).getReg(); 367 const LLT CastSrcTy = MRI.getType(CastSrcReg); 368 const LLT DestTy = MRI.getType(MI.getOperand(0).getReg()); 369 const LLT SrcTy = MRI.getType(MI.getOperand(NumDefs).getReg()); 370 371 const unsigned CastSrcSize = CastSrcTy.getSizeInBits(); 372 const unsigned DestSize = DestTy.getSizeInBits(); 373 374 if (CastOpc == TargetOpcode::G_TRUNC) { 375 if (SrcTy.isVector() && SrcTy.getScalarType() == DestTy.getScalarType()) { 376 // %1:_(<4 x s8>) = G_TRUNC %0(<4 x s32>) 377 // %2:_(s8), %3:_(s8), %4:_(s8), %5:_(s8) = G_UNMERGE_VALUES %1 378 // => 379 // %6:_(s32), %7:_(s32), %8:_(s32), %9:_(s32) = G_UNMERGE_VALUES %0 380 // %2:_(s8) = G_TRUNC %6 381 // %3:_(s8) = G_TRUNC %7 382 // %4:_(s8) = G_TRUNC %8 383 // %5:_(s8) = G_TRUNC %9 384 385 unsigned UnmergeNumElts = 386 DestTy.isVector() ? CastSrcTy.getNumElements() / NumDefs : 1; 387 LLT UnmergeTy = CastSrcTy.changeNumElements(UnmergeNumElts); 388 389 if (isInstUnsupported( 390 {TargetOpcode::G_UNMERGE_VALUES, {UnmergeTy, CastSrcTy}})) 391 return false; 392 393 Builder.setInstr(MI); 394 auto NewUnmerge = Builder.buildUnmerge(UnmergeTy, CastSrcReg); 395 396 for (unsigned I = 0; I != NumDefs; ++I) { 397 Register DefReg = MI.getOperand(I).getReg(); 398 UpdatedDefs.push_back(DefReg); 399 Builder.buildTrunc(DefReg, NewUnmerge.getReg(I)); 400 } 401 402 markInstAndDefDead(MI, CastMI, DeadInsts); 403 return true; 404 } 405 406 if (CastSrcTy.isScalar() && SrcTy.isScalar() && !DestTy.isVector()) { 407 // %1:_(s16) = G_TRUNC %0(s32) 408 // %2:_(s8), %3:_(s8) = G_UNMERGE_VALUES %1 409 // => 410 // %2:_(s8), %3:_(s8), %4:_(s8), %5:_(s8) = G_UNMERGE_VALUES %0 411 412 // Unmerge(trunc) can be combined if the trunc source size is a multiple 413 // of the unmerge destination size 414 if (CastSrcSize % DestSize != 0) 415 return false; 416 417 // Check if the new unmerge is supported 418 if (isInstUnsupported( 419 {TargetOpcode::G_UNMERGE_VALUES, {DestTy, CastSrcTy}})) 420 return false; 421 422 // Gather the original destination registers and create new ones for the 423 // unused bits 424 const unsigned NewNumDefs = CastSrcSize / DestSize; 425 SmallVector<Register, 8> DstRegs(NewNumDefs); 426 for (unsigned Idx = 0; Idx < NewNumDefs; ++Idx) { 427 if (Idx < NumDefs) 428 DstRegs[Idx] = MI.getOperand(Idx).getReg(); 429 else 430 DstRegs[Idx] = MRI.createGenericVirtualRegister(DestTy); 431 } 432 433 // Build new unmerge 434 Builder.setInstr(MI); 435 Builder.buildUnmerge(DstRegs, CastSrcReg); 436 UpdatedDefs.append(DstRegs.begin(), DstRegs.begin() + NewNumDefs); 437 markInstAndDefDead(MI, CastMI, DeadInsts); 438 return true; 439 } 440 } 441 442 // TODO: support combines with other casts as well 443 return false; 444 } 445 canFoldMergeOpcode(unsigned MergeOp,unsigned ConvertOp,LLT OpTy,LLT DestTy)446 static bool canFoldMergeOpcode(unsigned MergeOp, unsigned ConvertOp, 447 LLT OpTy, LLT DestTy) { 448 // Check if we found a definition that is like G_MERGE_VALUES. 449 switch (MergeOp) { 450 default: 451 return false; 452 case TargetOpcode::G_BUILD_VECTOR: 453 case TargetOpcode::G_MERGE_VALUES: 454 // The convert operation that we will need to insert is 455 // going to convert the input of that type of instruction (scalar) 456 // to the destination type (DestTy). 457 // The conversion needs to stay in the same domain (scalar to scalar 458 // and vector to vector), so if we were to allow to fold the merge 459 // we would need to insert some bitcasts. 460 // E.g., 461 // <2 x s16> = build_vector s16, s16 462 // <2 x s32> = zext <2 x s16> 463 // <2 x s16>, <2 x s16> = unmerge <2 x s32> 464 // 465 // As is the folding would produce: 466 // <2 x s16> = zext s16 <-- scalar to vector 467 // <2 x s16> = zext s16 <-- scalar to vector 468 // Which is invalid. 469 // Instead we would want to generate: 470 // s32 = zext s16 471 // <2 x s16> = bitcast s32 472 // s32 = zext s16 473 // <2 x s16> = bitcast s32 474 // 475 // That is not done yet. 476 if (ConvertOp == 0) 477 return true; 478 return !DestTy.isVector() && OpTy.isVector(); 479 case TargetOpcode::G_CONCAT_VECTORS: { 480 if (ConvertOp == 0) 481 return true; 482 if (!DestTy.isVector()) 483 return false; 484 485 const unsigned OpEltSize = OpTy.getElementType().getSizeInBits(); 486 487 // Don't handle scalarization with a cast that isn't in the same 488 // direction as the vector cast. This could be handled, but it would 489 // require more intermediate unmerges. 490 if (ConvertOp == TargetOpcode::G_TRUNC) 491 return DestTy.getSizeInBits() <= OpEltSize; 492 return DestTy.getSizeInBits() >= OpEltSize; 493 } 494 } 495 } 496 497 /// Try to replace DstReg with SrcReg or build a COPY instruction 498 /// depending on the register constraints. replaceRegOrBuildCopy(Register DstReg,Register SrcReg,MachineRegisterInfo & MRI,MachineIRBuilder & Builder,SmallVectorImpl<Register> & UpdatedDefs,GISelChangeObserver & Observer)499 static void replaceRegOrBuildCopy(Register DstReg, Register SrcReg, 500 MachineRegisterInfo &MRI, 501 MachineIRBuilder &Builder, 502 SmallVectorImpl<Register> &UpdatedDefs, 503 GISelChangeObserver &Observer) { 504 if (!llvm::canReplaceReg(DstReg, SrcReg, MRI)) { 505 Builder.buildCopy(DstReg, SrcReg); 506 UpdatedDefs.push_back(DstReg); 507 return; 508 } 509 SmallVector<MachineInstr *, 4> UseMIs; 510 // Get the users and notify the observer before replacing. 511 for (auto &UseMI : MRI.use_instructions(DstReg)) { 512 UseMIs.push_back(&UseMI); 513 Observer.changingInstr(UseMI); 514 } 515 // Replace the registers. 516 MRI.replaceRegWith(DstReg, SrcReg); 517 UpdatedDefs.push_back(SrcReg); 518 // Notify the observer that we changed the instructions. 519 for (auto *UseMI : UseMIs) 520 Observer.changedInstr(*UseMI); 521 } 522 523 /// Return the operand index in \p MI that defines \p Def getDefIndex(const MachineInstr & MI,Register SearchDef)524 static unsigned getDefIndex(const MachineInstr &MI, Register SearchDef) { 525 unsigned DefIdx = 0; 526 for (const MachineOperand &Def : MI.defs()) { 527 if (Def.getReg() == SearchDef) 528 break; 529 ++DefIdx; 530 } 531 532 return DefIdx; 533 } 534 tryCombineUnmergeValues(MachineInstr & MI,SmallVectorImpl<MachineInstr * > & DeadInsts,SmallVectorImpl<Register> & UpdatedDefs,GISelChangeObserver & Observer)535 bool tryCombineUnmergeValues(MachineInstr &MI, 536 SmallVectorImpl<MachineInstr *> &DeadInsts, 537 SmallVectorImpl<Register> &UpdatedDefs, 538 GISelChangeObserver &Observer) { 539 assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES); 540 541 unsigned NumDefs = MI.getNumOperands() - 1; 542 Register SrcReg = MI.getOperand(NumDefs).getReg(); 543 MachineInstr *SrcDef = getDefIgnoringCopies(SrcReg, MRI); 544 if (!SrcDef) 545 return false; 546 547 LLT OpTy = MRI.getType(MI.getOperand(NumDefs).getReg()); 548 LLT DestTy = MRI.getType(MI.getOperand(0).getReg()); 549 550 if (SrcDef->getOpcode() == TargetOpcode::G_UNMERGE_VALUES) { 551 // %0:_(<4 x s16>) = G_FOO 552 // %1:_(<2 x s16>), %2:_(<2 x s16>) = G_UNMERGE_VALUES %0 553 // %3:_(s16), %4:_(s16) = G_UNMERGE_VALUES %1 554 // 555 // %3:_(s16), %4:_(s16), %5:_(s16), %6:_(s16) = G_UNMERGE_VALUES %0 556 const unsigned NumSrcOps = SrcDef->getNumOperands(); 557 Register SrcUnmergeSrc = SrcDef->getOperand(NumSrcOps - 1).getReg(); 558 LLT SrcUnmergeSrcTy = MRI.getType(SrcUnmergeSrc); 559 560 // If we need to decrease the number of vector elements in the result type 561 // of an unmerge, this would involve the creation of an equivalent unmerge 562 // to copy back to the original result registers. 563 LegalizeActionStep ActionStep = LI.getAction( 564 {TargetOpcode::G_UNMERGE_VALUES, {OpTy, SrcUnmergeSrcTy}}); 565 switch (ActionStep.Action) { 566 case LegalizeActions::Lower: 567 case LegalizeActions::Unsupported: 568 break; 569 case LegalizeActions::FewerElements: 570 case LegalizeActions::NarrowScalar: 571 if (ActionStep.TypeIdx == 1) 572 return false; 573 break; 574 default: 575 return false; 576 } 577 578 Builder.setInstrAndDebugLoc(MI); 579 auto NewUnmerge = Builder.buildUnmerge(DestTy, SrcUnmergeSrc); 580 581 // TODO: Should we try to process out the other defs now? If the other 582 // defs of the source unmerge are also unmerged, we end up with a separate 583 // unmerge for each one. 584 unsigned SrcDefIdx = getDefIndex(*SrcDef, SrcReg); 585 for (unsigned I = 0; I != NumDefs; ++I) { 586 Register Def = MI.getOperand(I).getReg(); 587 replaceRegOrBuildCopy(Def, NewUnmerge.getReg(SrcDefIdx * NumDefs + I), 588 MRI, Builder, UpdatedDefs, Observer); 589 } 590 591 markInstAndDefDead(MI, *SrcDef, DeadInsts, SrcDefIdx); 592 return true; 593 } 594 595 MachineInstr *MergeI = SrcDef; 596 unsigned ConvertOp = 0; 597 598 // Handle intermediate conversions 599 unsigned SrcOp = SrcDef->getOpcode(); 600 if (isArtifactCast(SrcOp)) { 601 ConvertOp = SrcOp; 602 MergeI = getDefIgnoringCopies(SrcDef->getOperand(1).getReg(), MRI); 603 } 604 605 if (!MergeI || !canFoldMergeOpcode(MergeI->getOpcode(), 606 ConvertOp, OpTy, DestTy)) { 607 // We might have a chance to combine later by trying to combine 608 // unmerge(cast) first 609 return tryFoldUnmergeCast(MI, *SrcDef, DeadInsts, UpdatedDefs); 610 } 611 612 const unsigned NumMergeRegs = MergeI->getNumOperands() - 1; 613 614 if (NumMergeRegs < NumDefs) { 615 if (NumDefs % NumMergeRegs != 0) 616 return false; 617 618 Builder.setInstr(MI); 619 // Transform to UNMERGEs, for example 620 // %1 = G_MERGE_VALUES %4, %5 621 // %9, %10, %11, %12 = G_UNMERGE_VALUES %1 622 // to 623 // %9, %10 = G_UNMERGE_VALUES %4 624 // %11, %12 = G_UNMERGE_VALUES %5 625 626 const unsigned NewNumDefs = NumDefs / NumMergeRegs; 627 for (unsigned Idx = 0; Idx < NumMergeRegs; ++Idx) { 628 SmallVector<Register, 8> DstRegs; 629 for (unsigned j = 0, DefIdx = Idx * NewNumDefs; j < NewNumDefs; 630 ++j, ++DefIdx) 631 DstRegs.push_back(MI.getOperand(DefIdx).getReg()); 632 633 if (ConvertOp) { 634 LLT MergeSrcTy = MRI.getType(MergeI->getOperand(1).getReg()); 635 636 // This is a vector that is being split and casted. Extract to the 637 // element type, and do the conversion on the scalars (or smaller 638 // vectors). 639 LLT MergeEltTy = MergeSrcTy.divide(NewNumDefs); 640 641 // Handle split to smaller vectors, with conversions. 642 // %2(<8 x s8>) = G_CONCAT_VECTORS %0(<4 x s8>), %1(<4 x s8>) 643 // %3(<8 x s16>) = G_SEXT %2 644 // %4(<2 x s16>), %5(<2 x s16>), %6(<2 x s16>), %7(<2 x s16>) = G_UNMERGE_VALUES %3 645 // 646 // => 647 // 648 // %8(<2 x s8>), %9(<2 x s8>) = G_UNMERGE_VALUES %0 649 // %10(<2 x s8>), %11(<2 x s8>) = G_UNMERGE_VALUES %1 650 // %4(<2 x s16>) = G_SEXT %8 651 // %5(<2 x s16>) = G_SEXT %9 652 // %6(<2 x s16>) = G_SEXT %10 653 // %7(<2 x s16>)= G_SEXT %11 654 655 SmallVector<Register, 4> TmpRegs(NewNumDefs); 656 for (unsigned k = 0; k < NewNumDefs; ++k) 657 TmpRegs[k] = MRI.createGenericVirtualRegister(MergeEltTy); 658 659 Builder.buildUnmerge(TmpRegs, MergeI->getOperand(Idx + 1).getReg()); 660 661 for (unsigned k = 0; k < NewNumDefs; ++k) 662 Builder.buildInstr(ConvertOp, {DstRegs[k]}, {TmpRegs[k]}); 663 } else { 664 Builder.buildUnmerge(DstRegs, MergeI->getOperand(Idx + 1).getReg()); 665 } 666 UpdatedDefs.append(DstRegs.begin(), DstRegs.end()); 667 } 668 669 } else if (NumMergeRegs > NumDefs) { 670 if (ConvertOp != 0 || NumMergeRegs % NumDefs != 0) 671 return false; 672 673 Builder.setInstr(MI); 674 // Transform to MERGEs 675 // %6 = G_MERGE_VALUES %17, %18, %19, %20 676 // %7, %8 = G_UNMERGE_VALUES %6 677 // to 678 // %7 = G_MERGE_VALUES %17, %18 679 // %8 = G_MERGE_VALUES %19, %20 680 681 const unsigned NumRegs = NumMergeRegs / NumDefs; 682 for (unsigned DefIdx = 0; DefIdx < NumDefs; ++DefIdx) { 683 SmallVector<Register, 8> Regs; 684 for (unsigned j = 0, Idx = NumRegs * DefIdx + 1; j < NumRegs; 685 ++j, ++Idx) 686 Regs.push_back(MergeI->getOperand(Idx).getReg()); 687 688 Register DefReg = MI.getOperand(DefIdx).getReg(); 689 Builder.buildMerge(DefReg, Regs); 690 UpdatedDefs.push_back(DefReg); 691 } 692 693 } else { 694 LLT MergeSrcTy = MRI.getType(MergeI->getOperand(1).getReg()); 695 696 if (!ConvertOp && DestTy != MergeSrcTy) 697 ConvertOp = TargetOpcode::G_BITCAST; 698 699 if (ConvertOp) { 700 Builder.setInstr(MI); 701 702 for (unsigned Idx = 0; Idx < NumDefs; ++Idx) { 703 Register MergeSrc = MergeI->getOperand(Idx + 1).getReg(); 704 Register DefReg = MI.getOperand(Idx).getReg(); 705 Builder.buildInstr(ConvertOp, {DefReg}, {MergeSrc}); 706 UpdatedDefs.push_back(DefReg); 707 } 708 709 markInstAndDefDead(MI, *MergeI, DeadInsts); 710 return true; 711 } 712 713 assert(DestTy == MergeSrcTy && 714 "Bitcast and the other kinds of conversions should " 715 "have happened earlier"); 716 717 Builder.setInstr(MI); 718 for (unsigned Idx = 0; Idx < NumDefs; ++Idx) { 719 Register DstReg = MI.getOperand(Idx).getReg(); 720 Register SrcReg = MergeI->getOperand(Idx + 1).getReg(); 721 replaceRegOrBuildCopy(DstReg, SrcReg, MRI, Builder, UpdatedDefs, 722 Observer); 723 } 724 } 725 726 markInstAndDefDead(MI, *MergeI, DeadInsts); 727 return true; 728 } 729 isMergeLikeOpcode(unsigned Opc)730 static bool isMergeLikeOpcode(unsigned Opc) { 731 switch (Opc) { 732 case TargetOpcode::G_MERGE_VALUES: 733 case TargetOpcode::G_BUILD_VECTOR: 734 case TargetOpcode::G_CONCAT_VECTORS: 735 return true; 736 default: 737 return false; 738 } 739 } 740 tryCombineExtract(MachineInstr & MI,SmallVectorImpl<MachineInstr * > & DeadInsts,SmallVectorImpl<Register> & UpdatedDefs)741 bool tryCombineExtract(MachineInstr &MI, 742 SmallVectorImpl<MachineInstr *> &DeadInsts, 743 SmallVectorImpl<Register> &UpdatedDefs) { 744 assert(MI.getOpcode() == TargetOpcode::G_EXTRACT); 745 746 // Try to use the source registers from a G_MERGE_VALUES 747 // 748 // %2 = G_MERGE_VALUES %0, %1 749 // %3 = G_EXTRACT %2, N 750 // => 751 // 752 // for N < %2.getSizeInBits() / 2 753 // %3 = G_EXTRACT %0, N 754 // 755 // for N >= %2.getSizeInBits() / 2 756 // %3 = G_EXTRACT %1, (N - %0.getSizeInBits() 757 758 Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg()); 759 MachineInstr *MergeI = MRI.getVRegDef(SrcReg); 760 if (!MergeI || !isMergeLikeOpcode(MergeI->getOpcode())) 761 return false; 762 763 Register DstReg = MI.getOperand(0).getReg(); 764 LLT DstTy = MRI.getType(DstReg); 765 LLT SrcTy = MRI.getType(SrcReg); 766 767 // TODO: Do we need to check if the resulting extract is supported? 768 unsigned ExtractDstSize = DstTy.getSizeInBits(); 769 unsigned Offset = MI.getOperand(2).getImm(); 770 unsigned NumMergeSrcs = MergeI->getNumOperands() - 1; 771 unsigned MergeSrcSize = SrcTy.getSizeInBits() / NumMergeSrcs; 772 unsigned MergeSrcIdx = Offset / MergeSrcSize; 773 774 // Compute the offset of the last bit the extract needs. 775 unsigned EndMergeSrcIdx = (Offset + ExtractDstSize - 1) / MergeSrcSize; 776 777 // Can't handle the case where the extract spans multiple inputs. 778 if (MergeSrcIdx != EndMergeSrcIdx) 779 return false; 780 781 // TODO: We could modify MI in place in most cases. 782 Builder.setInstr(MI); 783 Builder.buildExtract(DstReg, MergeI->getOperand(MergeSrcIdx + 1).getReg(), 784 Offset - MergeSrcIdx * MergeSrcSize); 785 UpdatedDefs.push_back(DstReg); 786 markInstAndDefDead(MI, *MergeI, DeadInsts); 787 return true; 788 } 789 790 /// Try to combine away MI. 791 /// Returns true if it combined away the MI. 792 /// Adds instructions that are dead as a result of the combine 793 /// into DeadInsts, which can include MI. tryCombineInstruction(MachineInstr & MI,SmallVectorImpl<MachineInstr * > & DeadInsts,GISelObserverWrapper & WrapperObserver)794 bool tryCombineInstruction(MachineInstr &MI, 795 SmallVectorImpl<MachineInstr *> &DeadInsts, 796 GISelObserverWrapper &WrapperObserver) { 797 // This might be a recursive call, and we might have DeadInsts already 798 // populated. To avoid bad things happening later with multiple vreg defs 799 // etc, process the dead instructions now if any. 800 if (!DeadInsts.empty()) 801 deleteMarkedDeadInsts(DeadInsts, WrapperObserver); 802 803 // Put here every vreg that was redefined in such a way that it's at least 804 // possible that one (or more) of its users (immediate or COPY-separated) 805 // could become artifact combinable with the new definition (or the 806 // instruction reachable from it through a chain of copies if any). 807 SmallVector<Register, 4> UpdatedDefs; 808 bool Changed = false; 809 switch (MI.getOpcode()) { 810 default: 811 return false; 812 case TargetOpcode::G_ANYEXT: 813 Changed = tryCombineAnyExt(MI, DeadInsts, UpdatedDefs); 814 break; 815 case TargetOpcode::G_ZEXT: 816 Changed = tryCombineZExt(MI, DeadInsts, UpdatedDefs, WrapperObserver); 817 break; 818 case TargetOpcode::G_SEXT: 819 Changed = tryCombineSExt(MI, DeadInsts, UpdatedDefs); 820 break; 821 case TargetOpcode::G_UNMERGE_VALUES: 822 Changed = 823 tryCombineUnmergeValues(MI, DeadInsts, UpdatedDefs, WrapperObserver); 824 break; 825 case TargetOpcode::G_MERGE_VALUES: 826 case TargetOpcode::G_BUILD_VECTOR: 827 case TargetOpcode::G_CONCAT_VECTORS: 828 // If any of the users of this merge are an unmerge, then add them to the 829 // artifact worklist in case there's folding that can be done looking up. 830 for (MachineInstr &U : MRI.use_instructions(MI.getOperand(0).getReg())) { 831 if (U.getOpcode() == TargetOpcode::G_UNMERGE_VALUES || 832 U.getOpcode() == TargetOpcode::G_TRUNC) { 833 UpdatedDefs.push_back(MI.getOperand(0).getReg()); 834 break; 835 } 836 } 837 break; 838 case TargetOpcode::G_EXTRACT: 839 Changed = tryCombineExtract(MI, DeadInsts, UpdatedDefs); 840 break; 841 case TargetOpcode::G_TRUNC: 842 Changed = tryCombineTrunc(MI, DeadInsts, UpdatedDefs, WrapperObserver); 843 if (!Changed) { 844 // Try to combine truncates away even if they are legal. As all artifact 845 // combines at the moment look only "up" the def-use chains, we achieve 846 // that by throwing truncates' users (with look through copies) into the 847 // ArtifactList again. 848 UpdatedDefs.push_back(MI.getOperand(0).getReg()); 849 } 850 break; 851 } 852 // If the main loop through the ArtifactList found at least one combinable 853 // pair of artifacts, not only combine it away (as done above), but also 854 // follow the def-use chain from there to combine everything that can be 855 // combined within this def-use chain of artifacts. 856 while (!UpdatedDefs.empty()) { 857 Register NewDef = UpdatedDefs.pop_back_val(); 858 assert(NewDef.isVirtual() && "Unexpected redefinition of a physreg"); 859 for (MachineInstr &Use : MRI.use_instructions(NewDef)) { 860 switch (Use.getOpcode()) { 861 // Keep this list in sync with the list of all artifact combines. 862 case TargetOpcode::G_ANYEXT: 863 case TargetOpcode::G_ZEXT: 864 case TargetOpcode::G_SEXT: 865 case TargetOpcode::G_UNMERGE_VALUES: 866 case TargetOpcode::G_EXTRACT: 867 case TargetOpcode::G_TRUNC: 868 // Adding Use to ArtifactList. 869 WrapperObserver.changedInstr(Use); 870 break; 871 case TargetOpcode::COPY: { 872 Register Copy = Use.getOperand(0).getReg(); 873 if (Copy.isVirtual()) 874 UpdatedDefs.push_back(Copy); 875 break; 876 } 877 default: 878 // If we do not have an artifact combine for the opcode, there is no 879 // point in adding it to the ArtifactList as nothing interesting will 880 // be done to it anyway. 881 break; 882 } 883 } 884 } 885 return Changed; 886 } 887 888 private: getArtifactSrcReg(const MachineInstr & MI)889 static Register getArtifactSrcReg(const MachineInstr &MI) { 890 switch (MI.getOpcode()) { 891 case TargetOpcode::COPY: 892 case TargetOpcode::G_TRUNC: 893 case TargetOpcode::G_ZEXT: 894 case TargetOpcode::G_ANYEXT: 895 case TargetOpcode::G_SEXT: 896 case TargetOpcode::G_EXTRACT: 897 return MI.getOperand(1).getReg(); 898 case TargetOpcode::G_UNMERGE_VALUES: 899 return MI.getOperand(MI.getNumOperands() - 1).getReg(); 900 default: 901 llvm_unreachable("Not a legalization artifact happen"); 902 } 903 } 904 905 /// Mark a def of one of MI's original operands, DefMI, as dead if changing MI 906 /// (either by killing it or changing operands) results in DefMI being dead 907 /// too. In-between COPYs or artifact-casts are also collected if they are 908 /// dead. 909 /// MI is not marked dead. 910 void markDefDead(MachineInstr &MI, MachineInstr &DefMI, 911 SmallVectorImpl<MachineInstr *> &DeadInsts, 912 unsigned DefIdx = 0) { 913 // Collect all the copy instructions that are made dead, due to deleting 914 // this instruction. Collect all of them until the Trunc(DefMI). 915 // Eg, 916 // %1(s1) = G_TRUNC %0(s32) 917 // %2(s1) = COPY %1(s1) 918 // %3(s1) = COPY %2(s1) 919 // %4(s32) = G_ANYEXT %3(s1) 920 // In this case, we would have replaced %4 with a copy of %0, 921 // and as a result, %3, %2, %1 are dead. 922 MachineInstr *PrevMI = &MI; 923 while (PrevMI != &DefMI) { 924 Register PrevRegSrc = getArtifactSrcReg(*PrevMI); 925 926 MachineInstr *TmpDef = MRI.getVRegDef(PrevRegSrc); 927 if (MRI.hasOneUse(PrevRegSrc)) { 928 if (TmpDef != &DefMI) { 929 assert((TmpDef->getOpcode() == TargetOpcode::COPY || 930 isArtifactCast(TmpDef->getOpcode())) && 931 "Expecting copy or artifact cast here"); 932 933 DeadInsts.push_back(TmpDef); 934 } 935 } else 936 break; 937 PrevMI = TmpDef; 938 } 939 940 if (PrevMI == &DefMI) { 941 unsigned I = 0; 942 bool IsDead = true; 943 for (MachineOperand &Def : DefMI.defs()) { 944 if (I != DefIdx) { 945 if (!MRI.use_empty(Def.getReg())) { 946 IsDead = false; 947 break; 948 } 949 } else { 950 if (!MRI.hasOneUse(DefMI.getOperand(DefIdx).getReg())) 951 break; 952 } 953 954 ++I; 955 } 956 957 if (IsDead) 958 DeadInsts.push_back(&DefMI); 959 } 960 } 961 962 /// Mark MI as dead. If a def of one of MI's operands, DefMI, would also be 963 /// dead due to MI being killed, then mark DefMI as dead too. 964 /// Some of the combines (extends(trunc)), try to walk through redundant 965 /// copies in between the extends and the truncs, and this attempts to collect 966 /// the in between copies if they're dead. 967 void markInstAndDefDead(MachineInstr &MI, MachineInstr &DefMI, 968 SmallVectorImpl<MachineInstr *> &DeadInsts, 969 unsigned DefIdx = 0) { 970 DeadInsts.push_back(&MI); 971 markDefDead(MI, DefMI, DeadInsts, DefIdx); 972 } 973 974 /// Erase the dead instructions in the list and call the observer hooks. 975 /// Normally the Legalizer will deal with erasing instructions that have been 976 /// marked dead. However, for the trunc(ext(x)) cases we can end up trying to 977 /// process instructions which have been marked dead, but otherwise break the 978 /// MIR by introducing multiple vreg defs. For those cases, allow the combines 979 /// to explicitly delete the instructions before we run into trouble. deleteMarkedDeadInsts(SmallVectorImpl<MachineInstr * > & DeadInsts,GISelObserverWrapper & WrapperObserver)980 void deleteMarkedDeadInsts(SmallVectorImpl<MachineInstr *> &DeadInsts, 981 GISelObserverWrapper &WrapperObserver) { 982 for (auto *DeadMI : DeadInsts) { 983 LLVM_DEBUG(dbgs() << *DeadMI << "Is dead, eagerly deleting\n"); 984 WrapperObserver.erasingInstr(*DeadMI); 985 DeadMI->eraseFromParentAndMarkDBGValuesForRemoval(); 986 } 987 DeadInsts.clear(); 988 } 989 990 /// Checks if the target legalizer info has specified anything about the 991 /// instruction, or if unsupported. isInstUnsupported(const LegalityQuery & Query)992 bool isInstUnsupported(const LegalityQuery &Query) const { 993 using namespace LegalizeActions; 994 auto Step = LI.getAction(Query); 995 return Step.Action == Unsupported || Step.Action == NotFound; 996 } 997 isInstLegal(const LegalityQuery & Query)998 bool isInstLegal(const LegalityQuery &Query) const { 999 return LI.getAction(Query).Action == LegalizeActions::Legal; 1000 } 1001 isConstantUnsupported(LLT Ty)1002 bool isConstantUnsupported(LLT Ty) const { 1003 if (!Ty.isVector()) 1004 return isInstUnsupported({TargetOpcode::G_CONSTANT, {Ty}}); 1005 1006 LLT EltTy = Ty.getElementType(); 1007 return isInstUnsupported({TargetOpcode::G_CONSTANT, {EltTy}}) || 1008 isInstUnsupported({TargetOpcode::G_BUILD_VECTOR, {Ty, EltTy}}); 1009 } 1010 1011 /// Looks through copy instructions and returns the actual 1012 /// source register. lookThroughCopyInstrs(Register Reg)1013 Register lookThroughCopyInstrs(Register Reg) { 1014 Register TmpReg; 1015 while (mi_match(Reg, MRI, m_Copy(m_Reg(TmpReg)))) { 1016 if (MRI.getType(TmpReg).isValid()) 1017 Reg = TmpReg; 1018 else 1019 break; 1020 } 1021 return Reg; 1022 } 1023 }; 1024 1025 } // namespace llvm 1026 1027 #endif // LLVM_CODEGEN_GLOBALISEL_LEGALIZATIONARTIFACTCOMBINER_H 1028