LLVM: lib/CodeGen/GlobalISel/Localizer.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

22

23#define DEBUG_TYPE "localizer"

24

25using namespace llvm;

26

29 "Move/duplicate certain instructions close to their use",

30 false, false)

35

38

41

44 TTI = &getAnalysis().getTTI(MF.getFunction());

45}

46

51}

52

57 if (MIUse.isPHI())

59 return InsertMBB == Def.getParent();

60}

61

63 auto *MI = dyn_cast(&*Op.getParent());

64 if (MI)

65 return 0;

66

68 unsigned NumUses = 0;

69 for (unsigned I = 0, NumVals = MI->getNumIncomingValues(); I < NumVals; ++I) {

70 if (MI->getIncomingValue(I) == SrcReg)

71 ++NumUses;

72 }

73 return NumUses;

74}

75

77 LocalizedSetVecT &LocalizedInstrs) {

78 bool Changed = false;

80

81

82

83

84

88 if (!TL.shouldLocalize(MI, TTI))

89 continue;

91 assert(MI.getDesc().getNumDefs() == 1 &&

92 "More than one definition not supported yet");

94

95

96

99

102 dbgs() << "Checking use: " << MIUse

103 << " #Opd: " << MOUse.getOperandNo() << '\n');

104 if (isLocalUse(MOUse, MI, InsertMBB)) {

105

106

107

108 LocalizedInstrs.insert(&MI);

109 continue;

110 }

111

112

113

114

115 unsigned NumPhiUses = getNumPhiUses(MOUse);

116 const unsigned PhiThreshold = 2;

117 if (NumPhiUses > PhiThreshold)

118 continue;

119

121 Changed = true;

122 auto MBBAndReg = std::make_pair(InsertMBB, Reg);

123 auto NewVRegIt = MBBWithLocalDef.find(MBBAndReg);

124 if (NewVRegIt == MBBWithLocalDef.end()) {

125

127 LocalizedInstrs.insert(LocalizedMI);

131 else

133 LocalizedMI);

134

135

138 NewVRegIt =

139 MBBWithLocalDef.insert(std::make_pair(MBBAndReg, NewReg)).first;

141 }

143 << '\n');

144

145 MOUse.setReg(NewVRegIt->second);

146 }

147 }

148 return Changed;

149}

150

151bool Localizer::localizeIntraBlock(LocalizedSetVecT &LocalizedInstrs) {

152 bool Changed = false;

153

154

155

156

157

158

159

163

166 if (UseMI.isPHI())

168 }

170

171

172

173 if (Users.empty()) {

174

175

177 LLVM_DEBUG(dbgs() << "Only phi users: moving inst to end: " << *MI);

178 } else {

179 ++II;

181 ++II;

182 assert(II != MBB.end() && "Didn't find the user in the MBB");

183 LLVM_DEBUG(dbgs() << "Intra-block: moving " << *MI << " before " << *II);

184 }

185

186 MI->removeFromParent();

188 Changed = true;

189

190

191

192 if (Users.size() == 1) {

193 const auto &DefDL = MI->getDebugLoc();

195

196 if ((!DefDL || DefDL.getLine() == 0) && UserDL && UserDL.getLine() != 0) {

197 MI->setDebugLoc(UserDL);

198 }

199 }

200 }

201 return Changed;

202}

203

205

208 return false;

209

210

211 if (DoNotRunPass(MF))

212 return false;

213

215

216 init(MF);

217

218

219

221

222 bool Changed = localizeInterBlock(MF, LocalizedInstrs);

223 Changed |= localizeIntraBlock(LocalizedInstrs);

224 return Changed;

225}

MachineInstrBuilder & UseMI

Expand Atomic instructions

Performs the initial survey of the specified function

This file defines the DenseMap class.

Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...

iv Induction Variable Users

Move duplicate certain instructions close to their use

static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)

Return the first found DebugLoc that has a DILocation, given a range of instructions.

uint64_t IntrinsicInst * II

#define INITIALIZE_PASS_DEPENDENCY(depName)

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

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

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

This file describes how to lower LLVM code to machine code.

This pass exposes codegen information to IR-level passes.

Represent the analysis usage information of a pass.

AnalysisUsage & addRequired()

This class represents an Operation in the Expression.

iterator find(const_arg_type_t< KeyT > Val)

std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)

This pass implements the localization mechanism described at the top of this file.

void getAnalysisUsage(AnalysisUsage &AU) const override

getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...

bool runOnMachineFunction(MachineFunction &MF) override

runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...

iterator getFirstTerminatorForward()

Finds the first terminator in a block by scanning forward.

instr_iterator insert(instr_iterator I, MachineInstr *M)

Insert MI into the instruction list before I, possibly inside a bundle.

iterator SkipPHIsAndLabels(iterator I)

Return the first instruction in MBB after I that is not a PHI or a label.

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.

bool hasProperty(Property P) const

const TargetSubtargetInfo & getSubtarget() const

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

StringRef getName() const

getName - Return the name of the corresponding LLVM function.

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

Function & getFunction()

Return the LLVM function that this machine code represents.

const MachineFunctionProperties & getProperties() const

Get the function properties.

MachineInstr * CloneMachineInstr(const MachineInstr *Orig)

Create a new MachineInstr which is a copy of Orig, identical in all ways except the instruction has n...

const MachineBasicBlock & front() const

Representation of each machine instruction.

const MachineBasicBlock * getParent() const

void insert(mop_iterator InsertBefore, ArrayRef< MachineOperand > Ops)

Inserts Ops BEFORE It. Can untie/retie tied operands.

const MachineOperand & getOperand(unsigned i) const

MachineOperand class - Representation of each machine instruction operand.

unsigned getOperandNo() const

Returns the index of this operand in the instruction that it belongs to.

MachineBasicBlock * getMBB() const

void setReg(Register Reg)

Change the register this operand corresponds to.

MachineInstr * getParent()

getParent - Return the instruction that this operand belongs to.

bool hasOneUse(Register RegNo) const

hasOneUse - Return true if there is exactly one instruction using the specified register.

iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(Register Reg) const

Register cloneVirtualRegister(Register VReg, StringRef Name="")

Create and return a new virtual register in the function with the same attributes as the given regist...

iterator_range< use_iterator > use_operands(Register Reg) const

Wrapper class representing virtual and physical registers.

SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.

A SetVector that performs no allocations if smaller than a certain size.

virtual const TargetLowering * getTargetLowering() const

Wrapper pass for TargetTransformInfo.

This pass provides access to the codegen interfaces that are needed for IR-level transformations.

Reg

All possible values of the reg field in the ModR/M byte.

This is an optimization pass for GlobalISel generic memory operations.

iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)

Make a range that does early increment to allow mutation of the underlying range without disrupting i...

auto reverse(ContainerTy &&C)

raw_ostream & dbgs()

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

void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)

Modify analysis usage so it preserves passes required for the SelectionDAG fallback.

Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)

Prints virtual and physical registers with or without a TRI instance.

Implement std::hash so that hash_code can be used in STL containers.