LLVM 19.0.0git
GenericMachineInstrs.h
Go to the documentation of this file.
1//===- llvm/CodeGen/GlobalISel/GenericMachineInstrs.h -----------*- 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/// \file
9/// Declares convenience wrapper classes for interpreting MachineInstr instances
10/// as specific generic operations.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CODEGEN_GLOBALISEL_GENERICMACHINEINSTRS_H
15#define LLVM_CODEGEN_GLOBALISEL_GENERICMACHINEINSTRS_H
16
22
23namespace llvm {
24
25/// A base class for all GenericMachineInstrs.
27public:
29
30 /// Access the Idx'th operand as a register and return it.
31 /// This assumes that the Idx'th operand is a Register type.
32 Register getReg(unsigned Idx) const { return getOperand(Idx).getReg(); }
33
34 static bool classof(const MachineInstr *MI) {
35 return isPreISelGenericOpcode(MI->getOpcode());
36 }
37};
38
39/// Provides common memory operand functionality.
41public:
42 /// Get the MachineMemOperand on this instruction.
44
45 /// Returns true if the attached MachineMemOperand has the atomic flag set.
46 bool isAtomic() const { return getMMO().isAtomic(); }
47 /// Returns true if the attached MachineMemOpeand as the volatile flag set.
48 bool isVolatile() const { return getMMO().isVolatile(); }
49 /// Returns true if the memory operation is neither atomic or volatile.
50 bool isSimple() const { return !isAtomic() && !isVolatile(); }
51 /// Returns true if this memory operation doesn't have any ordering
52 /// constraints other than normal aliasing. Volatile and (ordered) atomic
53 /// memory operations can't be reordered.
54 bool isUnordered() const { return getMMO().isUnordered(); }
55
56 /// Returns the size in bytes of the memory access.
57 LocationSize getMemSize() const { return getMMO().getSize(); }
58 /// Returns the size in bits of the memory access.
60
61 static bool classof(const MachineInstr *MI) {
62 return GenericMachineInstr::classof(MI) && MI->hasOneMemOperand();
63 }
64};
65
66/// Represents any type of generic load or store.
67/// G_LOAD, G_STORE, G_ZEXTLOAD, G_SEXTLOAD.
68class GLoadStore : public GMemOperation {
69public:
70 /// Get the source register of the pointer value.
71 Register getPointerReg() const { return getOperand(1).getReg(); }
72
73 static bool classof(const MachineInstr *MI) {
74 switch (MI->getOpcode()) {
75 case TargetOpcode::G_LOAD:
76 case TargetOpcode::G_STORE:
77 case TargetOpcode::G_ZEXTLOAD:
78 case TargetOpcode::G_SEXTLOAD:
79 return true;
80 default:
81 return false;
82 }
83 }
84};
85
86/// Represents indexed loads. These are different enough from regular loads
87/// that they get their own class. Including them in GAnyLoad would probably
88/// make a footgun for someone.
90public:
91 /// Get the definition register of the loaded value.
92 Register getDstReg() const { return getOperand(0).getReg(); }
93 /// Get the def register of the writeback value.
94 Register getWritebackReg() const { return getOperand(1).getReg(); }
95 /// Get the base register of the pointer value.
96 Register getBaseReg() const { return getOperand(2).getReg(); }
97 /// Get the offset register of the pointer value.
98 Register getOffsetReg() const { return getOperand(3).getReg(); }
99
100 bool isPre() const { return getOperand(4).getImm() == 1; }
101 bool isPost() const { return !isPre(); }
102
103 static bool classof(const MachineInstr *MI) {
104 return MI->getOpcode() == TargetOpcode::G_INDEXED_LOAD;
105 }
106};
107
108/// Represents a G_INDEX_ZEXTLOAD/G_INDEXED_SEXTLOAD.
110public:
111 static bool classof(const MachineInstr *MI) {
112 return MI->getOpcode() == TargetOpcode::G_INDEXED_SEXTLOAD ||
113 MI->getOpcode() == TargetOpcode::G_INDEXED_ZEXTLOAD;
114 }
115};
116
117/// Represents either G_INDEXED_LOAD, G_INDEXED_ZEXTLOAD or G_INDEXED_SEXTLOAD.
119public:
120 static bool classof(const MachineInstr *MI) {
121 switch (MI->getOpcode()) {
122 case TargetOpcode::G_INDEXED_LOAD:
123 case TargetOpcode::G_INDEXED_ZEXTLOAD:
124 case TargetOpcode::G_INDEXED_SEXTLOAD:
125 return true;
126 default:
127 return false;
128 }
129 }
130};
131
132/// Represents a G_ZEXTLOAD.
134public:
135 static bool classof(const MachineInstr *MI) {
136 return MI->getOpcode() == TargetOpcode::G_INDEXED_ZEXTLOAD;
137 }
138};
139
140/// Represents a G_SEXTLOAD.
142public:
143 static bool classof(const MachineInstr *MI) {
144 return MI->getOpcode() == TargetOpcode::G_INDEXED_SEXTLOAD;
145 }
146};
147
148/// Represents indexed stores.
150public:
151 /// Get the def register of the writeback value.
152 Register getWritebackReg() const { return getOperand(0).getReg(); }
153 /// Get the stored value register.
154 Register getValueReg() const { return getOperand(1).getReg(); }
155 /// Get the base register of the pointer value.
156 Register getBaseReg() const { return getOperand(2).getReg(); }
157 /// Get the offset register of the pointer value.
158 Register getOffsetReg() const { return getOperand(3).getReg(); }
159
160 bool isPre() const { return getOperand(4).getImm() == 1; }
161 bool isPost() const { return !isPre(); }
162
163 static bool classof(const MachineInstr *MI) {
164 return MI->getOpcode() == TargetOpcode::G_INDEXED_STORE;
165 }
166};
167
168/// Represents any generic load, including sign/zero extending variants.
169class GAnyLoad : public GLoadStore {
170public:
171 /// Get the definition register of the loaded value.
172 Register getDstReg() const { return getOperand(0).getReg(); }
173
174 static bool classof(const MachineInstr *MI) {
175 switch (MI->getOpcode()) {
176 case TargetOpcode::G_LOAD:
177 case TargetOpcode::G_ZEXTLOAD:
178 case TargetOpcode::G_SEXTLOAD:
179 return true;
180 default:
181 return false;
182 }
183 }
184};
185
186/// Represents a G_LOAD.
187class GLoad : public GAnyLoad {
188public:
189 static bool classof(const MachineInstr *MI) {
190 return MI->getOpcode() == TargetOpcode::G_LOAD;
191 }
192};
193
194/// Represents either a G_SEXTLOAD or G_ZEXTLOAD.
195class GExtLoad : public GAnyLoad {
196public:
197 static bool classof(const MachineInstr *MI) {
198 return MI->getOpcode() == TargetOpcode::G_SEXTLOAD ||
199 MI->getOpcode() == TargetOpcode::G_ZEXTLOAD;
200 }
201};
202
203/// Represents a G_SEXTLOAD.
204class GSExtLoad : public GExtLoad {
205public:
206 static bool classof(const MachineInstr *MI) {
207 return MI->getOpcode() == TargetOpcode::G_SEXTLOAD;
208 }
209};
210
211/// Represents a G_ZEXTLOAD.
212class GZExtLoad : public GExtLoad {
213public:
214 static bool classof(const MachineInstr *MI) {
215 return MI->getOpcode() == TargetOpcode::G_ZEXTLOAD;
216 }
217};
218
219/// Represents a G_STORE.
220class GStore : public GLoadStore {
221public:
222 /// Get the stored value register.
223 Register getValueReg() const { return getOperand(0).getReg(); }
224
225 static bool classof(const MachineInstr *MI) {
226 return MI->getOpcode() == TargetOpcode::G_STORE;
227 }
228};
229
230/// Represents a G_UNMERGE_VALUES.
232public:
233 /// Returns the number of def registers.
234 unsigned getNumDefs() const { return getNumOperands() - 1; }
235 /// Get the unmerge source register.
237
238 static bool classof(const MachineInstr *MI) {
239 return MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES;
240 }
241};
242
243/// Represents G_BUILD_VECTOR, G_CONCAT_VECTORS or G_MERGE_VALUES.
244/// All these have the common property of generating a single value from
245/// multiple sources.
247public:
248 /// Returns the number of source registers.
249 unsigned getNumSources() const { return getNumOperands() - 1; }
250 /// Returns the I'th source register.
251 Register getSourceReg(unsigned I) const { return getReg(I + 1); }
252
253 static bool classof(const MachineInstr *MI) {
254 switch (MI->getOpcode()) {
255 case TargetOpcode::G_MERGE_VALUES:
256 case TargetOpcode::G_CONCAT_VECTORS:
257 case TargetOpcode::G_BUILD_VECTOR:
258 return true;
259 default:
260 return false;
261 }
262 }
263};
264
265/// Represents a G_MERGE_VALUES.
266class GMerge : public GMergeLikeInstr {
267public:
268 static bool classof(const MachineInstr *MI) {
269 return MI->getOpcode() == TargetOpcode::G_MERGE_VALUES;
270 }
271};
272
273/// Represents a G_CONCAT_VECTORS.
275public:
276 static bool classof(const MachineInstr *MI) {
277 return MI->getOpcode() == TargetOpcode::G_CONCAT_VECTORS;
278 }
279};
280
281/// Represents a G_BUILD_VECTOR.
283public:
284 static bool classof(const MachineInstr *MI) {
285 return MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR;
286 }
287};
288
289/// Represents a G_BUILD_VECTOR_TRUNC.
291public:
292 static bool classof(const MachineInstr *MI) {
293 return MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR_TRUNC;
294 }
295};
296
297/// Represents a G_SHUFFLE_VECTOR.
299public:
300 Register getSrc1Reg() const { return getOperand(1).getReg(); }
301 Register getSrc2Reg() const { return getOperand(2).getReg(); }
303
304 static bool classof(const MachineInstr *MI) {
305 return MI->getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR;
306 }
307};
308
309/// Represents a G_PTR_ADD.
311public:
312 Register getBaseReg() const { return getReg(1); }
313 Register getOffsetReg() const { return getReg(2); }
314
315 static bool classof(const MachineInstr *MI) {
316 return MI->getOpcode() == TargetOpcode::G_PTR_ADD;
317 }
318};
319
320/// Represents a G_IMPLICIT_DEF.
322public:
323 static bool classof(const MachineInstr *MI) {
324 return MI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF;
325 }
326};
327
328/// Represents a G_SELECT.
330public:
331 Register getCondReg() const { return getReg(1); }
332 Register getTrueReg() const { return getReg(2); }
333 Register getFalseReg() const { return getReg(3); }
334
335 static bool classof(const MachineInstr *MI) {
336 return MI->getOpcode() == TargetOpcode::G_SELECT;
337 }
338};
339
340/// Represent a G_ICMP or G_FCMP.
342public:
344 return static_cast<CmpInst::Predicate>(getOperand(1).getPredicate());
345 }
346 Register getLHSReg() const { return getReg(2); }
347 Register getRHSReg() const { return getReg(3); }
348
349 static bool classof(const MachineInstr *MI) {
350 return MI->getOpcode() == TargetOpcode::G_ICMP ||
351 MI->getOpcode() == TargetOpcode::G_FCMP;
352 }
353};
354
355/// Represent a G_ICMP.
356class GICmp : public GAnyCmp {
357public:
358 static bool classof(const MachineInstr *MI) {
359 return MI->getOpcode() == TargetOpcode::G_ICMP;
360 }
361};
362
363/// Represent a G_FCMP.
364class GFCmp : public GAnyCmp {
365public:
366 static bool classof(const MachineInstr *MI) {
367 return MI->getOpcode() == TargetOpcode::G_FCMP;
368 }
369};
370
371/// Represents overflowing binary operations.
372/// Only carry-out:
373/// G_UADDO, G_SADDO, G_USUBO, G_SSUBO, G_UMULO, G_SMULO
374/// Carry-in and carry-out:
375/// G_UADDE, G_SADDE, G_USUBE, G_SSUBE
377public:
378 Register getDstReg() const { return getReg(0); }
379 Register getCarryOutReg() const { return getReg(1); }
382 Register getLHSReg() const { return getOperand(2).getReg(); }
383 Register getRHSReg() const { return getOperand(3).getReg(); }
384
385 static bool classof(const MachineInstr *MI) {
386 switch (MI->getOpcode()) {
387 case TargetOpcode::G_UADDO:
388 case TargetOpcode::G_SADDO:
389 case TargetOpcode::G_USUBO:
390 case TargetOpcode::G_SSUBO:
391 case TargetOpcode::G_UADDE:
392 case TargetOpcode::G_SADDE:
393 case TargetOpcode::G_USUBE:
394 case TargetOpcode::G_SSUBE:
395 case TargetOpcode::G_UMULO:
396 case TargetOpcode::G_SMULO:
397 return true;
398 default:
399 return false;
400 }
401 }
402};
403
404/// Represents overflowing add/sub operations.
405/// Only carry-out:
406/// G_UADDO, G_SADDO, G_USUBO, G_SSUBO
407/// Carry-in and carry-out:
408/// G_UADDE, G_SADDE, G_USUBE, G_SSUBE
410public:
411 bool isAdd() const {
412 switch (getOpcode()) {
413 case TargetOpcode::G_UADDO:
414 case TargetOpcode::G_SADDO:
415 case TargetOpcode::G_UADDE:
416 case TargetOpcode::G_SADDE:
417 return true;
418 default:
419 return false;
420 }
421 }
422 bool isSub() const { return !isAdd(); }
423
424 bool isSigned() const {
425 switch (getOpcode()) {
426 case TargetOpcode::G_SADDO:
427 case TargetOpcode::G_SSUBO:
428 case TargetOpcode::G_SADDE:
429 case TargetOpcode::G_SSUBE:
430 return true;
431 default:
432 return false;
433 }
434 }
435 bool isUnsigned() const { return !isSigned(); }
436
437 static bool classof(const MachineInstr *MI) {
438 switch (MI->getOpcode()) {
439 case TargetOpcode::G_UADDO:
440 case TargetOpcode::G_SADDO:
441 case TargetOpcode::G_USUBO:
442 case TargetOpcode::G_SSUBO:
443 case TargetOpcode::G_UADDE:
444 case TargetOpcode::G_SADDE:
445 case TargetOpcode::G_USUBE:
446 case TargetOpcode::G_SSUBE:
447 return true;
448 default:
449 return false;
450 }
451 }
452};
453
454/// Represents overflowing add operations.
455/// G_UADDO, G_SADDO
457public:
458 bool isSigned() const { return getOpcode() == TargetOpcode::G_SADDO; }
459
460 static bool classof(const MachineInstr *MI) {
461 switch (MI->getOpcode()) {
462 case TargetOpcode::G_UADDO:
463 case TargetOpcode::G_SADDO:
464 return true;
465 default:
466 return false;
467 }
468 }
469};
470
471/// Represents overflowing add/sub operations that also consume a carry-in.
472/// G_UADDE, G_SADDE, G_USUBE, G_SSUBE
474public:
475 Register getCarryInReg() const { return getReg(4); }
476
477 static bool classof(const MachineInstr *MI) {
478 switch (MI->getOpcode()) {
479 case TargetOpcode::G_UADDE:
480 case TargetOpcode::G_SADDE:
481 case TargetOpcode::G_USUBE:
482 case TargetOpcode::G_SSUBE:
483 return true;
484 default:
485 return false;
486 }
487 }
488};
489
490/// Represents a call to an intrinsic.
491class GIntrinsic final : public GenericMachineInstr {
492public:
495 }
496
497 bool is(Intrinsic::ID ID) const { return getIntrinsicID() == ID; }
498
499 bool hasSideEffects() const {
500 switch (getOpcode()) {
501 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
502 case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
503 return true;
504 default:
505 return false;
506 }
507 }
508
509 bool isConvergent() const {
510 switch (getOpcode()) {
511 case TargetOpcode::G_INTRINSIC_CONVERGENT:
512 case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
513 return true;
514 default:
515 return false;
516 }
517 }
518
519 static bool classof(const MachineInstr *MI) {
520 switch (MI->getOpcode()) {
521 case TargetOpcode::G_INTRINSIC:
522 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
523 case TargetOpcode::G_INTRINSIC_CONVERGENT:
524 case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
525 return true;
526 default:
527 return false;
528 }
529 }
530};
531
532// Represents a (non-sequential) vector reduction operation.
534public:
535 static bool classof(const MachineInstr *MI) {
536 switch (MI->getOpcode()) {
537 case TargetOpcode::G_VECREDUCE_FADD:
538 case TargetOpcode::G_VECREDUCE_FMUL:
539 case TargetOpcode::G_VECREDUCE_FMAX:
540 case TargetOpcode::G_VECREDUCE_FMIN:
541 case TargetOpcode::G_VECREDUCE_FMAXIMUM:
542 case TargetOpcode::G_VECREDUCE_FMINIMUM:
543 case TargetOpcode::G_VECREDUCE_ADD:
544 case TargetOpcode::G_VECREDUCE_MUL:
545 case TargetOpcode::G_VECREDUCE_AND:
546 case TargetOpcode::G_VECREDUCE_OR:
547 case TargetOpcode::G_VECREDUCE_XOR:
548 case TargetOpcode::G_VECREDUCE_SMAX:
549 case TargetOpcode::G_VECREDUCE_SMIN:
550 case TargetOpcode::G_VECREDUCE_UMAX:
551 case TargetOpcode::G_VECREDUCE_UMIN:
552 return true;
553 default:
554 return false;
555 }
556 }
557
558 /// Get the opcode for the equivalent scalar operation for this reduction.
559 /// E.g. for G_VECREDUCE_FADD, this returns G_FADD.
561 unsigned ScalarOpc;
562 switch (getOpcode()) {
563 case TargetOpcode::G_VECREDUCE_FADD:
564 ScalarOpc = TargetOpcode::G_FADD;
565 break;
566 case TargetOpcode::G_VECREDUCE_FMUL:
567 ScalarOpc = TargetOpcode::G_FMUL;
568 break;
569 case TargetOpcode::G_VECREDUCE_FMAX:
570 ScalarOpc = TargetOpcode::G_FMAXNUM;
571 break;
572 case TargetOpcode::G_VECREDUCE_FMIN:
573 ScalarOpc = TargetOpcode::G_FMINNUM;
574 break;
575 case TargetOpcode::G_VECREDUCE_FMAXIMUM:
576 ScalarOpc = TargetOpcode::G_FMAXIMUM;
577 break;
578 case TargetOpcode::G_VECREDUCE_FMINIMUM:
579 ScalarOpc = TargetOpcode::G_FMINIMUM;
580 break;
581 case TargetOpcode::G_VECREDUCE_ADD:
582 ScalarOpc = TargetOpcode::G_ADD;
583 break;
584 case TargetOpcode::G_VECREDUCE_MUL:
585 ScalarOpc = TargetOpcode::G_MUL;
586 break;
587 case TargetOpcode::G_VECREDUCE_AND:
588 ScalarOpc = TargetOpcode::G_AND;
589 break;
590 case TargetOpcode::G_VECREDUCE_OR:
591 ScalarOpc = TargetOpcode::G_OR;
592 break;
593 case TargetOpcode::G_VECREDUCE_XOR:
594 ScalarOpc = TargetOpcode::G_XOR;
595 break;
596 case TargetOpcode::G_VECREDUCE_SMAX:
597 ScalarOpc = TargetOpcode::G_SMAX;
598 break;
599 case TargetOpcode::G_VECREDUCE_SMIN:
600 ScalarOpc = TargetOpcode::G_SMIN;
601 break;
602 case TargetOpcode::G_VECREDUCE_UMAX:
603 ScalarOpc = TargetOpcode::G_UMAX;
604 break;
605 case TargetOpcode::G_VECREDUCE_UMIN:
606 ScalarOpc = TargetOpcode::G_UMIN;
607 break;
608 default:
609 llvm_unreachable("Unhandled reduction");
610 }
611 return ScalarOpc;
612 }
613};
614
615/// Represents a G_PHI.
616class GPhi : public GenericMachineInstr {
617public:
618 /// Returns the number of incoming values.
619 unsigned getNumIncomingValues() const { return (getNumOperands() - 1) / 2; }
620 /// Returns the I'th incoming vreg.
621 Register getIncomingValue(unsigned I) const {
622 return getOperand(I * 2 + 1).getReg();
623 }
624 /// Returns the I'th incoming basic block.
626 return getOperand(I * 2 + 2).getMBB();
627 }
628
629 static bool classof(const MachineInstr *MI) {
630 return MI->getOpcode() == TargetOpcode::G_PHI;
631 }
632};
633
634/// Represents a binary operation, i.e, x = y op z.
636public:
637 Register getLHSReg() const { return getReg(1); }
638 Register getRHSReg() const { return getReg(2); }
639
640 static bool classof(const MachineInstr *MI) {
641 switch (MI->getOpcode()) {
642 // Integer.
643 case TargetOpcode::G_ADD:
644 case TargetOpcode::G_SUB:
645 case TargetOpcode::G_MUL:
646 case TargetOpcode::G_SDIV:
647 case TargetOpcode::G_UDIV:
648 case TargetOpcode::G_SREM:
649 case TargetOpcode::G_UREM:
650 case TargetOpcode::G_SMIN:
651 case TargetOpcode::G_SMAX:
652 case TargetOpcode::G_UMIN:
653 case TargetOpcode::G_UMAX:
654 // Floating point.
655 case TargetOpcode::G_FMINNUM:
656 case TargetOpcode::G_FMAXNUM:
657 case TargetOpcode::G_FMINNUM_IEEE:
658 case TargetOpcode::G_FMAXNUM_IEEE:
659 case TargetOpcode::G_FMINIMUM:
660 case TargetOpcode::G_FMAXIMUM:
661 case TargetOpcode::G_FADD:
662 case TargetOpcode::G_FSUB:
663 case TargetOpcode::G_FMUL:
664 case TargetOpcode::G_FDIV:
665 case TargetOpcode::G_FPOW:
666 // Logical.
667 case TargetOpcode::G_AND:
668 case TargetOpcode::G_OR:
669 case TargetOpcode::G_XOR:
670 return true;
671 default:
672 return false;
673 }
674 };
675};
676
677/// Represents an integer binary operation.
678class GIntBinOp : public GBinOp {
679public:
680 static bool classof(const MachineInstr *MI) {
681 switch (MI->getOpcode()) {
682 case TargetOpcode::G_ADD:
683 case TargetOpcode::G_SUB:
684 case TargetOpcode::G_MUL:
685 case TargetOpcode::G_SDIV:
686 case TargetOpcode::G_UDIV:
687 case TargetOpcode::G_SREM:
688 case TargetOpcode::G_UREM:
689 case TargetOpcode::G_SMIN:
690 case TargetOpcode::G_SMAX:
691 case TargetOpcode::G_UMIN:
692 case TargetOpcode::G_UMAX:
693 return true;
694 default:
695 return false;
696 }
697 };
698};
699
700/// Represents a floating point binary operation.
701class GFBinOp : public GBinOp {
702public:
703 static bool classof(const MachineInstr *MI) {
704 switch (MI->getOpcode()) {
705 case TargetOpcode::G_FMINNUM:
706 case TargetOpcode::G_FMAXNUM:
707 case TargetOpcode::G_FMINNUM_IEEE:
708 case TargetOpcode::G_FMAXNUM_IEEE:
709 case TargetOpcode::G_FMINIMUM:
710 case TargetOpcode::G_FMAXIMUM:
711 case TargetOpcode::G_FADD:
712 case TargetOpcode::G_FSUB:
713 case TargetOpcode::G_FMUL:
714 case TargetOpcode::G_FDIV:
715 case TargetOpcode::G_FPOW:
716 return true;
717 default:
718 return false;
719 }
720 };
721};
722
723/// Represents a logical binary operation.
724class GLogicalBinOp : public GBinOp {
725public:
726 static bool classof(const MachineInstr *MI) {
727 switch (MI->getOpcode()) {
728 case TargetOpcode::G_AND:
729 case TargetOpcode::G_OR:
730 case TargetOpcode::G_XOR:
731 return true;
732 default:
733 return false;
734 }
735 };
736};
737
738/// Represents an integer addition.
739class GAdd : public GIntBinOp {
740public:
741 static bool classof(const MachineInstr *MI) {
742 return MI->getOpcode() == TargetOpcode::G_ADD;
743 };
744};
745
746/// Represents a logical and.
747class GAnd : public GLogicalBinOp {
748public:
749 static bool classof(const MachineInstr *MI) {
750 return MI->getOpcode() == TargetOpcode::G_AND;
751 };
752};
753
754/// Represents a logical or.
755class GOr : public GLogicalBinOp {
756public:
757 static bool classof(const MachineInstr *MI) {
758 return MI->getOpcode() == TargetOpcode::G_OR;
759 };
760};
761
762/// Represents an extract vector element.
764public:
765 Register getVectorReg() const { return getOperand(1).getReg(); }
766 Register getIndexReg() const { return getOperand(2).getReg(); }
767
768 static bool classof(const MachineInstr *MI) {
769 return MI->getOpcode() == TargetOpcode::G_EXTRACT_VECTOR_ELT;
770 }
771};
772
773/// Represents an insert vector element.
775public:
776 Register getVectorReg() const { return getOperand(1).getReg(); }
777 Register getElementReg() const { return getOperand(2).getReg(); }
778 Register getIndexReg() const { return getOperand(3).getReg(); }
779
780 static bool classof(const MachineInstr *MI) {
781 return MI->getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT;
782 }
783};
784
785/// Represents a freeze.
787public:
788 Register getSourceReg() const { return getOperand(1).getReg(); }
789
790 static bool classof(const MachineInstr *MI) {
791 return MI->getOpcode() == TargetOpcode::G_FREEZE;
792 }
793};
794
795} // namespace llvm
796
797#endif // LLVM_CODEGEN_GLOBALISEL_GENERICMACHINEINSTRS_H
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:993
Represents overflowing add operations.
static bool classof(const MachineInstr *MI)
Represents overflowing add/sub operations that also consume a carry-in.
static bool classof(const MachineInstr *MI)
Represents overflowing add/sub operations.
static bool classof(const MachineInstr *MI)
Represents an integer addition.
static bool classof(const MachineInstr *MI)
Represents a logical and.
static bool classof(const MachineInstr *MI)
Represent a G_ICMP or G_FCMP.
static bool classof(const MachineInstr *MI)
CmpInst::Predicate getCond() const
Register getLHSReg() const
Register getRHSReg() const
Represents any generic load, including sign/zero extending variants.
Register getDstReg() const
Get the definition register of the loaded value.
static bool classof(const MachineInstr *MI)
Represents overflowing binary operations.
MachineOperand & getRHS()
MachineOperand & getLHS()
Register getCarryOutReg() const
Register getDstReg() const
static bool classof(const MachineInstr *MI)
Register getRHSReg() const
Register getLHSReg() const
Represents a binary operation, i.e, x = y op z.
Register getLHSReg() const
static bool classof(const MachineInstr *MI)
Register getRHSReg() const
Represents a G_BUILD_VECTOR_TRUNC.
static bool classof(const MachineInstr *MI)
Represents a G_BUILD_VECTOR.
static bool classof(const MachineInstr *MI)
Represents a G_CONCAT_VECTORS.
static bool classof(const MachineInstr *MI)
Represents either a G_SEXTLOAD or G_ZEXTLOAD.
static bool classof(const MachineInstr *MI)
Represents an extract vector element.
static bool classof(const MachineInstr *MI)
Represents a floating point binary operation.
static bool classof(const MachineInstr *MI)
Represent a G_FCMP.
static bool classof(const MachineInstr *MI)
Represents a freeze.
Register getSourceReg() const
static bool classof(const MachineInstr *MI)
Represent a G_ICMP.
static bool classof(const MachineInstr *MI)
Represents a G_IMPLICIT_DEF.
static bool classof(const MachineInstr *MI)
Represents either G_INDEXED_LOAD, G_INDEXED_ZEXTLOAD or G_INDEXED_SEXTLOAD.
static bool classof(const MachineInstr *MI)
Represents a G_INDEX_ZEXTLOAD/G_INDEXED_SEXTLOAD.
static bool classof(const MachineInstr *MI)
Represents indexed loads.
static bool classof(const MachineInstr *MI)
Register getOffsetReg() const
Get the offset register of the pointer value.
Register getWritebackReg() const
Get the def register of the writeback value.
Register getDstReg() const
Get the definition register of the loaded value.
Register getBaseReg() const
Get the base register of the pointer value.
Represents a G_SEXTLOAD.
static bool classof(const MachineInstr *MI)
Represents indexed stores.
Register getOffsetReg() const
Get the offset register of the pointer value.
Register getValueReg() const
Get the stored value register.
Register getBaseReg() const
Get the base register of the pointer value.
static bool classof(const MachineInstr *MI)
Register getWritebackReg() const
Get the def register of the writeback value.
Represents a G_ZEXTLOAD.
static bool classof(const MachineInstr *MI)
Represents an insert vector element.
static bool classof(const MachineInstr *MI)
Represents an integer binary operation.
static bool classof(const MachineInstr *MI)
Represents a call to an intrinsic.
Intrinsic::ID getIntrinsicID() const
bool is(Intrinsic::ID ID) const
static bool classof(const MachineInstr *MI)
bool hasSideEffects() const
Represents any type of generic load or store.
Register getPointerReg() const
Get the source register of the pointer value.
static bool classof(const MachineInstr *MI)
Represents a G_LOAD.
static bool classof(const MachineInstr *MI)
Represents a logical binary operation.
static bool classof(const MachineInstr *MI)
Provides common memory operand functionality.
MachineMemOperand & getMMO() const
Get the MachineMemOperand on this instruction.
LocationSize getMemSize() const
Returns the size in bytes of the memory access.
bool isUnordered() const
Returns true if this memory operation doesn't have any ordering constraints other than normal aliasin...
bool isAtomic() const
Returns true if the attached MachineMemOperand has the atomic flag set.
bool isVolatile() const
Returns true if the attached MachineMemOpeand as the volatile flag set.
static bool classof(const MachineInstr *MI)
LocationSize getMemSizeInBits() const
Returns the size in bits of the memory access.
bool isSimple() const
Returns true if the memory operation is neither atomic or volatile.
Represents G_BUILD_VECTOR, G_CONCAT_VECTORS or G_MERGE_VALUES.
Register getSourceReg(unsigned I) const
Returns the I'th source register.
unsigned getNumSources() const
Returns the number of source registers.
static bool classof(const MachineInstr *MI)
Represents a G_MERGE_VALUES.
static bool classof(const MachineInstr *MI)
Represents a logical or.
static bool classof(const MachineInstr *MI)
Represents a G_PHI.
MachineBasicBlock * getIncomingBlock(unsigned I) const
Returns the I'th incoming basic block.
Register getIncomingValue(unsigned I) const
Returns the I'th incoming vreg.
static bool classof(const MachineInstr *MI)
unsigned getNumIncomingValues() const
Returns the number of incoming values.
Represents a G_PTR_ADD.
Register getOffsetReg() const
static bool classof(const MachineInstr *MI)
Register getBaseReg() const
Represents a G_SEXTLOAD.
static bool classof(const MachineInstr *MI)
Represents a G_SELECT.
Register getCondReg() const
static bool classof(const MachineInstr *MI)
Register getFalseReg() const
Register getTrueReg() const
Represents a G_SHUFFLE_VECTOR.
static bool classof(const MachineInstr *MI)
Register getSrc2Reg() const
Register getSrc1Reg() const
ArrayRef< int > getMask() const
Represents a G_STORE.
static bool classof(const MachineInstr *MI)
Register getValueReg() const
Get the stored value register.
Represents a G_UNMERGE_VALUES.
unsigned getNumDefs() const
Returns the number of def registers.
static bool classof(const MachineInstr *MI)
Register getSourceReg() const
Get the unmerge source register.
unsigned getScalarOpcForReduction()
Get the opcode for the equivalent scalar operation for this reduction.
static bool classof(const MachineInstr *MI)
Represents a G_ZEXTLOAD.
static bool classof(const MachineInstr *MI)
A base class for all GenericMachineInstrs.
static bool classof(const MachineInstr *MI)
Register getReg(unsigned Idx) const
Access the Idx'th operand as a register and return it.
Representation of each machine instruction.
Definition: MachineInstr.h:69
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:558
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:561
unsigned getNumExplicitDefs() const
Returns the number of non-implicit definitions.
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
Definition: MachineInstr.h:789
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:568
A description of a memory reference used in the backend.
LocationSize getSize() const
Return the size in bytes of the memory reference.
bool isUnordered() const
Returns true if this memory operation doesn't have any ordering constraints other than normal aliasin...
bool isAtomic() const
Returns true if this operation has an atomic ordering requirement of unordered or higher,...
LocationSize getSizeInBits() const
Return the size in bits of the memory reference.
MachineOperand class - Representation of each machine instruction operand.
int64_t getImm() const
MachineBasicBlock * getMBB() const
ArrayRef< int > getShuffleMask() const
Register getReg() const
getReg - Returns the register number.
Intrinsic::ID getIntrinsicID() const
unsigned getPredicate() const
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
#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
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
bool isPreISelGenericOpcode(unsigned Opcode)
Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel.
Definition: TargetOpcodes.h:30