77#define DEBUG_TYPE "riscv-make-compressible"
78#define RISCV_COMPRESS_INSTRS_NAME "RISC-V Make Compressible"
93char RISCVMakeCompressibleOpt::ID = 0;
98static
unsigned log2LdstWidth(
unsigned Opcode) {
104 case RISCV::QC_E_LBU:
113 case RISCV::QC_E_LHU:
142 case RISCV::QC_E_LBU:
151 case RISCV::QC_E_LHU:
175 return offsetMask(Opcode) << log2LdstWidth(Opcode);
182 switch (log2LdstWidth(Opcode)) {
201 return RISCV::GPRCRegClass.contains(
Reg) ||
202 RISCV::GPRF16CRegClass.contains(
Reg) ||
203 RISCV::GPRF32CRegClass.contains(
Reg) ||
204 RISCV::FPR32CRegClass.contains(
Reg) ||
205 RISCV::FPR64CRegClass.contains(
Reg) ||
206 RISCV::GPRPairCRegClass.contains(
Reg);
213 switch (
MI.getOpcode()) {
220 return STI.hasStdExtZcb();
224 return STI.hasStdExtZca();
226 return STI.hasStdExtZclsd();
228 return !STI.
is64Bit() && STI.hasStdExtZcf();
230 return STI.hasStdExtZcd();
233 case RISCV::QC_E_LBU:
235 case RISCV::QC_E_LHU:
236 return !STI.
is64Bit() && STI.hasVendorXqcilo() && STI.hasVendorXqcilia() &&
239 return !STI.
is64Bit() && STI.hasVendorXqcilo() && STI.hasVendorXqcilia();
247 switch (
MI.getOpcode()) {
253 return STI.hasStdExtZcb();
257 return STI.hasStdExtZca();
259 return STI.hasStdExtZclsd();
261 return !STI.
is64Bit() && STI.hasStdExtZcf();
263 return STI.hasStdExtZcd();
268 return !STI.
is64Bit() && STI.hasVendorXqcilo() && STI.hasVendorXqcilia() &&
271 return !STI.
is64Bit() && STI.hasVendorXqcilo() && STI.hasVendorXqcilia();
288 const unsigned Opcode =
MI.getOpcode();
311 if ((!BaseCompressed || NewBaseAdjust) && SrcDestCompressed)
320 if (!SrcDestCompressed && (BaseCompressed || SrcDest ==
Base) &&
330 switch (
MI.getOpcode()) {
336 case RISCV::QC_E_LBU:
338 case RISCV::QC_E_LHU:
355 MBB.getParent()->getSubtarget().getRegisterInfo();
356 bool XqciloLdSt =
false;
366 if (CandidateRegImm.
Reg == RegImm.Reg &&
367 CandidateRegImm.
Imm == RegImm.Imm) {
377 if (
MI.modifiesRegister(RegImm.Reg,
TRI))
397 unsigned BaseCost = XqciloLdSt ? 2 : 3;
398 unsigned CopyCost = RISCV::GPRPairRegClass.contains(RegImm.Reg) ? 2 : 1;
399 assert((RegImm.Imm == 0 || CopyCost == 1) &&
"GPRPair should have zero imm");
400 if (MIs.
size() <= CopyCost || (RegImm.Imm != 0 && MIs.
size() < BaseCost))
408 if (RISCV::GPRRegClass.
contains(RegImm.Reg))
409 RCToScavenge = &RISCV::GPRCRegClass;
410 else if (RISCV::GPRF16RegClass.
contains(RegImm.Reg))
411 RCToScavenge = &RISCV::GPRF16CRegClass;
412 else if (RISCV::GPRF32RegClass.
contains(RegImm.Reg))
413 RCToScavenge = &RISCV::GPRF32CRegClass;
414 else if (RISCV::FPR32RegClass.
contains(RegImm.Reg))
415 RCToScavenge = &RISCV::FPR32CRegClass;
416 else if (RISCV::FPR64RegClass.
contains(RegImm.Reg))
417 RCToScavenge = &RISCV::FPR64CRegClass;
418 else if (RISCV::GPRPairRegClass.
contains(RegImm.Reg))
419 RCToScavenge = &RISCV::GPRPairCRegClass;
424 RS.enterBasicBlockEnd(
MBB);
425 RS.backward(std::next(MIs.
back()->getIterator()));
426 return RS.scavengeRegisterBackwards(*RCToScavenge, FirstMI.
getIterator(),
434 unsigned Opcode =
MI.getOpcode();
439 "Unsupported instruction for this optimization.");
451 if (MO.isReg() && MO.getReg() == OldRegImm.
Reg) {
471bool RISCVMakeCompressibleOpt::runOnMachineFunction(
MachineFunction &Fn) {
476 const RISCVSubtarget &STI = Fn.
getSubtarget<RISCVSubtarget>();
480 if (!STI.hasStdExtZca())
483 for (MachineBasicBlock &
MBB : Fn) {
485 for (MachineInstr &
MI :
MBB) {
495 SmallVector<MachineInstr *, 8> MIs;
523 for (MachineInstr *UpdateMI : MIs)
532 return new RISCVMakeCompressibleOpt();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static bool isXqciloLdSt(const MachineInstr &MI)
static bool isCompressibleLoad(const MachineInstr &MI)
#define RISCV_COMPRESS_INSTRS_NAME
static unsigned offsetMask(unsigned Opcode)
static bool isCompressibleStore(const MachineInstr &MI)
static uint8_t compressedLDSTOffsetMask(unsigned Opcode)
static bool isCompressedReg(Register Reg)
static Register analyzeCompressibleUses(MachineInstr &FirstMI, RegImmPair RegImm, SmallVectorImpl< MachineInstr * > &MIs)
static int64_t getBaseAdjustForCompression(int64_t Offset, unsigned Opcode)
static void updateOperands(MachineInstr &MI, RegImmPair OldRegImm, Register NewReg)
static bool compressibleSPOffset(int64_t Offset, unsigned Opcode)
static RegImmPair getRegImmPairPreventingCompression(const MachineInstr &MI)
This file declares the machine register scavenger class.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
FunctionPass class - This class is used to implement most global optimizations.
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, Register DestReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
Emit instructions to copy a pair of physical registers.
Instructions::iterator instr_iterator
LLVM_ABI StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
MachineOperand class - Representation of each machine instruction operand.
void setImm(int64_t immVal)
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
const RISCVInstrInfo * getInstrInfo() const override
Wrapper class representing virtual and physical registers.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
Represent a constant reference to a string, i.e.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
FunctionPass * createRISCVMakeCompressibleOptPass()
Returns an instance of the Make Compressible Optimization pass.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
MCRegisterClass TargetRegisterClass
Used to describe a register and immediate addition.