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