LLVM: lib/Target/AArch64/AArch64DeadRegisterDefinitionsPass.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

25using namespace llvm;

26

27#define DEBUG_TYPE "aarch64-dead-defs"

28

29STATISTIC(NumDeadDefsReplaced, "Number of dead definitions replaced");

30

31#define AARCH64_DEAD_REG_DEF_NAME "AArch64 Dead register definitions"

32

33namespace {

35private:

41public:

42 static char ID;

44

46

48

49 void getAnalysisUsage(AnalysisUsage &AU) const override {

52 }

53};

54char AArch64DeadRegisterDefinitions::ID = 0;

55}

56

57INITIALIZE_PASS(AArch64DeadRegisterDefinitions, "aarch64-dead-defs",

59

62 if (MO.isFI())

63 return true;

64 return false;

65}

66

67

68

69

70

71

72

74 switch (Opcode) {

75 case AArch64::LDADDB: case AArch64::LDADDH:

76 case AArch64::LDADDW: case AArch64::LDADDX:

77 case AArch64::LDADDLB: case AArch64::LDADDLH:

78 case AArch64::LDADDLW: case AArch64::LDADDLX:

79 case AArch64::LDCLRB: case AArch64::LDCLRH:

80 case AArch64::LDCLRW: case AArch64::LDCLRX:

81 case AArch64::LDCLRLB: case AArch64::LDCLRLH:

82 case AArch64::LDCLRLW: case AArch64::LDCLRLX:

83 case AArch64::LDEORB: case AArch64::LDEORH:

84 case AArch64::LDEORW: case AArch64::LDEORX:

85 case AArch64::LDEORLB: case AArch64::LDEORLH:

86 case AArch64::LDEORLW: case AArch64::LDEORLX:

87 case AArch64::LDSETB: case AArch64::LDSETH:

88 case AArch64::LDSETW: case AArch64::LDSETX:

89 case AArch64::LDSETLB: case AArch64::LDSETLH:

90 case AArch64::LDSETLW: case AArch64::LDSETLX:

91 case AArch64::LDSMAXB: case AArch64::LDSMAXH:

92 case AArch64::LDSMAXW: case AArch64::LDSMAXX:

93 case AArch64::LDSMAXLB: case AArch64::LDSMAXLH:

94 case AArch64::LDSMAXLW: case AArch64::LDSMAXLX:

95 case AArch64::LDSMINB: case AArch64::LDSMINH:

96 case AArch64::LDSMINW: case AArch64::LDSMINX:

97 case AArch64::LDSMINLB: case AArch64::LDSMINLH:

98 case AArch64::LDSMINLW: case AArch64::LDSMINLX:

99 case AArch64::LDUMAXB: case AArch64::LDUMAXH:

100 case AArch64::LDUMAXW: case AArch64::LDUMAXX:

101 case AArch64::LDUMAXLB: case AArch64::LDUMAXLH:

102 case AArch64::LDUMAXLW: case AArch64::LDUMAXLX:

103 case AArch64::LDUMINB: case AArch64::LDUMINH:

104 case AArch64::LDUMINW: case AArch64::LDUMINX:

105 case AArch64::LDUMINLB: case AArch64::LDUMINLH:

106 case AArch64::LDUMINLW: case AArch64::LDUMINLX:

107 case AArch64::SWPB: case AArch64::SWPH:

108 case AArch64::SWPW: case AArch64::SWPX:

109 case AArch64::SWPLB: case AArch64::SWPLH:

110 case AArch64::SWPLW: case AArch64::SWPLX:

111 return true;

112 }

113 return false;

114}

115

