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 // FIXME: Need to clone MachineFunctionInfo, which may also depend on frame 244 // index and block mapping. 245 // Clone virtual registers 246 for (unsigned I = 0, E = SrcMRI->getNumVirtRegs(); I != E; ++I) { 247 Register Reg = Register::index2VirtReg(I); 248 Register NewReg = DstMRI->createIncompleteVirtualRegister( 249 SrcMRI->getVRegName(Reg)); 250 assert(NewReg == Reg && "expected to preserve virtreg number"); 251 252 DstMRI->setRegClassOrRegBank(NewReg, SrcMRI->getRegClassOrRegBank(Reg)); 253 254 LLT RegTy = SrcMRI->getType(Reg); 255 if (RegTy.isValid()) 256 DstMRI->setType(NewReg, RegTy); 257 258 // Copy register allocation hints. 259 const auto &Hints = SrcMRI->getRegAllocationHints(Reg); 260 for (Register PrefReg : Hints.second) 261 DstMRI->addRegAllocationHint(NewReg, PrefReg); 262 } 263 264 const TargetSubtargetInfo &STI = DstMF->getSubtarget(); 265 const TargetInstrInfo *TII = STI.getInstrInfo(); 266 const TargetRegisterInfo *TRI = STI.getRegisterInfo(); 267 268 // Link blocks. 269 for (auto &SrcMBB : *SrcMF) { 270 auto *DstMBB = Src2DstMBB[&SrcMBB]; 271 DstMF->push_back(DstMBB); 272 273 for (auto It = SrcMBB.succ_begin(), IterEnd = SrcMBB.succ_end(); 274 It != IterEnd; ++It) { 275 auto *SrcSuccMBB = *It; 276 auto *DstSuccMBB = Src2DstMBB[SrcSuccMBB]; 277 DstMBB->addSuccessor(DstSuccMBB, SrcMBB.getSuccProbability(It)); 278 } 279 for (auto &LI : SrcMBB.liveins()) 280 DstMBB->addLiveIn(LI); 281 282 // Make sure MRI knows about registers clobbered by unwinder. 283 if (DstMBB->isEHPad()) { 284 if (auto *RegMask = TRI->getCustomEHPadPreservedMask(*DstMF)) 285 DstMRI->addPhysRegsUsedFromRegMask(RegMask); 286 } 287 } 288 289 // Clone instructions. 290 for (auto &SrcMBB : *SrcMF) { 291 auto *DstMBB = Src2DstMBB[&SrcMBB]; 292 for (auto &SrcMI : SrcMBB) { 293 const auto &MCID = TII->get(SrcMI.getOpcode()); 294 auto *DstMI = DstMF->CreateMachineInstr(MCID, SrcMI.getDebugLoc(), 295 /*NoImplicit=*/true); 296 DstMI->setFlags(SrcMI.getFlags()); 297 DstMI->setAsmPrinterFlag(SrcMI.getAsmPrinterFlags()); 298 299 DstMBB->push_back(DstMI); 300 for (auto &SrcMO : SrcMI.operands()) { 301 MachineOperand DstMO(SrcMO); 302 DstMO.clearParent(); 303 304 // Update MBB. 305 if (DstMO.isMBB()) 306 DstMO.setMBB(Src2DstMBB[DstMO.getMBB()]); 307 else if (DstMO.isRegMask()) 308 DstMRI->addPhysRegsUsedFromRegMask(DstMO.getRegMask()); 309 310 DstMI->addOperand(DstMO); 311 } 312 313 cloneMemOperands(*DstMI, SrcMI, *SrcMF, *DstMF); 314 } 315 } 316 317 DstMF->setAlignment(SrcMF->getAlignment()); 318 DstMF->setExposesReturnsTwice(SrcMF->exposesReturnsTwice()); 319 DstMF->setHasInlineAsm(SrcMF->hasInlineAsm()); 320 DstMF->setHasWinCFI(SrcMF->hasWinCFI()); 321 322 DstMF->getProperties().reset().set(SrcMF->getProperties()); 323 324 if (!SrcMF->getFrameInstructions().empty() || 325 !SrcMF->getLongjmpTargets().empty() || 326 !SrcMF->getCatchretTargets().empty()) 327 report_fatal_error("cloning not implemented for machine function property"); 328 329 DstMF->setCallsEHReturn(SrcMF->callsEHReturn()); 330 DstMF->setCallsUnwindInit(SrcMF->callsUnwindInit()); 331 DstMF->setHasEHCatchret(SrcMF->hasEHCatchret()); 332 DstMF->setHasEHScopes(SrcMF->hasEHScopes()); 333 DstMF->setHasEHFunclets(SrcMF->hasEHFunclets()); 334 335 if (!SrcMF->getLandingPads().empty() || 336 !SrcMF->getCodeViewAnnotations().empty() || 337 !SrcMF->getTypeInfos().empty() || 338 !SrcMF->getFilterIds().empty() || 339 SrcMF->hasAnyWasmLandingPadIndex() || 340 SrcMF->hasAnyCallSiteLandingPad() || 341 SrcMF->hasAnyCallSiteLabel() || 342 !SrcMF->getCallSitesInfo().empty()) 343 report_fatal_error("cloning not implemented for machine function property"); 344 345 DstMF->setDebugInstrNumberingCount(SrcMF->DebugInstrNumberingCount); 346 347 DstMF->verify(nullptr, "", /*AbortOnError=*/true); 348 return DstMF; 349 } 350 351 std::unique_ptr<ReducerWorkItem> 352 parseReducerWorkItem(const char *ToolName, StringRef Filename, 353 LLVMContext &Ctxt, std::unique_ptr<TargetMachine> &TM, 354 bool IsMIR) { 355 Triple TheTriple; 356 357 auto MMM = std::make_unique<ReducerWorkItem>(); 358 359 if (IsMIR) { 360 auto FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename, /*IsText=*/true); 361 if (std::error_code EC = FileOrErr.getError()) { 362 WithColor::error(errs(), ToolName) << EC.message() << '\n'; 363 return nullptr; 364 } 365 366 std::unique_ptr<MIRParser> MParser = 367 createMIRParser(std::move(FileOrErr.get()), Ctxt); 368 369 auto SetDataLayout = 370 [&](StringRef DataLayoutTargetTriple) -> Optional<std::string> { 371 // If we are supposed to override the target triple, do so now. 372 std::string IRTargetTriple = DataLayoutTargetTriple.str(); 373 if (!TargetTriple.empty()) 374 IRTargetTriple = Triple::normalize(TargetTriple); 375 TheTriple = Triple(IRTargetTriple); 376 if (TheTriple.getTriple().empty()) 377 TheTriple.setTriple(sys::getDefaultTargetTriple()); 378 379 std::string Error; 380 const Target *TheTarget = 381 TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error); 382 if (!TheTarget) { 383 WithColor::error(errs(), ToolName) << Error; 384 exit(1); 385 } 386 387 // Hopefully the MIR parsing doesn't depend on any options. 388 TargetOptions Options; 389 Optional<Reloc::Model> RM = codegen::getExplicitRelocModel(); 390 std::string CPUStr = codegen::getCPUStr(); 391 std::string FeaturesStr = codegen::getFeaturesStr(); 392 TM = std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine( 393 TheTriple.getTriple(), CPUStr, FeaturesStr, Options, RM, 394 codegen::getExplicitCodeModel(), CodeGenOpt::Default)); 395 assert(TM && "Could not allocate target machine!"); 396 397 return TM->createDataLayout().getStringRepresentation(); 398 }; 399 400 std::unique_ptr<Module> M = MParser->parseIRModule(SetDataLayout); 401 LLVMTargetMachine *LLVMTM = static_cast<LLVMTargetMachine *>(TM.get()); 402 403 MMM->MMI = std::make_unique<MachineModuleInfo>(LLVMTM); 404 MParser->parseMachineFunctions(*M, *MMM->MMI); 405 MMM->M = std::move(M); 406 } else { 407 SMDiagnostic Err; 408 std::unique_ptr<Module> Result = parseIRFile(Filename, Err, Ctxt); 409 if (!Result) { 410 Err.print(ToolName, errs()); 411 return std::unique_ptr<ReducerWorkItem>(); 412 } 413 MMM->M = std::move(Result); 414 } 415 if (verifyReducerWorkItem(*MMM, &errs())) { 416 WithColor::error(errs(), ToolName) 417 << Filename << " - input module is broken!\n"; 418 return std::unique_ptr<ReducerWorkItem>(); 419 } 420 return MMM; 421 } 422 423 std::unique_ptr<ReducerWorkItem> 424 cloneReducerWorkItem(const ReducerWorkItem &MMM, const TargetMachine *TM) { 425 auto CloneMMM = std::make_unique<ReducerWorkItem>(); 426 if (TM) { 427 // We're assuming the Module IR contents are always unchanged by MIR 428 // reductions, and can share it as a constant. 429 CloneMMM->M = MMM.M; 430 431 // MachineModuleInfo contains a lot of other state used during codegen which 432 // we won't be using here, but we should be able to ignore it (although this 433 // is pretty ugly). 434 const LLVMTargetMachine *LLVMTM = 435 static_cast<const LLVMTargetMachine *>(TM); 436 CloneMMM->MMI = std::make_unique<MachineModuleInfo>(LLVMTM); 437 438 for (const Function &F : MMM.getModule()) { 439 if (auto *MF = MMM.MMI->getMachineFunction(F)) 440 CloneMMM->MMI->insertFunction(F, cloneMF(MF, *CloneMMM->MMI)); 441 } 442 } else { 443 CloneMMM->M = CloneModule(*MMM.M); 444 } 445 return CloneMMM; 446 } 447 448 bool verifyReducerWorkItem(const ReducerWorkItem &MMM, raw_fd_ostream *OS) { 449 if (verifyModule(*MMM.M, OS)) 450 return true; 451 452 if (!MMM.MMI) 453 return false; 454 455 for (const Function &F : MMM.getModule()) { 456 if (const MachineFunction *MF = MMM.MMI->getMachineFunction(F)) { 457 if (!MF->verify(nullptr, "", /*AbortOnError=*/false)) 458 return true; 459 } 460 } 461 462 return false; 463 } 464 465 void ReducerWorkItem::print(raw_ostream &ROS, void *p) const { 466 if (MMI) { 467 printMIR(ROS, *M); 468 for (Function &F : *M) { 469 if (auto *MF = MMI->getMachineFunction(F)) 470 printMIR(ROS, *MF); 471 } 472 } else { 473 M->print(ROS, /*AssemblyAnnotationWriter=*/nullptr, 474 /*ShouldPreserveUseListOrder=*/true); 475 } 476 } 477 478 // FIXME: We might want to use a different metric than "number of 479 // bytes in serialized IR" to detect non-progress of the main delta 480 // loop 481 uint64_t ReducerWorkItem::getIRSize() const { 482 std::string Str; 483 raw_string_ostream SS(Str); 484 print(SS, /*AnnotationWriter=*/nullptr); 485 return Str.length(); 486 } 487 488 /// Try to produce some number that indicates a function is getting smaller / 489 /// simpler. 490 static uint64_t computeMIRComplexityScoreImpl(const MachineFunction &MF) { 491 uint64_t Score = 0; 492 const MachineFrameInfo &MFI = MF.getFrameInfo(); 493 494 // Add for stack objects 495 Score += MFI.getNumObjects(); 496 497 // Add in the block count. 498 Score += 2 * MF.size(); 499 500 const MachineRegisterInfo &MRI = MF.getRegInfo(); 501 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) { 502 Register Reg = Register::index2VirtReg(I); 503 Score += MRI.getRegAllocationHints(Reg).second.size(); 504 } 505 506 for (const MachineBasicBlock &MBB : MF) { 507 for (const MachineInstr &MI : MBB) { 508 const unsigned Opc = MI.getOpcode(); 509 510 // Reductions may want or need to introduce implicit_defs, so don't count 511 // them. 512 // TODO: These probably should count in some way. 513 if (Opc == TargetOpcode::IMPLICIT_DEF || 514 Opc == TargetOpcode::G_IMPLICIT_DEF) 515 continue; 516 517 // Each instruction adds to the score 518 Score += 4; 519 520 if (Opc == TargetOpcode::PHI || Opc == TargetOpcode::G_PHI || 521 Opc == TargetOpcode::INLINEASM || Opc == TargetOpcode::INLINEASM_BR) 522 ++Score; 523 524 if (MI.getFlags() != 0) 525 ++Score; 526 527 // Increase weight for more operands. 528 for (const MachineOperand &MO : MI.operands()) { 529 ++Score; 530 531 // Treat registers as more complex. 532 if (MO.isReg()) { 533 ++Score; 534 535 // And subregisters as even more complex. 536 if (MO.getSubReg()) { 537 ++Score; 538 if (MO.isDef()) 539 ++Score; 540 } 541 } else if (MO.isRegMask()) 542 ++Score; 543 } 544 } 545 } 546 547 return Score; 548 } 549 550 uint64_t ReducerWorkItem::computeMIRComplexityScore() const { 551 uint64_t Score = 0; 552 553 for (const Function &F : getModule()) { 554 if (auto *MF = MMI->getMachineFunction(F)) 555 Score += computeMIRComplexityScoreImpl(*MF); 556 } 557 558 return Score; 559 } 560