LLVM: lib/Target/SystemZ/SystemZRegisterInfo.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

19

20using namespace llvm;

21

22#define GET_REGINFO_TARGET_DESC

23#include "SystemZGenRegisterInfo.inc"

24

25

26

31

32 if (SystemZ::GR32BitRegClass.hasSubClassEq(RC) ||

33 MO.getSubReg() == SystemZ::subreg_ll32 ||

34 MO.getSubReg() == SystemZ::subreg_l32)

35 return &SystemZ::GR32BitRegClass;

36 if (SystemZ::GRH32BitRegClass.hasSubClassEq(RC) ||

37 MO.getSubReg() == SystemZ::subreg_lh32 ||

38 MO.getSubReg() == SystemZ::subreg_h32)

39 return &SystemZ::GRH32BitRegClass;

40

43 if (SystemZ::GR32BitRegClass.contains(PhysReg))

44 return &SystemZ::GR32BitRegClass;

45 assert (SystemZ::GRH32BitRegClass.contains(PhysReg) &&

46 "Phys reg not in GR32 or GRH32?");

47 return &SystemZ::GRH32BitRegClass;

48 }

49

50 assert (RC == &SystemZ::GRX32BitRegClass);

51 return RC;

52}

53

54

55

56

65 if (CopyHints.count(Reg) &&

66 RC->contains(Reg) && MRI->isReserved(Reg))

69 if (!CopyHints.count(Reg) &&

70 RC->contains(Reg) && MRI->isReserved(Reg))

72}

73

81

83 VirtReg, Order, Hints, MF, VRM, Matrix);

84

85 if (VRM != nullptr) {

86

88 for (auto &Use : MRI->reg_nodbg_instructions(VirtReg))

93 if (VirtReg == Use.getOperand(0).getReg()) {

94 VRRegMO = &Use.getOperand(0);

95 OtherMO = &Use.getOperand(1);

96 if (Use.isCommutable())

97 CommuMO = &Use.getOperand(2);

98 } else if (VirtReg == Use.getOperand(1).getReg()) {

99 VRRegMO = &Use.getOperand(1);

100 OtherMO = &Use.getOperand(0);

101 } else if (VirtReg == Use.getOperand(2).getReg() &&

102 Use.isCommutable()) {

103 VRRegMO = &Use.getOperand(2);

104 OtherMO = &Use.getOperand(0);

105 } else

106 continue;

107

108 auto tryAddHint = [&](const MachineOperand *MO) -> void {

112 if (PhysReg) {

113 if (MO->getSubReg())

114 PhysReg = getSubReg(PhysReg, MO->getSubReg());

116 PhysReg = getMatchingSuperReg(PhysReg, VRRegMO->getSubReg(),

117 MRI->getRegClass(VirtReg));

118 if (MRI->isReserved(PhysReg) && is\_contained(Hints, PhysReg))

119 TwoAddrHints.insert(PhysReg);

120 }

121 };

122 tryAddHint(OtherMO);

123 if (CommuMO)

124 tryAddHint(CommuMO);

125 }

127 if (TwoAddrHints.count(OrderReg))

129 }

130

131 if (MRI->getRegClass(VirtReg) == &SystemZ::GRX32BitRegClass) {

135 while (Worklist.size()) {

137 if (!DoneRegs.insert(Reg).second)

138 continue;

139

140 for (auto &Use : MRI->reg_instructions(Reg)) {

141

142

143

144

145 if (Use.getOpcode() == SystemZ::LOCRMux ||

146 Use.getOpcode() == SystemZ::SELRMux) {

150 TRI->getCommonSubClass(getRC32(FalseMO, VRM, MRI),

152 if (Use.getOpcode() == SystemZ::SELRMux)

153 RC = TRI->getCommonSubClass(RC,

155 if (RC && RC != &SystemZ::GRX32BitRegClass) {

157

158

159

160 return true;

161 }

162

163

166 if (MRI->getRegClass(OtherReg) == &SystemZ::GRX32BitRegClass)

168 }

169 else if (Use.getOpcode() == SystemZ::CHIMux ||

170 Use.getOpcode() == SystemZ::CFIMux) {

171 if (Use.getOperand(1).getImm() == 0) {

172 bool OnlyLMuxes = true;

174 if (DefMI.getOpcode() != SystemZ::LMux)

175 OnlyLMuxes = false;

176 if (OnlyLMuxes) {

177 addHints(Order, Hints, &SystemZ::GR32BitRegClass, MRI);

178

179 return false;

180 }

181 }

182 }

183 }

184 }

185 }

186

187 return BaseImplRetVal;

188}

189

193 return Subtarget.hasVector() ? CSR_SystemZ_XPLINK64_Vector_SaveList

194 : CSR_SystemZ_XPLINK64_SaveList;

195}

196

201 return CSR_SystemZ_NoRegs_SaveList;

203 return Subtarget.hasVector()? CSR_SystemZ_AllRegs_Vector_SaveList

204 : CSR_SystemZ_AllRegs_SaveList;

207 Attribute::SwiftError))

208 return CSR_SystemZ_SwiftError_SaveList;

