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