LLVM 20.0.0git
LanaiInstrInfo.cpp
Go to the documentation of this file.
1//===-- LanaiInstrInfo.cpp - Lanai Instruction Information ------*- C++ -*-===//
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// This file contains the Lanai implementation of the TargetInstrInfo class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "LanaiInstrInfo.h"
14#include "LanaiAluCode.h"
15#include "LanaiCondCode.h"
17#include "llvm/ADT/STLExtras.h"
22
23using namespace llvm;
24
25#define GET_INSTRINFO_CTOR_DTOR
26#include "LanaiGenInstrInfo.inc"
27
29 : LanaiGenInstrInfo(Lanai::ADJCALLSTACKDOWN, Lanai::ADJCALLSTACKUP),
30 RegisterInfo() {}
31
34 const DebugLoc &DL,
35 MCRegister DestinationRegister,
36 MCRegister SourceRegister, bool KillSource,
37 bool RenamableDest, bool RenamableSrc) const {
38 if (!Lanai::GPRRegClass.contains(DestinationRegister, SourceRegister)) {
39 llvm_unreachable("Impossible reg-to-reg copy");
40 }
41
42 BuildMI(MBB, Position, DL, get(Lanai::OR_I_LO), DestinationRegister)
43 .addReg(SourceRegister, getKillRegState(KillSource))
44 .addImm(0);
45}
46
49 Register SourceRegister, bool IsKill, int FrameIndex,
50 const TargetRegisterClass *RegisterClass,
51 const TargetRegisterInfo * /*RegisterInfo*/, Register /*VReg*/) const {
53 if (Position != MBB.end()) {
54 DL = Position->getDebugLoc();
55 }
56
57 if (!Lanai::GPRRegClass.hasSubClassEq(RegisterClass)) {
58 llvm_unreachable("Can't store this register to stack slot");
59 }
60 BuildMI(MBB, Position, DL, get(Lanai::SW_RI))
61 .addReg(SourceRegister, getKillRegState(IsKill))
62 .addFrameIndex(FrameIndex)
63 .addImm(0)
65}
66
69 Register DestinationRegister, int FrameIndex,
70 const TargetRegisterClass *RegisterClass,
71 const TargetRegisterInfo * /*RegisterInfo*/, Register /*VReg*/) const {
73 if (Position != MBB.end()) {
74 DL = Position->getDebugLoc();
75 }
76
77 if (!Lanai::GPRRegClass.hasSubClassEq(RegisterClass)) {
78 llvm_unreachable("Can't load this register from stack slot");
79 }
80 BuildMI(MBB, Position, DL, get(Lanai::LDW_RI), DestinationRegister)
81 .addFrameIndex(FrameIndex)
82 .addImm(0)
84}
85
87 const MachineInstr &MIa, const MachineInstr &MIb) const {
88 assert(MIa.mayLoadOrStore() && "MIa must be a load or store.");
89 assert(MIb.mayLoadOrStore() && "MIb must be a load or store.");
90
93 return false;
94
95 // Retrieve the base register, offset from the base register and width. Width
96 // is the size of memory that is being loaded/stored (e.g. 1, 2, 4). If
97 // base registers are identical, and the offset of a lower memory access +
98 // the width doesn't overlap the offset of a higher memory access,
99 // then the memory accesses are different.
101 const MachineOperand *BaseOpA = nullptr, *BaseOpB = nullptr;
102 int64_t OffsetA = 0, OffsetB = 0;
103 LocationSize WidthA = 0, WidthB = 0;
104 if (getMemOperandWithOffsetWidth(MIa, BaseOpA, OffsetA, WidthA, TRI) &&
105 getMemOperandWithOffsetWidth(MIb, BaseOpB, OffsetB, WidthB, TRI)) {
106 if (BaseOpA->isIdenticalTo(*BaseOpB)) {
107 int LowOffset = std::min(OffsetA, OffsetB);
108 int HighOffset = std::max(OffsetA, OffsetB);
109 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
110 if (LowWidth.hasValue() &&
111 LowOffset + (int)LowWidth.getValue() <= HighOffset)
112 return true;
113 }
114 }
115 return false;
116}
117
119 return false;
120}
121
123 switch (CC) {
124 case LPCC::ICC_T: // true
125 return LPCC::ICC_F;
126 case LPCC::ICC_F: // false
127 return LPCC::ICC_T;
128 case LPCC::ICC_HI: // high
129 return LPCC::ICC_LS;
130 case LPCC::ICC_LS: // low or same
131 return LPCC::ICC_HI;
132 case LPCC::ICC_CC: // carry cleared
133 return LPCC::ICC_CS;
134 case LPCC::ICC_CS: // carry set
135 return LPCC::ICC_CC;
136 case LPCC::ICC_NE: // not equal
137 return LPCC::ICC_EQ;
138 case LPCC::ICC_EQ: // equal
139 return LPCC::ICC_NE;
140 case LPCC::ICC_VC: // oVerflow cleared
141 return LPCC::ICC_VS;
142 case LPCC::ICC_VS: // oVerflow set
143 return LPCC::ICC_VC;
144 case LPCC::ICC_PL: // plus (note: 0 is "minus" too here)
145 return LPCC::ICC_MI;
146 case LPCC::ICC_MI: // minus
147 return LPCC::ICC_PL;
148 case LPCC::ICC_GE: // greater than or equal
149 return LPCC::ICC_LT;
150 case LPCC::ICC_LT: // less than
151 return LPCC::ICC_GE;
152 case LPCC::ICC_GT: // greater than
153 return LPCC::ICC_LE;
154 case LPCC::ICC_LE: // less than or equal
155 return LPCC::ICC_GT;
156 default:
157 llvm_unreachable("Invalid condtional code");
158 }
159}
160
161std::pair<unsigned, unsigned>
163 return std::make_pair(TF, 0u);
164}
165
168 using namespace LanaiII;
169 static const std::pair<unsigned, const char *> TargetFlags[] = {
170 {MO_ABS_HI, "lanai-hi"},
171 {MO_ABS_LO, "lanai-lo"},
172 {MO_NO_FLAG, "lanai-nf"}};
173 return ArrayRef(TargetFlags);
174}
175
177 Register &SrcReg2, int64_t &CmpMask,
178 int64_t &CmpValue) const {
179 switch (MI.getOpcode()) {
180 default:
181 break;
182 case Lanai::SFSUB_F_RI_LO:
183 case Lanai::SFSUB_F_RI_HI:
184 SrcReg = MI.getOperand(0).getReg();
185 SrcReg2 = Register();
186 CmpMask = ~0;
187 CmpValue = MI.getOperand(1).getImm();
188 return true;
189 case Lanai::SFSUB_F_RR:
190 SrcReg = MI.getOperand(0).getReg();
191 SrcReg2 = MI.getOperand(1).getReg();
192 CmpMask = ~0;
193 CmpValue = 0;
194 return true;
195 }
196
197 return false;
198}
199
200// isRedundantFlagInstr - check whether the first instruction, whose only
201// purpose is to update flags, can be made redundant.
202// * SFSUB_F_RR can be made redundant by SUB_RI if the operands are the same.
203// * SFSUB_F_RI can be made redundant by SUB_I if the operands are the same.
204inline static bool isRedundantFlagInstr(MachineInstr *CmpI, unsigned SrcReg,
205 unsigned SrcReg2, int64_t ImmValue,
206 MachineInstr *OI) {
207 if (CmpI->getOpcode() == Lanai::SFSUB_F_RR &&
208 OI->getOpcode() == Lanai::SUB_R &&
209 ((OI->getOperand(1).getReg() == SrcReg &&
210 OI->getOperand(2).getReg() == SrcReg2) ||
211 (OI->getOperand(1).getReg() == SrcReg2 &&
212 OI->getOperand(2).getReg() == SrcReg)))
213 return true;
214
215 if (((CmpI->getOpcode() == Lanai::SFSUB_F_RI_LO &&
216 OI->getOpcode() == Lanai::SUB_I_LO) ||
217 (CmpI->getOpcode() == Lanai::SFSUB_F_RI_HI &&
218 OI->getOpcode() == Lanai::SUB_I_HI)) &&
219 OI->getOperand(1).getReg() == SrcReg &&
220 OI->getOperand(2).getImm() == ImmValue)
221 return true;
222 return false;
223}
224
225inline static unsigned flagSettingOpcodeVariant(unsigned OldOpcode) {
226 switch (OldOpcode) {
227 case Lanai::ADD_I_HI:
228 return Lanai::ADD_F_I_HI;
229 case Lanai::ADD_I_LO:
230 return Lanai::ADD_F_I_LO;
231 case Lanai::ADD_R:
232 return Lanai::ADD_F_R;
233 case Lanai::ADDC_I_HI:
234 return Lanai::ADDC_F_I_HI;
235 case Lanai::ADDC_I_LO:
236 return Lanai::ADDC_F_I_LO;
237 case Lanai::ADDC_R:
238 return Lanai::ADDC_F_R;
239 case Lanai::AND_I_HI:
240 return Lanai::AND_F_I_HI;
241 case Lanai::AND_I_LO:
242 return Lanai::AND_F_I_LO;
243 case Lanai::AND_R:
244 return Lanai::AND_F_R;
245 case Lanai::OR_I_HI:
246 return Lanai::OR_F_I_HI;
247 case Lanai::OR_I_LO:
248 return Lanai::OR_F_I_LO;
249 case Lanai::OR_R:
250 return Lanai::OR_F_R;
251 case Lanai::SL_I:
252 return Lanai::SL_F_I;
253 case Lanai::SRL_R:
254 return Lanai::SRL_F_R;
255 case Lanai::SA_I:
256 return Lanai::SA_F_I;
257 case Lanai::SRA_R:
258 return Lanai::SRA_F_R;
259 case Lanai::SUB_I_HI:
260 return Lanai::SUB_F_I_HI;
261 case Lanai::SUB_I_LO:
262 return Lanai::SUB_F_I_LO;
263 case Lanai::SUB_R:
264 return Lanai::SUB_F_R;
265 case Lanai::SUBB_I_HI:
266 return Lanai::SUBB_F_I_HI;
267 case Lanai::SUBB_I_LO:
268 return Lanai::SUBB_F_I_LO;
269 case Lanai::SUBB_R:
270 return Lanai::SUBB_F_R;
271 case Lanai::XOR_I_HI:
272 return Lanai::XOR_F_I_HI;
273 case Lanai::XOR_I_LO:
274 return Lanai::XOR_F_I_LO;
275 case Lanai::XOR_R:
276 return Lanai::XOR_F_R;
277 default:
278 return Lanai::NOP;
279 }
280}
281
283 MachineInstr &CmpInstr, Register SrcReg, Register SrcReg2,
284 int64_t /*CmpMask*/, int64_t CmpValue,
285 const MachineRegisterInfo *MRI) const {
286 // Get the unique definition of SrcReg.
287 MachineInstr *MI = MRI->getUniqueVRegDef(SrcReg);
288 if (!MI)
289 return false;
290
291 // Get ready to iterate backward from CmpInstr.
292 MachineBasicBlock::iterator I = CmpInstr, E = MI,
293 B = CmpInstr.getParent()->begin();
294
295 // Early exit if CmpInstr is at the beginning of the BB.
296 if (I == B)
297 return false;
298
299 // There are two possible candidates which can be changed to set SR:
300 // One is MI, the other is a SUB instruction.
301 // * For SFSUB_F_RR(r1,r2), we are looking for SUB(r1,r2) or SUB(r2,r1).
302 // * For SFSUB_F_RI(r1, CmpValue), we are looking for SUB(r1, CmpValue).
303 MachineInstr *Sub = nullptr;
304 if (SrcReg2 != 0)
305 // MI is not a candidate to transform into a flag setting instruction.
306 MI = nullptr;
307 else if (MI->getParent() != CmpInstr.getParent() || CmpValue != 0) {
308 // Conservatively refuse to convert an instruction which isn't in the same
309 // BB as the comparison. Don't return if SFSUB_F_RI and CmpValue != 0 as Sub
310 // may still be a candidate.
311 if (CmpInstr.getOpcode() == Lanai::SFSUB_F_RI_LO)
312 MI = nullptr;
313 else
314 return false;
315 }
316
317 // Check that SR isn't set between the comparison instruction and the
318 // instruction we want to change while searching for Sub.
320 for (--I; I != E; --I) {
321 const MachineInstr &Instr = *I;
322
323 if (Instr.modifiesRegister(Lanai::SR, TRI) ||
324 Instr.readsRegister(Lanai::SR, TRI))
325 // This instruction modifies or uses SR after the one we want to change.
326 // We can't do this transformation.
327 return false;
328
329 // Check whether CmpInstr can be made redundant by the current instruction.
330 if (isRedundantFlagInstr(&CmpInstr, SrcReg, SrcReg2, CmpValue, &*I)) {
331 Sub = &*I;
332 break;
333 }
334
335 // Don't search outside the containing basic block.
336 if (I == B)
337 return false;
338 }
339
340 // Return false if no candidates exist.
341 if (!MI && !Sub)
342 return false;
343
344 // The single candidate is called MI.
345 if (!MI)
346 MI = Sub;
347
348 if (flagSettingOpcodeVariant(MI->getOpcode()) != Lanai::NOP) {
349 bool isSafe = false;
350
352 OperandsToUpdate;
353 I = CmpInstr;
354 E = CmpInstr.getParent()->end();
355 while (!isSafe && ++I != E) {
356 const MachineInstr &Instr = *I;
357 for (unsigned IO = 0, EO = Instr.getNumOperands(); !isSafe && IO != EO;
358 ++IO) {
359 const MachineOperand &MO = Instr.getOperand(IO);
360 if (MO.isRegMask() && MO.clobbersPhysReg(Lanai::SR)) {
361 isSafe = true;
362 break;
363 }
364 if (!MO.isReg() || MO.getReg() != Lanai::SR)
365 continue;
366 if (MO.isDef()) {
367 isSafe = true;
368 break;
369 }
370 // Condition code is after the operand before SR.
372 CC = (LPCC::CondCode)Instr.getOperand(IO - 1).getImm();
373
374 if (Sub) {
376 if (NewCC == LPCC::ICC_T)
377 return false;
378 // If we have SUB(r1, r2) and CMP(r2, r1), the condition code based on
379 // CMP needs to be updated to be based on SUB. Push the condition
380 // code operands to OperandsToUpdate. If it is safe to remove
381 // CmpInstr, the condition code of these operands will be modified.
382 if (SrcReg2 != 0 && Sub->getOperand(1).getReg() == SrcReg2 &&
383 Sub->getOperand(2).getReg() == SrcReg) {
384 OperandsToUpdate.push_back(
385 std::make_pair(&((*I).getOperand(IO - 1)), NewCC));
386 }
387 } else {
388 // No Sub, so this is x = <op> y, z; cmp x, 0.
389 switch (CC) {
390 case LPCC::ICC_EQ: // Z
391 case LPCC::ICC_NE: // Z
392 case LPCC::ICC_MI: // N
393 case LPCC::ICC_PL: // N
394 case LPCC::ICC_F: // none
395 case LPCC::ICC_T: // none
396 // SR can be used multiple times, we should continue.
397 break;
398 case LPCC::ICC_CS: // C
399 case LPCC::ICC_CC: // C
400 case LPCC::ICC_VS: // V
401 case LPCC::ICC_VC: // V
402 case LPCC::ICC_HI: // C Z
403 case LPCC::ICC_LS: // C Z
404 case LPCC::ICC_GE: // N V
405 case LPCC::ICC_LT: // N V
406 case LPCC::ICC_GT: // Z N V
407 case LPCC::ICC_LE: // Z N V
408 // The instruction uses the V bit or C bit which is not safe.
409 return false;
410 case LPCC::UNKNOWN:
411 return false;
412 }
413 }
414 }
415 }
416
417 // If SR is not killed nor re-defined, we should check whether it is
418 // live-out. If it is live-out, do not optimize.
419 if (!isSafe) {
420 MachineBasicBlock *MBB = CmpInstr.getParent();
421 for (const MachineBasicBlock *Succ : MBB->successors())
422 if (Succ->isLiveIn(Lanai::SR))
423 return false;
424 }
425
426 // Toggle the optional operand to SR.
427 MI->setDesc(get(flagSettingOpcodeVariant(MI->getOpcode())));
428 MI->addRegisterDefined(Lanai::SR);
429 CmpInstr.eraseFromParent();
430 return true;
431 }
432
433 return false;
434}
435
438 unsigned &TrueOp, unsigned &FalseOp,
439 bool &Optimizable) const {
440 assert(MI.getOpcode() == Lanai::SELECT && "unknown select instruction");
441 // Select operands:
442 // 0: Def.
443 // 1: True use.
444 // 2: False use.
445 // 3: Condition code.
446 TrueOp = 1;
447 FalseOp = 2;
448 Cond.push_back(MI.getOperand(3));
449 Optimizable = true;
450 return false;
451}
452
453// Identify instructions that can be folded into a SELECT instruction, and
454// return the defining instruction.
456 const MachineRegisterInfo &MRI) {
457 if (!Reg.isVirtual())
458 return nullptr;
459 if (!MRI.hasOneNonDBGUse(Reg))
460 return nullptr;
461 MachineInstr *MI = MRI.getVRegDef(Reg);
462 if (!MI)
463 return nullptr;
464 // MI is folded into the SELECT by predicating it.
465 if (!MI->isPredicable())
466 return nullptr;
467 // Check if MI has any non-dead defs or physreg uses. This also detects
468 // predicated instructions which will be reading SR.
469 for (const MachineOperand &MO : llvm::drop_begin(MI->operands(), 1)) {
470 // Reject frame index operands.
471 if (MO.isFI() || MO.isCPI() || MO.isJTI())
472 return nullptr;
473 if (!MO.isReg())
474 continue;
475 // MI can't have any tied operands, that would conflict with predication.
476 if (MO.isTied())
477 return nullptr;
478 if (MO.getReg().isPhysical())
479 return nullptr;
480 if (MO.isDef() && !MO.isDead())
481 return nullptr;
482 }
483 bool DontMoveAcrossStores = true;
484 if (!MI->isSafeToMove(DontMoveAcrossStores))
485 return nullptr;
486 return MI;
487}
488
492 bool /*PreferFalse*/) const {
493 assert(MI.getOpcode() == Lanai::SELECT && "unknown select instruction");
494 MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
495 MachineInstr *DefMI = canFoldIntoSelect(MI.getOperand(1).getReg(), MRI);
496 bool Invert = !DefMI;
497 if (!DefMI)
498 DefMI = canFoldIntoSelect(MI.getOperand(2).getReg(), MRI);
499 if (!DefMI)
500 return nullptr;
501
502 // Find new register class to use.
503 MachineOperand FalseReg = MI.getOperand(Invert ? 1 : 2);
504 Register DestReg = MI.getOperand(0).getReg();
505 const TargetRegisterClass *PreviousClass = MRI.getRegClass(FalseReg.getReg());
506 if (!MRI.constrainRegClass(DestReg, PreviousClass))
507 return nullptr;
508
509 // Create a new predicated version of DefMI.
510 MachineInstrBuilder NewMI =
511 BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), DefMI->getDesc(), DestReg);
512
513 // Copy all the DefMI operands, excluding its (null) predicate.
514 const MCInstrDesc &DefDesc = DefMI->getDesc();
515 for (unsigned i = 1, e = DefDesc.getNumOperands();
516 i != e && !DefDesc.operands()[i].isPredicate(); ++i)
517 NewMI.add(DefMI->getOperand(i));
518
519 unsigned CondCode = MI.getOperand(3).getImm();
520 if (Invert)
522 else
523 NewMI.addImm(CondCode);
524 NewMI.copyImplicitOps(MI);
525
526 // The output register value when the predicate is false is an implicit
527 // register operand tied to the first def. The tie makes the register
528 // allocator ensure the FalseReg is allocated the same register as operand 0.
529 FalseReg.setImplicit();
530 NewMI.add(FalseReg);
531 NewMI->tieOperands(0, NewMI->getNumOperands() - 1);
532
533 // Update SeenMIs set: register newly created MI and erase removed DefMI.
534 SeenMIs.insert(NewMI);
535 SeenMIs.erase(DefMI);
536
537 // If MI is inside a loop, and DefMI is outside the loop, then kill flags on
538 // DefMI would be invalid when transferred inside the loop. Checking for a
539 // loop is expensive, but at least remove kill flags if they are in different
540 // BBs.
541 if (DefMI->getParent() != MI.getParent())
542 NewMI->clearKillInfo();
543
544 // The caller will erase MI, but not DefMI.
546 return NewMI;
547}
548
549// The analyzeBranch function is used to examine conditional instructions and
550// remove unnecessary instructions. This method is used by BranchFolder and
551// IfConverter machine function passes to improve the CFG.
552// - TrueBlock is set to the destination if condition evaluates true (it is the
553// nullptr if the destination is the fall-through branch);
554// - FalseBlock is set to the destination if condition evaluates to false (it
555// is the nullptr if the branch is unconditional);
556// - condition is populated with machine operands needed to generate the branch
557// to insert in insertBranch;
558// Returns: false if branch could successfully be analyzed.
560 MachineBasicBlock *&TrueBlock,
561 MachineBasicBlock *&FalseBlock,
563 bool AllowModify) const {
564 // Iterator to current instruction being considered.
566
567 // Start from the bottom of the block and work up, examining the
568 // terminator instructions.
569 while (Instruction != MBB.begin()) {
570 --Instruction;
571
572 // Skip over debug instructions.
573 if (Instruction->isDebugInstr())
574 continue;
575
576 // Working from the bottom, when we see a non-terminator
577 // instruction, we're done.
578 if (!isUnpredicatedTerminator(*Instruction))
579 break;
580
581 // A terminator that isn't a branch can't easily be handled
582 // by this analysis.
583 if (!Instruction->isBranch())
584 return true;
585
586 // Handle unconditional branches.
587 if (Instruction->getOpcode() == Lanai::BT) {
588 if (!AllowModify) {
589 TrueBlock = Instruction->getOperand(0).getMBB();
590 continue;
591 }
592
593 // If the block has any instructions after a branch, delete them.
594 MBB.erase(std::next(Instruction), MBB.end());
595
596 Condition.clear();
597 FalseBlock = nullptr;
598
599 // Delete the jump if it's equivalent to a fall-through.
600 if (MBB.isLayoutSuccessor(Instruction->getOperand(0).getMBB())) {
601 TrueBlock = nullptr;
603 Instruction = MBB.end();
604 continue;
605 }
606
607 // TrueBlock is used to indicate the unconditional destination.
608 TrueBlock = Instruction->getOperand(0).getMBB();
609 continue;
610 }
611
612 // Handle conditional branches
613 unsigned Opcode = Instruction->getOpcode();
614 if (Opcode != Lanai::BRCC)
615 return true; // Unknown opcode.
616
617 // Multiple conditional branches are not handled here so only proceed if
618 // there are no conditions enqueued.
619 if (Condition.empty()) {
620 LPCC::CondCode BranchCond =
621 static_cast<LPCC::CondCode>(Instruction->getOperand(1).getImm());
622
623 // TrueBlock is the target of the previously seen unconditional branch.
624 FalseBlock = TrueBlock;
625 TrueBlock = Instruction->getOperand(0).getMBB();
626 Condition.push_back(MachineOperand::CreateImm(BranchCond));
627 continue;
628 }
629
630 // Multiple conditional branches are not handled.
631 return true;
632 }
633
634 // Return false indicating branch successfully analyzed.
635 return false;
636}
637
638// reverseBranchCondition - Reverses the branch condition of the specified
639// condition list, returning false on success and true if it cannot be
640// reversed.
642 SmallVectorImpl<llvm::MachineOperand> &Condition) const {
643 assert((Condition.size() == 1) &&
644 "Lanai branch conditions should have one component.");
645
646 LPCC::CondCode BranchCond =
647 static_cast<LPCC::CondCode>(Condition[0].getImm());
648 Condition[0].setImm(getOppositeCondition(BranchCond));
649 return false;
650}
651
652// Insert the branch with condition specified in condition and given targets
653// (TrueBlock and FalseBlock). This function returns the number of machine
654// instructions inserted.
656 MachineBasicBlock *TrueBlock,
657 MachineBasicBlock *FalseBlock,
658 ArrayRef<MachineOperand> Condition,
659 const DebugLoc &DL,
660 int *BytesAdded) const {
661 // Shouldn't be a fall through.
662 assert(TrueBlock && "insertBranch must not be told to insert a fallthrough");
663 assert(!BytesAdded && "code size not handled");
664
665 // If condition is empty then an unconditional branch is being inserted.
666 if (Condition.empty()) {
667 assert(!FalseBlock && "Unconditional branch with multiple successors!");
668 BuildMI(&MBB, DL, get(Lanai::BT)).addMBB(TrueBlock);
669 return 1;
670 }
671
672 // Else a conditional branch is inserted.
673 assert((Condition.size() == 1) &&
674 "Lanai branch conditions should have one component.");
675 unsigned ConditionalCode = Condition[0].getImm();
676 BuildMI(&MBB, DL, get(Lanai::BRCC)).addMBB(TrueBlock).addImm(ConditionalCode);
677
678 // If no false block, then false behavior is fall through and no branch needs
679 // to be inserted.
680 if (!FalseBlock)
681 return 1;
682
683 BuildMI(&MBB, DL, get(Lanai::BT)).addMBB(FalseBlock);
684 return 2;
685}
686
688 int *BytesRemoved) const {
689 assert(!BytesRemoved && "code size not handled");
690
692 unsigned Count = 0;
693
694 while (Instruction != MBB.begin()) {
695 --Instruction;
696 if (Instruction->isDebugInstr())
697 continue;
698 if (Instruction->getOpcode() != Lanai::BT &&
699 Instruction->getOpcode() != Lanai::BRCC) {
700 break;
701 }
702
703 // Remove the branch.
705 Instruction = MBB.end();
706 ++Count;
707 }
708
709 return Count;
710}
711
713 int &FrameIndex) const {
714 if (MI.getOpcode() == Lanai::LDW_RI)
715 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
716 MI.getOperand(2).getImm() == 0) {
717 FrameIndex = MI.getOperand(1).getIndex();
718 return MI.getOperand(0).getReg();
719 }
720 return 0;
721}
722
724 int &FrameIndex) const {
725 if (MI.getOpcode() == Lanai::LDW_RI) {
726 unsigned Reg;
727 if ((Reg = isLoadFromStackSlot(MI, FrameIndex)))
728 return Reg;
729 // Check for post-frame index elimination operations
731 if (hasLoadFromStackSlot(MI, Accesses)){
732 FrameIndex =
733 cast<FixedStackPseudoSourceValue>(Accesses.front()->getPseudoValue())
734 ->getFrameIndex();
735 return 1;
736 }
737 }
738 return 0;
739}
740
742 int &FrameIndex) const {
743 if (MI.getOpcode() == Lanai::SW_RI)
744 if (MI.getOperand(0).isFI() && MI.getOperand(1).isImm() &&
745 MI.getOperand(1).getImm() == 0) {
746 FrameIndex = MI.getOperand(0).getIndex();
747 return MI.getOperand(2).getReg();
748 }
749 return 0;
750}
751
753 const MachineInstr &LdSt, const MachineOperand *&BaseOp, int64_t &Offset,
754 LocationSize &Width, const TargetRegisterInfo * /*TRI*/) const {
755 // Handle only loads/stores with base register followed by immediate offset
756 // and with add as ALU op.
757 if (LdSt.getNumOperands() != 4)
758 return false;
759 if (!LdSt.getOperand(1).isReg() || !LdSt.getOperand(2).isImm() ||
760 !(LdSt.getOperand(3).isImm() && LdSt.getOperand(3).getImm() == LPAC::ADD))
761 return false;
762
763 switch (LdSt.getOpcode()) {
764 default:
765 return false;
766 case Lanai::LDW_RI:
767 case Lanai::LDW_RR:
768 case Lanai::SW_RR:
769 case Lanai::SW_RI:
770 Width = 4;
771 break;
772 case Lanai::LDHs_RI:
773 case Lanai::LDHz_RI:
774 case Lanai::STH_RI:
775 Width = 2;
776 break;
777 case Lanai::LDBs_RI:
778 case Lanai::LDBz_RI:
779 case Lanai::STB_RI:
780 Width = 1;
781 break;
782 }
783
784 BaseOp = &LdSt.getOperand(1);
785 Offset = LdSt.getOperand(2).getImm();
786
787 if (!BaseOp->isReg())
788 return false;
789
790 return true;
791}
792
795 int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width,
796 const TargetRegisterInfo *TRI) const {
797 switch (LdSt.getOpcode()) {
798 default:
799 return false;
800 case Lanai::LDW_RI:
801 case Lanai::LDW_RR:
802 case Lanai::SW_RR:
803 case Lanai::SW_RI:
804 case Lanai::LDHs_RI:
805 case Lanai::LDHz_RI:
806 case Lanai::STH_RI:
807 case Lanai::LDBs_RI:
808 case Lanai::LDBz_RI:
809 const MachineOperand *BaseOp;
810 OffsetIsScalable = false;
811 if (!getMemOperandWithOffsetWidth(LdSt, BaseOp, Offset, Width, TRI))
812 return false;
813 BaseOps.push_back(BaseOp);
814 return true;
815 }
816}
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder MachineInstrBuilder & DefMI
static bool isRedundantFlagInstr(const MachineInstr *CmpI, Register SrcReg, Register SrcReg2, int64_t ImmValue, const MachineInstr *OI, bool &IsThumb1)
isRedundantFlagInstr - check whether the first instruction, whose only purpose is to update flags,...
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
IRTranslator LLVM IR MI
static LPCC::CondCode getOppositeCondition(LPCC::CondCode CC)
static unsigned flagSettingOpcodeVariant(unsigned OldOpcode)
static MachineInstr * canFoldIntoSelect(Register Reg, const MachineRegisterInfo &MRI)
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some templates that are useful if you are working with the STL at all.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition: Value.cpp:469
This file defines the SmallVector class.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:168
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:163
A debug info location.
Definition: DebugLoc.h:33
InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Definition: Instruction.cpp:92
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
Definition: Instruction.h:274
bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, const MachineInstr &MIb) const override
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TrueBlock, MachineBasicBlock *FalseBlock, ArrayRef< MachineOperand > Condition, const DebugLoc &DL, int *BytesAdded=nullptr) const override
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
bool analyzeSelect(const MachineInstr &MI, SmallVectorImpl< MachineOperand > &Cond, unsigned &TrueOp, unsigned &FalseOp, bool &Optimizable) const override
Register isLoadFromStackSlotPostFE(const MachineInstr &MI, int &FrameIndex) const override
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TrueBlock, MachineBasicBlock *&FalseBlock, SmallVectorImpl< MachineOperand > &Condition, bool AllowModify) const override
virtual const LanaiRegisterInfo & getRegisterInfo() const
MachineInstr * optimizeSelect(MachineInstr &MI, SmallPtrSetImpl< MachineInstr * > &SeenMIs, bool PreferFalse) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator Position, Register DestinationRegister, int FrameIndex, const TargetRegisterClass *RegisterClass, const TargetRegisterInfo *RegisterInfo, Register VReg) const override
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator Position, const DebugLoc &DL, MCRegister DestinationRegister, MCRegister SourceRegister, bool KillSource, bool RenamableDest=false, bool RenamableSrc=false) const override
bool expandPostRAPseudo(MachineInstr &MI) const override
bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt, const MachineOperand *&BaseOp, int64_t &Offset, LocationSize &Width, const TargetRegisterInfo *TRI) const
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
bool optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg, Register SrcReg2, int64_t CmpMask, int64_t CmpValue, const MachineRegisterInfo *MRI) const override
bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, Register &SrcReg2, int64_t &CmpMask, int64_t &CmpValue) const override
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
bool getMemOperandsWithOffsetWidth(const MachineInstr &LdSt, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width, const TargetRegisterInfo *TRI) const override
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Condition) const override
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator Position, Register SourceRegister, bool IsKill, int FrameIndex, const TargetRegisterClass *RegisterClass, const TargetRegisterInfo *RegisterInfo, Register VReg) const override
bool hasValue() const
TypeSize getValue() const
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:198
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
Definition: MCInstrDesc.h:237
ArrayRef< MCOperandInfo > operands() const
Definition: MCInstrDesc.h:239
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
iterator_range< succ_iterator > successors()
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const
Copy all the implicit operands from OtherMI onto this one.
Representation of each machine instruction.
Definition: MachineInstr.h:69
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:575
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:347
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:578
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
Definition: MachineInstr.h:572
bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore,...
void tieOperands(unsigned DefIdx, unsigned UseIdx)
Add a tie between the register operands at DefIdx and UseIdx.
bool hasOrderedMemoryRef() const
Return true if this instruction may have an ordered or volatile memory reference, or if the informati...
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:585
void clearKillInfo()
Clears kill flags on all operands.
MachineOperand class - Representation of each machine instruction operand.
void setImplicit(bool Val=true)
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
static MachineOperand CreateImm(int64_t Val)
Register getReg() const
getReg - Returns the register number.
bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
static bool clobbersPhysReg(const uint32_t *RegMask, MCRegister PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
Definition: SmallPtrSet.h:363
bool erase(PtrType Ptr)
Remove pointer from the set.
Definition: SmallPtrSet.h:401
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:384
bool empty() const
Definition: SmallVector.h:81
size_t size() const
Definition: SmallVector.h:78
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Value * getOperand(unsigned i) const
Definition: User.h:228
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:329
@ Offset
Definition: DWP.cpp:480
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
unsigned getKillRegState(bool B)