LLVM: lib/Target/PowerPC/PPCTLSDynamicCall.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

33

34using namespace llvm;

35

36#define DEBUG_TYPE "ppc-tls-dynamic-call"

37

38namespace {

40 static char ID;

43 }

44

46

47protected:

49 bool Changed = false;

50 bool NeedFence = true;

53 bool Is64Bit = Subtarget.isPPC64();

54 bool IsAIX = Subtarget.isAIXABI();

55 bool IsLargeModel =

57 bool IsPCREL = false;

60

62 I != IE;) {

64 IsPCREL = isPCREL(MI);

65

66

67 bool IsTLSTPRelMI = MI.getOpcode() == PPC::GETtlsTpointer32AIX;

68 bool IsTLSLDAIXMI = (MI.getOpcode() == PPC::TLSLDAIX8 ||

69 MI.getOpcode() == PPC::TLSLDAIX);

70

71 if (MI.getOpcode() != PPC::ADDItlsgdLADDR &&

72 MI.getOpcode() != PPC::ADDItlsldLADDR &&

73 MI.getOpcode() != PPC::ADDItlsgdLADDR32 &&

74 MI.getOpcode() != PPC::ADDItlsldLADDR32 &&

75 MI.getOpcode() != PPC::TLSGDAIX &&

76 MI.getOpcode() != PPC::TLSGDAIX8 && !IsTLSTPRelMI && !IsPCREL &&

77 !IsTLSLDAIXMI) {

78

79

80

81

82 if (MI.getOpcode() == PPC::ADJCALLSTACKDOWN)

83 NeedFence = false;

84 else if (MI.getOpcode() == PPC::ADJCALLSTACKUP)

85 NeedFence = true;

86

87 ++I;

88 continue;

89 }

90

92

93 Register OutReg = MI.getOperand(0).getReg();

94 Register InReg = PPC::NoRegister;

95 Register GPR3 = Is64Bit ? PPC::X3 : PPC::R3;

96 Register GPR4 = Is64Bit ? PPC::X4 : PPC::R4;

97 if (!IsPCREL && !IsTLSTPRelMI)

98 InReg = MI.getOperand(1).getReg();

100

101 unsigned Opc1, Opc2;

102 switch (MI.getOpcode()) {

103 default:

105 case PPC::ADDItlsgdLADDR:

106 Opc1 = PPC::ADDItlsgdL;

107 Opc2 = PPC::GETtlsADDR;

108 break;

109 case PPC::ADDItlsldLADDR:

110 Opc1 = PPC::ADDItlsldL;

111 Opc2 = PPC::GETtlsldADDR;

112 break;

113 case PPC::ADDItlsgdLADDR32:

114 Opc1 = PPC::ADDItlsgdL32;

115 Opc2 = PPC::GETtlsADDR32;

116 break;

117 case PPC::ADDItlsldLADDR32:

118 Opc1 = PPC::ADDItlsldL32;

119 Opc2 = PPC::GETtlsldADDR32;

120 break;

121 case PPC::TLSLDAIX:

122

123

124 Opc2 = PPC::GETtlsMOD32AIX;

125 break;

126 case PPC::TLSLDAIX8:

127

128

129 Opc2 = PPC::GETtlsMOD64AIX;

130 break;

131 case PPC::TLSGDAIX8:

132

133

134 Opc2 = PPC::GETtlsADDR64AIX;

135 break;

136 case PPC::TLSGDAIX:

137

138

139 Opc2 = PPC::GETtlsADDR32AIX;

140 break;

141 case PPC::GETtlsTpointer32AIX:

142

143

144

145 Opc2 = PPC::GETtlsTpointer32AIX;

146 break;

147 case PPC::PADDI8pc:

148 assert(IsPCREL && "Expecting General/Local Dynamic PCRel");

149 Opc1 = PPC::PADDI8pc;

150 Opc2 = MI.getOperand(2).getTargetFlags() ==

152 ? PPC::GETtlsADDRPCREL

153 : PPC::GETtlsldADDRPCREL;

154 }

155

156

157

158

159

160

161

162 if (NeedFence) {

166 }

167

168 if (IsAIX) {

169 if (IsTLSLDAIXMI) {

170

171

172

173

174

175

176

177

178 unsigned LDTocOp =

179 Is64Bit ? (IsLargeModel ? PPC::LDtocL : PPC::LDtoc)

180 : (IsLargeModel ? PPC::LWZtocL : PPC::LWZtoc);

181 if (RegInfo.use_empty(OutReg)) {

182 std::set<MachineInstr *> Uses;

183

185 Uses.insert(MO.getParent());

186

187

190 ++UseIter)

191 if (Uses.count(&*UseIter))

192 break;

193

194

195

196

197 if (UseIter != MBB.end()) {

198

199

200 std::set<MachineInstr *> LoadFromTocs;

202 if (MO.isReg() && MO.isUse()) {

203 Register MOReg = MO.getReg();

204 if (RegInfo.hasOneDef(MOReg)) {

206 RegInfo.getOneDef(MOReg)->getParent();

207

208

209

210

211 if (Temp == &MI && RegInfo.hasOneDef(InReg))

212 Temp = RegInfo.getOneDef(InReg)->getParent();

213 if (Temp->getOpcode() == LDTocOp)

214 LoadFromTocs.insert(Temp);

215 } else {

216

217 LoadFromTocs.clear();

218 break;

219 }

220 }

221

222

223

224

225 if (LoadFromTocs.size() == 2) {

228

229

230

233 I != IE; ++I)

234 if (LoadFromTocs.count(&*I)) {

238 TLSMLIter = I;

239 else

240 OffsetIter = I;

241 }

242

243

244

245 if (TLSMLIter != MBB.end() && OffsetIter != MBB.end())

246 OffsetIter->moveBefore(&*UseIter);

247 }

248 }

249 }

250

251

254

256 } else if (!IsTLSTPRelMI) {

257

258

259

261 .addReg(MI.getOperand(1).getReg());

263 .addReg(MI.getOperand(2).getReg());

265 } else

