LLVM: lib/Target/Mips/MipsCallLowering.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

22

23using namespace llvm;

24

27

28namespace {

31

32public:

35 : IncomingValueHandler(MIRBuilder, MRI),

36 STI(MIRBuilder.getMF().getSubtarget<MipsSubtarget>()) {}

37

38private:

41

48

51 std::function<void()> *Thunk = nullptr) override;

52

53 virtual void markPhysRegUsed(unsigned PhysReg) {

54 MIRBuilder.getMRI()->addLiveIn(PhysReg);

55 MIRBuilder.getMBB().addLiveIn(PhysReg);

56 }

57};

58

59class CallReturnHandler : public MipsIncomingValueHandler {

60public:

61 CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,

62 MachineInstrBuilder &MIB)

63 : MipsIncomingValueHandler(MIRBuilder, MRI), MIB(MIB) {}

64

65private:

66 void markPhysRegUsed(unsigned PhysReg) override {

68 }

69

70 MachineInstrBuilder &MIB;

71};

72

73}

74

75void MipsIncomingValueHandler::assignValueToReg(Register ValVReg,

78 markPhysRegUsed(PhysReg);

79 IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA);

80}

81

82Register MipsIncomingValueHandler::getStackAddress(uint64_t Size,

86

89

90

93

94 return MIRBuilder.buildFrameIndex(LLT::pointer(0, 32), FI).getReg(0);

95}

96

97void MipsIncomingValueHandler::assignValueToAddress(

103 MIRBuilder.buildLoad(ValVReg, Addr, *MMO);

104}

105

106

107

108

109

110unsigned

113 std::function<void()> *Thunk) {

116

118 VALo.getValVT() == MVT::f64 && VAHi.getValVT() == MVT::f64 &&

119 "unexpected custom value");

120

125

127 Arg.Regs = { CopyLo.getReg(0), CopyHi.getReg(0) };

128 MIRBuilder.buildMergeLikeInstr(Arg.OrigRegs[0], {CopyLo, CopyHi});

129

130 markPhysRegUsed(VALo.getLocReg());

131 markPhysRegUsed(VAHi.getLocReg());

132 return 2;

133}

134

135namespace {

137 const MipsSubtarget &STI;

138

139public:

140 MipsOutgoingValueHandler(MachineIRBuilder &MIRBuilder,

141 MachineRegisterInfo &MRI, MachineInstrBuilder &MIB)

142 : OutgoingValueHandler(MIRBuilder, MRI),

143 STI(MIRBuilder.getMF().getSubtarget()), MIB(MIB) {}

144

145private:

147 const CCValAssign &VA) override;

148

150 MachinePointerInfo &MPO,

151 ISD::ArgFlagsTy Flags) override;

152

153 void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy,

154 const MachinePointerInfo &MPO,

155 const CCValAssign &VA) override;

156 unsigned assignCustomValue(CallLowering::ArgInfo &Arg,

158 std::function<void()> *Thunk) override;

159

160 MachineInstrBuilder &MIB;

161};

162}

163

164void MipsOutgoingValueHandler::assignValueToReg(Register ValVReg,

167 Register ExtReg = extendRegister(ValVReg, VA);

168 MIRBuilder.buildCopy(PhysReg, ExtReg);

170}

171

172Register MipsOutgoingValueHandler::getStackAddress(uint64_t Size,

178

181 auto SPReg = MIRBuilder.buildCopy(p0, Register(Mips::SP));

182

183 auto OffsetReg = MIRBuilder.buildConstant(s32, Offset);

184 auto AddrReg = MIRBuilder.buildPtrAdd(p0, SPReg, OffsetReg);

185 return AddrReg.getReg(0);

186}

187

188void MipsOutgoingValueHandler::assignValueToAddress(

193

197

198 Register ExtReg = extendRegister(ValVReg, VA);

199 MIRBuilder.buildStore(ExtReg, Addr, *MMO);

200}

201

202unsigned

205 std::function<void()> *Thunk) {

208

210 VALo.getValVT() == MVT::f64 && VAHi.getValVT() == MVT::f64 &&

211 "unexpected custom value");

212

213 auto Unmerge =

217

222

223

224

225 if (Thunk) {

227 MIRBuilder.buildCopy(VALo.getLocReg(), Lo);

228 MIRBuilder.buildCopy(VAHi.getLocReg(), Hi);

229 };