209 return CSR_SystemZ_ELF_SaveList;

210}

211

216 return Subtarget.hasVector() ? CSR_SystemZ_XPLINK64_Vector_RegMask

217 : CSR_SystemZ_XPLINK64_RegMask;

218}

219

225 return CSR_SystemZ_NoRegs_RegMask;

227 return Subtarget.hasVector()? CSR_SystemZ_AllRegs_Vector_RegMask

228 : CSR_SystemZ_AllRegs_RegMask;

231 Attribute::SwiftError))

232 return CSR_SystemZ_SwiftError_RegMask;

233 return CSR_SystemZ_ELF_RegMask;

234}

235

238

241

244

246}

247

251

255}

256

258 return CSR_SystemZ_NoRegs_RegMask;

259}

260

267 if (TFI->hasFP(MF))

268

269 for (MCRegAliasIterator AI(Regs->getFramePointerRegister(), this, true);

272

273

274 for (MCRegAliasIterator AI(Regs->getStackPointerRegister(), this, true);

277

278

281

282

284

286}

287

288bool

290 int SPAdj, unsigned FIOperandNum,

292 assert(SPAdj == 0 && "Outgoing arguments should be part of the frame");

293

299

300

301 int FrameIndex = MI->getOperand(FIOperandNum).getIndex();

305 MI->getOperand(FIOperandNum + 1).getImm());

306

307

308 if (MI->isDebugValue()) {

309 MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, false);

310 if (MI->isNonListDebugValue()) {

311 MI->getDebugOffset().ChangeToImmediate(Offset);

312 } else {

313 unsigned OpIdx = MI->getDebugOperandIndex(&MI->getOperand(FIOperandNum));

317 MI->getDebugExpressionOp().setMetadata(

319 }

320 return false;

321 }

322

323

324

325 unsigned Opcode = MI->getOpcode();

326 unsigned OpcodeForOffset = TII->getOpcodeForOffset(Opcode, Offset, &*MI);

327 if (OpcodeForOffset) {

328 if (OpcodeForOffset == SystemZ::LE &&

330

331 OpcodeForOffset = SystemZ::LDE32;

332 }

333 MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, false);

334 }

335 else {

336

337

338 int64_t OldOffset = Offset;

339 int64_t Mask = 0xffff;

340 do {

341 Offset = OldOffset & Mask;

342 OpcodeForOffset = TII->getOpcodeForOffset(Opcode, Offset);

343 Mask >>= 1;

344 assert(Mask && "One offset must be OK");

345 } while (!OpcodeForOffset);

346

349 int64_t HighOffset = OldOffset - Offset;

350

352 && MI->getOperand(FIOperandNum + 2).getReg() == 0) {

353

354

355 TII->loadImmediate(MBB, MI, ScratchReg, HighOffset);

356 MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, false);

357 MI->getOperand(FIOperandNum + 2).ChangeToRegister(ScratchReg,

358 false, false, true);

359 } else {

360

361 unsigned LAOpcode = TII->getOpcodeForOffset(SystemZ::LA, HighOffset);

362 if (LAOpcode)

365 else {

366

367

368 TII->loadImmediate(MBB, MI, ScratchReg, HighOffset);

371 }

372

373

374 MI->getOperand(FIOperandNum).ChangeToRegister(ScratchReg,

375 false, false, true);

376 }

377 }

378 MI->setDesc(TII->get(OpcodeForOffset));

379 MI->getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);

380 return false;

381}

382

387 unsigned DstSubReg,

390 assert (MI->isCopy() && "Only expecting COPY instructions");

391

392

393 if (!(NewRC->hasSuperClassEq(&SystemZ::GR128BitRegClass) &&

394 (getRegSizeInBits(*SrcRC) <= 64 || getRegSizeInBits(*DstRC) <= 64) &&

395 MI->getOperand(1).isUndef()))

396 return true;

397

398

399

400

401 unsigned SubregOpIdx = getRegSizeInBits(*SrcRC) == 128 ? 0 : 1;

403

404

408 if (!FirstMI || FirstMI->getParent() != MBB ||

410 return false;

411

412

413

414 BitVector PhysClobbered(getNumRegs());

417 MII != MEE; ++MII)

419 if (MO.isReg() && MO.getReg().isPhysical()) {

420 for (MCPhysReg SI : superregs_inclusive(MO.getReg()))

422 PhysClobbered.set(SI);

423 break;

424 }

425 }

426

427

428 unsigned const DemandedFreeGR128 = 3;

429 if (PhysClobbered.count() > (NewRC->getNumRegs() - DemandedFreeGR128))

430 return false;

431

432 return true;

433}

434

440

441 return TFI->hasFP(MF) ? Regs->getFramePointerRegister()

442 : Regs->getStackPointerRegister();

443}

444

447 if (RC == &SystemZ::CCRRegClass)

448 return &SystemZ::GR32BitRegClass;

449 return RC;

450}

451

unsigned const MachineRegisterInfo * MRI

MachineInstrBuilder MachineInstrBuilder & DefMI

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

const HexagonInstrInfo * TII

unsigned const TargetRegisterInfo * TRI

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

SI optimize exec mask operations pre RA

