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