annotate lib/Target/PowerPC/PPCExpandISEL.cpp @ 128:c347d3398279 default tip

fix
author mir3636
date Wed, 06 Dec 2017 14:37:17 +0900
parents 803732b1fca8
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
1 //===------------- PPCExpandISEL.cpp - Expand ISEL instruction ------------===//
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
2 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
3 // The LLVM Compiler Infrastructure
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
4 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
5 // This file is distributed under the University of Illinois Open Source
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
6 // License. See LICENSE.TXT for details.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
7 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
8 //===----------------------------------------------------------------------===//
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
9 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
10 // A pass that expands the ISEL instruction into an if-then-else sequence.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
11 // This pass must be run post-RA since all operands must be physical registers.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
12 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
13 //===----------------------------------------------------------------------===//
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
14
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
15 #include "PPC.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
16 #include "PPCInstrInfo.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
17 #include "PPCSubtarget.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
18 #include "llvm/ADT/DenseMap.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
19 #include "llvm/ADT/Statistic.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
20 #include "llvm/CodeGen/LivePhysRegs.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
21 #include "llvm/CodeGen/MachineFunctionPass.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
22 #include "llvm/CodeGen/MachineInstrBuilder.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
23 #include "llvm/CodeGen/MachineRegisterInfo.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
24 #include "llvm/Support/CommandLine.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
25 #include "llvm/Support/Debug.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
26 #include "llvm/Support/raw_ostream.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
27
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
28 using namespace llvm;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
29
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
30 #define DEBUG_TYPE "ppc-expand-isel"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
31
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
32 STATISTIC(NumExpanded, "Number of ISEL instructions expanded");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
33 STATISTIC(NumRemoved, "Number of ISEL instructions removed");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
34 STATISTIC(NumFolded, "Number of ISEL instructions folded");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
35
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
36 // If -ppc-gen-isel=false is set, we will disable generating the ISEL
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
37 // instruction on all PPC targets. Otherwise, if the user set option
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
38 // -misel or the platform supports ISEL by default, still generate the
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
39 // ISEL instruction, else expand it.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
40 static cl::opt<bool>
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
41 GenerateISEL("ppc-gen-isel",
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
42 cl::desc("Enable generating the ISEL instruction."),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
43 cl::init(true), cl::Hidden);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
44
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
45 namespace {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
46 class PPCExpandISEL : public MachineFunctionPass {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
47 DebugLoc dl;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
48 MachineFunction *MF;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
49 const TargetInstrInfo *TII;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
50 bool IsTrueBlockRequired;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
51 bool IsFalseBlockRequired;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
52 MachineBasicBlock *TrueBlock;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
53 MachineBasicBlock *FalseBlock;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
54 MachineBasicBlock *NewSuccessor;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
55 MachineBasicBlock::iterator TrueBlockI;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
56 MachineBasicBlock::iterator FalseBlockI;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
57
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
58 typedef SmallVector<MachineInstr *, 4> BlockISELList;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
59 typedef SmallDenseMap<int, BlockISELList> ISELInstructionList;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
60
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
61 // A map of MBB numbers to their lists of contained ISEL instructions.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
62 ISELInstructionList ISELInstructions;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
63
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
64 /// Initialize the object.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
65 void initialize(MachineFunction &MFParam);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
66
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
67 void handleSpecialCases(BlockISELList &BIL, MachineBasicBlock *MBB);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
68 void reorganizeBlockLayout(BlockISELList &BIL, MachineBasicBlock *MBB);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
69 void populateBlocks(BlockISELList &BIL);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
70 void expandMergeableISELs(BlockISELList &BIL);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
71 void expandAndMergeISELs();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
72
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
73 bool canMerge(MachineInstr *PrevPushedMI, MachineInstr *MI);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
74
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
75 /// Is this instruction an ISEL or ISEL8?
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
76 static bool isISEL(const MachineInstr &MI) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
77 return (MI.getOpcode() == PPC::ISEL || MI.getOpcode() == PPC::ISEL8);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
78 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
79
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
80 /// Is this instruction an ISEL8?
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
81 static bool isISEL8(const MachineInstr &MI) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
82 return (MI.getOpcode() == PPC::ISEL8);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
83 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
84
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
85 /// Are the two operands using the same register?
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
86 bool useSameRegister(const MachineOperand &Op1, const MachineOperand &Op2) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
87 return (Op1.getReg() == Op2.getReg());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
88 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
89
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
90 ///
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
91 /// Collect all ISEL instructions from the current function.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
92 ///
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
93 /// Walk the current function and collect all the ISEL instructions that are
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
94 /// found. The instructions are placed in the ISELInstructions vector.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
95 ///
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
96 /// \return true if any ISEL instructions were found, false otherwise
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
97 ///
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
98 bool collectISELInstructions();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
99
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
100 public:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
101 static char ID;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
102 PPCExpandISEL() : MachineFunctionPass(ID) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
103 initializePPCExpandISELPass(*PassRegistry::getPassRegistry());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
104 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
105
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
106 ///
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
107 /// Determine whether to generate the ISEL instruction or expand it.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
108 ///
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
109 /// Expand ISEL instruction into if-then-else sequence when one of
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
110 /// the following two conditions hold:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
111 /// (1) -ppc-gen-isel=false
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
112 /// (2) hasISEL() return false
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
113 /// Otherwise, still generate ISEL instruction.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
114 /// The -ppc-gen-isel option is set to true by default. Which means the ISEL
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
115 /// instruction is still generated by default on targets that support them.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
116 ///
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
117 /// \return true if ISEL should be expanded into if-then-else code sequence;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
118 /// false if ISEL instruction should be generated, i.e. not expaned.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
119 ///
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
120 static bool isExpandISELEnabled(const MachineFunction &MF);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
122 #ifndef NDEBUG
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
123 void DumpISELInstructions() const;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
124 #endif
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
125
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
126 bool runOnMachineFunction(MachineFunction &MF) override {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
127 if (!isExpandISELEnabled(MF))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
128 return false;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
129
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
130 DEBUG(dbgs() << "Function: "; MF.dump(); dbgs() << "\n");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
131 initialize(MF);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
132
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
133 if (!collectISELInstructions()) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
134 DEBUG(dbgs() << "No ISEL instructions in this function\n");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
135 return false;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
136 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
137
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
138 #ifndef NDEBUG
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
139 DumpISELInstructions();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
140 #endif
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
141
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
142 expandAndMergeISELs();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
143
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
144 return true;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
145 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
146 };
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
147 } // end anonymous namespace
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
148
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
149 void PPCExpandISEL::initialize(MachineFunction &MFParam) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
150 MF = &MFParam;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
151 TII = MF->getSubtarget().getInstrInfo();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
152 ISELInstructions.clear();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
153 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
154
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
155 bool PPCExpandISEL::isExpandISELEnabled(const MachineFunction &MF) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
156 return !GenerateISEL || !MF.getSubtarget<PPCSubtarget>().hasISEL();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
157 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
158
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
159 bool PPCExpandISEL::collectISELInstructions() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
160 for (MachineBasicBlock &MBB : *MF) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
161 BlockISELList thisBlockISELs;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
162 for (MachineInstr &MI : MBB)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
163 if (isISEL(MI))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
164 thisBlockISELs.push_back(&MI);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
165 if (!thisBlockISELs.empty())
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
166 ISELInstructions.insert(std::make_pair(MBB.getNumber(), thisBlockISELs));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
167 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
168 return !ISELInstructions.empty();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
169 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
170
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
171 #ifndef NDEBUG
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
172 void PPCExpandISEL::DumpISELInstructions() const {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
173 for (const auto &I : ISELInstructions) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
174 DEBUG(dbgs() << "BB#" << I.first << ":\n");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
175 for (const auto &VI : I.second)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
176 DEBUG(dbgs() << " "; VI->print(dbgs()));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
177 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
178 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
179 #endif
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
180
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
181 /// Contiguous ISELs that have the same condition can be merged.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
182 bool PPCExpandISEL::canMerge(MachineInstr *PrevPushedMI, MachineInstr *MI) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
183 // Same Condition Register?
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
184 if (!useSameRegister(PrevPushedMI->getOperand(3), MI->getOperand(3)))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
185 return false;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
186
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
187 MachineBasicBlock::iterator PrevPushedMBBI = *PrevPushedMI;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
188 MachineBasicBlock::iterator MBBI = *MI;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
189 return (std::prev(MBBI) == PrevPushedMBBI); // Contiguous ISELs?
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
190 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
191
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
192 void PPCExpandISEL::expandAndMergeISELs() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
193 for (auto &BlockList : ISELInstructions) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
194 DEBUG(dbgs() << "Expanding ISEL instructions in BB#" << BlockList.first
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
195 << "\n");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
196
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
197 BlockISELList &CurrentISELList = BlockList.second;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
198 auto I = CurrentISELList.begin();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
199 auto E = CurrentISELList.end();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
200
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
201 while (I != E) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
202 BlockISELList SubISELList;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
203
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
204 SubISELList.push_back(*I++);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
205
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
206 // Collect the ISELs that can be merged together.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
207 while (I != E && canMerge(SubISELList.back(), *I))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
208 SubISELList.push_back(*I++);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
209
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
210 expandMergeableISELs(SubISELList);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
211 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
212 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
213 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
214
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
215 void PPCExpandISEL::handleSpecialCases(BlockISELList &BIL,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
216 MachineBasicBlock *MBB) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
217 IsTrueBlockRequired = false;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
218 IsFalseBlockRequired = false;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
219
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
220 auto MI = BIL.begin();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
221 while (MI != BIL.end()) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
222 assert(isISEL(**MI) && "Expecting an ISEL instruction");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
223 DEBUG(dbgs() << "ISEL: " << **MI << "\n");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
224
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
225 MachineOperand &Dest = (*MI)->getOperand(0);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
226 MachineOperand &TrueValue = (*MI)->getOperand(1);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
227 MachineOperand &FalseValue = (*MI)->getOperand(2);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
228
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
229 // If at least one of the ISEL instructions satisfy the following
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
230 // condition, we need the True Block:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
231 // The Dest Register and True Value Register are not the same
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
232 // Similarly, if at least one of the ISEL instructions satisfy the
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
233 // following condition, we need the False Block:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
234 // The Dest Register and False Value Register are not the same.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
235
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
236 bool IsADDIInstRequired = !useSameRegister(Dest, TrueValue);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
237 bool IsORIInstRequired = !useSameRegister(Dest, FalseValue);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
238
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
239 // Special case 1, all registers used by ISEL are the same one.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
240 if (!IsADDIInstRequired && !IsORIInstRequired) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
241 DEBUG(dbgs() << "Remove redudant ISEL instruction.");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
242 NumRemoved++;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
243 (*MI)->eraseFromParent();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
244 // Setting MI to the erase result keeps the iterator valid and increased.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
245 MI = BIL.erase(MI);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
246 continue;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
247 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
248
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
249 // Special case 2, the two input registers used by ISEL are the same.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
250 // Note 1: We favor merging ISEL expansions over folding a single one. If
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
251 // the passed list has multiple merge-able ISEL's, we won't fold any.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
252 // Note 2: There is no need to test for PPC::R0/PPC::X0 because PPC::ZERO/
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
253 // PPC::ZERO8 will be used for the first operand if the value is meant to
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
254 // be zero. In this case, the useSameRegister method will return false,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
255 // thereby preventing this ISEL from being folded.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
256
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
257 if (useSameRegister(TrueValue, FalseValue) && (BIL.size() == 1)) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
258 DEBUG(dbgs() << "Fold the ISEL instruction to an unconditonal copy.");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
259 NumFolded++;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
260 BuildMI(*MBB, (*MI), dl, TII->get(isISEL8(**MI) ? PPC::ADDI8 : PPC::ADDI))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
261 .add(Dest)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
262 .add(TrueValue)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
263 .add(MachineOperand::CreateImm(0));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
264 (*MI)->eraseFromParent();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
265 // Setting MI to the erase result keeps the iterator valid and increased.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
266 MI = BIL.erase(MI);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
267 continue;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
268 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
269
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
270 IsTrueBlockRequired |= IsADDIInstRequired;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
271 IsFalseBlockRequired |= IsORIInstRequired;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
272 MI++;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
273 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
274 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
275
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
276 void PPCExpandISEL::reorganizeBlockLayout(BlockISELList &BIL,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
277 MachineBasicBlock *MBB) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
278 if (BIL.empty())
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
279 return;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
280
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
281 assert((IsTrueBlockRequired || IsFalseBlockRequired) &&
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
282 "Should have been handled by special cases earlier!");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
283
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
284 MachineBasicBlock *Successor = nullptr;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
285 const BasicBlock *LLVM_BB = MBB->getBasicBlock();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
286 MachineBasicBlock::iterator MBBI = (*BIL.back());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
287 NewSuccessor = (MBBI != MBB->getLastNonDebugInstr() || !MBB->canFallThrough())
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
288 // Another BB is needed to move the instructions that
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
289 // follow this ISEL. If the ISEL is the last instruction
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
290 // in a block that can't fall through, we also need a block
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
291 // to branch to.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
292 ? MF->CreateMachineBasicBlock(LLVM_BB)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
293 : nullptr;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
294
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
295 MachineFunction::iterator It = MBB->getIterator();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
296 ++It; // Point to the successor block of MBB.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
297
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
298 // If NewSuccessor is NULL then the last ISEL in this group is the last
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
299 // non-debug instruction in this block. Find the fall-through successor
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
300 // of this block to use when updating the CFG below.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
301 if (!NewSuccessor) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
302 for (auto &Succ : MBB->successors()) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
303 if (MBB->isLayoutSuccessor(Succ)) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
304 Successor = Succ;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
305 break;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
306 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
307 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
308 } else
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
309 Successor = NewSuccessor;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
310
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
311 // The FalseBlock and TrueBlock are inserted after the MBB block but before
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
312 // its successor.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
313 // Note this need to be done *after* the above setting the Successor code.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
314 if (IsFalseBlockRequired) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
315 FalseBlock = MF->CreateMachineBasicBlock(LLVM_BB);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
316 MF->insert(It, FalseBlock);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
317 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
318
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
319 if (IsTrueBlockRequired) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
320 TrueBlock = MF->CreateMachineBasicBlock(LLVM_BB);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
321 MF->insert(It, TrueBlock);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
322 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
323
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
324 if (NewSuccessor) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
325 MF->insert(It, NewSuccessor);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
326
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
327 // Transfer the rest of this block into the new successor block.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
328 NewSuccessor->splice(NewSuccessor->end(), MBB,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
329 std::next(MachineBasicBlock::iterator(BIL.back())),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
330 MBB->end());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
331 NewSuccessor->transferSuccessorsAndUpdatePHIs(MBB);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
332
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
333 // Copy the original liveIns of MBB to NewSuccessor.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
334 for (auto &LI : MBB->liveins())
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
335 NewSuccessor->addLiveIn(LI);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
336
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
337 // After splitting the NewSuccessor block, Regs defined but not killed
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
338 // in MBB should be treated as liveins of NewSuccessor.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
339 // Note: Cannot use stepBackward instead since we are using the Reg
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
340 // liveness state at the end of MBB (liveOut of MBB) as the liveIn for
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
341 // NewSuccessor. Otherwise, will cause cyclic dependence.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
342 LivePhysRegs LPR(*MF->getSubtarget<PPCSubtarget>().getRegisterInfo());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
343 SmallVector<std::pair<unsigned, const MachineOperand *>, 2> Clobbers;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
344 for (MachineInstr &MI : *MBB)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
345 LPR.stepForward(MI, Clobbers);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
346 for (auto &LI : LPR)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
347 NewSuccessor->addLiveIn(LI);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
348 } else {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
349 // Remove successor from MBB.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
350 MBB->removeSuccessor(Successor);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
351 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
352
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
353 // Note that this needs to be done *after* transfering the successors from MBB
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
354 // to the NewSuccessor block, otherwise these blocks will also be transferred
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
355 // as successors!
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
356 MBB->addSuccessor(IsTrueBlockRequired ? TrueBlock : Successor);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
357 MBB->addSuccessor(IsFalseBlockRequired ? FalseBlock : Successor);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
358
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
359 if (IsTrueBlockRequired) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
360 TrueBlockI = TrueBlock->begin();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
361 TrueBlock->addSuccessor(Successor);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
362 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
363
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
364 if (IsFalseBlockRequired) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
365 FalseBlockI = FalseBlock->begin();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
366 FalseBlock->addSuccessor(Successor);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
367 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
368
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
369 // Conditional branch to the TrueBlock or Successor
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
370 BuildMI(*MBB, BIL.back(), dl, TII->get(PPC::BC))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
371 .add(BIL.back()->getOperand(3))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
372 .addMBB(IsTrueBlockRequired ? TrueBlock : Successor);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
373
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
374 // Jump over the true block to the new successor if the condition is false.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
375 BuildMI(*(IsFalseBlockRequired ? FalseBlock : MBB),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
376 (IsFalseBlockRequired ? FalseBlockI : BIL.back()), dl,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
377 TII->get(PPC::B))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
378 .addMBB(Successor);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
379
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
380 if (IsFalseBlockRequired)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
381 FalseBlockI = FalseBlock->begin(); // get the position of PPC::B
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
382 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
383
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
384 void PPCExpandISEL::populateBlocks(BlockISELList &BIL) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
385 for (auto &MI : BIL) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
386 assert(isISEL(*MI) && "Expecting an ISEL instruction");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
387
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
388 MachineOperand &Dest = MI->getOperand(0); // location to store to
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
389 MachineOperand &TrueValue = MI->getOperand(1); // Value to store if
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
390 // condition is true
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
391 MachineOperand &FalseValue = MI->getOperand(2); // Value to store if
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
392 // condition is false
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
393 MachineOperand &ConditionRegister = MI->getOperand(3); // Condition
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
394
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
395 DEBUG(dbgs() << "Dest: " << Dest << "\n");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
396 DEBUG(dbgs() << "TrueValue: " << TrueValue << "\n");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
397 DEBUG(dbgs() << "FalseValue: " << FalseValue << "\n");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
398 DEBUG(dbgs() << "ConditionRegister: " << ConditionRegister << "\n");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
399
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
400
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
401 // If the Dest Register and True Value Register are not the same one, we
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
402 // need the True Block.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
403 bool IsADDIInstRequired = !useSameRegister(Dest, TrueValue);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
404 bool IsORIInstRequired = !useSameRegister(Dest, FalseValue);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
405
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
406 if (IsADDIInstRequired) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
407 // Copy the result into the destination if the condition is true.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
408 BuildMI(*TrueBlock, TrueBlockI, dl,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
409 TII->get(isISEL8(*MI) ? PPC::ADDI8 : PPC::ADDI))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
410 .add(Dest)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
411 .add(TrueValue)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
412 .add(MachineOperand::CreateImm(0));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
413
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
414 // Add the LiveIn registers required by true block.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
415 TrueBlock->addLiveIn(TrueValue.getReg());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
416 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
417
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
418 if (IsORIInstRequired) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
419 // Add the LiveIn registers required by false block.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
420 FalseBlock->addLiveIn(FalseValue.getReg());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
421 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
422
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
423 if (NewSuccessor) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
424 // Add the LiveIn registers required by NewSuccessor block.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
425 NewSuccessor->addLiveIn(Dest.getReg());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
426 NewSuccessor->addLiveIn(TrueValue.getReg());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
427 NewSuccessor->addLiveIn(FalseValue.getReg());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
428 NewSuccessor->addLiveIn(ConditionRegister.getReg());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
429 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
430
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
431 // Copy the value into the destination if the condition is false.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
432 if (IsORIInstRequired)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
433 BuildMI(*FalseBlock, FalseBlockI, dl,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
434 TII->get(isISEL8(*MI) ? PPC::ORI8 : PPC::ORI))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
435 .add(Dest)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
436 .add(FalseValue)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
437 .add(MachineOperand::CreateImm(0));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
438
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
439 MI->eraseFromParent(); // Remove the ISEL instruction.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
440
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
441 NumExpanded++;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
442 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
443 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
444
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
445 void PPCExpandISEL::expandMergeableISELs(BlockISELList &BIL) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
446 // At this stage all the ISELs of BIL are in the same MBB.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
447 MachineBasicBlock *MBB = BIL.back()->getParent();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
448
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
449 handleSpecialCases(BIL, MBB);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
450 reorganizeBlockLayout(BIL, MBB);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
451 populateBlocks(BIL);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
452 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
453
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
454 INITIALIZE_PASS(PPCExpandISEL, DEBUG_TYPE, "PowerPC Expand ISEL Generation",
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
455 false, false)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
456 char PPCExpandISEL::ID = 0;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
457
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
458 FunctionPass *llvm::createPPCExpandISELPass() { return new PPCExpandISEL(); }