LLVM 23.0.0git
MipsCallLowering.cpp
Go to the documentation of this file.
1//===- MipsCallLowering.cpp -------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file
10/// This file implements the lowering of LLVM calls to machine code calls for
11/// GlobalISel.
12//
13//===----------------------------------------------------------------------===//
14
15#include "MipsCallLowering.h"
16#include "MipsCCState.h"
17#include "MipsMachineFunction.h"
18#include "MipsTargetMachine.h"
22
23using namespace llvm;
24
27
28namespace {
29class MipsIncomingValueHandler : public CallLowering::IncomingValueHandler {
30 const MipsSubtarget &STI;
31
32public:
33 MipsIncomingValueHandler(MachineIRBuilder &MIRBuilder,
35 : IncomingValueHandler(MIRBuilder, MRI),
36 STI(MIRBuilder.getMF().getSubtarget<MipsSubtarget>()) {}
37
38private:
39 void assignValueToReg(Register ValVReg, Register PhysReg,
40 const CCValAssign &VA,
41 ISD::ArgFlagsTy Flags = {}) override;
42
43 Register getStackAddress(uint64_t Size, int64_t Offset,
44 MachinePointerInfo &MPO,
45 ISD::ArgFlagsTy Flags) override;
46 void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy,
47 const MachinePointerInfo &MPO,
48 const CCValAssign &VA) override;
49
50 unsigned assignCustomValue(CallLowering::ArgInfo &Arg,
52 std::function<void()> *Thunk = nullptr) override;
53
54 virtual void markPhysRegUsed(unsigned PhysReg) {
55 MIRBuilder.getMRI()->addLiveIn(PhysReg);
56 MIRBuilder.getMBB().addLiveIn(PhysReg);
57 }
58};
59
60class CallReturnHandler : public MipsIncomingValueHandler {
61public:
62 CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
63 MachineInstrBuilder &MIB)
64 : MipsIncomingValueHandler(MIRBuilder, MRI), MIB(MIB) {}
65
66private:
67 void markPhysRegUsed(unsigned PhysReg) override {
68 MIB.addDef(PhysReg, RegState::Implicit);
69 }
70
71 MachineInstrBuilder &MIB;
72};
73
74} // end anonymous namespace
75
76void MipsIncomingValueHandler::assignValueToReg(Register ValVReg,
77 Register PhysReg,
78 const CCValAssign &VA,
79 ISD::ArgFlagsTy Flags) {
80 markPhysRegUsed(PhysReg);
81 IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA);
82}
83
84Register MipsIncomingValueHandler::getStackAddress(uint64_t Size,
85 int64_t Offset,
87 ISD::ArgFlagsTy Flags) {
88
89 MachineFunction &MF = MIRBuilder.getMF();
91
92 // FIXME: This should only be immutable for non-byval memory arguments.
93 int FI = MFI.CreateFixedObject(Size, Offset, true);
94 MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
95
96 return MIRBuilder.buildFrameIndex(LLT::pointer(0, 32), FI).getReg(0);
97}
98
99void MipsIncomingValueHandler::assignValueToAddress(
100 Register ValVReg, Register Addr, LLT MemTy, const MachinePointerInfo &MPO,
101 const CCValAssign &VA) {
102 MachineFunction &MF = MIRBuilder.getMF();
103 auto MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, MemTy,
104 inferAlignFromPtrInfo(MF, MPO));
105 MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
106}
107
108/// Handle cases when f64 is split into 2 32-bit GPRs. This is a custom
109/// assignment because generic code assumes getNumRegistersForCallingConv is
110/// accurate. In this case it is not because the type/number are context
111/// dependent on other arguments.
112unsigned
113MipsIncomingValueHandler::assignCustomValue(CallLowering::ArgInfo &Arg,
115 std::function<void()> *Thunk) {
116 const CCValAssign &VALo = VAs[0];
117 const CCValAssign &VAHi = VAs[1];
118
119 assert(VALo.getLocVT() == MVT::i32 && VAHi.getLocVT() == MVT::i32 &&
120 VALo.getValVT() == MVT::f64 && VAHi.getValVT() == MVT::f64 &&
121 "unexpected custom value");
122
123 auto CopyLo = MIRBuilder.buildCopy(LLT::scalar(32), VALo.getLocReg());
124 auto CopyHi = MIRBuilder.buildCopy(LLT::scalar(32), VAHi.getLocReg());
125 if (!STI.isLittle())
126 std::swap(CopyLo, CopyHi);
127
128 Arg.OrigRegs.assign(Arg.Regs.begin(), Arg.Regs.end());
129 Arg.Regs = { CopyLo.getReg(0), CopyHi.getReg(0) };
130 MIRBuilder.buildMergeLikeInstr(Arg.OrigRegs[0], {CopyLo, CopyHi});
131
132 markPhysRegUsed(VALo.getLocReg());
133 markPhysRegUsed(VAHi.getLocReg());
134 return 2;
135}
136
137namespace {
138class MipsOutgoingValueHandler : public CallLowering::OutgoingValueHandler {
139 const MipsSubtarget &STI;
140
141public:
142 MipsOutgoingValueHandler(MachineIRBuilder &MIRBuilder,
143 MachineRegisterInfo &MRI, MachineInstrBuilder &MIB)
144 : OutgoingValueHandler(MIRBuilder, MRI),
145 STI(MIRBuilder.getMF().getSubtarget<MipsSubtarget>()), MIB(MIB) {}
146
147private:
148 void assignValueToReg(Register ValVReg, Register PhysReg,
149 const CCValAssign &VA,
150 ISD::ArgFlagsTy Flags = {}) override;
151
152 Register getStackAddress(uint64_t Size, int64_t Offset,
153 MachinePointerInfo &MPO,
154 ISD::ArgFlagsTy Flags) override;
155
156 void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy,
157 const MachinePointerInfo &MPO,
158 const CCValAssign &VA) override;
159 unsigned assignCustomValue(CallLowering::ArgInfo &Arg,
161 std::function<void()> *Thunk) override;
162
163 MachineInstrBuilder &MIB;
164};
165} // end anonymous namespace
166
167void MipsOutgoingValueHandler::assignValueToReg(Register ValVReg,
168 Register PhysReg,
169 const CCValAssign &VA,
170 ISD::ArgFlagsTy Flags) {
171 Register ExtReg = extendRegister(ValVReg, VA);
172 MIRBuilder.buildCopy(PhysReg, ExtReg);
173 MIB.addUse(PhysReg, RegState::Implicit);
174}
175
176Register MipsOutgoingValueHandler::getStackAddress(uint64_t Size,
177 int64_t Offset,
179 ISD::ArgFlagsTy Flags) {
180 MachineFunction &MF = MIRBuilder.getMF();
182
183 LLT p0 = LLT::pointer(0, 32);
184 LLT s32 = LLT::scalar(32);
185 auto SPReg = MIRBuilder.buildCopy(p0, Register(Mips::SP));
186
187 auto OffsetReg = MIRBuilder.buildConstant(s32, Offset);
188 auto AddrReg = MIRBuilder.buildPtrAdd(p0, SPReg, OffsetReg);
189 return AddrReg.getReg(0);
190}
191
192void MipsOutgoingValueHandler::assignValueToAddress(
193 Register ValVReg, Register Addr, LLT MemTy, const MachinePointerInfo &MPO,
194 const CCValAssign &VA) {
195 MachineFunction &MF = MIRBuilder.getMF();
196 uint64_t LocMemOffset = VA.getLocMemOffset();
197
198 auto MMO = MF.getMachineMemOperand(
199 MPO, MachineMemOperand::MOStore, MemTy,
200 commonAlignment(STI.getStackAlignment(), LocMemOffset));
201
202 Register ExtReg = extendRegister(ValVReg, VA);
203 MIRBuilder.buildStore(ExtReg, Addr, *MMO);
204}
205
206unsigned
207MipsOutgoingValueHandler::assignCustomValue(CallLowering::ArgInfo &Arg,
209 std::function<void()> *Thunk) {
210 const CCValAssign &VALo = VAs[0];
211 const CCValAssign &VAHi = VAs[1];
212
213 assert(VALo.getLocVT() == MVT::i32 && VAHi.getLocVT() == MVT::i32 &&
214 VALo.getValVT() == MVT::f64 && VAHi.getValVT() == MVT::f64 &&
215 "unexpected custom value");
216
217 auto Unmerge =
218 MIRBuilder.buildUnmerge({LLT::scalar(32), LLT::scalar(32)}, Arg.Regs[0]);
219 Register Lo = Unmerge.getReg(0);
220 Register Hi = Unmerge.getReg(1);
221
222 Arg.OrigRegs.assign(Arg.Regs.begin(), Arg.Regs.end());
223 Arg.Regs = { Lo, Hi };
224 if (!STI.isLittle())
225 std::swap(Lo, Hi);
226
227 // If we can return a thunk, just include the register copies. The unmerge can
228 // be emitted earlier.
229 if (Thunk) {
230 *Thunk = [=]() {
231 MIRBuilder.buildCopy(VALo.getLocReg(), Lo);
232 MIRBuilder.buildCopy(VAHi.getLocReg(), Hi);
233 };
234 return 2;
235 }
236 MIRBuilder.buildCopy(VALo.getLocReg(), Lo);
237 MIRBuilder.buildCopy(VAHi.getLocReg(), Hi);
238 return 2;
239}
240
242 if (T->isIntegerTy())
243 return true;
244 if (T->isPointerTy())
245 return true;
246 if (T->isFloatingPointTy())
247 return true;
248 return false;
249}
250
252 if (T->isIntegerTy())
253 return true;
254 if (T->isPointerTy())
255 return true;
256 if (T->isFloatingPointTy())
257 return true;
258 if (T->isAggregateType())
259 return true;
260 return false;
261}
262
264 const Value *Val, ArrayRef<Register> VRegs,
265 FunctionLoweringInfo &FLI) const {
266
267 MachineInstrBuilder Ret = MIRBuilder.buildInstrNoInsert(Mips::RetRA);
268
269 if (Val != nullptr && !isSupportedReturnType(Val->getType()))
270 return false;
271
272 if (!VRegs.empty()) {
273 MachineFunction &MF = MIRBuilder.getMF();
274 const Function &F = MF.getFunction();
275 const DataLayout &DL = MF.getDataLayout();
277
279
280 ArgInfo ArgRetInfo(VRegs, *Val, 0);
281 setArgFlags(ArgRetInfo, AttributeList::ReturnIndex, DL, F);
282 splitToValueTypes(ArgRetInfo, RetInfos, DL, F.getCallingConv());
283
285
286 MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
287 F.getContext());
288
289 MipsOutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret);
290 OutgoingValueAssigner Assigner(TLI.CCAssignFnForReturn());
291
292 if (!determineAssignments(Assigner, RetInfos, CCInfo))
293 return false;
294
295 if (!handleAssignments(RetHandler, RetInfos, CCInfo, ArgLocs, MIRBuilder))
296 return false;
297 }
298
299 MIRBuilder.insertInstr(Ret);
300 return true;
301}
302
304 const Function &F,
306 FunctionLoweringInfo &FLI) const {
307
308 // Quick exit if there aren't any args.
309 if (F.arg_empty())
310 return true;
311
312 for (auto &Arg : F.args()) {
313 if (!isSupportedArgumentType(Arg.getType()))
314 return false;
315 }
316
317 MachineFunction &MF = MIRBuilder.getMF();
318 const DataLayout &DL = MF.getDataLayout();
320
322 unsigned i = 0;
323 for (auto &Arg : F.args()) {
324 ArgInfo AInfo(VRegs[i], Arg, i);
325 setArgFlags(AInfo, i + AttributeList::FirstArgIndex, DL, F);
326
327 splitToValueTypes(AInfo, ArgInfos, DL, F.getCallingConv());
328 ++i;
329 }
330
332 MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
333 F.getContext());
334
335 const MipsTargetMachine &TM =
336 static_cast<const MipsTargetMachine &>(MF.getTarget());
337 const MipsABIInfo &ABI = TM.getABI();
338 CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(F.getCallingConv()),
339 Align(1));
340
341 IncomingValueAssigner Assigner(TLI.CCAssignFnForCall());
342 if (!determineAssignments(Assigner, ArgInfos, CCInfo))
343 return false;
344
345 MipsIncomingValueHandler Handler(MIRBuilder, MF.getRegInfo());
346 if (!handleAssignments(Handler, ArgInfos, CCInfo, ArgLocs, MIRBuilder))
347 return false;
348
349 if (F.isVarArg()) {
350 ArrayRef<MCPhysReg> ArgRegs =
351 ABI.getVarArgRegs(MF.getSubtarget<MipsSubtarget>().isGP64bit());
352 unsigned Idx = CCInfo.getFirstUnallocated(ArgRegs);
353
354 int VaArgOffset;
355 unsigned RegSize = 4;
356 if (ArgRegs.size() == Idx)
357 VaArgOffset = alignTo(CCInfo.getStackSize(), RegSize);
358 else {
359 VaArgOffset =
360 (int)ABI.GetCalleeAllocdArgSizeInBytes(CCInfo.getCallingConv()) -
361 (int)(RegSize * (ArgRegs.size() - Idx));
362 }
363
364 MachineFrameInfo &MFI = MF.getFrameInfo();
365 int FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true);
366 MF.getInfo<MipsFunctionInfo>()->setVarArgsFrameIndex(FI);
367
368 for (unsigned I = Idx; I < ArgRegs.size(); ++I, VaArgOffset += RegSize) {
369 MIRBuilder.getMBB().addLiveIn(ArgRegs[I]);
370 LLT RegTy = LLT::scalar(RegSize * 8);
372 MIRBuilder.buildCopy(RegTy, Register(ArgRegs[I]));
373 FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true);
375
376 const LLT PtrTy = LLT::pointer(MPO.getAddrSpace(), 32);
377 auto FrameIndex = MIRBuilder.buildFrameIndex(PtrTy, FI);
380 MIRBuilder.buildStore(Copy, FrameIndex, *MMO);
381 }
382 }
383
384 return true;
385}
386
388 CallLoweringInfo &Info) const {
389
390 if (Info.CallConv != CallingConv::C)
391 return false;
392
393 for (auto &Arg : Info.OrigArgs) {
394 if (!isSupportedArgumentType(Arg.Ty))
395 return false;
396 if (Arg.Flags[0].isByVal())
397 return false;
398 if (Arg.Flags[0].isSRet() && !Arg.Ty->isPointerTy())
399 return false;
400 }
401
402 if (!Info.OrigRet.Ty->isVoidTy() && !isSupportedReturnType(Info.OrigRet.Ty))
403 return false;
404
405 MachineFunction &MF = MIRBuilder.getMF();
406 const Function &F = MF.getFunction();
407 const DataLayout &DL = MF.getDataLayout();
409 const MipsTargetMachine &TM =
410 static_cast<const MipsTargetMachine &>(MF.getTarget());
411 const MipsABIInfo &ABI = TM.getABI();
412
413 MachineInstrBuilder CallSeqStart =
414 MIRBuilder.buildInstr(Mips::ADJCALLSTACKDOWN);
415
416 const bool IsCalleeGlobalPIC =
417 Info.Callee.isGlobal() && TM.isPositionIndependent();
418
420 Info.Callee.isReg() || IsCalleeGlobalPIC ? Mips::JALRPseudo : Mips::JAL);
421 MIB.addDef(Mips::SP, RegState::Implicit);
422 if (IsCalleeGlobalPIC) {
423 Register CalleeReg =
425 MachineInstr *CalleeGlobalValue =
426 MIRBuilder.buildGlobalValue(CalleeReg, Info.Callee.getGlobal());
427 if (!Info.Callee.getGlobal()->hasLocalLinkage())
428 CalleeGlobalValue->getOperand(1).setTargetFlags(MipsII::MO_GOT_CALL);
429 MIB.addUse(CalleeReg);
430 } else
431 MIB.add(Info.Callee);
433 MIB.addRegMask(TRI->getCallPreservedMask(MF, Info.CallConv));
434
435 TargetLowering::ArgListTy FuncOrigArgs;
436 FuncOrigArgs.reserve(Info.OrigArgs.size());
437
439 for (auto &Arg : Info.OrigArgs)
440 splitToValueTypes(Arg, ArgInfos, DL, Info.CallConv);
441
443 bool IsCalleeVarArg = false;
444 if (Info.Callee.isGlobal()) {
445 const Function *CF = static_cast<const Function *>(Info.Callee.getGlobal());
446 IsCalleeVarArg = CF->isVarArg();
447 }
448
449 // FIXME: Should use MipsCCState::getSpecialCallingConvForCallee, but it
450 // depends on looking directly at the call target.
451 MipsCCState CCInfo(Info.CallConv, IsCalleeVarArg, MF, ArgLocs,
452 F.getContext());
453
454 CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(Info.CallConv),
455 Align(1));
456
457 OutgoingValueAssigner Assigner(TLI.CCAssignFnForCall());
458 if (!determineAssignments(Assigner, ArgInfos, CCInfo))
459 return false;
460
461 MipsOutgoingValueHandler ArgHandler(MIRBuilder, MF.getRegInfo(), MIB);
462 if (!handleAssignments(ArgHandler, ArgInfos, CCInfo, ArgLocs, MIRBuilder))
463 return false;
464
465 unsigned StackSize = CCInfo.getStackSize();
466 unsigned StackAlignment = F.getParent()->getOverrideStackAlignment();
467 if (!StackAlignment) {
469 StackAlignment = TFL->getStackAlignment();
470 }
471 StackSize = alignTo(StackSize, StackAlignment);
472 CallSeqStart.addImm(StackSize).addImm(0);
473
474 if (IsCalleeGlobalPIC) {
475 MIRBuilder.buildCopy(
476 Register(Mips::GP),
478 MIB.addDef(Mips::GP, RegState::Implicit);
479 }
480 MIRBuilder.insertInstr(MIB);
481 if (MIB->getOpcode() == Mips::JALRPseudo) {
482 const MipsSubtarget &STI = MIRBuilder.getMF().getSubtarget<MipsSubtarget>();
483 MIB.constrainAllUses(MIRBuilder.getTII(), *STI.getRegisterInfo(),
484 *STI.getRegBankInfo());
485 }
486
487 if (!Info.OrigRet.Ty->isVoidTy()) {
488 ArgInfos.clear();
489
490 CallLowering::splitToValueTypes(Info.OrigRet, ArgInfos, DL,
491 F.getCallingConv());
492
494 IncomingValueAssigner Assigner(TLI.CCAssignFnForReturn());
495 CallReturnHandler RetHandler(MIRBuilder, MF.getRegInfo(), MIB);
496
497 MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
498 F.getContext());
499
500 if (!determineAssignments(Assigner, ArgInfos, CCInfo))
501 return false;
502
503 if (!handleAssignments(RetHandler, ArgInfos, CCInfo, ArgLocs, MIRBuilder))
504 return false;
505 }
506
507 MIRBuilder.buildInstr(Mips::ADJCALLSTACKUP).addImm(StackSize).addImm(0);
508
509 return true;
510}
unsigned RegSize
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
This file declares the MachineIRBuilder class.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
#define T
static bool isSupportedReturnType(Type *T)
static bool isSupportedArgumentType(Type *T)
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),...
Definition ArrayRef.h:40
size_t size() const
size - Get the array size.
Definition ArrayRef.h:142
bool empty() const
empty - Check if the array is empty.
Definition ArrayRef.h:137
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< TypeSize > *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.
Definition DataLayout.h:64
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.
Definition Function.h:229
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 <empty> = Opcode <empty>.
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 <empty> = Opcode <empty>.
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
void constrainAllUses(const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI) const
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
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
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, 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)
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,...
bool lowerCall(MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info) const override
This hook must be implemented to lower the given call instruction, including argument and return valu...
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...
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
Register getGlobalBaseRegForGlobalISel(MachineFunction &MF)
bool isLittle() const
const MipsRegisterInfo * getRegisterInfo() const override
const RegisterBankInfo * getRegBankInfo() const override
bool isGP64bit() const
Align getStackAlignment() const
const MipsABIInfo & getABI() const
Wrapper class representing virtual and physical registers.
Definition Register.h:20
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.
Definition Type.h:45
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:267
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:256
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
@ Offset
Definition DWP.cpp:532
@ Implicit
Not emitted register (e.g. carry, or temporary result).
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
ArrayRef(const T &OneElt) -> ArrayRef< T >
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Definition Alignment.h:201
LLVM_ABI Align inferAlignFromPtrInfo(MachineFunction &MF, const MachinePointerInfo &MPO)
Definition Utils.cpp:900
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:872
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
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.