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