1 //===- ReducerWorkItem.cpp - Wrapper for Module and MachineFunction -------===//
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
7 //===----------------------------------------------------------------------===//
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/MachineFunction.h"
14 #include "llvm/CodeGen/MachineFunctionPass.h"
15 #include "llvm/CodeGen/MachineRegisterInfo.h"
16 #include "llvm/CodeGen/TargetInstrInfo.h"
17 #include "llvm/IR/Verifier.h"
18 #include "llvm/IRReader/IRReader.h"
19 #include "llvm/Target/TargetMachine.h"
20 #include "llvm/Transforms/Utils/Cloning.h"
22 static std::unique_ptr
<MachineFunction
> cloneMF(MachineFunction
*SrcMF
) {
23 auto DstMF
= std::make_unique
<MachineFunction
>(
24 SrcMF
->getFunction(), SrcMF
->getTarget(), SrcMF
->getSubtarget(),
25 SrcMF
->getFunctionNumber(), SrcMF
->getMMI());
26 DenseMap
<MachineBasicBlock
*, MachineBasicBlock
*> Src2DstMBB
;
27 DenseMap
<Register
, Register
> Src2DstReg
;
29 auto *SrcMRI
= &SrcMF
->getRegInfo();
30 auto *DstMRI
= &DstMF
->getRegInfo();
33 for (auto &SrcMBB
: *SrcMF
) {
34 for (auto &SrcMI
: SrcMBB
) {
35 for (unsigned I
= 0, E
= SrcMI
.getNumOperands(); I
< E
; ++I
) {
36 auto &DMO
= SrcMI
.getOperand(I
);
37 if (!DMO
.isReg() || !DMO
.isDef())
39 Register SrcReg
= DMO
.getReg();
40 if (Register::isPhysicalRegister(SrcReg
))
42 auto SrcRC
= SrcMRI
->getRegClass(SrcReg
);
43 auto DstReg
= DstMRI
->createVirtualRegister(SrcRC
);
44 Src2DstReg
[SrcReg
] = DstReg
;
50 for (auto &SrcMBB
: *SrcMF
)
51 Src2DstMBB
[&SrcMBB
] = DstMF
->CreateMachineBasicBlock();
53 for (auto &SrcMBB
: *SrcMF
) {
54 auto *DstMBB
= Src2DstMBB
[&SrcMBB
];
55 DstMF
->push_back(DstMBB
);
56 for (auto It
= SrcMBB
.succ_begin(), IterEnd
= SrcMBB
.succ_end();
57 It
!= IterEnd
; ++It
) {
58 auto *SrcSuccMBB
= *It
;
59 auto *DstSuccMBB
= Src2DstMBB
[SrcSuccMBB
];
60 DstMBB
->addSuccessor(DstSuccMBB
);
62 for (auto &LI
: SrcMBB
.liveins())
63 DstMBB
->addLiveIn(LI
);
65 // Clone instructions.
66 for (auto &SrcMBB
: *SrcMF
) {
67 auto *DstMBB
= Src2DstMBB
[&SrcMBB
];
68 for (auto &SrcMI
: SrcMBB
) {
70 DstMF
->getSubtarget().getInstrInfo()->get(SrcMI
.getOpcode());
71 auto *DstMI
= DstMF
->CreateMachineInstr(MCID
, SrcMI
.getDebugLoc(),
73 DstMBB
->push_back(DstMI
);
74 for (auto &SrcMO
: SrcMI
.operands()) {
75 MachineOperand
DstMO(SrcMO
);
78 if (DstMO
.isReg() && Src2DstReg
.count(DstMO
.getReg())) {
79 DstMO
.setReg(Src2DstReg
[DstMO
.getReg()]);
83 DstMO
.setMBB(Src2DstMBB
[DstMO
.getMBB()]);
85 DstMI
->addOperand(DstMO
);
87 DstMI
->setMemRefs(*DstMF
, SrcMI
.memoperands());
91 DstMF
->verify(nullptr, "", /*AbortOnError=*/true);
95 std::unique_ptr
<ReducerWorkItem
> parseReducerWorkItem(StringRef Filename
,
97 MachineModuleInfo
*MMI
) {
98 auto MMM
= std::make_unique
<ReducerWorkItem
>();
100 auto FileOrErr
= MemoryBuffer::getFileOrSTDIN(Filename
, /*IsText=*/true);
101 std::unique_ptr
<MIRParser
> MParser
=
102 createMIRParser(std::move(FileOrErr
.get()), Ctxt
);
105 [&](StringRef DataLayoutTargetTriple
) -> Optional
<std::string
> {
106 return MMI
->getTarget().createDataLayout().getStringRepresentation();
109 std::unique_ptr
<Module
> M
= MParser
->parseIRModule(SetDataLayout
);
110 MParser
->parseMachineFunctions(*M
, *MMI
);
111 MachineFunction
*MF
= nullptr;
113 if (auto *MF4F
= MMI
->getMachineFunction(F
)) {
114 // XXX: Maybe it would not be a lot of effort to handle multiple MFs by
115 // simply storing them in a ReducerWorkItem::SmallVector or similar. The
116 // single MF use-case seems a lot more common though so that will do for
118 assert(!MF
&& "Only single MF supported!");
122 assert(MF
&& "No MF found!");
124 MMM
->M
= std::move(M
);
125 MMM
->MF
= cloneMF(MF
);
128 std::unique_ptr
<Module
> Result
= parseIRFile(Filename
, Err
, Ctxt
);
130 Err
.print("llvm-reduce", errs());
131 return std::unique_ptr
<ReducerWorkItem
>();
133 MMM
->M
= std::move(Result
);
135 if (verifyReducerWorkItem(*MMM
, &errs())) {
136 errs() << "Error: " << Filename
<< " - input module is broken!\n";
137 return std::unique_ptr
<ReducerWorkItem
>();
142 std::unique_ptr
<ReducerWorkItem
>
143 cloneReducerWorkItem(const ReducerWorkItem
&MMM
) {
144 auto CloneMMM
= std::make_unique
<ReducerWorkItem
>();
146 // Note that we cannot clone the Module as then we would need a way to
147 // updated the cloned MachineFunction's IR references.
148 // XXX: Actually have a look at
149 // std::unique_ptr<Module> CloneModule(const Module &M, ValueToValueMapTy
152 CloneMMM
->MF
= cloneMF(MMM
.MF
.get());
154 CloneMMM
->M
= CloneModule(*MMM
.M
);
159 bool verifyReducerWorkItem(const ReducerWorkItem
&MMM
, raw_fd_ostream
*OS
) {
160 if (verifyModule(*MMM
.M
, OS
))
162 if (MMM
.MF
&& !MMM
.MF
->verify(nullptr, "", /*AbortOnError=*/false))
167 void ReducerWorkItem::print(raw_ostream
&ROS
, void *p
) const {
172 M
->print(ROS
, nullptr);