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