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