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 DenseSet<const uint32_t *> ConstRegisterMasks; 295 296 // Track predefined/named regmasks which we ignore. 297 for (const uint32_t *Mask : TRI->getRegMasks()) 298 ConstRegisterMasks.insert(Mask); 299 300 // Clone instructions. 301 for (auto &SrcMBB : *SrcMF) { 302 auto *DstMBB = Src2DstMBB[&SrcMBB]; 303 for (auto &SrcMI : SrcMBB) { 304 const auto &MCID = TII->get(SrcMI.getOpcode()); 305 auto *DstMI = DstMF->CreateMachineInstr(MCID, SrcMI.getDebugLoc(), 306 /*NoImplicit=*/true); 307 DstMI->setFlags(SrcMI.getFlags()); 308 DstMI->setAsmPrinterFlag(SrcMI.getAsmPrinterFlags()); 309 310 DstMBB->push_back(DstMI); 311 for (auto &SrcMO : SrcMI.operands()) { 312 MachineOperand DstMO(SrcMO); 313 DstMO.clearParent(); 314 315 // Update MBB. 316 if (DstMO.isMBB()) 317 DstMO.setMBB(Src2DstMBB[DstMO.getMBB()]); 318 else if (DstMO.isRegMask()) { 319 DstMRI->addPhysRegsUsedFromRegMask(DstMO.getRegMask()); 320 321 if (!ConstRegisterMasks.count(DstMO.getRegMask())) { 322 uint32_t *DstMask = DstMF->allocateRegMask(); 323 std::memcpy(DstMask, SrcMO.getRegMask(), 324 sizeof(*DstMask) * 325 MachineOperand::getRegMaskSize(TRI->getNumRegs())); 326 DstMO.setRegMask(DstMask); 327 } 328 } 329 330 DstMI->addOperand(DstMO); 331 } 332 333 cloneMemOperands(*DstMI, SrcMI, *SrcMF, *DstMF); 334 } 335 } 336 337 DstMF->setAlignment(SrcMF->getAlignment()); 338 DstMF->setExposesReturnsTwice(SrcMF->exposesReturnsTwice()); 339 DstMF->setHasInlineAsm(SrcMF->hasInlineAsm()); 340 DstMF->setHasWinCFI(SrcMF->hasWinCFI()); 341 342 DstMF->getProperties().reset().set(SrcMF->getProperties()); 343 344 if (!SrcMF->getFrameInstructions().empty() || 345 !SrcMF->getLongjmpTargets().empty() || 346 !SrcMF->getCatchretTargets().empty()) 347 report_fatal_error("cloning not implemented for machine function property"); 348 349 DstMF->setCallsEHReturn(SrcMF->callsEHReturn()); 350 DstMF->setCallsUnwindInit(SrcMF->callsUnwindInit()); 351 DstMF->setHasEHCatchret(SrcMF->hasEHCatchret()); 352 DstMF->setHasEHScopes(SrcMF->hasEHScopes()); 353 DstMF->setHasEHFunclets(SrcMF->hasEHFunclets()); 354 355 if (!SrcMF->getLandingPads().empty() || 356 !SrcMF->getCodeViewAnnotations().empty() || 357 !SrcMF->getTypeInfos().empty() || 358 !SrcMF->getFilterIds().empty() || 359 SrcMF->hasAnyWasmLandingPadIndex() || 360 SrcMF->hasAnyCallSiteLandingPad() || 361 SrcMF->hasAnyCallSiteLabel() || 362 !SrcMF->getCallSitesInfo().empty()) 363 report_fatal_error("cloning not implemented for machine function property"); 364 365 DstMF->setDebugInstrNumberingCount(SrcMF->DebugInstrNumberingCount); 366 367 if (!DstMF->cloneInfoFrom(*SrcMF, Src2DstMBB)) 368 report_fatal_error("target does not implement MachineFunctionInfo cloning"); 369 370 DstMRI->freezeReservedRegs(*DstMF); 371 372 DstMF->verify(nullptr, "", /*AbortOnError=*/true); 373 return DstMF; 374 } 375 376 static void initializeTargetInfo() { 377 InitializeAllTargets(); 378 InitializeAllTargetMCs(); 379 InitializeAllAsmPrinters(); 380 InitializeAllAsmParsers(); 381 } 382 383 std::unique_ptr<ReducerWorkItem> 384 parseReducerWorkItem(const char *ToolName, StringRef Filename, 385 LLVMContext &Ctxt, std::unique_ptr<TargetMachine> &TM, 386 bool IsMIR) { 387 Triple TheTriple; 388 389 auto MMM = std::make_unique<ReducerWorkItem>(); 390 391 if (IsMIR) { 392 initializeTargetInfo(); 393 394 auto FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename, /*IsText=*/true); 395 if (std::error_code EC = FileOrErr.getError()) { 396 WithColor::error(errs(), ToolName) << EC.message() << '\n'; 397 return nullptr; 398 } 399 400 std::unique_ptr<MIRParser> MParser = 401 createMIRParser(std::move(FileOrErr.get()), Ctxt); 402 403 auto SetDataLayout = 404 [&](StringRef DataLayoutTargetTriple) -> Optional<std::string> { 405 // If we are supposed to override the target triple, do so now. 406 std::string IRTargetTriple = DataLayoutTargetTriple.str(); 407 if (!TargetTriple.empty()) 408 IRTargetTriple = Triple::normalize(TargetTriple); 409 TheTriple = Triple(IRTargetTriple); 410 if (TheTriple.getTriple().empty()) 411 TheTriple.setTriple(sys::getDefaultTargetTriple()); 412 413 std::string Error; 414 const Target *TheTarget = 415 TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error); 416 if (!TheTarget) { 417 WithColor::error(errs(), ToolName) << Error; 418 exit(1); 419 } 420 421 // Hopefully the MIR parsing doesn't depend on any options. 422 TargetOptions Options; 423 Optional<Reloc::Model> RM = codegen::getExplicitRelocModel(); 424 std::string CPUStr = codegen::getCPUStr(); 425 std::string FeaturesStr = codegen::getFeaturesStr(); 426 TM = std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine( 427 TheTriple.getTriple(), CPUStr, FeaturesStr, Options, RM, 428 codegen::getExplicitCodeModel(), CodeGenOpt::Default)); 429 assert(TM && "Could not allocate target machine!"); 430 431 return TM->createDataLayout().getStringRepresentation(); 432 }; 433 434 std::unique_ptr<Module> M = MParser->parseIRModule(SetDataLayout); 435 LLVMTargetMachine *LLVMTM = static_cast<LLVMTargetMachine *>(TM.get()); 436 437 MMM->MMI = std::make_unique<MachineModuleInfo>(LLVMTM); 438 MParser->parseMachineFunctions(*M, *MMM->MMI); 439 MMM->M = std::move(M); 440 } else { 441 SMDiagnostic Err; 442 ErrorOr<std::unique_ptr<MemoryBuffer>> MB = MemoryBuffer::getFileOrSTDIN(Filename); 443 if (std::error_code EC = MB.getError()) { 444 WithColor::error(errs(), ToolName) << Filename << ": " << EC.message() << "\n"; 445 return nullptr; 446 } 447 448 if (!isBitcode((const unsigned char *)(*MB)->getBufferStart(), 449 (const unsigned char *)(*MB)->getBufferEnd())) { 450 std::unique_ptr<Module> Result = parseIRFile(Filename, Err, Ctxt); 451 if (!Result) { 452 Err.print(ToolName, errs()); 453 return nullptr; 454 } 455 MMM->M = std::move(Result); 456 } else { 457 readBitcode(*MMM, MemoryBufferRef(**MB), Ctxt, ToolName); 458 459 if (MMM->LTOInfo->IsThinLTO && MMM->LTOInfo->EnableSplitLTOUnit) 460 initializeTargetInfo(); 461 } 462 } 463 if (verifyReducerWorkItem(*MMM, &errs())) { 464 WithColor::error(errs(), ToolName) 465 << Filename << " - input module is broken!\n"; 466 return nullptr; 467 } 468 return MMM; 469 } 470 471 std::unique_ptr<ReducerWorkItem> 472 cloneReducerWorkItem(const ReducerWorkItem &MMM, const TargetMachine *TM) { 473 auto CloneMMM = std::make_unique<ReducerWorkItem>(); 474 if (TM) { 475 // We're assuming the Module IR contents are always unchanged by MIR 476 // reductions, and can share it as a constant. 477 CloneMMM->M = MMM.M; 478 479 // MachineModuleInfo contains a lot of other state used during codegen which 480 // we won't be using here, but we should be able to ignore it (although this 481 // is pretty ugly). 482 const LLVMTargetMachine *LLVMTM = 483 static_cast<const LLVMTargetMachine *>(TM); 484 CloneMMM->MMI = std::make_unique<MachineModuleInfo>(LLVMTM); 485 486 for (const Function &F : MMM.getModule()) { 487 if (auto *MF = MMM.MMI->getMachineFunction(F)) 488 CloneMMM->MMI->insertFunction(F, cloneMF(MF, *CloneMMM->MMI)); 489 } 490 } else { 491 CloneMMM->M = CloneModule(*MMM.M); 492 } 493 return CloneMMM; 494 } 495 496 bool verifyReducerWorkItem(const ReducerWorkItem &MMM, raw_fd_ostream *OS) { 497 if (verifyModule(*MMM.M, OS)) 498 return true; 499 500 if (!MMM.MMI) 501 return false; 502 503 for (const Function &F : MMM.getModule()) { 504 if (const MachineFunction *MF = MMM.MMI->getMachineFunction(F)) { 505 if (!MF->verify(nullptr, "", /*AbortOnError=*/false)) 506 return true; 507 } 508 } 509 510 return false; 511 } 512 513 void ReducerWorkItem::print(raw_ostream &ROS, void *p) const { 514 if (MMI) { 515 printMIR(ROS, *M); 516 for (Function &F : *M) { 517 if (auto *MF = MMI->getMachineFunction(F)) 518 printMIR(ROS, *MF); 519 } 520 } else { 521 M->print(ROS, /*AssemblyAnnotationWriter=*/nullptr, 522 /*ShouldPreserveUseListOrder=*/true); 523 } 524 } 525 526 // FIXME: We might want to use a different metric than "number of 527 // bytes in serialized IR" to detect non-progress of the main delta 528 // loop 529 uint64_t ReducerWorkItem::getIRSize() const { 530 std::string Str; 531 raw_string_ostream SS(Str); 532 print(SS, /*AnnotationWriter=*/nullptr); 533 return Str.length(); 534 } 535 536 /// Try to produce some number that indicates a function is getting smaller / 537 /// simpler. 538 static uint64_t computeMIRComplexityScoreImpl(const MachineFunction &MF) { 539 uint64_t Score = 0; 540 const MachineFrameInfo &MFI = MF.getFrameInfo(); 541 542 // Add for stack objects 543 Score += MFI.getNumObjects(); 544 545 // Add in the block count. 546 Score += 2 * MF.size(); 547 548 const MachineRegisterInfo &MRI = MF.getRegInfo(); 549 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) { 550 Register Reg = Register::index2VirtReg(I); 551 Score += MRI.getRegAllocationHints(Reg).second.size(); 552 } 553 554 for (const MachineBasicBlock &MBB : MF) { 555 for (const MachineInstr &MI : MBB) { 556 const unsigned Opc = MI.getOpcode(); 557 558 // Reductions may want or need to introduce implicit_defs, so don't count 559 // them. 560 // TODO: These probably should count in some way. 561 if (Opc == TargetOpcode::IMPLICIT_DEF || 562 Opc == TargetOpcode::G_IMPLICIT_DEF) 563 continue; 564 565 // Each instruction adds to the score 566 Score += 4; 567 568 if (Opc == TargetOpcode::PHI || Opc == TargetOpcode::G_PHI || 569 Opc == TargetOpcode::INLINEASM || Opc == TargetOpcode::INLINEASM_BR) 570 ++Score; 571 572 if (MI.getFlags() != 0) 573 ++Score; 574 575 // Increase weight for more operands. 576 for (const MachineOperand &MO : MI.operands()) { 577 ++Score; 578 579 // Treat registers as more complex. 580 if (MO.isReg()) { 581 ++Score; 582 583 // And subregisters as even more complex. 584 if (MO.getSubReg()) { 585 ++Score; 586 if (MO.isDef()) 587 ++Score; 588 } 589 } else if (MO.isRegMask()) 590 ++Score; 591 } 592 } 593 } 594 595 return Score; 596 } 597 598 uint64_t ReducerWorkItem::computeMIRComplexityScore() const { 599 uint64_t Score = 0; 600 601 for (const Function &F : getModule()) { 602 if (auto *MF = MMI->getMachineFunction(F)) 603 Score += computeMIRComplexityScoreImpl(*MF); 604 } 605 606 return Score; 607 } 608