230 return 2;

231 }

232 MIRBuilder.buildCopy(VALo.getLocReg(), Lo);

233 MIRBuilder.buildCopy(VAHi.getLocReg(), Hi);

234 return 2;

235}

236

238 if (T->isIntegerTy())

239 return true;

240 if (T->isPointerTy())

241 return true;

242 if (T->isFloatingPointTy())

243 return true;

244 return false;

245}

246

248 if (T->isIntegerTy())

249 return true;

250 if (T->isPointerTy())

251 return true;

252 if (T->isFloatingPointTy())

253 return true;

254 if (T->isAggregateType())

255 return true;

256 return false;

257}

258

262

264

266 return false;

267

268 if (!VRegs.empty()) {

273

275

276 ArgInfo ArgRetInfo(VRegs, *Val, 0);

277 setArgFlags(ArgRetInfo, AttributeList::ReturnIndex, DL, F);

279

281

282 MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,

283 F.getContext());

284

285 MipsOutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret);

287

289 return false;

290

291 if (handleAssignments(RetHandler, RetInfos, CCInfo, ArgLocs, MIRBuilder))

292 return false;

293 }

294

296 return true;

297}

298

303

304

305 if (F.arg_empty())

306 return true;

307

308 for (auto &Arg : F.args()) {

310 return false;

311 }

312

316

318 unsigned i = 0;

319 for (auto &Arg : F.args()) {

320 ArgInfo AInfo(VRegs[i], Arg, i);

321 setArgFlags(AInfo, i + AttributeList::FirstArgIndex, DL, F);

322

324 ++i;

325 }

326

328 MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,

329 F.getContext());

330

334 CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(F.getCallingConv()),

336

339 return false;

340

341 MipsIncomingValueHandler Handler(MIRBuilder, MF.getRegInfo());

342 if (handleAssignments(Handler, ArgInfos, CCInfo, ArgLocs, MIRBuilder))

343 return false;

344

345 if (F.isVarArg()) {

349

350 int VaArgOffset;

352 if (ArgRegs.size() == Idx)

354 else {

355 VaArgOffset =

356 (int)ABI.GetCalleeAllocdArgSizeInBytes(CCInfo.getCallingConv()) -

358 }

359

363

364 for (unsigned I = Idx; I < ArgRegs.size(); ++I, VaArgOffset += RegSize) {

371

376 MIRBuilder.buildStore(Copy, FrameIndex, *MMO);

377 }

378 }

379

380 return true;

381}

382

385

387 return false;

388

389 for (auto &Arg : Info.OrigArgs) {

391 return false;

392 if (Arg.Flags[0].isByVal())

393 return false;

395 return false;

396 }

397

399 return false;

400

408

410 MIRBuilder.buildInstr(Mips::ADJCALLSTACKDOWN);

411

412 const bool IsCalleeGlobalPIC =

414

416 Info.Callee.isReg() || IsCalleeGlobalPIC ? Mips::JALRPseudo : Mips::JAL);

418 if (IsCalleeGlobalPIC) {

422 MIRBuilder.buildGlobalValue(CalleeReg, Info.Callee.getGlobal());

423 if (!Info.Callee.getGlobal()->hasLocalLinkage())

425 MIB.addUse(CalleeReg);

426 } else

427 MIB.add(Info.Callee);

429 MIB.addRegMask(TRI->getCallPreservedMask(MF, Info.CallConv));

430

432 FuncOrigArgs.reserve(Info.OrigArgs.size());

433

435 for (auto &Arg : Info.OrigArgs)

437

439 bool IsCalleeVarArg = false;

440 if (Info.Callee.isGlobal()) {

441 const Function *CF = static_cast<const Function *>(Info.Callee.getGlobal());

442 IsCalleeVarArg = CF->isVarArg();

443 }

444

445

446

447 MipsCCState CCInfo(Info.CallConv, IsCalleeVarArg, MF, ArgLocs,

448 F.getContext());

449

450 CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(Info.CallConv),

452

455 return false;

456

457 MipsOutgoingValueHandler ArgHandler(MIRBuilder, MF.getRegInfo(), MIB);

458 if (handleAssignments(ArgHandler, ArgInfos, CCInfo, ArgLocs, MIRBuilder))

459 return false;

460

462 unsigned StackAlignment = F.getParent()->getOverrideStackAlignment();

