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