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/MIRParser/MIRParser.h" 11 #include "llvm/CodeGen/MIRPrinter.h" 12 #include "llvm/CodeGen/MachineDominators.h" 13 #include "llvm/CodeGen/MachineFrameInfo.h" 14 #include "llvm/CodeGen/MachineFunction.h" 15 #include "llvm/CodeGen/MachineFunctionPass.h" 16 #include "llvm/CodeGen/MachineRegisterInfo.h" 17 #include "llvm/CodeGen/TargetInstrInfo.h" 18 #include "llvm/IR/Verifier.h" 19 #include "llvm/IRReader/IRReader.h" 20 #include "llvm/Support/SourceMgr.h" 21 #include "llvm/Target/TargetMachine.h" 22 #include "llvm/Transforms/Utils/Cloning.h" 23 24 // FIXME: Preserve frame index numbers. The numbering is off for fixed objects 25 // since they are inserted at the beginning. This would avoid the need for the 26 // Src2DstFrameIndex map and in the future target MFI code wouldn't need to 27 // worry about it either. 28 static void cloneFrameInfo( 29 MachineFrameInfo &DstMFI, const MachineFrameInfo &SrcMFI, 30 const DenseMap<MachineBasicBlock *, MachineBasicBlock *> Src2DstMBB, 31 DenseMap<int, int> &Src2DstFrameIndex) { 32 DstMFI.setFrameAddressIsTaken(SrcMFI.isFrameAddressTaken()); 33 DstMFI.setReturnAddressIsTaken(SrcMFI.isReturnAddressTaken()); 34 DstMFI.setHasStackMap(SrcMFI.hasStackMap()); 35 DstMFI.setHasPatchPoint(SrcMFI.hasPatchPoint()); 36 DstMFI.setUseLocalStackAllocationBlock( 37 SrcMFI.getUseLocalStackAllocationBlock()); 38 DstMFI.setOffsetAdjustment(SrcMFI.getOffsetAdjustment()); 39 40 DstMFI.ensureMaxAlignment(SrcMFI.getMaxAlign()); 41 assert(DstMFI.getMaxAlign() == SrcMFI.getMaxAlign() && 42 "we need to set exact alignment"); 43 44 DstMFI.setAdjustsStack(SrcMFI.adjustsStack()); 45 DstMFI.setHasCalls(SrcMFI.hasCalls()); 46 DstMFI.setHasOpaqueSPAdjustment(SrcMFI.hasOpaqueSPAdjustment()); 47 DstMFI.setHasCopyImplyingStackAdjustment( 48 SrcMFI.hasCopyImplyingStackAdjustment()); 49 DstMFI.setHasVAStart(SrcMFI.hasVAStart()); 50 DstMFI.setHasMustTailInVarArgFunc(SrcMFI.hasMustTailInVarArgFunc()); 51 DstMFI.setHasTailCall(SrcMFI.hasTailCall()); 52 53 if (SrcMFI.isMaxCallFrameSizeComputed()) 54 DstMFI.setMaxCallFrameSize(SrcMFI.getMaxCallFrameSize()); 55 56 DstMFI.setCVBytesOfCalleeSavedRegisters( 57 SrcMFI.getCVBytesOfCalleeSavedRegisters()); 58 59 if (MachineBasicBlock *SavePt = SrcMFI.getSavePoint()) 60 DstMFI.setSavePoint(Src2DstMBB.find(SavePt)->second); 61 if (MachineBasicBlock *RestorePt = SrcMFI.getRestorePoint()) 62 DstMFI.setRestorePoint(Src2DstMBB.find(RestorePt)->second); 63 64 for (int i = SrcMFI.getObjectIndexBegin(), e = SrcMFI.getObjectIndexEnd(); 65 i != e; ++i) { 66 int NewFI; 67 68 if (SrcMFI.isFixedObjectIndex(i)) { 69 NewFI = DstMFI.CreateFixedObject( 70 SrcMFI.getObjectSize(i), SrcMFI.getObjectOffset(i), 71 SrcMFI.isImmutableObjectIndex(i), SrcMFI.isAliasedObjectIndex(i)); 72 } else if (SrcMFI.isVariableSizedObjectIndex(i)) { 73 NewFI = DstMFI.CreateVariableSizedObject(SrcMFI.getObjectAlign(i), 74 SrcMFI.getObjectAllocation(i)); 75 } else { 76 NewFI = DstMFI.CreateStackObject( 77 SrcMFI.getObjectSize(i), SrcMFI.getObjectAlign(i), 78 SrcMFI.isSpillSlotObjectIndex(i), SrcMFI.getObjectAllocation(i), 79 SrcMFI.getStackID(i)); 80 DstMFI.setObjectOffset(NewFI, SrcMFI.getObjectOffset(i)); 81 } 82 83 if (SrcMFI.isStatepointSpillSlotObjectIndex(i)) 84 DstMFI.markAsStatepointSpillSlotObjectIndex(NewFI); 85 DstMFI.setObjectSSPLayout(NewFI, SrcMFI.getObjectSSPLayout(i)); 86 DstMFI.setObjectZExt(NewFI, SrcMFI.isObjectZExt(i)); 87 DstMFI.setObjectSExt(NewFI, SrcMFI.isObjectSExt(i)); 88 89 Src2DstFrameIndex[i] = NewFI; 90 } 91 92 for (unsigned I = 0, E = SrcMFI.getLocalFrameObjectCount(); I < E; ++I) { 93 auto LocalObject = SrcMFI.getLocalFrameObjectMap(I); 94 DstMFI.mapLocalFrameObject(LocalObject.first, LocalObject.second); 95 } 96 97 // Remap the frame indexes in the CalleeSavedInfo 98 std::vector<CalleeSavedInfo> CalleeSavedInfos = SrcMFI.getCalleeSavedInfo(); 99 for (CalleeSavedInfo &CSInfo : CalleeSavedInfos) { 100 if (!CSInfo.isSpilledToReg()) 101 CSInfo.setFrameIdx(Src2DstFrameIndex[CSInfo.getFrameIdx()]); 102 } 103 104 DstMFI.setCalleeSavedInfo(std::move(CalleeSavedInfos)); 105 106 if (SrcMFI.hasStackProtectorIndex()) { 107 DstMFI.setStackProtectorIndex( 108 Src2DstFrameIndex[SrcMFI.getStackProtectorIndex()]); 109 } 110 111 // FIXME: Needs test, missing MIR serialization. 112 if (SrcMFI.hasFunctionContextIndex()) { 113 DstMFI.setFunctionContextIndex( 114 Src2DstFrameIndex[SrcMFI.getFunctionContextIndex()]); 115 } 116 } 117 118 static std::unique_ptr<MachineFunction> cloneMF(MachineFunction *SrcMF) { 119 auto DstMF = std::make_unique<MachineFunction>( 120 SrcMF->getFunction(), SrcMF->getTarget(), SrcMF->getSubtarget(), 121 SrcMF->getFunctionNumber(), SrcMF->getMMI()); 122 DenseMap<MachineBasicBlock *, MachineBasicBlock *> Src2DstMBB; 123 DenseMap<Register, Register> Src2DstReg; 124 DenseMap<int, int> Src2DstFrameIndex; 125 126 auto *SrcMRI = &SrcMF->getRegInfo(); 127 auto *DstMRI = &DstMF->getRegInfo(); 128 129 // Clone blocks. 130 for (MachineBasicBlock &SrcMBB : *SrcMF) { 131 MachineBasicBlock *DstMBB = 132 DstMF->CreateMachineBasicBlock(SrcMBB.getBasicBlock()); 133 Src2DstMBB[&SrcMBB] = DstMBB; 134 135 if (SrcMBB.hasAddressTaken()) 136 DstMBB->setHasAddressTaken(); 137 138 // FIXME: This is not serialized 139 if (SrcMBB.hasLabelMustBeEmitted()) 140 DstMBB->setLabelMustBeEmitted(); 141 142 DstMBB->setAlignment(SrcMBB.getAlignment()); 143 144 // FIXME: This is not serialized 145 DstMBB->setMaxBytesForAlignment(SrcMBB.getMaxBytesForAlignment()); 146 147 DstMBB->setIsEHPad(SrcMBB.isEHPad()); 148 DstMBB->setIsEHScopeEntry(SrcMBB.isEHScopeEntry()); 149 DstMBB->setIsEHCatchretTarget(SrcMBB.isEHCatchretTarget()); 150 DstMBB->setIsEHFuncletEntry(SrcMBB.isEHFuncletEntry()); 151 152 // FIXME: These are not serialized 153 DstMBB->setIsCleanupFuncletEntry(SrcMBB.isCleanupFuncletEntry()); 154 DstMBB->setIsBeginSection(SrcMBB.isBeginSection()); 155 DstMBB->setIsEndSection(SrcMBB.isEndSection()); 156 157 DstMBB->setSectionID(SrcMBB.getSectionID()); 158 DstMBB->setIsInlineAsmBrIndirectTarget( 159 SrcMBB.isInlineAsmBrIndirectTarget()); 160 161 // FIXME: This is not serialized 162 if (Optional<uint64_t> Weight = SrcMBB.getIrrLoopHeaderWeight()) 163 DstMBB->setIrrLoopHeaderWeight(*Weight); 164 } 165 166 const MachineFrameInfo &SrcMFI = SrcMF->getFrameInfo(); 167 MachineFrameInfo &DstMFI = DstMF->getFrameInfo(); 168 169 // Copy stack objects and other info 170 cloneFrameInfo(DstMFI, SrcMFI, Src2DstMBB, Src2DstFrameIndex); 171 172 // Remap the debug info frame index references. 173 DstMF->VariableDbgInfos = SrcMF->VariableDbgInfos; 174 for (MachineFunction::VariableDbgInfo &DbgInfo : DstMF->VariableDbgInfos) 175 DbgInfo.Slot = Src2DstFrameIndex[DbgInfo.Slot]; 176 177 // FIXME: Need to clone MachineFunctionInfo, which may also depend on frame 178 // index and block mapping. 179 180 // Create vregs. 181 for (auto &SrcMBB : *SrcMF) { 182 for (auto &SrcMI : SrcMBB) { 183 for (unsigned I = 0, E = SrcMI.getNumOperands(); I < E; ++I) { 184 auto &DMO = SrcMI.getOperand(I); 185 if (DMO.isRegMask()) { 186 DstMRI->addPhysRegsUsedFromRegMask(DMO.getRegMask()); 187 continue; 188 } 189 190 if (!DMO.isReg()) 191 continue; 192 Register SrcReg = DMO.getReg(); 193 if (Register::isPhysicalRegister(SrcReg)) 194 continue; 195 196 if (Src2DstReg.find(SrcReg) != Src2DstReg.end()) 197 continue; 198 199 Register DstReg = DstMRI->createIncompleteVirtualRegister( 200 SrcMRI->getVRegName(SrcReg)); 201 DstMRI->setRegClassOrRegBank(DstReg, 202 SrcMRI->getRegClassOrRegBank(SrcReg)); 203 204 LLT RegTy = SrcMRI->getType(SrcReg); 205 if (RegTy.isValid()) 206 DstMRI->setType(DstReg, RegTy); 207 Src2DstReg[SrcReg] = DstReg; 208 } 209 } 210 } 211 212 // Copy register allocation hints. 213 for (std::pair<Register, Register> RegMapEntry : Src2DstReg) { 214 const auto &Hints = SrcMRI->getRegAllocationHints(RegMapEntry.first); 215 for (Register PrefReg : Hints.second) { 216 if (PrefReg.isVirtual()) { 217 auto PrefRegEntry = Src2DstReg.find(PrefReg); 218 assert(PrefRegEntry !=Src2DstReg.end()); 219 DstMRI->addRegAllocationHint(RegMapEntry.second, PrefRegEntry->second); 220 } else 221 DstMRI->addRegAllocationHint(RegMapEntry.second, PrefReg); 222 } 223 } 224 225 const TargetSubtargetInfo &STI = DstMF->getSubtarget(); 226 const TargetInstrInfo *TII = STI.getInstrInfo(); 227 const TargetRegisterInfo *TRI = STI.getRegisterInfo(); 228 229 // Link blocks. 230 for (auto &SrcMBB : *SrcMF) { 231 auto *DstMBB = Src2DstMBB[&SrcMBB]; 232 DstMF->push_back(DstMBB); 233 234 for (auto It = SrcMBB.succ_begin(), IterEnd = SrcMBB.succ_end(); 235 It != IterEnd; ++It) { 236 auto *SrcSuccMBB = *It; 237 auto *DstSuccMBB = Src2DstMBB[SrcSuccMBB]; 238 DstMBB->addSuccessor(DstSuccMBB, SrcMBB.getSuccProbability(It)); 239 } 240 for (auto &LI : SrcMBB.liveins()) 241 DstMBB->addLiveIn(LI); 242 243 // Make sure MRI knows about registers clobbered by unwinder. 244 if (DstMBB->isEHPad()) { 245 if (auto *RegMask = TRI->getCustomEHPadPreservedMask(*DstMF)) 246 DstMRI->addPhysRegsUsedFromRegMask(RegMask); 247 } 248 } 249 250 // Clone instructions. 251 for (auto &SrcMBB : *SrcMF) { 252 auto *DstMBB = Src2DstMBB[&SrcMBB]; 253 for (auto &SrcMI : SrcMBB) { 254 const auto &MCID = TII->get(SrcMI.getOpcode()); 255 auto *DstMI = DstMF->CreateMachineInstr(MCID, SrcMI.getDebugLoc(), 256 /*NoImplicit=*/true); 257 DstMBB->push_back(DstMI); 258 for (auto &SrcMO : SrcMI.operands()) { 259 MachineOperand DstMO(SrcMO); 260 DstMO.clearParent(); 261 // Update vreg. 262 if (DstMO.isReg() && Src2DstReg.count(DstMO.getReg())) { 263 DstMO.setReg(Src2DstReg[DstMO.getReg()]); 264 } 265 // Update MBB. 266 if (DstMO.isMBB()) { 267 DstMO.setMBB(Src2DstMBB[DstMO.getMBB()]); 268 } else if (DstMO.isFI()) { 269 // Update frame indexes 270 DstMO.setIndex(Src2DstFrameIndex[DstMO.getIndex()]); 271 } 272 273 DstMI->addOperand(DstMO); 274 } 275 DstMI->setMemRefs(*DstMF, SrcMI.memoperands()); 276 } 277 } 278 279 DstMF->setAlignment(SrcMF->getAlignment()); 280 DstMF->setExposesReturnsTwice(SrcMF->exposesReturnsTwice()); 281 DstMF->setHasInlineAsm(SrcMF->hasInlineAsm()); 282 DstMF->setHasWinCFI(SrcMF->hasWinCFI()); 283 284 DstMF->getProperties().reset().set(SrcMF->getProperties()); 285 286 if (!SrcMF->getFrameInstructions().empty() || 287 !SrcMF->getLongjmpTargets().empty() || 288 !SrcMF->getCatchretTargets().empty()) 289 report_fatal_error("cloning not implemented for machine function property"); 290 291 DstMF->setCallsEHReturn(SrcMF->callsEHReturn()); 292 DstMF->setCallsUnwindInit(SrcMF->callsUnwindInit()); 293 DstMF->setHasEHCatchret(SrcMF->hasEHCatchret()); 294 DstMF->setHasEHScopes(SrcMF->hasEHScopes()); 295 DstMF->setHasEHFunclets(SrcMF->hasEHFunclets()); 296 297 if (!SrcMF->getLandingPads().empty() || 298 !SrcMF->getCodeViewAnnotations().empty() || 299 !SrcMF->getTypeInfos().empty() || 300 !SrcMF->getFilterIds().empty() || 301 SrcMF->hasAnyWasmLandingPadIndex() || 302 SrcMF->hasAnyCallSiteLandingPad() || 303 SrcMF->hasAnyCallSiteLabel() || 304 !SrcMF->getCallSitesInfo().empty()) 305 report_fatal_error("cloning not implemented for machine function property"); 306 307 DstMF->setDebugInstrNumberingCount(SrcMF->DebugInstrNumberingCount); 308 309 DstMF->verify(nullptr, "", /*AbortOnError=*/true); 310 return DstMF; 311 } 312 313 std::unique_ptr<ReducerWorkItem> parseReducerWorkItem(StringRef Filename, 314 LLVMContext &Ctxt, 315 MachineModuleInfo *MMI) { 316 auto MMM = std::make_unique<ReducerWorkItem>(); 317 if (MMI) { 318 auto FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename, /*IsText=*/true); 319 std::unique_ptr<MIRParser> MParser = 320 createMIRParser(std::move(FileOrErr.get()), Ctxt); 321 322 auto SetDataLayout = 323 [&](StringRef DataLayoutTargetTriple) -> Optional<std::string> { 324 return MMI->getTarget().createDataLayout().getStringRepresentation(); 325 }; 326 327 std::unique_ptr<Module> M = MParser->parseIRModule(SetDataLayout); 328 MParser->parseMachineFunctions(*M, *MMI); 329 MachineFunction *MF = nullptr; 330 for (auto &F : *M) { 331 if (auto *MF4F = MMI->getMachineFunction(F)) { 332 // XXX: Maybe it would not be a lot of effort to handle multiple MFs by 333 // simply storing them in a ReducerWorkItem::SmallVector or similar. The 334 // single MF use-case seems a lot more common though so that will do for 335 // now. 336 assert(!MF && "Only single MF supported!"); 337 MF = MF4F; 338 } 339 } 340 assert(MF && "No MF found!"); 341 342 MMM->M = std::move(M); 343 MMM->MF = cloneMF(MF); 344 } else { 345 SMDiagnostic Err; 346 std::unique_ptr<Module> Result = parseIRFile(Filename, Err, Ctxt); 347 if (!Result) { 348 Err.print("llvm-reduce", errs()); 349 return std::unique_ptr<ReducerWorkItem>(); 350 } 351 MMM->M = std::move(Result); 352 } 353 if (verifyReducerWorkItem(*MMM, &errs())) { 354 errs() << "Error: " << Filename << " - input module is broken!\n"; 355 return std::unique_ptr<ReducerWorkItem>(); 356 } 357 return MMM; 358 } 359 360 std::unique_ptr<ReducerWorkItem> 361 cloneReducerWorkItem(const ReducerWorkItem &MMM) { 362 auto CloneMMM = std::make_unique<ReducerWorkItem>(); 363 if (MMM.MF) { 364 // Note that we cannot clone the Module as then we would need a way to 365 // updated the cloned MachineFunction's IR references. 366 // XXX: Actually have a look at 367 // std::unique_ptr<Module> CloneModule(const Module &M, ValueToValueMapTy 368 // &VMap); 369 CloneMMM->M = MMM.M; 370 CloneMMM->MF = cloneMF(MMM.MF.get()); 371 } else { 372 CloneMMM->M = CloneModule(*MMM.M); 373 } 374 return CloneMMM; 375 } 376 377 bool verifyReducerWorkItem(const ReducerWorkItem &MMM, raw_fd_ostream *OS) { 378 if (verifyModule(*MMM.M, OS)) 379 return true; 380 if (MMM.MF && !MMM.MF->verify(nullptr, "", /*AbortOnError=*/false)) 381 return true; 382 return false; 383 } 384 385 void ReducerWorkItem::print(raw_ostream &ROS, void *p) const { 386 if (MF) { 387 printMIR(ROS, *M); 388 printMIR(ROS, *MF); 389 } else { 390 M->print(ROS, /*AssemblyAnnotationWriter=*/nullptr, 391 /*ShouldPreserveUseListOrder=*/true); 392 } 393 } 394