LLVM 19.0.0git
RISCVOptWInstrs.cpp
Go to the documentation of this file.
1//===- RISCVOptWInstrs.cpp - MI W instruction optimizations ---------------===//
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 pass does some optimizations for *W instructions at the MI level.
10//
11// First it removes unneeded sext.w instructions. Either because the sign
12// extended bits aren't consumed or because the input was already sign extended
13// by an earlier instruction.
14//
15// Then it removes the -w suffix from opw instructions whenever all users are
16// dependent only on the lower word of the result of the instruction.
17// The cases handled are:
18// * addw because c.add has a larger register encoding than c.addw.
19// * addiw because it helps reduce test differences between RV32 and RV64
20// w/o being a pessimization.
21// * mulw because c.mulw doesn't exist but c.mul does (w/ zcb)
22// * slliw because c.slliw doesn't exist and c.slli does
23//
24//===---------------------------------------------------------------------===//
25
26#include "RISCV.h"
28#include "RISCVSubtarget.h"
29#include "llvm/ADT/SmallSet.h"
30#include "llvm/ADT/Statistic.h"
33
34using namespace llvm;
35
36#define DEBUG_TYPE "riscv-opt-w-instrs"
37#define RISCV_OPT_W_INSTRS_NAME "RISC-V Optimize W Instructions"
38
39STATISTIC(NumRemovedSExtW, "Number of removed sign-extensions");
40STATISTIC(NumTransformedToWInstrs,
41 "Number of instructions transformed to W-ops");
42
43static cl::opt<bool> DisableSExtWRemoval("riscv-disable-sextw-removal",
44 cl::desc("Disable removal of sext.w"),
45 cl::init(false), cl::Hidden);
46static cl::opt<bool> DisableStripWSuffix("riscv-disable-strip-w-suffix",
47 cl::desc("Disable strip W suffix"),
48 cl::init(false), cl::Hidden);
49
50namespace {
51
52class RISCVOptWInstrs : public MachineFunctionPass {
53public:
54 static char ID;
55
56 RISCVOptWInstrs() : MachineFunctionPass(ID) {}
57
58 bool runOnMachineFunction(MachineFunction &MF) override;
59 bool removeSExtWInstrs(MachineFunction &MF, const RISCVInstrInfo &TII,
61 bool stripWSuffixes(MachineFunction &MF, const RISCVInstrInfo &TII,
63
64 void getAnalysisUsage(AnalysisUsage &AU) const override {
65 AU.setPreservesCFG();
67 }
68
69 StringRef getPassName() const override { return RISCV_OPT_W_INSTRS_NAME; }
70};
71
72} // end anonymous namespace
73
74char RISCVOptWInstrs::ID = 0;
76 false)
77
79 return new RISCVOptWInstrs();
80}
81
83 unsigned Bits) {
84 const MachineInstr &MI = *UserOp.getParent();
85 unsigned MCOpcode = RISCV::getRVVMCOpcode(MI.getOpcode());
86
87 if (!MCOpcode)
88 return false;
89
90 const MCInstrDesc &MCID = MI.getDesc();
91 const uint64_t TSFlags = MCID.TSFlags;
92 if (!RISCVII::hasSEWOp(TSFlags))
93 return false;
94 assert(RISCVII::hasVLOp(TSFlags));
95 const unsigned Log2SEW = MI.getOperand(RISCVII::getSEWOpNum(MCID)).getImm();
96
97 if (UserOp.getOperandNo() == RISCVII::getVLOpNum(MCID))
98 return false;
99
100 auto NumDemandedBits =
101 RISCV::getVectorLowDemandedScalarBits(MCOpcode, Log2SEW);
102 return NumDemandedBits && Bits >= *NumDemandedBits;
103}
104
105// Checks if all users only demand the lower \p OrigBits of the original
106// instruction's result.
107// TODO: handle multiple interdependent transformations
108static bool hasAllNBitUsers(const MachineInstr &OrigMI,
109 const RISCVSubtarget &ST,
110 const MachineRegisterInfo &MRI, unsigned OrigBits) {
111
114
115 Worklist.push_back(std::make_pair(&OrigMI, OrigBits));
116
117 while (!Worklist.empty()) {
118 auto P = Worklist.pop_back_val();
119 const MachineInstr *MI = P.first;
120 unsigned Bits = P.second;
121
122 if (!Visited.insert(P).second)
123 continue;
124
125 // Only handle instructions with one def.
126 if (MI->getNumExplicitDefs() != 1)
127 return false;
128
129 Register DestReg = MI->getOperand(0).getReg();
130 if (!DestReg.isVirtual())
131 return false;
132
133 for (auto &UserOp : MRI.use_nodbg_operands(DestReg)) {
134 const MachineInstr *UserMI = UserOp.getParent();
135 unsigned OpIdx = UserOp.getOperandNo();
136
137 switch (UserMI->getOpcode()) {
138 default:
139 if (vectorPseudoHasAllNBitUsers(UserOp, Bits))
140 break;
141 return false;
142
143 case RISCV::ADDIW:
144 case RISCV::ADDW:
145 case RISCV::DIVUW:
146 case RISCV::DIVW:
147 case RISCV::MULW:
148 case RISCV::REMUW:
149 case RISCV::REMW:
150 case RISCV::SLLIW:
151 case RISCV::SLLW:
152 case RISCV::SRAIW:
153 case RISCV::SRAW:
154 case RISCV::SRLIW:
155 case RISCV::SRLW:
156 case RISCV::SUBW:
157 case RISCV::ROLW:
158 case RISCV::RORW:
159 case RISCV::RORIW:
160 case RISCV::CLZW:
161 case RISCV::CTZW:
162 case RISCV::CPOPW:
163 case RISCV::SLLI_UW:
164 case RISCV::FMV_W_X:
165 case RISCV::FCVT_H_W:
166 case RISCV::FCVT_H_WU:
167 case RISCV::FCVT_S_W:
168 case RISCV::FCVT_S_WU:
169 case RISCV::FCVT_D_W:
170 case RISCV::FCVT_D_WU:
171 if (Bits >= 32)
172 break;
173 return false;
174 case RISCV::SEXT_B:
175 case RISCV::PACKH:
176 if (Bits >= 8)
177 break;
178 return false;
179 case RISCV::SEXT_H:
180 case RISCV::FMV_H_X:
181 case RISCV::ZEXT_H_RV32:
182 case RISCV::ZEXT_H_RV64:
183 case RISCV::PACKW:
184 if (Bits >= 16)
185 break;
186 return false;
187
188 case RISCV::PACK:
189 if (Bits >= (ST.getXLen() / 2))
190 break;
191 return false;
192
193 case RISCV::SRLI: {
194 // If we are shifting right by less than Bits, and users don't demand
195 // any bits that were shifted into [Bits-1:0], then we can consider this
196 // as an N-Bit user.
197 unsigned ShAmt = UserMI->getOperand(2).getImm();
198 if (Bits > ShAmt) {
199 Worklist.push_back(std::make_pair(UserMI, Bits - ShAmt));
200 break;
201 }
202 return false;
203 }
204
205 // these overwrite higher input bits, otherwise the lower word of output
206 // depends only on the lower word of input. So check their uses read W.
207 case RISCV::SLLI:
208 if (Bits >= (ST.getXLen() - UserMI->getOperand(2).getImm()))
209 break;
210 Worklist.push_back(std::make_pair(UserMI, Bits));
211 break;
212 case RISCV::ANDI: {
213 uint64_t Imm = UserMI->getOperand(2).getImm();
214 if (Bits >= (unsigned)llvm::bit_width(Imm))
215 break;
216 Worklist.push_back(std::make_pair(UserMI, Bits));
217 break;
218 }
219 case RISCV::ORI: {
220 uint64_t Imm = UserMI->getOperand(2).getImm();
221 if (Bits >= (unsigned)llvm::bit_width<uint64_t>(~Imm))
222 break;
223 Worklist.push_back(std::make_pair(UserMI, Bits));
224 break;
225 }
226
227 case RISCV::SLL:
228 case RISCV::BSET:
229 case RISCV::BCLR:
230 case RISCV::BINV:
231 // Operand 2 is the shift amount which uses log2(xlen) bits.
232 if (OpIdx == 2) {
233 if (Bits >= Log2_32(ST.getXLen()))
234 break;
235 return false;
236 }
237 Worklist.push_back(std::make_pair(UserMI, Bits));
238 break;
239
240 case RISCV::SRA:
241 case RISCV::SRL:
242 case RISCV::ROL:
243 case RISCV::ROR:
244 // Operand 2 is the shift amount which uses 6 bits.
245 if (OpIdx == 2 && Bits >= Log2_32(ST.getXLen()))
246 break;
247 return false;
248
249 case RISCV::ADD_UW:
250 case RISCV::SH1ADD_UW:
251 case RISCV::SH2ADD_UW:
252 case RISCV::SH3ADD_UW:
253 // Operand 1 is implicitly zero extended.
254 if (OpIdx == 1 && Bits >= 32)
255 break;
256 Worklist.push_back(std::make_pair(UserMI, Bits));
257 break;
258
259 case RISCV::BEXTI:
260 if (UserMI->getOperand(2).getImm() >= Bits)
261 return false;
262 break;
263
264 case RISCV::SB:
265 // The first argument is the value to store.
266 if (OpIdx == 0 && Bits >= 8)
267 break;
268 return false;
269 case RISCV::SH:
270 // The first argument is the value to store.
271 if (OpIdx == 0 && Bits >= 16)
272 break;
273 return false;
274 case RISCV::SW:
275 // The first argument is the value to store.
276 if (OpIdx == 0 && Bits >= 32)
277 break;
278 return false;
279
280 // For these, lower word of output in these operations, depends only on
281 // the lower word of input. So, we check all uses only read lower word.
282 case RISCV::COPY:
283 case RISCV::PHI:
284
285 case RISCV::ADD:
286 case RISCV::ADDI:
287 case RISCV::AND:
288 case RISCV::MUL:
289 case RISCV::OR:
290 case RISCV::SUB:
291 case RISCV::XOR:
292 case RISCV::XORI:
293
294 case RISCV::ANDN:
295 case RISCV::BREV8:
296 case RISCV::CLMUL:
297 case RISCV::ORC_B:
298 case RISCV::ORN:
299 case RISCV::SH1ADD:
300 case RISCV::SH2ADD:
301 case RISCV::SH3ADD:
302 case RISCV::XNOR:
303 case RISCV::BSETI:
304 case RISCV::BCLRI:
305 case RISCV::BINVI:
306 Worklist.push_back(std::make_pair(UserMI, Bits));
307 break;
308
309 case RISCV::PseudoCCMOVGPR:
310 // Either operand 4 or operand 5 is returned by this instruction. If
311 // only the lower word of the result is used, then only the lower word
312 // of operand 4 and 5 is used.
313 if (OpIdx != 4 && OpIdx != 5)
314 return false;
315 Worklist.push_back(std::make_pair(UserMI, Bits));
316 break;
317
318 case RISCV::CZERO_EQZ:
319 case RISCV::CZERO_NEZ:
320 case RISCV::VT_MASKC:
321 case RISCV::VT_MASKCN:
322 if (OpIdx != 1)
323 return false;
324 Worklist.push_back(std::make_pair(UserMI, Bits));
325 break;
326 }
327 }
328 }
329
330 return true;
331}
332
333static bool hasAllWUsers(const MachineInstr &OrigMI, const RISCVSubtarget &ST,
334 const MachineRegisterInfo &MRI) {
335 return hasAllNBitUsers(OrigMI, ST, MRI, 32);
336}
337
338// This function returns true if the machine instruction always outputs a value
339// where bits 63:32 match bit 31.
341 const MachineRegisterInfo &MRI, unsigned OpNo) {
342 uint64_t TSFlags = MI.getDesc().TSFlags;
343
344 // Instructions that can be determined from opcode are marked in tablegen.
346 return true;
347
348 // Special cases that require checking operands.
349 switch (MI.getOpcode()) {
350 // shifting right sufficiently makes the value 32-bit sign-extended
351 case RISCV::SRAI:
352 return MI.getOperand(2).getImm() >= 32;
353 case RISCV::SRLI:
354 return MI.getOperand(2).getImm() > 32;
355 // The LI pattern ADDI rd, X0, imm is sign extended.
356 case RISCV::ADDI:
357 return MI.getOperand(1).isReg() && MI.getOperand(1).getReg() == RISCV::X0;
358 // An ANDI with an 11 bit immediate will zero bits 63:11.
359 case RISCV::ANDI:
360 return isUInt<11>(MI.getOperand(2).getImm());
361 // An ORI with an >11 bit immediate (negative 12-bit) will set bits 63:11.
362 case RISCV::ORI:
363 return !isUInt<11>(MI.getOperand(2).getImm());
364 // A bseti with X0 is sign extended if the immediate is less than 31.
365 case RISCV::BSETI:
366 return MI.getOperand(2).getImm() < 31 &&
367 MI.getOperand(1).getReg() == RISCV::X0;
368 // Copying from X0 produces zero.
369 case RISCV::COPY:
370 return MI.getOperand(1).getReg() == RISCV::X0;
371 // Ignore the scratch register destination.
372 case RISCV::PseudoAtomicLoadNand32:
373 return OpNo == 0;
374 case RISCV::PseudoVMV_X_S: {
375 // vmv.x.s has at least 33 sign bits if log2(sew) <= 5.
376 int64_t Log2SEW = MI.getOperand(2).getImm();
377 assert(Log2SEW >= 3 && Log2SEW <= 6 && "Unexpected Log2SEW");
378 return Log2SEW <= 5;
379 }
380 }
381
382 return false;
383}
384
385static bool isSignExtendedW(Register SrcReg, const RISCVSubtarget &ST,
388 SmallSet<Register, 4> Visited;
390
391 auto AddRegToWorkList = [&](Register SrcReg) {
392 if (!SrcReg.isVirtual())
393 return false;
394 Worklist.push_back(SrcReg);
395 return true;
396 };
397
398 if (!AddRegToWorkList(SrcReg))
399 return false;
400
401 while (!Worklist.empty()) {
402 Register Reg = Worklist.pop_back_val();
403
404 // If we already visited this register, we don't need to check it again.
405 if (!Visited.insert(Reg).second)
406 continue;
407
408 MachineInstr *MI = MRI.getVRegDef(Reg);
409 if (!MI)
410 continue;
411
412 int OpNo = MI->findRegisterDefOperandIdx(Reg);
413 assert(OpNo != -1 && "Couldn't find register");
414
415 // If this is a sign extending operation we don't need to look any further.
416 if (isSignExtendingOpW(*MI, MRI, OpNo))
417 continue;
418
419 // Is this an instruction that propagates sign extend?
420 switch (MI->getOpcode()) {
421 default:
422 // Unknown opcode, give up.
423 return false;
424 case RISCV::COPY: {
425 const MachineFunction *MF = MI->getMF();
426 const RISCVMachineFunctionInfo *RVFI =
428
429 // If this is the entry block and the register is livein, see if we know
430 // it is sign extended.
431 if (MI->getParent() == &MF->front()) {
432 Register VReg = MI->getOperand(0).getReg();
433 if (MF->getRegInfo().isLiveIn(VReg) && RVFI->isSExt32Register(VReg))
434 continue;
435 }
436
437 Register CopySrcReg = MI->getOperand(1).getReg();
438 if (CopySrcReg == RISCV::X10) {
439 // For a method return value, we check the ZExt/SExt flags in attribute.
440 // We assume the following code sequence for method call.
441 // PseudoCALL @bar, ...
442 // ADJCALLSTACKUP 0, 0, implicit-def dead $x2, implicit $x2
443 // %0:gpr = COPY $x10
444 //
445 // We use the PseudoCall to look up the IR function being called to find
446 // its return attributes.
447 const MachineBasicBlock *MBB = MI->getParent();
448 auto II = MI->getIterator();
449 if (II == MBB->instr_begin() ||
450 (--II)->getOpcode() != RISCV::ADJCALLSTACKUP)
451 return false;
452
453 const MachineInstr &CallMI = *(--II);
454 if (!CallMI.isCall() || !CallMI.getOperand(0).isGlobal())
455 return false;
456
457 auto *CalleeFn =
458 dyn_cast_if_present<Function>(CallMI.getOperand(0).getGlobal());
459 if (!CalleeFn)
460 return false;
461
462 auto *IntTy = dyn_cast<IntegerType>(CalleeFn->getReturnType());
463 if (!IntTy)
464 return false;
465
466 const AttributeSet &Attrs = CalleeFn->getAttributes().getRetAttrs();
467 unsigned BitWidth = IntTy->getBitWidth();
468 if ((BitWidth <= 32 && Attrs.hasAttribute(Attribute::SExt)) ||
469 (BitWidth < 32 && Attrs.hasAttribute(Attribute::ZExt)))
470 continue;
471 }
472
473 if (!AddRegToWorkList(CopySrcReg))
474 return false;
475
476 break;
477 }
478
479 // For these, we just need to check if the 1st operand is sign extended.
480 case RISCV::BCLRI:
481 case RISCV::BINVI:
482 case RISCV::BSETI:
483 if (MI->getOperand(2).getImm() >= 31)
484 return false;
485 [[fallthrough]];
486 case RISCV::REM:
487 case RISCV::ANDI:
488 case RISCV::ORI:
489 case RISCV::XORI:
490 // |Remainder| is always <= |Dividend|. If D is 32-bit, then so is R.
491 // DIV doesn't work because of the edge case 0xf..f 8000 0000 / (long)-1
492 // Logical operations use a sign extended 12-bit immediate.
493 if (!AddRegToWorkList(MI->getOperand(1).getReg()))
494 return false;
495
496 break;
497 case RISCV::PseudoCCADDW:
498 case RISCV::PseudoCCADDIW:
499 case RISCV::PseudoCCSUBW:
500 case RISCV::PseudoCCSLLW:
501 case RISCV::PseudoCCSRLW:
502 case RISCV::PseudoCCSRAW:
503 case RISCV::PseudoCCSLLIW:
504 case RISCV::PseudoCCSRLIW:
505 case RISCV::PseudoCCSRAIW:
506 // Returns operand 4 or an ADDW/SUBW/etc. of operands 5 and 6. We only
507 // need to check if operand 4 is sign extended.
508 if (!AddRegToWorkList(MI->getOperand(4).getReg()))
509 return false;
510 break;
511 case RISCV::REMU:
512 case RISCV::AND:
513 case RISCV::OR:
514 case RISCV::XOR:
515 case RISCV::ANDN:
516 case RISCV::ORN:
517 case RISCV::XNOR:
518 case RISCV::MAX:
519 case RISCV::MAXU:
520 case RISCV::MIN:
521 case RISCV::MINU:
522 case RISCV::PseudoCCMOVGPR:
523 case RISCV::PseudoCCAND:
524 case RISCV::PseudoCCOR:
525 case RISCV::PseudoCCXOR:
526 case RISCV::PHI: {
527 // If all incoming values are sign-extended, the output of AND, OR, XOR,
528 // MIN, MAX, or PHI is also sign-extended.
529
530 // The input registers for PHI are operand 1, 3, ...
531 // The input registers for PseudoCCMOVGPR are 4 and 5.
532 // The input registers for PseudoCCAND/OR/XOR are 4, 5, and 6.
533 // The input registers for others are operand 1 and 2.
534 unsigned B = 1, E = 3, D = 1;
535 switch (MI->getOpcode()) {
536 case RISCV::PHI:
537 E = MI->getNumOperands();
538 D = 2;
539 break;
540 case RISCV::PseudoCCMOVGPR:
541 B = 4;
542 E = 6;
543 break;
544 case RISCV::PseudoCCAND:
545 case RISCV::PseudoCCOR:
546 case RISCV::PseudoCCXOR:
547 B = 4;
548 E = 7;
549 break;
550 }
551
552 for (unsigned I = B; I != E; I += D) {
553 if (!MI->getOperand(I).isReg())
554 return false;
555
556 if (!AddRegToWorkList(MI->getOperand(I).getReg()))
557 return false;
558 }
559
560 break;
561 }
562
563 case RISCV::CZERO_EQZ:
564 case RISCV::CZERO_NEZ:
565 case RISCV::VT_MASKC:
566 case RISCV::VT_MASKCN:
567 // Instructions return zero or operand 1. Result is sign extended if
568 // operand 1 is sign extended.
569 if (!AddRegToWorkList(MI->getOperand(1).getReg()))
570 return false;
571 break;
572
573 // With these opcode, we can "fix" them with the W-version
574 // if we know all users of the result only rely on bits 31:0
575 case RISCV::SLLI:
576 // SLLIW reads the lowest 5 bits, while SLLI reads lowest 6 bits
577 if (MI->getOperand(2).getImm() >= 32)
578 return false;
579 [[fallthrough]];
580 case RISCV::ADDI:
581 case RISCV::ADD:
582 case RISCV::LD:
583 case RISCV::LWU:
584 case RISCV::MUL:
585 case RISCV::SUB:
586 if (hasAllWUsers(*MI, ST, MRI)) {
587 FixableDef.insert(MI);
588 break;
589 }
590 return false;
591 }
592 }
593
594 // If we get here, then every node we visited produces a sign extended value
595 // or propagated sign extended values. So the result must be sign extended.
596 return true;
597}
598
599static unsigned getWOp(unsigned Opcode) {
600 switch (Opcode) {
601 case RISCV::ADDI:
602 return RISCV::ADDIW;
603 case RISCV::ADD:
604 return RISCV::ADDW;
605 case RISCV::LD:
606 case RISCV::LWU:
607 return RISCV::LW;
608 case RISCV::MUL:
609 return RISCV::MULW;
610 case RISCV::SLLI:
611 return RISCV::SLLIW;
612 case RISCV::SUB:
613 return RISCV::SUBW;
614 default:
615 llvm_unreachable("Unexpected opcode for replacement with W variant");
616 }
617}
618
619bool RISCVOptWInstrs::removeSExtWInstrs(MachineFunction &MF,
620 const RISCVInstrInfo &TII,
621 const RISCVSubtarget &ST,
624 return false;
625
626 bool MadeChange = false;
627 for (MachineBasicBlock &MBB : MF) {
629 // We're looking for the sext.w pattern ADDIW rd, rs1, 0.
630 if (!RISCV::isSEXT_W(MI))
631 continue;
632
633 Register SrcReg = MI.getOperand(1).getReg();
634
636
637 // If all users only use the lower bits, this sext.w is redundant.
638 // Or if all definitions reaching MI sign-extend their output,
639 // then sext.w is redundant.
640 if (!hasAllWUsers(MI, ST, MRI) &&
641 !isSignExtendedW(SrcReg, ST, MRI, FixableDefs))
642 continue;
643
644 Register DstReg = MI.getOperand(0).getReg();
645 if (!MRI.constrainRegClass(SrcReg, MRI.getRegClass(DstReg)))
646 continue;
647
648 // Convert Fixable instructions to their W versions.
649 for (MachineInstr *Fixable : FixableDefs) {
650 LLVM_DEBUG(dbgs() << "Replacing " << *Fixable);
651 Fixable->setDesc(TII.get(getWOp(Fixable->getOpcode())));
652 Fixable->clearFlag(MachineInstr::MIFlag::NoSWrap);
653 Fixable->clearFlag(MachineInstr::MIFlag::NoUWrap);
654 Fixable->clearFlag(MachineInstr::MIFlag::IsExact);
655 LLVM_DEBUG(dbgs() << " with " << *Fixable);
656 ++NumTransformedToWInstrs;
657 }
658
659 LLVM_DEBUG(dbgs() << "Removing redundant sign-extension\n");
660 MRI.replaceRegWith(DstReg, SrcReg);
661 MRI.clearKillFlags(SrcReg);
662 MI.eraseFromParent();
663 ++NumRemovedSExtW;
664 MadeChange = true;
665 }
666 }
667
668 return MadeChange;
669}
670
671bool RISCVOptWInstrs::stripWSuffixes(MachineFunction &MF,
672 const RISCVInstrInfo &TII,
673 const RISCVSubtarget &ST,
676 return false;
677
678 bool MadeChange = false;
679 for (MachineBasicBlock &MBB : MF) {
680 for (MachineInstr &MI : MBB) {
681 unsigned Opc;
682 switch (MI.getOpcode()) {
683 default:
684 continue;
685 case RISCV::ADDW: Opc = RISCV::ADD; break;
686 case RISCV::ADDIW: Opc = RISCV::ADDI; break;
687 case RISCV::MULW: Opc = RISCV::MUL; break;
688 case RISCV::SLLIW: Opc = RISCV::SLLI; break;
689 }
690
691 if (hasAllWUsers(MI, ST, MRI)) {
692 MI.setDesc(TII.get(Opc));
693 MadeChange = true;
694 }
695 }
696 }
697
698 return MadeChange;
699}
700
701bool RISCVOptWInstrs::runOnMachineFunction(MachineFunction &MF) {
702 if (skipFunction(MF.getFunction()))
703 return false;
704
707 const RISCVInstrInfo &TII = *ST.getInstrInfo();
708
709 if (!ST.is64Bit())
710 return false;
711
712 bool MadeChange = false;
713 MadeChange |= removeSExtWInstrs(MF, TII, ST, MRI);
714 MadeChange |= stripWSuffixes(MF, TII, ST, MRI);
715
716 return MadeChange;
717}
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock & MBB
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_DEBUG(X)
Definition: Debug.h:101
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
#define P(N)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:38
static bool isSignExtendedW(Register SrcReg, const RISCVSubtarget &ST, const MachineRegisterInfo &MRI, SmallPtrSetImpl< MachineInstr * > &FixableDef)
static bool hasAllWUsers(const MachineInstr &OrigMI, const RISCVSubtarget &ST, const MachineRegisterInfo &MRI)
static bool isSignExtendingOpW(const MachineInstr &MI, const MachineRegisterInfo &MRI, unsigned OpNo)
static cl::opt< bool > DisableStripWSuffix("riscv-disable-strip-w-suffix", cl::desc("Disable strip W suffix"), cl::init(false), cl::Hidden)
static bool hasAllNBitUsers(const MachineInstr &OrigMI, const RISCVSubtarget &ST, const MachineRegisterInfo &MRI, unsigned OrigBits)
#define RISCV_OPT_W_INSTRS_NAME
static bool vectorPseudoHasAllNBitUsers(const MachineOperand &UserOp, unsigned Bits)
static cl::opt< bool > DisableSExtWRemoval("riscv-disable-sextw-removal", cl::desc("Disable removal of sext.w"), cl::init(false), cl::Hidden)
#define DEBUG_TYPE
static unsigned getWOp(unsigned Opcode)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallSet class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition: Statistic.h:167
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
Definition: VPlanSLP.cpp:191
Represent the analysis usage information of a pass.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:269
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:311
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:198
instr_iterator instr_begin()
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
Representation of each machine instruction.
Definition: MachineInstr.h:68
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:543
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:326
bool isCall(QueryType Type=AnyInBundle) const
Definition: MachineInstr.h:915
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:553
MachineOperand class - Representation of each machine instruction operand.
unsigned getOperandNo() const
Returns the index of this operand in the instruction that it belongs to.
const GlobalValue * getGlobal() const
int64_t getImm() const
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
bool isLiveIn(Register Reg) const
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Definition: Pass.cpp:81
RISCVMachineFunctionInfo - This class is derived from MachineFunctionInfo and contains private RISCV-...
bool isSExt32Register(Register Reg) const
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:91
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
Definition: SmallPtrSet.h:321
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:342
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:427
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:135
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition: SmallSet.h:179
bool empty() const
Definition: SmallVector.h:94
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
static unsigned getVLOpNum(const MCInstrDesc &Desc)
static bool hasVLOp(uint64_t TSFlags)
static unsigned getSEWOpNum(const MCInstrDesc &Desc)
static bool hasSEWOp(uint64_t TSFlags)
std::optional< unsigned > getVectorLowDemandedScalarBits(uint16_t Opcode, unsigned Log2SEW)
unsigned getRVVMCOpcode(unsigned RVVPseudoOpcode)
bool isSEXT_W(const MachineInstr &MI)
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:450
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
int bit_width(T Value)
Returns the number of bits needed to represent Value if Value is nonzero.
Definition: bit.h:317
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition: STLExtras.h:665
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition: MathExtras.h:313
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
FunctionPass * createRISCVOptWInstrsPass()
constexpr unsigned BitWidth
Definition: BitmaskEnum.h:191