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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

34#ifndef NDEBUG

36#endif

38

39using namespace llvm;

40

41#define DEBUG_TYPE "riscv-vmv0-elimination"

42

43namespace {

44

46public:

47 static char ID;

49

51

52 void getAnalysisUsage(AnalysisUsage &AU) const override {

55 }

56

58

59

60

62 }

63};

64

65}

66

67char RISCVVMV0Elimination::ID = 0;

68

70 false, false)

71

73 return new RISCVVMV0Elimination();

74}

75

77 return MCOI.RegClass == RISCV::VMV0RegClassID;

78}

79

80bool RISCVVMV0Elimination::runOnMachineFunction(MachineFunction &MF) {

81

82 const RISCVSubtarget *ST = &MF.getSubtarget();

83 if (ST->hasVInstructions())

84 return false;

85

87 const TargetInstrInfo *TII = ST->getInstrInfo();

88

89#ifndef NDEBUG

90

91

92 const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();

93 ReversePostOrderTraversal<MachineBasicBlock *> RPOT(&*MF.begin());

94 for (MachineBasicBlock *MBB : RPOT) {

95 bool V0Clobbered = false;

96 for (MachineInstr &MI : *MBB) {

97 assert(!(MI.readsRegister(RISCV::V0, TRI) && V0Clobbered) &&

98 "Inserting a copy to v0 would clobber a read");

99 if (MI.modifiesRegister(RISCV::V0, TRI))

100 V0Clobbered = false;

101

103 V0Clobbered = true;

104 }

105

106 assert(!(V0Clobbered &&

108 [](auto *Succ) { return Succ->isLiveIn(RISCV::V0); })) &&

109 "Clobbered a v0 used in a successor");

110 }

111#endif

112

113 bool MadeChange = false;

115

116

117 for (MachineBasicBlock &MBB : MF) {

118 for (MachineInstr &MI : MBB) {

120 "Expected only one or zero vmv0 operands");

121

122 for (auto [OpNo, MCOI] : enumerate(MI.getDesc().operands())) {

124 MachineOperand &MO = MI.getOperand(OpNo);

127 Src.isVirtual() && "vmv0 use in unexpected form");

128

129

130 if (MachineInstr *SrcMI = MRI.getVRegDef(Src);

131 SrcMI->isCopy() && SrcMI->getOperand(1).getReg().isVirtual() &&

132 SrcMI->getOperand(1).getSubReg() == RISCV::NoSubRegister) {

133

134 if (MRI.hasOneNonDBGUse(Src))

136 Src = SrcMI->getOperand(1).getReg();

137 }

138

139 BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(RISCV::COPY), RISCV::V0)

141

142 MO.setReg(RISCV::V0);

143 MadeChange = true;

144 break;

145 }

146 }

147 }

148 }

149

150 for (MachineInstr *MI : DeadCopies)

151 MI->eraseFromParent();

152

153 if (!MadeChange)

154 return false;

155

156

157

158

159 for (MachineBasicBlock &MBB : MF) {

160 for (MachineInstr &MI : MBB) {

161 for (MachineOperand &MO : MI.uses()) {

163 MRI.getRegClass(MO.getReg()) == &RISCV::VMV0RegClass) {

164 MRI.recomputeRegClass(MO.getReg());

165 assert((MRI.getRegClass(MO.getReg()) != &RISCV::VMV0RegClass ||

166 MI.isInlineAsm() ||

167 MRI.getVRegDef(MO.getReg())->isInlineAsm()) &&

168 "Non-inline-asm use of vmv0 left behind");

169 }

170 }

171 }

172 }

173

174 return true;

175}

unsigned const MachineRegisterInfo * MRI

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

const HexagonInstrInfo * TII

Register const TargetRegisterInfo * TRI

Promote Memory to Register

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

This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.

static bool isVMV0(const MCOperandInfo &MCOI)

Definition RISCVVMV0Elimination.cpp:76

Represent the analysis usage information of a pass.

LLVM_ABI void setPreservesCFG()

This function should be called by the pass, iff they do not:

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

This holds information about one operand of a machine instruction, indicating the register class for ...

iterator_range< succ_iterator > successors()

MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...

void getAnalysisUsage(AnalysisUsage &AU) const override

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.

Properties which a MachineFunction may have at a given point in time.

const TargetSubtargetInfo & getSubtarget() const

getSubtarget - Return the subtarget for which this machine code is being compiled.

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const

Add a new virtual register operand.

unsigned getSubReg() const

bool isReg() const

isReg - Tests if this is a MO_Register operand.

LLVM_ABI void setReg(Register Reg)

Change the register this operand corresponds to.

Register getReg() const

getReg - Returns the register number.

constexpr bool isVirtual() const

Return true if the specified register number is in the virtual register namespace.

void push_back(const T &Elt)

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

This is an optimization pass for GlobalISel generic memory operations.

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

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

auto enumerate(FirstRange &&First, RestRanges &&...Rest)

Given two or more input ranges, returns a new range whose values are tuples (A, B,...

bool any_of(R &&range, UnaryPredicate P)

Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.

FunctionPass * createRISCVVMV0EliminationPass()

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

auto count_if(R &&Range, UnaryPredicate P)

Wrapper function around std::count_if to count the number of times an element satisfying a given pred...