463 if (!StackAlignment) {

466 }

467 StackSize = alignTo(StackSize, StackAlignment);

469

470 if (IsCalleeGlobalPIC) {

475 }

477 if (MIB->getOpcode() == Mips::JALRPseudo) {

481 }

482

483 if (!Info.OrigRet.Ty->isVoidTy()) {

484 ArgInfos.clear();

485

487 F.getCallingConv());

488

491 CallReturnHandler RetHandler(MIRBuilder, MF.getRegInfo(), MIB);

492

493 MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,

494 F.getContext());

495

497 return false;

498

499 if (handleAssignments(RetHandler, ArgInfos, CCInfo, ArgLocs, MIRBuilder))

500 return false;

501 }

502

504

505 return true;

506}

unsigned const MachineRegisterInfo * MRI

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

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

This file declares the MachineIRBuilder class.

Register const TargetRegisterInfo * TRI

Promote Memory to Register

static bool isSupportedReturnType(Type *T)

Definition MipsCallLowering.cpp:247

static bool isSupportedArgumentType(Type *T)

Definition MipsCallLowering.cpp:237

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

static constexpr MCPhysReg SPReg

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

size_t size() const

size - Get the array size.

bool empty() const

empty - Check if the array is empty.

unsigned getFirstUnallocated(ArrayRef< MCPhysReg > Regs) const

getFirstUnallocated - Return the index of the first unallocated register in the set,...

CallingConv::ID getCallingConv() const

int64_t AllocateStack(unsigned Size, Align Alignment)

AllocateStack - Allocate a chunk of stack space with the specified size and alignment.

uint64_t getStackSize() const

Returns the size of the currently allocated portion of the stack.

CCValAssign - Represent assignment of one arg/retval to a location.

Register getLocReg() const

int64_t getLocMemOffset() const

bool handleAssignments(ValueHandler &Handler, SmallVectorImpl< ArgInfo > &Args, CCState &CCState, SmallVectorImpl< CCValAssign > &ArgLocs, MachineIRBuilder &MIRBuilder, ArrayRef< Register > ThisReturnRegs={}) const

Use Handler to insert code to handle the argument/return values represented by Args.

void splitToValueTypes(const ArgInfo &OrigArgInfo, SmallVectorImpl< ArgInfo > &SplitArgs, const DataLayout &DL, CallingConv::ID CallConv, SmallVectorImpl< uint64_t > *Offsets=nullptr) const

Break OrigArgInfo into one or more pieces the calling convention can process, returned in SplitArgs.

bool determineAssignments(ValueAssigner &Assigner, SmallVectorImpl< ArgInfo > &Args, CCState &CCInfo) const

Analyze the argument list in Args, using Assigner to populate CCInfo.

CallLowering(const TargetLowering *TLI)

const TargetLowering * getTLI() const

Getter for generic TargetLowering class.

void setArgFlags(ArgInfo &Arg, unsigned OpIdx, const DataLayout &DL, const FuncInfoTy &FuncInfo) const

A parsed version of the target data layout string in and methods for querying it.

FunctionLoweringInfo - This contains information that is global to a function that is used when lower...

bool isVarArg() const

isVarArg - Return true if this function takes a variable number of arguments.

static constexpr LLT scalar(unsigned SizeInBits)

Get a low-level scalar or aggregate "bag of bits".

static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)

Get a low-level pointer in the given address space.

void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())

Adds the specified register as a live in.

The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.

LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)

Create a new object at a fixed location on the stack.

const TargetSubtargetInfo & getSubtarget() const

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

MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)

getMachineMemOperand - Allocate a new MachineMemOperand.

MachineFrameInfo & getFrameInfo()

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

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

const DataLayout & getDataLayout() const

Return the DataLayout attached to the Module associated to this MF.

Function & getFunction()

Return the LLVM function that this machine code represents.

Ty * getInfo()

getInfo - Keep track of various per-function pieces of information for backends that would like to do...

const TargetMachine & getTarget() const

getTarget - Return the target machine this machine code is compiled with

Helper class to build MachineInstr.

MachineInstrBuilder insertInstr(MachineInstrBuilder MIB)

Insert an existing instruction at the insertion point.

MachineInstrBuilder buildGlobalValue(const DstOp &Res, const GlobalValue *GV)

Build and insert Res = G_GLOBAL_VALUE GV.

