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