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();
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();
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 hasMinSize() const
Optimize this function for 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 & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register 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.
bool hasStdExtCOrZcfOrZce() const
const RISCVInstrInfo * getInstrInfo() const override
bool hasStdExtCOrZcd() const
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)
StringRef - 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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
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.
Used to describe a register and immediate addition.