LLVM 23.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.
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
439// Identify instructions that can be folded into a SELECT instruction, and
440// return the defining instruction.
442 const MachineRegisterInfo &MRI) {
443 if (!Reg.isVirtual())
444 return nullptr;
445 if (!MRI.hasOneNonDBGUse(Reg))
446 return nullptr;
447 MachineInstr *MI = MRI.getVRegDef(Reg);
448 if (!MI)
449 return nullptr;
450 // MI is folded into the SELECT by predicating it.
451 if (!MI->isPredicable())
452 return nullptr;
453 // Check if MI has any non-dead defs or physreg uses. This also detects
454 // predicated instructions which will be reading SR.
455 for (const MachineOperand &MO : llvm::drop_begin(MI->operands(), 1)) {
456 // Reject frame index operands.
457 if (MO.isFI() || MO.isCPI() || MO.isJTI())
458 return nullptr;
459 if (!MO.isReg())
460 continue;
461 // MI can't have any tied operands, that would conflict with predication.
462 if (MO.isTied())
463 return nullptr;
464 if (MO.getReg().isPhysical())
465 return nullptr;
466 if (MO.isDef() && !MO.isDead())
467 return nullptr;
468 }
469 bool DontMoveAcrossStores = true;
470 if (!MI->isSafeToMove(DontMoveAcrossStores))
471 return nullptr;
472 return MI;
473}
474
478 bool /*PreferFalse*/) const {
479 assert(MI.getOpcode() == Lanai::SELECT && "unknown select instruction");
480 MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
481 MachineInstr *DefMI = canFoldIntoSelect(MI.getOperand(1).getReg(), MRI);
482 bool Invert = !DefMI;
483 if (!DefMI)
484 DefMI = canFoldIntoSelect(MI.getOperand(2).getReg(), MRI);
485 if (!DefMI)
486 return nullptr;
487
488 // Find new register class to use.
489 MachineOperand FalseReg = MI.getOperand(Invert ? 1 : 2);
490 Register DestReg = MI.getOperand(0).getReg();
491 const TargetRegisterClass *PreviousClass = MRI.getRegClass(FalseReg.getReg());
492 if (!MRI.constrainRegClass(DestReg, PreviousClass))
493 return nullptr;
494
495 // Create a new predicated version of DefMI.
496 MachineInstrBuilder NewMI =
497 BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), DefMI->getDesc(), DestReg);
498
499 // Copy all the DefMI operands, excluding its (null) predicate.
500 const MCInstrDesc &DefDesc = DefMI->getDesc();
501 for (unsigned i = 1, e = DefDesc.getNumOperands();
502 i != e && !DefDesc.operands()[i].isPredicate(); ++i)
503 NewMI.add(DefMI->getOperand(i));
504
505 unsigned CondCode = MI.getOperand(3).getImm();
506 if (Invert)
508 else
509 NewMI.addImm(CondCode);
510 NewMI.copyImplicitOps(MI);
511
512 // The output register value when the predicate is false is an implicit
513 // register operand tied to the first def. The tie makes the register
514 // allocator ensure the FalseReg is allocated the same register as operand 0.
515 FalseReg.setImplicit();
516 NewMI.add(FalseReg);
517 NewMI->tieOperands(0, NewMI->getNumOperands() - 1);
518
519 // Update SeenMIs set: register newly created MI and erase removed DefMI.
520 SeenMIs.insert(NewMI);
521 SeenMIs.erase(DefMI);
522
523 // If MI is inside a loop, and DefMI is outside the loop, then kill flags on
524 // DefMI would be invalid when transferred inside the loop. Checking for a
525 // loop is expensive, but at least remove kill flags if they are in different
526 // BBs.
527 if (DefMI->getParent() != MI.getParent())
528 NewMI->clearKillInfo();
529
530 // The caller will erase MI, but not DefMI.
531 DefMI->eraseFromParent();
532 return NewMI;
533}
534
535// The analyzeBranch function is used to examine conditional instructions and
536// remove unnecessary instructions. This method is used by BranchFolder and
537// IfConverter machine function passes to improve the CFG.
538// - TrueBlock is set to the destination if condition evaluates true (it is the
539// nullptr if the destination is the fall-through branch);
540// - FalseBlock is set to the destination if condition evaluates to false (it
541// is the nullptr if the branch is unconditional);
542// - condition is populated with machine operands needed to generate the branch
543// to insert in insertBranch;
544// Returns: false if branch could successfully be analyzed.
546 MachineBasicBlock *&TrueBlock,
547 MachineBasicBlock *&FalseBlock,
549 bool AllowModify) const {
550 // Iterator to current instruction being considered.
552
553 // Start from the bottom of the block and work up, examining the
554 // terminator instructions.
555 while (Instruction != MBB.begin()) {
556 --Instruction;
557
558 // Skip over debug instructions.
559 if (Instruction->isDebugInstr())
560 continue;
561
562 // Working from the bottom, when we see a non-terminator
563 // instruction, we're done.
564 if (!isUnpredicatedTerminator(*Instruction))
565 break;
566
567 // A terminator that isn't a branch can't easily be handled
568 // by this analysis.
569 if (!Instruction->isBranch())
570 return true;
571
572 // Handle unconditional branches.
573 if (Instruction->getOpcode() == Lanai::BT) {
574 if (!AllowModify) {
575 TrueBlock = Instruction->getOperand(0).getMBB();
576 continue;
577 }
578
579 // If the block has any instructions after a branch, delete them.
580 MBB.erase(std::next(Instruction), MBB.end());
581
582 Condition.clear();
583 FalseBlock = nullptr;
584
585 // Delete the jump if it's equivalent to a fall-through.
586 if (MBB.isLayoutSuccessor(Instruction->getOperand(0).getMBB())) {
587 TrueBlock = nullptr;
589 Instruction = MBB.end();
590 continue;
591 }
592
593 // TrueBlock is used to indicate the unconditional destination.
594 TrueBlock = Instruction->getOperand(0).getMBB();
595 continue;
596 }
597
598 // Handle conditional branches
599 unsigned Opcode = Instruction->getOpcode();
600 if (Opcode != Lanai::BRCC)
601 return true; // Unknown opcode.
602
603 // Multiple conditional branches are not handled here so only proceed if
604 // there are no conditions enqueued.
605 if (Condition.empty()) {
606 LPCC::CondCode BranchCond =
607 static_cast<LPCC::CondCode>(Instruction->getOperand(1).getImm());
608
609 // TrueBlock is the target of the previously seen unconditional branch.
610 FalseBlock = TrueBlock;
611 TrueBlock = Instruction->getOperand(0).getMBB();
612 Condition.push_back(MachineOperand::CreateImm(BranchCond));
613 continue;
614 }
615
616 // Multiple conditional branches are not handled.
617 return true;
618 }
619
620 // Return false indicating branch successfully analyzed.
621 return false;
622}
623
624// reverseBranchCondition - Reverses the branch condition of the specified
625// condition list, returning false on success and true if it cannot be
626// reversed.
628 SmallVectorImpl<llvm::MachineOperand> &Condition) const {
629 assert((Condition.size() == 1) &&
630 "Lanai branch conditions should have one component.");
631
632 LPCC::CondCode BranchCond =
633 static_cast<LPCC::CondCode>(Condition[0].getImm());
634 Condition[0].setImm(getOppositeCondition(BranchCond));
635 return false;
636}
637
638// Insert the branch with condition specified in condition and given targets
639// (TrueBlock and FalseBlock). This function returns the number of machine
640// instructions inserted.
642 MachineBasicBlock *TrueBlock,
643 MachineBasicBlock *FalseBlock,
644 ArrayRef<MachineOperand> Condition,
645 const DebugLoc &DL,
646 int *BytesAdded) const {
647 // Shouldn't be a fall through.
648 assert(TrueBlock && "insertBranch must not be told to insert a fallthrough");
649 assert(!BytesAdded && "code size not handled");
650
651 // If condition is empty then an unconditional branch is being inserted.
652 if (Condition.empty()) {
653 assert(!FalseBlock && "Unconditional branch with multiple successors!");
654 BuildMI(&MBB, DL, get(Lanai::BT)).addMBB(TrueBlock);
655 return 1;
656 }
657
658 // Else a conditional branch is inserted.
659 assert((Condition.size() == 1) &&
660 "Lanai branch conditions should have one component.");
661 unsigned ConditionalCode = Condition[0].getImm();
662 BuildMI(&MBB, DL, get(Lanai::BRCC)).addMBB(TrueBlock).addImm(ConditionalCode);
663
664 // If no false block, then false behavior is fall through and no branch needs
665 // to be inserted.
666 if (!FalseBlock)
667 return 1;
668
669 BuildMI(&MBB, DL, get(Lanai::BT)).addMBB(FalseBlock);
670 return 2;
671}
672
674 int *BytesRemoved) const {
675 assert(!BytesRemoved && "code size not handled");
676
678 unsigned Count = 0;
679
680 while (Instruction != MBB.begin()) {
681 --Instruction;
682 if (Instruction->isDebugInstr())
683 continue;
684 if (Instruction->getOpcode() != Lanai::BT &&
685 Instruction->getOpcode() != Lanai::BRCC) {
686 break;
687 }
688
689 // Remove the branch.
691 Instruction = MBB.end();
692 ++Count;
693 }
694
695 return Count;
696}
697
699 int &FrameIndex) const {
700 if (MI.getOpcode() == Lanai::LDW_RI)
701 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
702 MI.getOperand(2).getImm() == 0) {
703 FrameIndex = MI.getOperand(1).getIndex();
704 return MI.getOperand(0).getReg();
705 }
706 return 0;
707}
708
710 int &FrameIndex) const {
711 if (MI.getOpcode() == Lanai::LDW_RI) {
712 unsigned Reg;
713 if ((Reg = isLoadFromStackSlot(MI, FrameIndex)))
714 return Reg;
715 // Check for post-frame index elimination operations
717 if (hasLoadFromStackSlot(MI, Accesses)){
718 FrameIndex =
719 cast<FixedStackPseudoSourceValue>(Accesses.front()->getPseudoValue())
720 ->getFrameIndex();
721 return 1;
722 }
723 }
724 return 0;
725}
726
728 int &FrameIndex) const {
729 if (MI.getOpcode() == Lanai::SW_RI)
730 if (MI.getOperand(0).isFI() && MI.getOperand(1).isImm() &&
731 MI.getOperand(1).getImm() == 0) {
732 FrameIndex = MI.getOperand(0).getIndex();
733 return MI.getOperand(2).getReg();
734 }
735 return 0;
736}
737
739 const MachineInstr &LdSt, const MachineOperand *&BaseOp, int64_t &Offset,
740 LocationSize &Width, const TargetRegisterInfo * /*TRI*/) 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,
782 const TargetRegisterInfo *TRI) const {
783 switch (LdSt.getOpcode()) {
784 default:
785 return false;
786 case Lanai::LDW_RI:
787 case Lanai::LDW_RR:
788 case Lanai::SW_RR:
789 case Lanai::SW_RI:
790 case Lanai::LDHs_RI:
791 case Lanai::LDHz_RI:
792 case Lanai::STH_RI:
793 case Lanai::LDBs_RI:
794 case Lanai::LDBz_RI:
795 const MachineOperand *BaseOp;
796 OffsetIsScalable = false;
797 if (!getMemOperandWithOffsetWidth(LdSt, BaseOp, Offset, Width, TRI))
798 return false;
799 BaseOps.push_back(BaseOp);
800 return true;
801 }
802}
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
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:487
This file defines the SmallVector class.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
size - Get the array size.
Definition ArrayRef.h:142
bool empty() const
empty - Check if the array is empty.
Definition ArrayRef.h:137
A debug info location.
Definition DebugLoc.h:123
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
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
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 getMemOperandsWithOffsetWidth(const MachineInstr &LdSt, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width, const TargetRegisterInfo *TRI) const override
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Condition) const override
void 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...
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: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.
Definition Types.h:26
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:532
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)
FunctionAddr VTableAddr Count
Definition InstrProf.h:139
@ Sub
Subtraction of integers.
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