266

267

268

270 } else {

272 if (IsPCREL) {

274 } else {

275

276 assert(InReg != PPC::NoRegister && "Operand must be a register");

278 }

279

281

284 if (IsPCREL)

285 Call->addOperand(MI.getOperand(2));

286 else

287 Call->addOperand(MI.getOperand(3));

288 }

289 if (NeedFence)

291

294

295

296 ++I;

297 MI.removeFromParent();

298

299 Changed = true;

300 }

301

302 return Changed;

303 }

304

305public:

307 return (MI.getOpcode() == PPC::PADDI8pc) &&

308 (MI.getOperand(2).getTargetFlags() ==

310 MI.getOperand(2).getTargetFlags() ==

312 }

313

316

317 bool Changed = false;

318

320 if (processBlock(B))

321 Changed = true;

322

323 return Changed;

324 }

325

330 }

331 };

332}

333

335 "PowerPC TLS Dynamic Call Fixup", false, false)

340

341char PPCTLSDynamicCall::ID = 0;

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

const HexagonInstrInfo * TII

PowerPC TLS Dynamic Call Fixup

#define INITIALIZE_PASS_DEPENDENCY(depName)

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

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

Remove Loads Into Fake Uses

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

Represent the analysis usage information of a pass.

AnalysisUsage & addRequired()

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

const MachineFunction * getParent() const

Return the MachineFunction containing this basic block.

void setAdjustsStack(bool V)

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.

virtual bool runOnMachineFunction(MachineFunction &MF)=0

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

const TargetSubtargetInfo & getSubtarget() const

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

MachineFrameInfo & getFrameInfo()

getFrameInfo - Return the frame info object for the current function.

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

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.

unsigned getOpcode() const

Returns the opcode of this MachineInstr.

void addOperand(MachineFunction &MF, const MachineOperand &Op)

Add the specified operand to the instruction.

MachineOperand class - Representation of each machine instruction operand.

const GlobalValue * getGlobal() const

bool isGlobal() const

isGlobal - Tests if this is a MO_GlobalAddress operand.

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

bool isPPC64() const

isPPC64 - Return true if we are generating code for 64-bit pointer mode.

const PPCTargetMachine & getTargetMachine() const

static PassRegistry * getPassRegistry()

getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...

Wrapper class representing virtual and physical registers.

CodeModel::Model getCodeModel() const

Returns the code model.

StringRef getName() const

Return a constant reference to the value's name.

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

@ MO_GOT_TLSLD_PCREL_FLAG

MO_GOT_TLSLD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...

@ MO_GOT_TLSGD_PCREL_FLAG

MO_GOT_TLSGD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...

This is an optimization pass for GlobalISel generic memory operations.

void initializePPCTLSDynamicCallPass(PassRegistry &)

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

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

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

FunctionPass * createPPCTLSDynamicCallPass()

raw_ostream & dbgs()

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

@ Dynamic

Denotes mode unknown at compile time.