1//===- LanaiInstrInfo.h - 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#ifndef LLVM_LIB_TARGET_LANAI_LANAIINSTRINFO_H
14#define LLVM_LIB_TARGET_LANAI_LANAIINSTRINFO_H
15
16#include "LanaiRegisterInfo.h"
17#include "MCTargetDesc/LanaiMCTargetDesc.h"
18#include "llvm/CodeGen/TargetInstrInfo.h"
19
20#define GET_INSTRINFO_HEADER
21#include "LanaiGenInstrInfo.inc"
22
23namespace llvm {
24
25class LanaiSubtarget;
26
27class LanaiInstrInfo : public LanaiGenInstrInfo {
28 const LanaiRegisterInfo RegisterInfo;
29
30public:
31 LanaiInstrInfo(const LanaiSubtarget &STI);
32
33 // getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As
34 // such, whenever a client has an instance of instruction info, it should
35 // always be able to get register info as well (through this method).
36 virtual const LanaiRegisterInfo &getRegisterInfo() const {
37 return RegisterInfo;
38 }
39
40 bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa,
41 const MachineInstr &MIb) const override;
42
43 Register isLoadFromStackSlot(const MachineInstr &MI,
44 int &FrameIndex) const override;
45
46 Register isLoadFromStackSlotPostFE(const MachineInstr &MI,
47 int &FrameIndex) const override;
48
49 Register isStoreToStackSlot(const MachineInstr &MI,
50 int &FrameIndex) const override;
51
52 void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator Position,
53 const DebugLoc &DL, Register DestinationRegister,
54 Register SourceRegister, bool KillSource,
55 bool RenamableDest = false,
56 bool RenamableSrc = false) const override;
57
58 void storeRegToStackSlot(
59 MachineBasicBlock &MBB, MachineBasicBlock::iterator Position,
60 Register SourceRegister, bool IsKill, int FrameIndex,
61 const TargetRegisterClass *RegisterClass, Register VReg,
62 MachineInstr::MIFlag Flags = MachineInstr::NoFlags) const override;
63
64 void loadRegFromStackSlot(
65 MachineBasicBlock &MBB, MachineBasicBlock::iterator Position,
66 Register DestinationRegister, int FrameIndex,
67 const TargetRegisterClass *RegisterClass, Register VReg,
68 unsigned SubReg = 0,
69 MachineInstr::MIFlag Flags = MachineInstr::NoFlags) const override;
70
71 bool expandPostRAPseudo(MachineInstr &MI) const override;
72
73 bool getMemOperandsWithOffsetWidth(
74 const MachineInstr &LdSt,
75 SmallVectorImpl<const MachineOperand *> &BaseOps, int64_t &Offset,
76 bool &OffsetIsScalable, LocationSize &Width,
77 const TargetRegisterInfo *TRI) const override;
78
79 bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt,
80 const MachineOperand *&BaseOp,
81 int64_t &Offset, LocationSize &Width,
82 const TargetRegisterInfo *TRI) const;
83
84 std::pair<unsigned, unsigned>
85 decomposeMachineOperandsTargetFlags(unsigned TF) const override;
86
87 ArrayRef<std::pair<unsigned, const char *>>
88 getSerializableDirectMachineOperandTargetFlags() const override;
89
90 bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TrueBlock,
91 MachineBasicBlock *&FalseBlock,
92 SmallVectorImpl<MachineOperand> &Condition,
93 bool AllowModify) const override;
94
95 unsigned removeBranch(MachineBasicBlock &MBB,
96 int *BytesRemoved = nullptr) const override;
97
98 // For a comparison instruction, return the source registers in SrcReg and
99 // SrcReg2 if having two register operands, and the value it compares against
100 // in CmpValue. Return true if the comparison instruction can be analyzed.
101 bool analyzeCompare(const MachineInstr &MI, Register &SrcReg,
102 Register &SrcReg2, int64_t &CmpMask,
103 int64_t &CmpValue) const override;
104
105 // See if the comparison instruction can be converted into something more
106 // efficient. E.g., on Lanai register-register instructions can set the flag
107 // register, obviating the need for a separate compare.
108 bool optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg,
109 Register SrcReg2, int64_t CmpMask, int64_t CmpValue,
110 const MachineRegisterInfo *MRI) const override;
111
112 // Analyze the given select instruction, returning true if it cannot be
113 // understood. It is assumed that MI->isSelect() is true.
114 //
115 // When successful, return the controlling condition and the operands that
116 // determine the true and false result values.
117 //
118 // Result = SELECT Cond, TrueOp, FalseOp
119 //
120 // Lanai can optimize certain select instructions, for example by predicating
121 // the instruction defining one of the operands and sets Optimizable to true.
122 bool analyzeSelect(const MachineInstr &MI,
123 SmallVectorImpl<MachineOperand> &Cond, unsigned &TrueOp,
124 unsigned &FalseOp, bool &Optimizable) const override;
125
126 // Given a select instruction that was understood by analyzeSelect and
127 // returned Optimizable = true, attempt to optimize MI by merging it with one
128 // of its operands. Returns NULL on failure.
129 //
130 // When successful, returns the new select instruction. The client is
131 // responsible for deleting MI.
132 //
133 // If both sides of the select can be optimized, the TrueOp is modifed.
134 // PreferFalse is not used.
135 MachineInstr *optimizeSelect(MachineInstr &MI,
136 SmallPtrSetImpl<MachineInstr *> &SeenMIs,
137 bool PreferFalse) const override;
138
139 bool reverseBranchCondition(
140 SmallVectorImpl<MachineOperand> &Condition) const override;
141
142 unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TrueBlock,
143 MachineBasicBlock *FalseBlock,
144 ArrayRef<MachineOperand> Condition,
145 const DebugLoc &DL,
146 int *BytesAdded = nullptr) const override;
147};
148
149static inline bool isSPLSOpcode(unsigned Opcode) {
150 switch (Opcode) {
151 case Lanai::LDBs_RI:
152 case Lanai::LDBz_RI:
153 case Lanai::LDHs_RI:
154 case Lanai::LDHz_RI:
155 case Lanai::STB_RI:
156 case Lanai::STH_RI:
157 return true;
158 default:
159 return false;
160 }
161}
162
163static inline bool isRMOpcode(unsigned Opcode) {
164 switch (Opcode) {
165 case Lanai::LDW_RI:
166 case Lanai::SW_RI:
167 return true;
168 default:
169 return false;
170 }
171}
172
173static inline bool isRRMOpcode(unsigned Opcode) {
174 switch (Opcode) {
175 case Lanai::LDBs_RR:
176 case Lanai::LDBz_RR:
177 case Lanai::LDHs_RR:
178 case Lanai::LDHz_RR:
179 case Lanai::LDWz_RR:
180 case Lanai::LDW_RR:
181 case Lanai::STB_RR:
182 case Lanai::STH_RR:
183 case Lanai::SW_RR:
184 return true;
185 default:
186 return false;
187 }
188}
189
190} // namespace llvm
191
192#endif // LLVM_LIB_TARGET_LANAI_LANAIINSTRINFO_H
193