@@ -57,11 +57,20 @@ class RISCVInstructionSelector : public InstructionSelector {
57
57
const TargetRegisterClass *
58
58
getRegClassForTypeOnBank (LLT Ty, const RegisterBank &RB) const ;
59
59
60
+ static constexpr unsigned MaxRecursionDepth = 6 ;
61
+
60
62
// const MachineInstr &MI
61
- bool hasAllNBitUsers (const MachineInstr &MI, unsigned Bits, const unsigned Depth = 0 ) const ;
62
- bool hasAllBUsers (const MachineInstr &MI) const { return hasAllNBitUsers (MI, 8 ); }
63
- bool hasAllHUsers (const MachineInstr &MI) const { return hasAllNBitUsers (MI, 16 ); }
64
- bool hasAllWUsers (const MachineInstr &MI) const { return hasAllNBitUsers (MI, 32 ); }
63
+ bool hasAllNBitUsers (const MachineInstr &MI, unsigned Bits,
64
+ const unsigned Depth = 0 ) const ;
65
+ bool hasAllBUsers (const MachineInstr &MI) const {
66
+ return hasAllNBitUsers (MI, 8 );
67
+ }
68
+ bool hasAllHUsers (const MachineInstr &MI) const {
69
+ return hasAllNBitUsers (MI, 16 );
70
+ }
71
+ bool hasAllWUsers (const MachineInstr &MI) const {
72
+ return hasAllNBitUsers (MI, 32 );
73
+ }
65
74
66
75
bool isRegInGprb (Register Reg) const ;
67
76
bool isRegInFprb (Register Reg) const ;
@@ -192,9 +201,78 @@ RISCVInstructionSelector::RISCVInstructionSelector(
192
201
{
193
202
}
194
203
195
- bool RISCVInstructionSelector::hasAllNBitUsers (const MachineInstr &MI, unsigned Bits, const unsigned Depth) const {
204
+ // Mimics optimizations in ISel and RISCVOptWInst Pass
205
+ bool RISCVInstructionSelector::hasAllNBitUsers (const MachineInstr &MI,
206
+ unsigned Bits,
207
+ const unsigned Depth) const {
208
+
209
+ assert ((MI.getOpcode () == TargetOpcode::G_ADD ||
210
+ MI.getOpcode () == TargetOpcode::G_SUB ||
211
+ MI.getOpcode () == TargetOpcode::G_MUL ||
212
+ MI.getOpcode () == TargetOpcode::G_SHL ||
213
+ MI.getOpcode () == TargetOpcode::G_LSHR ||
214
+ MI.getOpcode () == TargetOpcode::G_AND ||
215
+ MI.getOpcode () == TargetOpcode::G_OR ||
216
+ MI.getOpcode () == TargetOpcode::G_XOR ||
217
+ MI.getOpcode () == TargetOpcode::G_SEXT_INREG || Depth != 0 ) &&
218
+ " Unexpected opcode" );
219
+
220
+ if (Depth >= RISCVInstructionSelector::MaxRecursionDepth)
196
221
return false ;
197
- };
222
+
223
+ auto DestReg = MI.getOperand (0 ).getReg ();
224
+ for (auto &UserOp : MRI->use_nodbg_operands (DestReg)) {
225
+ assert (UserOp.getParent () && " UserOp must have a parent" );
226
+ const MachineInstr &UserMI = *UserOp.getParent ();
227
+ unsigned OpIdx = UserOp.getOperandNo ();
228
+
229
+ switch (UserMI.getOpcode ()) {
230
+ default :
231
+ return false ;
232
+ case RISCV::ADDW:
233
+ case RISCV::ADDIW:
234
+ case RISCV::SUBW:
235
+ if (Bits >= 32 )
236
+ break ;
237
+ return false ;
238
+ case RISCV::SLL:
239
+ case RISCV::SRA:
240
+ case RISCV::SRL:
241
+ // Shift amount operands only use log2(Xlen) bits.
242
+ if (OpIdx == 2 && Bits >= Log2_32 (Subtarget->getXLen ()))
243
+ break ;
244
+ return false ;
245
+ case RISCV::SLLI:
246
+ // SLLI only uses the lower (XLen - ShAmt) bits.
247
+ if (Bits >= Subtarget->getXLen () - UserMI.getOperand (2 ).getImm ())
248
+ break ;
249
+ return false ;
250
+ case RISCV::ANDI:
251
+ if (Bits >= (unsigned )llvm::bit_width<uint64_t >(
252
+ (uint64_t )UserMI.getOperand (2 ).getImm ()))
253
+ break ;
254
+ goto RecCheck;
255
+ case RISCV::AND:
256
+ case RISCV::OR:
257
+ case RISCV::XOR:
258
+ RecCheck:
259
+ if (hasAllNBitUsers (UserMI, Bits, Depth + 1 ))
260
+ break ;
261
+ return false ;
262
+ case RISCV::SRLI: {
263
+ unsigned ShAmt = UserMI.getOperand (2 ).getImm ();
264
+ // If we are shifting right by less than Bits, and users don't demand any
265
+ // bits that were shifted into [Bits-1:0], then we can consider this as an
266
+ // N-Bit user.
267
+ if (Bits > ShAmt && hasAllNBitUsers (UserMI, Bits - ShAmt, Depth + 1 ))
268
+ break ;
269
+ return false ;
270
+ }
271
+ }
272
+ }
273
+
274
+ return true ;
275
+ }
198
276
199
277
InstructionSelector::ComplexRendererFns
200
278
RISCVInstructionSelector::selectShiftMask (MachineOperand &Root,
0 commit comments