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