1 //===- ReducerWorkItem.cpp - Wrapper for Module and MachineFunction -------===// 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 9 #include "ReducerWorkItem.h" 10 #include "llvm/CodeGen/CommandFlags.h" 11 #include "llvm/CodeGen/MIRParser/MIRParser.h" 12 #include "llvm/CodeGen/MIRPrinter.h" 13 #include "llvm/CodeGen/MachineDominators.h" 14 #include "llvm/CodeGen/MachineFrameInfo.h" 15 #include "llvm/CodeGen/MachineFunction.h" 16 #include "llvm/CodeGen/MachineFunctionPass.h" 17 #include "llvm/CodeGen/MachineRegisterInfo.h" 18 #include "llvm/CodeGen/TargetInstrInfo.h" 19 #include "llvm/IR/Verifier.h" 20 #include "llvm/IRReader/IRReader.h" 21 #include "llvm/MC/TargetRegistry.h" 22 #include "llvm/Support/Host.h" 23 #include "llvm/Support/SourceMgr.h" 24 #include "llvm/Support/WithColor.h" 25 #include "llvm/Target/TargetMachine.h" 26 #include "llvm/Transforms/Utils/Cloning.h" 27 28 extern cl::OptionCategory LLVMReduceOptions; 29 static cl::opt<std::string> TargetTriple("mtriple", 30 cl::desc("Set the target triple"), 31 cl::cat(LLVMReduceOptions)); 32 33 static void cloneFrameInfo( 34 MachineFrameInfo &DstMFI, const MachineFrameInfo &SrcMFI, 35 const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB) { 36 DstMFI.setFrameAddressIsTaken(SrcMFI.isFrameAddressTaken()); 37 DstMFI.setReturnAddressIsTaken(SrcMFI.isReturnAddressTaken()); 38 DstMFI.setHasStackMap(SrcMFI.hasStackMap()); 39 DstMFI.setHasPatchPoint(SrcMFI.hasPatchPoint()); 40 DstMFI.setUseLocalStackAllocationBlock( 41 SrcMFI.getUseLocalStackAllocationBlock()); 42 DstMFI.setOffsetAdjustment(SrcMFI.getOffsetAdjustment()); 43 44 DstMFI.ensureMaxAlignment(SrcMFI.getMaxAlign()); 45 assert(DstMFI.getMaxAlign() == SrcMFI.getMaxAlign() && 46 "we need to set exact alignment"); 47 48 DstMFI.setAdjustsStack(SrcMFI.adjustsStack()); 49 DstMFI.setHasCalls(SrcMFI.hasCalls()); 50 DstMFI.setHasOpaqueSPAdjustment(SrcMFI.hasOpaqueSPAdjustment()); 51 DstMFI.setHasCopyImplyingStackAdjustment( 52 SrcMFI.hasCopyImplyingStackAdjustment()); 53 DstMFI.setHasVAStart(SrcMFI.hasVAStart()); 54 DstMFI.setHasMustTailInVarArgFunc(SrcMFI.hasMustTailInVarArgFunc()); 55 DstMFI.setHasTailCall(SrcMFI.hasTailCall()); 56 57 if (SrcMFI.isMaxCallFrameSizeComputed()) 58 DstMFI.setMaxCallFrameSize(SrcMFI.getMaxCallFrameSize()); 59 60 DstMFI.setCVBytesOfCalleeSavedRegisters( 61 SrcMFI.getCVBytesOfCalleeSavedRegisters()); 62 63 if (MachineBasicBlock *SavePt = SrcMFI.getSavePoint()) 64 DstMFI.setSavePoint(Src2DstMBB.find(SavePt)->second); 65 if (MachineBasicBlock *RestorePt = SrcMFI.getRestorePoint()) 66 DstMFI.setRestorePoint(Src2DstMBB.find(RestorePt)->second); 67 68 69 auto CopyObjectProperties = [](MachineFrameInfo &DstMFI, 70 const MachineFrameInfo &SrcMFI, int FI) { 71 if (SrcMFI.isStatepointSpillSlotObjectIndex(FI)) 72 DstMFI.markAsStatepointSpillSlotObjectIndex(FI); 73 DstMFI.setObjectSSPLayout(FI, SrcMFI.getObjectSSPLayout(FI)); 74 DstMFI.setObjectZExt(FI, SrcMFI.isObjectZExt(FI)); 75 DstMFI.setObjectSExt(FI, SrcMFI.isObjectSExt(FI)); 76 }; 77 78 for (int i = 0, e = SrcMFI.getNumObjects() - SrcMFI.getNumFixedObjects(); 79 i != e; ++i) { 80 int NewFI; 81 82 assert(!SrcMFI.isFixedObjectIndex(i)); 83 if (SrcMFI.isVariableSizedObjectIndex(i)) { 84 NewFI = DstMFI.CreateVariableSizedObject(SrcMFI.getObjectAlign(i), 85 SrcMFI.getObjectAllocation(i)); 86 } else { 87 NewFI = DstMFI.CreateStackObject( 88 SrcMFI.getObjectSize(i), SrcMFI.getObjectAlign(i), 89 SrcMFI.isSpillSlotObjectIndex(i), SrcMFI.getObjectAllocation(i), 90 SrcMFI.getStackID(i)); 91 DstMFI.setObjectOffset(NewFI, SrcMFI.getObjectOffset(i)); 92 } 93 94 CopyObjectProperties(DstMFI, SrcMFI, i); 95 96 (void)NewFI; 97 assert(i == NewFI && "expected to keep stable frame index numbering"); 98 } 99 100 // Copy the fixed frame objects backwards to preserve frame index numbers, 101 // since CreateFixedObject uses front insertion. 102 for (int i = -1; i >= (int)-SrcMFI.getNumFixedObjects(); --i) { 103 assert(SrcMFI.isFixedObjectIndex(i)); 104 int NewFI = DstMFI.CreateFixedObject( 105 SrcMFI.getObjectSize(i), SrcMFI.getObjectOffset(i), 106 SrcMFI.isImmutableObjectIndex(i), SrcMFI.isAliasedObjectIndex(i)); 107 CopyObjectProperties(DstMFI, SrcMFI, i); 108 109 (void)NewFI; 110 assert(i == NewFI && "expected to keep stable frame index numbering"); 111 } 112 113 for (unsigned I = 0, E = SrcMFI.getLocalFrameObjectCount(); I < E; ++I) { 114 auto LocalObject = SrcMFI.getLocalFrameObjectMap(I); 115 DstMFI.mapLocalFrameObject(LocalObject.first, LocalObject.second); 116 } 117 118 DstMFI.setCalleeSavedInfo(SrcMFI.getCalleeSavedInfo()); 119 120 if (SrcMFI.hasStackProtectorIndex()) { 121 DstMFI.setStackProtectorIndex(SrcMFI.getStackProtectorIndex()); 122 } 123 124 // FIXME: Needs test, missing MIR serialization. 125 if (SrcMFI.hasFunctionContextIndex()) { 126 DstMFI.setFunctionContextIndex(SrcMFI.getFunctionContextIndex()); 127 } 128 } 129 130 static void cloneMemOperands(MachineInstr &DstMI, MachineInstr &SrcMI, 131 MachineFunction &SrcMF, MachineFunction &DstMF) { 132 // The new MachineMemOperands should be owned by the new function's 133 // Allocator. 134 PseudoSourceValueManager &PSVMgr = DstMF.getPSVManager(); 135 136 // We also need to remap the PseudoSourceValues from the new function's 137 // PseudoSourceValueManager. 138 SmallVector<MachineMemOperand *, 2> NewMMOs; 139 for (MachineMemOperand *OldMMO : SrcMI.memoperands()) { 140 MachinePointerInfo NewPtrInfo(OldMMO->getPointerInfo()); 141 if (const PseudoSourceValue *PSV = 142 NewPtrInfo.V.dyn_cast<const PseudoSourceValue *>()) { 143 switch (PSV->kind()) { 144 case PseudoSourceValue::Stack: 145 NewPtrInfo.V = PSVMgr.getStack(); 146 break; 147 case PseudoSourceValue::GOT: 148 NewPtrInfo.V = PSVMgr.getGOT(); 149 break; 150 case PseudoSourceValue::JumpTable: 151 NewPtrInfo.V = PSVMgr.getJumpTable(); 152 break; 153 case PseudoSourceValue::ConstantPool: 154 NewPtrInfo.V = PSVMgr.getConstantPool(); 155 break; 156 case PseudoSourceValue::FixedStack: 157 NewPtrInfo.V = PSVMgr.getFixedStack( 158 cast<FixedStackPseudoSourceValue>(PSV)->getFrameIndex()); 159 break; 160 case PseudoSourceValue::GlobalValueCallEntry: 161 NewPtrInfo.V = PSVMgr.getGlobalValueCallEntry( 162 cast<GlobalValuePseudoSourceValue>(PSV)->getValue()); 163 break; 164 case PseudoSourceValue::ExternalSymbolCallEntry: 165 NewPtrInfo.V = PSVMgr.getExternalSymbolCallEntry( 166 cast<ExternalSymbolPseudoSourceValue>(PSV)->getSymbol()); 167 break; 168 case PseudoSourceValue::TargetCustom: 169 default: 170 // FIXME: We have no generic interface for allocating custom PSVs. 171 report_fatal_error("Cloning TargetCustom PSV not handled"); 172 } 173 } 174 175 MachineMemOperand *NewMMO = DstMF.getMachineMemOperand( 176 NewPtrInfo, OldMMO->getFlags(), OldMMO->getMemoryType(), 177 OldMMO->getBaseAlign(), OldMMO->getAAInfo(), OldMMO->getRanges(), 178 OldMMO->getSyncScopeID(), OldMMO->getSuccessOrdering(), 179 OldMMO->getFailureOrdering()); 180 NewMMOs.push_back(NewMMO); 181 } 182 183 DstMI.setMemRefs(DstMF, NewMMOs); 184 } 185 186 static std::unique_ptr<MachineFunction> cloneMF(MachineFunction *SrcMF, 187 MachineModuleInfo &DestMMI) { 188 auto DstMF = std::make_unique<MachineFunction>( 189 SrcMF->getFunction(), SrcMF->getTarget(), SrcMF->getSubtarget(), 190 SrcMF->getFunctionNumber(), DestMMI); 191 DenseMap<MachineBasicBlock *, MachineBasicBlock *> Src2DstMBB; 192 193 auto *SrcMRI = &SrcMF->getRegInfo(); 194 auto *DstMRI = &DstMF->getRegInfo(); 195 196 // Clone blocks. 197 for (MachineBasicBlock &SrcMBB : *SrcMF) { 198 MachineBasicBlock *DstMBB = 199 DstMF->CreateMachineBasicBlock(SrcMBB.getBasicBlock()); 200 Src2DstMBB[&SrcMBB] = DstMBB; 201 202 if (SrcMBB.hasAddressTaken()) 203 DstMBB->setHasAddressTaken(); 204 205 // FIXME: This is not serialized 206 if (SrcMBB.hasLabelMustBeEmitted()) 207 DstMBB->setLabelMustBeEmitted(); 208 209 DstMBB->setAlignment(SrcMBB.getAlignment()); 210 211 // FIXME: This is not serialized 212 DstMBB->setMaxBytesForAlignment(SrcMBB.getMaxBytesForAlignment()); 213 214 DstMBB->setIsEHPad(SrcMBB.isEHPad()); 215 DstMBB->setIsEHScopeEntry(SrcMBB.isEHScopeEntry()); 216 DstMBB->setIsEHCatchretTarget(SrcMBB.isEHCatchretTarget()); 217 DstMBB->setIsEHFuncletEntry(SrcMBB.isEHFuncletEntry()); 218 219 // FIXME: These are not serialized 220 DstMBB->setIsCleanupFuncletEntry(SrcMBB.isCleanupFuncletEntry()); 221 DstMBB->setIsBeginSection(SrcMBB.isBeginSection()); 222 DstMBB->setIsEndSection(SrcMBB.isEndSection()); 223 224 DstMBB->setSectionID(SrcMBB.getSectionID()); 225 DstMBB->setIsInlineAsmBrIndirectTarget( 226 SrcMBB.isInlineAsmBrIndirectTarget()); 227 228 // FIXME: This is not serialized 229 if (Optional<uint64_t> Weight = SrcMBB.getIrrLoopHeaderWeight()) 230 DstMBB->setIrrLoopHeaderWeight(*Weight); 231 } 232 233 const MachineFrameInfo &SrcMFI = SrcMF->getFrameInfo(); 234 MachineFrameInfo &DstMFI = DstMF->getFrameInfo(); 235 236 // Copy stack objects and other info 237 cloneFrameInfo(DstMFI, SrcMFI, Src2DstMBB); 238 239 // Remap the debug info frame index references. 240 DstMF->VariableDbgInfos = SrcMF->VariableDbgInfos; 241 242 // FIXME: Need to clone MachineFunctionInfo, which may also depend on frame 243 // index and block mapping. 244 // Clone virtual registers 245 for (unsigned I = 0, E = SrcMRI->getNumVirtRegs(); I != E; ++I) { 246 Register Reg = Register::index2VirtReg(I); 247 Register NewReg = DstMRI->createIncompleteVirtualRegister( 248 SrcMRI->getVRegName(Reg)); 249 assert(NewReg == Reg && "expected to preserve virtreg number"); 250 251 DstMRI->setRegClassOrRegBank(NewReg, SrcMRI->getRegClassOrRegBank(Reg)); 252 253 LLT RegTy = SrcMRI->getType(Reg); 254 if (RegTy.isValid()) 255 DstMRI->setType(NewReg, RegTy); 256 257 // Copy register allocation hints. 258 const auto &Hints = SrcMRI->getRegAllocationHints(Reg); 259 for (Register PrefReg : Hints.second) 260 DstMRI->addRegAllocationHint(NewReg, PrefReg); 261 } 262 263 const TargetSubtargetInfo &STI = DstMF->getSubtarget(); 264 const TargetInstrInfo *TII = STI.getInstrInfo(); 265 const TargetRegisterInfo *TRI = STI.getRegisterInfo(); 266 267 // Link blocks. 268 for (auto &SrcMBB : *SrcMF) { 269 auto *DstMBB = Src2DstMBB[&SrcMBB]; 270 DstMF->push_back(DstMBB); 271 272 for (auto It = SrcMBB.succ_begin(), IterEnd = SrcMBB.succ_end(); 273 It != IterEnd; ++It) { 274 auto *SrcSuccMBB = *It; 275 auto *DstSuccMBB = Src2DstMBB[SrcSuccMBB]; 276 DstMBB->addSuccessor(DstSuccMBB, SrcMBB.getSuccProbability(It)); 277 } 278 for (auto &LI : SrcMBB.liveins()) 279 DstMBB->addLiveIn(LI); 280 281 // Make sure MRI knows about registers clobbered by unwinder. 282 if (DstMBB->isEHPad()) { 283 if (auto *RegMask = TRI->getCustomEHPadPreservedMask(*DstMF)) 284 DstMRI->addPhysRegsUsedFromRegMask(RegMask); 285 } 286 } 287 288 // Clone instructions. 289 for (auto &SrcMBB : *SrcMF) { 290 auto *DstMBB = Src2DstMBB[&SrcMBB]; 291 for (auto &SrcMI : SrcMBB) { 292 const auto &MCID = TII->get(SrcMI.getOpcode()); 293 auto *DstMI = DstMF->CreateMachineInstr(MCID, SrcMI.getDebugLoc(), 294 /*NoImplicit=*/true); 295 DstMI->setFlags(SrcMI.getFlags()); 296 DstMI->setAsmPrinterFlag(SrcMI.getAsmPrinterFlags()); 297 298 DstMBB->push_back(DstMI); 299 for (auto &SrcMO : SrcMI.operands()) { 300 MachineOperand DstMO(SrcMO); 301 DstMO.clearParent(); 302 303 // Update MBB. 304 if (DstMO.isMBB()) 305 DstMO.setMBB(Src2DstMBB[DstMO.getMBB()]); 306 else if (DstMO.isRegMask()) 307 DstMRI->addPhysRegsUsedFromRegMask(DstMO.getRegMask()); 308 309 DstMI->addOperand(DstMO); 310 } 311 312 cloneMemOperands(*DstMI, SrcMI, *SrcMF, *DstMF); 313 } 314 } 315 316 DstMF->setAlignment(SrcMF->getAlignment()); 317 DstMF->setExposesReturnsTwice(SrcMF->exposesReturnsTwice()); 318 DstMF->setHasInlineAsm(SrcMF->hasInlineAsm()); 319 DstMF->setHasWinCFI(SrcMF->hasWinCFI()); 320 321 DstMF->getProperties().reset().set(SrcMF->getProperties()); 322 323 if (!SrcMF->getFrameInstructions().empty() || 324 !SrcMF->getLongjmpTargets().empty() || 325 !SrcMF->getCatchretTargets().empty()) 326 report_fatal_error("cloning not implemented for machine function property"); 327 328 DstMF->setCallsEHReturn(SrcMF->callsEHReturn()); 329 DstMF->setCallsUnwindInit(SrcMF->callsUnwindInit()); 330 DstMF->setHasEHCatchret(SrcMF->hasEHCatchret()); 331 DstMF->setHasEHScopes(SrcMF->hasEHScopes()); 332 DstMF->setHasEHFunclets(SrcMF->hasEHFunclets()); 333 334 if (!SrcMF->getLandingPads().empty() || 335 !SrcMF->getCodeViewAnnotations().empty() || 336 !SrcMF->getTypeInfos().empty() || 337 !SrcMF->getFilterIds().empty() || 338 SrcMF->hasAnyWasmLandingPadIndex() || 339 SrcMF->hasAnyCallSiteLandingPad() || 340 SrcMF->hasAnyCallSiteLabel() || 341 !SrcMF->getCallSitesInfo().empty()) 342 report_fatal_error("cloning not implemented for machine function property"); 343 344 DstMF->setDebugInstrNumberingCount(SrcMF->DebugInstrNumberingCount); 345 346 DstMF->verify(nullptr, "", /*AbortOnError=*/true); 347 return DstMF; 348 } 349 350 std::unique_ptr<ReducerWorkItem> 351 parseReducerWorkItem(const char *ToolName, StringRef Filename, 352 LLVMContext &Ctxt, std::unique_ptr<TargetMachine> &TM, 353 bool IsMIR) { 354 Triple TheTriple; 355 356 auto MMM = std::make_unique<ReducerWorkItem>(); 357 358 if (IsMIR) { 359 auto FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename, /*IsText=*/true); 360 if (std::error_code EC = FileOrErr.getError()) { 361 WithColor::error(errs(), ToolName) << EC.message() << '\n'; 362 return nullptr; 363 } 364 365 std::unique_ptr<MIRParser> MParser = 366 createMIRParser(std::move(FileOrErr.get()), Ctxt); 367 368 auto SetDataLayout = 369 [&](StringRef DataLayoutTargetTriple) -> Optional<std::string> { 370 // If we are supposed to override the target triple, do so now. 371 std::string IRTargetTriple = DataLayoutTargetTriple.str(); 372 if (!TargetTriple.empty()) 373 IRTargetTriple = Triple::normalize(TargetTriple); 374 TheTriple = Triple(IRTargetTriple); 375 if (TheTriple.getTriple().empty()) 376 TheTriple.setTriple(sys::getDefaultTargetTriple()); 377 378 std::string Error; 379 const Target *TheTarget = 380 TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error); 381 if (!TheTarget) { 382 WithColor::error(errs(), ToolName) << Error; 383 exit(1); 384 } 385 386 // Hopefully the MIR parsing doesn't depend on any options. 387 TargetOptions Options; 388 Optional<Reloc::Model> RM = codegen::getExplicitRelocModel(); 389 std::string CPUStr = codegen::getCPUStr(); 390 std::string FeaturesStr = codegen::getFeaturesStr(); 391 TM = std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine( 392 TheTriple.getTriple(), CPUStr, FeaturesStr, Options, RM, 393 codegen::getExplicitCodeModel(), CodeGenOpt::Default)); 394 assert(TM && "Could not allocate target machine!"); 395 396 return TM->createDataLayout().getStringRepresentation(); 397 }; 398 399 std::unique_ptr<Module> M = MParser->parseIRModule(SetDataLayout); 400 LLVMTargetMachine *LLVMTM = static_cast<LLVMTargetMachine *>(TM.get()); 401 402 MMM->MMI = std::make_unique<MachineModuleInfo>(LLVMTM); 403 MParser->parseMachineFunctions(*M, *MMM->MMI); 404 MMM->M = std::move(M); 405 } else { 406 SMDiagnostic Err; 407 std::unique_ptr<Module> Result = parseIRFile(Filename, Err, Ctxt); 408 if (!Result) { 409 Err.print(ToolName, errs()); 410 return std::unique_ptr<ReducerWorkItem>(); 411 } 412 MMM->M = std::move(Result); 413 } 414 if (verifyReducerWorkItem(*MMM, &errs())) { 415 WithColor::error(errs(), ToolName) 416 << Filename << " - input module is broken!\n"; 417 return std::unique_ptr<ReducerWorkItem>(); 418 } 419 return MMM; 420 } 421 422 std::unique_ptr<ReducerWorkItem> 423 cloneReducerWorkItem(const ReducerWorkItem &MMM, const TargetMachine *TM) { 424 auto CloneMMM = std::make_unique<ReducerWorkItem>(); 425 if (TM) { 426 // We're assuming the Module IR contents are always unchanged by MIR 427 // reductions, and can share it as a constant. 428 CloneMMM->M = MMM.M; 429 430 // MachineModuleInfo contains a lot of other state used during codegen which 431 // we won't be using here, but we should be able to ignore it (although this 432 // is pretty ugly). 433 const LLVMTargetMachine *LLVMTM = 434 static_cast<const LLVMTargetMachine *>(TM); 435 CloneMMM->MMI = std::make_unique<MachineModuleInfo>(LLVMTM); 436 437 for (const Function &F : MMM.getModule()) { 438 if (auto *MF = MMM.MMI->getMachineFunction(F)) 439 CloneMMM->MMI->insertFunction(F, cloneMF(MF, *CloneMMM->MMI)); 440 } 441 } else { 442 CloneMMM->M = CloneModule(*MMM.M); 443 } 444 return CloneMMM; 445 } 446 447 bool verifyReducerWorkItem(const ReducerWorkItem &MMM, raw_fd_ostream *OS) { 448 if (verifyModule(*MMM.M, OS)) 449 return true; 450 451 if (!MMM.MMI) 452 return false; 453 454 for (const Function &F : MMM.getModule()) { 455 if (const MachineFunction *MF = MMM.MMI->getMachineFunction(F)) { 456 if (!MF->verify(nullptr, "", /*AbortOnError=*/false)) 457 return true; 458 } 459 } 460 461 return false; 462 } 463 464 void ReducerWorkItem::print(raw_ostream &ROS, void *p) const { 465 if (MMI) { 466 printMIR(ROS, *M); 467 for (Function &F : *M) { 468 if (auto *MF = MMI->getMachineFunction(F)) 469 printMIR(ROS, *MF); 470 } 471 } else { 472 M->print(ROS, /*AssemblyAnnotationWriter=*/nullptr, 473 /*ShouldPreserveUseListOrder=*/true); 474 } 475 } 476 477 // FIXME: We might want to use a different metric than "number of 478 // bytes in serialized IR" to detect non-progress of the main delta 479 // loop 480 uint64_t ReducerWorkItem::getIRSize() const { 481 std::string Str; 482 raw_string_ostream SS(Str); 483 print(SS, /*AnnotationWriter=*/nullptr); 484 return Str.length(); 485 } 486 487 /// Try to produce some number that indicates a function is getting smaller / 488 /// simpler. 489 static uint64_t computeMIRComplexityScoreImpl(const MachineFunction &MF) { 490 uint64_t Score = 0; 491 const MachineFrameInfo &MFI = MF.getFrameInfo(); 492 493 // Add for stack objects 494 Score += MFI.getNumObjects(); 495 496 // Add in the block count. 497 Score += 2 * MF.size(); 498 499 for (const MachineBasicBlock &MBB : MF) { 500 for (const MachineInstr &MI : MBB) { 501 const unsigned Opc = MI.getOpcode(); 502 503 // Reductions may want or need to introduce implicit_defs, so don't count 504 // them. 505 // TODO: These probably should count in some way. 506 if (Opc == TargetOpcode::IMPLICIT_DEF || 507 Opc == TargetOpcode::G_IMPLICIT_DEF) 508 continue; 509 510 // Each instruction adds to the score 511 Score += 4; 512 513 if (Opc == TargetOpcode::PHI || Opc == TargetOpcode::G_PHI || 514 Opc == TargetOpcode::INLINEASM || Opc == TargetOpcode::INLINEASM_BR) 515 ++Score; 516 517 if (MI.getFlags() != 0) 518 ++Score; 519 520 // Increase weight for more operands. 521 for (const MachineOperand &MO : MI.operands()) { 522 ++Score; 523 524 // Treat registers as more complex. 525 if (MO.isReg()) { 526 ++Score; 527 528 // And subregisters as even more complex. 529 if (MO.getSubReg()) { 530 ++Score; 531 if (MO.isDef()) 532 ++Score; 533 } 534 } else if (MO.isRegMask()) 535 ++Score; 536 } 537 } 538 } 539 540 return Score; 541 } 542 543 uint64_t ReducerWorkItem::computeMIRComplexityScore() const { 544 uint64_t Score = 0; 545 546 for (const Function &F : getModule()) { 547 if (auto *MF = MMI->getMachineFunction(F)) 548 Score += computeMIRComplexityScoreImpl(*MF); 549 } 550 551 return Score; 552 } 553