const TargetInstrInfo & getTII()

MachineInstrBuilder buildStore(const SrcOp &Val, const SrcOp &Addr, MachineMemOperand &MMO)

Build and insert G_STORE Val, Addr, MMO.

MachineInstrBuilder buildInstr(unsigned Opcode)

Build and insert = Opcode .

MachineInstrBuilder buildFrameIndex(const DstOp &Res, int Idx)

Build and insert Res = G_FRAME_INDEX Idx.

MachineFunction & getMF()

Getter for the function we currently build.

const MachineBasicBlock & getMBB() const

Getter for the basic block we currently build.

MachineInstrBuilder buildInstrNoInsert(unsigned Opcode)

Build but don't insert = Opcode .

MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)

Build and insert Res = COPY Op.

const MachineInstrBuilder & addImm(int64_t Val) const

Add a new immediate operand.

const MachineInstrBuilder & add(const MachineOperand &MO) const

const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const

bool constrainAllUses(const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI) const

const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const

Add a virtual register use operand.

const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const

Add a virtual register definition operand.

Representation of each machine instruction.

unsigned getOpcode() const

Returns the opcode of this MachineInstr.

const MachineOperand & getOperand(unsigned i) const

A description of a memory reference used in the backend.

@ MOLoad

The memory access reads data.

@ MOStore

The memory access writes data.

void setTargetFlags(unsigned F)

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

LLVM_ABI Register createGenericVirtualRegister(LLT Ty, StringRef Name="")

Create and return a new generic virtual register with low-level type Ty.

MipsCallLowering(const MipsTargetLowering &TLI)

Definition MipsCallLowering.cpp:25

bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F, ArrayRef< ArrayRef< Register > > VRegs, FunctionLoweringInfo &FLI) const override

This hook must be implemented to lower the incoming (formal) arguments, described by VRegs,...

Definition MipsCallLowering.cpp:299

bool lowerCall(MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info) const override

This hook must be implemented to lower the given call instruction, including argument and return valu...

Definition MipsCallLowering.cpp:383

bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val, ArrayRef< Register > VRegs, FunctionLoweringInfo &FLI) const override

This hook behaves as the extended lowerReturn function, but for targets that do not support swifterro...

Definition MipsCallLowering.cpp:259

MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...

Register getGlobalBaseRegForGlobalISel(MachineFunction &MF)

const MipsRegisterInfo * getRegisterInfo() const override

const RegisterBankInfo * getRegBankInfo() const override

Align getStackAlignment() const

const MipsABIInfo & getABI() const

Wrapper class representing virtual and physical registers.

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

Information about stack frame layout on the target.

unsigned getStackAlignment() const

getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...

std::vector< ArgListEntry > ArgListTy

bool isPositionIndependent() const

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

virtual const TargetFrameLowering * getFrameLowering() const

virtual const TargetRegisterInfo * getRegisterInfo() const =0

Return the target's register information.

The instances of the Type class are immutable: once they are created, they are never changed.

bool isPointerTy() const

True if this is an instance of PointerType.

LLVM Value Representation.

Type * getType() const

All values are typed, get the type of this value.

@ C

The default llvm calling convention, compatible with C.

@ Implicit

Not emitted register (e.g. carry, or temporary result).

This is an optimization pass for GlobalISel generic memory operations.

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

ArrayRef(const T &OneElt) -> ArrayRef< T >

Align commonAlignment(Align A, uint64_t Offset)

Returns the alignment that satisfies both alignments.

LLVM_ABI Align inferAlignFromPtrInfo(MachineFunction &MF, const MachinePointerInfo &MPO)

void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)

Implement std::swap in terms of BitVector swap.

This struct is a compact representation of a valid (non-zero power of two) alignment.

SmallVector< Register, 4 > Regs

SmallVector< Register, 2 > OrigRegs

SmallVector< ISD::ArgFlagsTy, 4 > Flags

Base class for ValueHandlers used for arguments coming into the current function, or for return value...

Base class for ValueHandlers used for arguments passed to a function call, or for return values.

This class contains a discriminated union of information about pointers in memory operands,...

LLVM_ABI unsigned getAddrSpace() const

Return the LLVM IR address space number that this pointer points into.

static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)

Stack pointer relative access.

static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)

Return a MachinePointerInfo record that refers to the specified FrameIndex.