LLVM: lib/Target/RISCV/RISCVPushPopOptimizer.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

17

18using namespace llvm;

19

20#define RISCV_PUSH_POP_OPT_NAME "RISC-V Zcmp Push/Pop optimization pass"

21

22namespace {

24 static char ID;

25

27

30

31

33

38

40};

41

42char RISCVPushPopOpt::ID = 0;

43

44}

45

47 false, false)

48

49static bool isPop(unsigned Opcode) {

50 switch (Opcode) {

51 case RISCV::CM_POP:

52 case RISCV::QC_CM_POP:

53 return true;

54 default:

55 return false;

56 }

57}

58

59static unsigned getPopRetOpcode(unsigned PopOpcode, bool IsReturnZero) {

60 assert(isPop(PopOpcode) && "Unexpected Pop Opcode");

61

62 switch (PopOpcode) {

63 case RISCV::CM_POP:

64 return IsReturnZero ? RISCV::CM_POPRETZ : RISCV::CM_POPRET;

65 case RISCV::QC_CM_POP:

66 return IsReturnZero ? RISCV::QC_CM_POPRETZ : RISCV::QC_CM_POPRET;

67 default:

69 }

70}

71

74 bool IsReturnZero) {

75

76

79 MachineInstrBuilder PopRetBuilder =

84

85

86

87 const MCInstrDesc &PopDesc = MBBI->getDesc();

88 unsigned FirstNonDeclaredOp = PopDesc.getNumOperands() +

91 for (unsigned i = FirstNonDeclaredOp; i < MBBI->getNumOperands(); ++i)

92 PopRetBuilder.add(MBBI->getOperand(i));

93

95 NextI->eraseFromParent();

96 return true;

97}

98

99

100

103

104

105 ModifiedRegUnits.clear();

106 UsedRegUnits.clear();

107

108

112 MachineInstr &MI = *I;

114 Register DestReg = OperandPair->Destination->getReg();

116 if (DestReg == RISCV::X10 && Source == RISCV::X0) {

117 MI.removeFromParent();

118 return true;

119 }

120 }

121

123

124

125 if (!ModifiedRegUnits.available(RISCV::X10) ||

126 !UsedRegUnits.available(RISCV::X10))

127 return false;

128 }

129 return false;

130}

131

132bool RISCVPushPopOpt::runOnMachineFunction(MachineFunction &Fn) {

134 return false;

135

136

137 const RISCVSubtarget *Subtarget = &Fn.getSubtarget();

138 if (!Subtarget->hasStdExtZcmp() && !Subtarget->hasVendorXqccmp())

139 return false;

140

143

144

145

146

147 ModifiedRegUnits.init(*TRI);

149

151 for (auto &MBB : Fn) {

152

154 if (RetMBBI == MBB.end() || RetMBBI->getOpcode() != RISCV::PseudoRET ||

156 continue;

157

158

160 if (isPop(PopMBBI->getOpcode()) &&

162 Modified |= usePopRet(PopMBBI, RetMBBI, adjustRetVal(PopMBBI));

163 }

164

166}

167

168

169

171 return new RISCVPushPopOpt();

172}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

const TargetInstrInfo & TII

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

MachineBasicBlock MachineBasicBlock::iterator MBBI

Register const TargetRegisterInfo * TRI

Promote Memory to Register

#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)

static bool isPop(unsigned Opcode)

#define RISCV_PUSH_POP_OPT_NAME

Definition RISCVPushPopOptimizer.cpp:20

static unsigned getPopRetOpcode(unsigned PopOpcode, bool IsReturnZero)

Definition RISCVPushPopOptimizer.cpp:59

FunctionPass class - This class is used to implement most global optimizations.

A set of register units used to track register liveness.

static void accumulateUsedDefed(const MachineInstr &MI, LiveRegUnits &ModifiedRegUnits, LiveRegUnits &UsedRegUnits, const TargetRegisterInfo *TRI)

For a machine instruction MI, adds all register units used in UsedRegUnits and defined or clobbered i...

bool available(MCRegister Reg) const

Returns true if no part of physical register Reg is live.

void init(const TargetRegisterInfo &TRI)

Initialize and clear the set.

void clear()

Clears the set.

unsigned char NumImplicitUses

unsigned getNumOperands() const

Return the number of declared MachineOperands for this MachineInstruction.

unsigned char NumImplicitDefs

const MCInstrDesc & get(unsigned Opcode) const

Return the machine instruction descriptor that corresponds to the specified instruction opcode.

LLVM_ABI iterator getFirstTerminator()

Returns an iterator to the first terminator instruction of this basic block.

MachineInstrBundleIterator< MachineInstr, true > reverse_iterator

LLVM_ABI void eraseFromParent()

This method unlinks 'this' from the containing function and deletes it.

const MachineFunction * getParent() const

Return the MachineFunction containing this basic block.

MachineInstrBundleIterator< MachineInstr > iterator

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 & setMIFlag(MachineInstr::MIFlag Flag) const

const MachineInstrBuilder & add(const MachineOperand &MO) const

const RISCVRegisterInfo * getRegisterInfo() const override

const RISCVInstrInfo * getInstrInfo() const override

StringRef - Represent a constant reference to a string, i.e.

virtual std::optional< DestSourcePair > isCopyInstrImpl(const MachineInstr &MI) const

Target-dependent implementation for IsCopyInstr.

TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...

#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.

IterT next_nodbg(IterT It, IterT End, bool SkipPseudoOp=true)

Increment It, then continue incrementing it while it points to a debug instruction.

MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)

Builder interface. Specify how to create the initial instruction itself.

FunctionPass * createRISCVPushPopOptimizationPass()

createRISCVPushPopOptimizationPass - returns an instance of the Push/Pop optimization pass.

Definition RISCVPushPopOptimizer.cpp:170

IterT prev_nodbg(IterT It, IterT Begin, bool SkipPseudoOp=true)

Decrement It, then continue decrementing it while it points to a debug instruction.