static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)

This file defines the SmallSet class.

static const TargetRegisterClass * getRC32(MachineOperand &MO, const VirtRegMap *VRM, const MachineRegisterInfo *MRI)

static void addHints(ArrayRef< MCPhysReg > Order, SmallVectorImpl< MCPhysReg > &Hints, const TargetRegisterClass *RC, const MachineRegisterInfo *MRI)

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

bool hasAttrSomewhere(Attribute::AttrKind Kind, unsigned *Index=nullptr) const

Return true if the specified attribute is set for at least one parameter or for the return value.

size_type count() const

count - Returns the number of bits which are set.

static void appendOffset(SmallVectorImpl< uint64_t > &Ops, int64_t Offset)

Append Ops with operations to apply the Offset.

static DIExpression * appendOpsToArg(const DIExpression *Expr, ArrayRef< uint64_t > Ops, unsigned ArgNo, bool StackValue=false)

Create a copy of Expr by appending the given list of Ops to each instance of the operand DW_OP_LLVM_a...

CallingConv::ID getCallingConv() const

getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...

AttributeList getAttributes() const

Return the attribute list for this Function.

LiveInterval - This class represents the liveness of a register, or stack slot.

MachineInstr * getInstructionFromIndex(SlotIndex index) const

Returns the instruction associated with the given index.

LiveInterval & getInterval(Register Reg)

SlotIndex beginIndex() const

beginIndex - Return the lowest numbered slot covered.

SlotIndex endIndex() const

endNumber - return the maximum point of the range of the whole, exclusive.

MCRegAliasIterator enumerates all registers aliasing Reg.

const MachineFunction * getParent() const

Return the MachineFunction containing this basic block.

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.

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.

const MachineBasicBlock * getParent() const

MachineOperand class - Representation of each machine instruction operand.

unsigned getSubReg() const

Register getReg() const

getReg - Returns the register number.

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

Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")

createVirtualRegister - Create and return a new virtual register in the function with the specified r...

Wrapper class representing virtual and physical registers.

SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...

size_type count(const T &V) const

count - Return 1 if the element is in the set, 0 otherwise.

std::pair< const_iterator, bool > insert(const T &V)

insert - Insert an element into the set if it isn't already there.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

static StackOffset getFixed(int64_t Fixed)

A SystemZ-specific class detailing special use registers particular for calling conventions.

virtual const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const =0

virtual const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID CC) const =0

const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const final

const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID CC) const final

SystemZCallingConventionRegisters * getSpecialRegisters() const

const SystemZRegisterInfo * getRegisterInfo() const override

const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const final

const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID CC) const final

bool hasFP(const MachineFunction &MF) const

hasFP - Return true if the specified function should have a dedicated frame pointer register.

virtual StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const

getFrameIndexReference - This method should return the base register and offset used to reference a f...

virtual bool supportSwiftError() const

Return true if the target supports swifterror attribute.

unsigned getNumRegs() const

Return the number of registers in this class.

bool contains(Register Reg) const

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

bool hasSuperClassEq(const TargetRegisterClass *RC) const

Returns true if RC is a super-class of or equal to this class.

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

virtual bool getRegAllocationHints(Register VirtReg, ArrayRef< MCPhysReg > Order, SmallVectorImpl< MCPhysReg > &Hints, const MachineFunction &MF, const VirtRegMap *VRM=nullptr, const LiveRegMatrix *Matrix=nullptr) const

Get a list of 'hint' registers that the register allocator should try first when allocating a physica...

virtual const TargetLowering * getTargetLowering() const

A Use represents the edge between a Value definition and its users.

MCRegister getPhys(Register virtReg) const

returns the physical register mapped to the specified virtual register

bool hasPhys(Register virtReg) const

returns true if the specified virtual register is mapped to a physical register

self_iterator getIterator()

@ AnyReg

OBSOLETED - Used for stack based JavaScript calls.

@ GHC

Used by the Glasgow Haskell Compiler (GHC).

@ Kill

The last use of a register.

int getTwoOperandOpcode(uint16_t Opcode)

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.

bool is_contained(R &&Range, const E &Element)

Returns true if Element is found in Range.

const uint32_t * getNoPreservedMask() const override

const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID CC) const override

bool eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS) const override

BitVector getReservedRegs(const MachineFunction &MF) const override

bool getRegAllocationHints(Register VirtReg, ArrayRef< MCPhysReg > Order, SmallVectorImpl< MCPhysReg > &Hints, const MachineFunction &MF, const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const override

const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override

SystemZRegisterInfo(unsigned int RA)

Register getFrameRegister(const MachineFunction &MF) const override

bool shouldCoalesce(MachineInstr *MI, const TargetRegisterClass *SrcRC, unsigned SubReg, const TargetRegisterClass *DstRC, unsigned DstSubReg, const TargetRegisterClass *NewRC, LiveIntervals &LIS) const override

SrcRC and DstRC will be morphed into NewRC if this returns true.

const TargetRegisterClass * getCrossCopyRegClass(const TargetRegisterClass *RC) const override

getCrossCopyRegClass - Returns a legal register class to copy a register in the specified class to or...