116void AArch64DeadRegisterDefinitions::processMachineBasicBlock(

118 for (MachineInstr &MI : MBB) {

119 if (usesFrameIndex(MI)) {

120

121

122

123 LLVM_DEBUG(dbgs() << " Ignoring, operand is frame index\n");

124 continue;

125 }

126 if (MI.definesRegister(AArch64::XZR, nullptr) ||

127 MI.definesRegister(AArch64::WZR, nullptr)) {

128

129

132 << " Ignoring, XZR or WZR already used by the instruction\n");

133 continue;

134 }

135

137 LLVM_DEBUG(dbgs() << " Ignoring, semantics change with xzr/wzr.\n");

138 continue;

139 }

140

141 const MCInstrDesc &Desc = MI.getDesc();

142 for (int I = 0, E = Desc.getNumDefs(); I != E; ++I) {

143 MachineOperand &MO = MI.getOperand(I);

145 continue;

146

147

150 continue;

152 LLVM_DEBUG(dbgs() << " Dead def operand #" << I << " in:\n ";

154

155 if (MI.isRegTiedToUseOperand(I)) {

156 LLVM_DEBUG(dbgs() << " Ignoring, def is tied operand.\n");

157 continue;

158 }

160 unsigned NewReg;

161 if (RC == nullptr) {

162 LLVM_DEBUG(dbgs() << " Ignoring, register is not a GPR.\n");

163 continue;

164 } else if (RC->contains(AArch64::WZR))

165 NewReg = AArch64::WZR;

166 else if (RC->contains(AArch64::XZR))

167 NewReg = AArch64::XZR;

168 else {

169 LLVM_DEBUG(dbgs() << " Ignoring, register is not a GPR.\n");

170 continue;

171 }

172 LLVM_DEBUG(dbgs() << " Replacing with zero register. New:\n ");

176 ++NumDeadDefsReplaced;

178

179 break;

180 }

181 }

182}

183

184

185

186bool AArch64DeadRegisterDefinitions::runOnMachineFunction(MachineFunction &MF) {

188 return false;

189

193 LLVM_DEBUG(dbgs() << "***** AArch64DeadRegisterDefinitions *****\n");

195 for (auto &MBB : MF)

196 processMachineBasicBlock(MBB);

198}

199

201 return new AArch64DeadRegisterDefinitions();

202}

unsigned const MachineRegisterInfo * MRI

static bool atomicReadDroppedOnZero(unsigned Opcode)

Definition AArch64DeadRegisterDefinitionsPass.cpp:73

#define AARCH64_DEAD_REG_DEF_NAME

Definition AArch64DeadRegisterDefinitionsPass.cpp:31

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

const TargetInstrInfo & TII

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

Register const TargetRegisterInfo * TRI

Promote Memory to Register

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

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

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.

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.

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.

Function & getFunction()

Return the LLVM function that this machine code represents.

Representation of each machine instruction.

MachineOperand class - Representation of each machine instruction operand.

bool isReg() const

isReg - Tests if this is a MO_Register operand.

void setIsDead(bool Val=true)

LLVM_ABI void setReg(Register Reg)

Change the register this operand corresponds to.

Register getReg() const

getReg - Returns the register number.

MachineRegisterInfo - Keep track of information for virtual and physical registers,...

virtual void print(raw_ostream &OS, const Module *M) const

print - Print out the internal state of the pass.

constexpr bool isVirtual() const

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

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

TargetInstrInfo - Interface to description of machine instruction set.

virtual const TargetRegisterClass * getRegClass(const MCInstrDesc &MCID, unsigned OpNum) const

Given a machine instruction descriptor, returns the register class constraint for OpNum,...

bool contains(Register Reg) const

Return true if the specified register is included in this register class.

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

virtual const TargetInstrInfo * getInstrInfo() const

virtual const TargetRegisterInfo * getRegisterInfo() const =0

Return the target's register information.

unsigned ID

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

This is an optimization pass for GlobalISel generic memory operations.

FunctionPass * createAArch64DeadRegisterDefinitions()

Definition AArch64DeadRegisterDefinitionsPass.cpp:200

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

static bool atomicBarrierDroppedOnZero(unsigned Opcode)