llvm.org GIT mirror llvm / 35d2a47
Added Branch Analysis support Added InsertNoop support git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41153 91177308-0d34-0410-b5e6-96231b3b80d8 Bruno Cardoso Lopes 13 years ago
1 changed file(s) with 235 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
6666 unsigned MipsInstrInfo::
6767 isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const
6868 {
69 // TODO: add lhu, lbu ???
7069 if (MI->getOpcode() == Mips::LW)
7170 {
7271 if ((MI->getOperand(2).isFrameIndex()) && // is a stack slot
8988 unsigned MipsInstrInfo::
9089 isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const
9190 {
92 // TODO: add sb, sh ???
9391 if (MI->getOpcode() == Mips::SW) {
9492 if ((MI->getOperand(0).isFrameIndex()) && // is a stack slot
9593 (MI->getOperand(1).isImmediate()) && // the imm is zero
102100 return 0;
103101 }
104102
103 /// insertNoop - If data hazard condition is found insert the target nop
104 /// instruction.
105 void MipsInstrInfo::
106 insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const
107 {
108 BuildMI(MBB, MI, get(Mips::NOP));
109 }
110
111 //===----------------------------------------------------------------------===//
112 // Branch Analysis
113 //===----------------------------------------------------------------------===//
114
115 /// GetCondFromBranchOpc - Return the Mips CC that matches
116 /// the correspondent Branch instruction opcode.
117 static Mips::CondCode GetCondFromBranchOpc(unsigned BrOpc)
118 {
119 switch (BrOpc) {
120 default: return Mips::COND_INVALID;
121 case Mips::BEQ : return Mips::COND_E;
122 case Mips::BNE : return Mips::COND_NE;
123 case Mips::BGTZ : return Mips::COND_GZ;
124 case Mips::BGEZ : return Mips::COND_GEZ;
125 case Mips::BLTZ : return Mips::COND_LZ;
126 case Mips::BLEZ : return Mips::COND_LEZ;
127 }
128 }
129
130 /// GetCondBranchFromCond - Return the Branch instruction
131 /// opcode that matches the cc.
132 unsigned Mips::GetCondBranchFromCond(Mips::CondCode CC)
133 {
134 switch (CC) {
135 default: assert(0 && "Illegal condition code!");
136 case Mips::COND_E : return Mips::BEQ;
137 case Mips::COND_NE : return Mips::BNE;
138 case Mips::COND_GZ : return Mips::BGTZ;
139 case Mips::COND_GEZ : return Mips::BGEZ;
140 case Mips::COND_LZ : return Mips::BLTZ;
141 case Mips::COND_LEZ : return Mips::BLEZ;
142 }
143 }
144
145 /// GetOppositeBranchCondition - Return the inverse of the specified
146 /// condition, e.g. turning COND_E to COND_NE.
147 Mips::CondCode Mips::GetOppositeBranchCondition(Mips::CondCode CC)
148 {
149 switch (CC) {
150 default: assert(0 && "Illegal condition code!");
151 case Mips::COND_E : return Mips::COND_NE;
152 case Mips::COND_NE : return Mips::COND_E;
153 case Mips::COND_GZ : return Mips::COND_LEZ;
154 case Mips::COND_GEZ : return Mips::COND_LZ;
155 case Mips::COND_LZ : return Mips::COND_GEZ;
156 case Mips::COND_LEZ : return Mips::COND_GZ;
157 }
158 }
159
160 bool MipsInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
161 MachineBasicBlock *&TBB,
162 MachineBasicBlock *&FBB,
163 std::vector &Cond) const
164 {
165 // If the block has no terminators, it just falls into the block after it.
166 MachineBasicBlock::iterator I = MBB.end();
167 if (I == MBB.begin() || !isUnpredicatedTerminator(--I))
168 return false;
169
170 // Get the last instruction in the block.
171 MachineInstr *LastInst = I;
172
173 // If there is only one terminator instruction, process it.
174 unsigned LastOpc = LastInst->getOpcode();
175 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
176 if (!isBranch(LastInst->getOpcode()))
177 return true;
178
179 // Unconditional branch
180 if (LastOpc == Mips::J) {
181 TBB = LastInst->getOperand(0).getMachineBasicBlock();
182 return false;
183 }
184
185 Mips::CondCode BranchCode = GetCondFromBranchOpc(LastInst->getOpcode());
186 if (BranchCode == Mips::COND_INVALID)
187 return true; // Can't handle indirect branch.
188
189 // Conditional branch
190 // Block ends with fall-through condbranch.
191 if (LastOpc != Mips::COND_INVALID) {
192 int LastNumOp = LastInst->getNumOperands();
193
194 TBB = LastInst->getOperand(LastNumOp-1).getMachineBasicBlock();
195 Cond.push_back(MachineOperand::CreateImm(BranchCode));
196
197 for (int i=0; i
198 Cond.push_back(LastInst->getOperand(i));
199 }
200
201 return false;
202 }
203 }
204
205 // Get the instruction before it if it is a terminator.
206 MachineInstr *SecondLastInst = I;
207
208 // If there are three terminators, we don't know what sort of block this is.
209 if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I))
210 return true;
211
212 // If the block ends with Mips::J and a Mips::BNE/Mips::BEQ, handle it.
213 unsigned SecondLastOpc = SecondLastInst->getOpcode();
214 Mips::CondCode BranchCode = GetCondFromBranchOpc(SecondLastOpc);
215
216 if (SecondLastOpc != Mips::COND_INVALID && LastOpc == Mips::J) {
217 int SecondNumOp = SecondLastInst->getNumOperands();
218
219 TBB = SecondLastInst->getOperand(SecondNumOp-1).getMachineBasicBlock();
220 Cond.push_back(MachineOperand::CreateImm(BranchCode));
221
222 for (int i=0; i
223 Cond.push_back(SecondLastInst->getOperand(i));
224 }
225
226 FBB = LastInst->getOperand(0).getMachineBasicBlock();
227 return false;
228 }
229
230 // If the block ends with two unconditional branches, handle it. The last
231 // one is not executed, so remove it.
232 if ((SecondLastOpc == Mips::J) && (LastOpc == Mips::J)) {
233 TBB = SecondLastInst->getOperand(0).getMachineBasicBlock();
234 I = LastInst;
235 I->eraseFromParent();
236 return false;
237 }
238
239 // Otherwise, can't handle this.
240 return true;
241 }
242
105243 unsigned MipsInstrInfo::
106244 InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
107245 MachineBasicBlock *FBB, const std::vector &Cond)
108246 const
109247 {
110 // TODO: add Mips::J here.
111 assert(0 && "Cant handle any kind of branches!");
112 return 1;
113 }
248 // Shouldn't be a fall through.
249 assert(TBB && "InsertBranch must not be told to insert a fallthrough");
250 assert((Cond.size() == 3 || Cond.size() == 2 || Cond.size() == 0) &&
251 "Mips branch conditions can have two|three components!");
252
253 if (FBB == 0) { // One way branch.
254 if (Cond.empty()) {
255 // Unconditional branch?
256 BuildMI(&MBB, get(Mips::J)).addMBB(TBB);
257 } else {
258 // Conditional branch.
259 unsigned Opc = GetCondBranchFromCond((Mips::CondCode)Cond[0].getImm());
260 const TargetInstrDescriptor &TID = get(Opc);
261
262 if (TID.numOperands == 3)
263 BuildMI(&MBB, TID).addReg(Cond[1].getReg())
264 .addReg(Cond[2].getReg())
265 .addMBB(TBB);
266 else
267 BuildMI(&MBB, TID).addReg(Cond[1].getReg())
268 .addMBB(TBB);
269
270 }
271 return 1;
272 }
273
274 // Two-way Conditional branch.
275 unsigned Opc = GetCondBranchFromCond((Mips::CondCode)Cond[0].getImm());
276 const TargetInstrDescriptor &TID = get(Opc);
277
278 if (TID.numOperands == 3)
279 BuildMI(&MBB, TID).addReg(Cond[1].getReg())
280 .addReg(Cond[2].getReg())
281 .addMBB(TBB);
282 else
283 BuildMI(&MBB, TID).addReg(Cond[1].getReg())
284 .addMBB(TBB);
285
286 BuildMI(&MBB, get(Mips::J)).addMBB(FBB);
287 return 2;
288 }
289
290 unsigned MipsInstrInfo::
291 RemoveBranch(MachineBasicBlock &MBB) const
292 {
293 MachineBasicBlock::iterator I = MBB.end();
294 if (I == MBB.begin()) return 0;
295 --I;
296 if (I->getOpcode() != Mips::J &&
297 GetCondFromBranchOpc(I->getOpcode()) == Mips::COND_INVALID)
298 return 0;
299
300 // Remove the branch.
301 I->eraseFromParent();
302
303 I = MBB.end();
304
305 if (I == MBB.begin()) return 1;
306 --I;
307 if (GetCondFromBranchOpc(I->getOpcode()) == Mips::COND_INVALID)
308 return 1;
309
310 // Remove the branch.
311 I->eraseFromParent();
312 return 2;
313 }
314
315 /// BlockHasNoFallThrough - Analyse if MachineBasicBlock does not
316 /// fall-through into its successor block.
317 bool MipsInstrInfo::
318 BlockHasNoFallThrough(MachineBasicBlock &MBB) const
319 {
320 if (MBB.empty()) return false;
321
322 switch (MBB.back().getOpcode()) {
323 case Mips::RET: // Return.
324 case Mips::JR: // Indirect branch.
325 case Mips::J: // Uncond branch.
326 return true;
327 default: return false;
328 }
329 }
330
331 /// ReverseBranchCondition - Return the inverse opcode of the
332 /// specified Branch instruction.
333 bool MipsInstrInfo::
334 ReverseBranchCondition(std::vector &Cond) const
335 {
336 assert( (Cond.size() == 3 || Cond.size() == 2) &&
337 "Invalid Mips branch condition!");
338 Cond[0].setImm(GetOppositeBranchCondition((Mips::CondCode)Cond[0].getImm()));
339 return false;
340 }
341
342