LLVM 17.0.0git
ARMCallLowering.cpp
Go to the documentation of this file.
1//===- llvm/lib/Target/ARM/ARMCallLowering.cpp - Call lowering ------------===//
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 "ARMCallLowering.h"
16#include "ARMBaseInstrInfo.h"
17#include "ARMISelLowering.h"
18#include "ARMSubtarget.h"
19#include "Utils/ARMBaseInfo.h"
38#include "llvm/IR/Attributes.h"
39#include "llvm/IR/DataLayout.h"
41#include "llvm/IR/Function.h"
42#include "llvm/IR/Type.h"
43#include "llvm/IR/Value.h"
45#include <algorithm>
46#include <cassert>
47#include <cstdint>
48#include <functional>
49#include <utility>
50
51using namespace llvm;
52
54 : CallLowering(&TLI) {}
55
56static bool isSupportedType(const DataLayout &DL, const ARMTargetLowering &TLI,
57 Type *T) {
58 if (T->isArrayTy())
59 return isSupportedType(DL, TLI, T->getArrayElementType());
60
61 if (T->isStructTy()) {
62 // For now we only allow homogeneous structs that we can manipulate with
63 // G_MERGE_VALUES and G_UNMERGE_VALUES
64 auto StructT = cast<StructType>(T);
65 for (unsigned i = 1, e = StructT->getNumElements(); i != e; ++i)
66 if (StructT->getElementType(i) != StructT->getElementType(0))
67 return false;
68 return isSupportedType(DL, TLI, StructT->getElementType(0));
69 }
70
71 EVT VT = TLI.getValueType(DL, T, true);
72 if (!VT.isSimple() || VT.isVector() ||
73 !(VT.isInteger() || VT.isFloatingPoint()))
74 return false;
75
76 unsigned VTSize = VT.getSimpleVT().getSizeInBits();
77
78 if (VTSize == 64)
79 // FIXME: Support i64 too
80 return VT.isFloatingPoint();
81
82 return VTSize == 1 || VTSize == 8 || VTSize == 16 || VTSize == 32;
83}
84
85namespace {
86
87/// Helper class for values going out through an ABI boundary (used for handling
88/// function return values and call parameters).
89struct ARMOutgoingValueHandler : public CallLowering::OutgoingValueHandler {
90 ARMOutgoingValueHandler(MachineIRBuilder &MIRBuilder,
92 : OutgoingValueHandler(MIRBuilder, MRI), MIB(MIB) {}
93
94 Register getStackAddress(uint64_t Size, int64_t Offset,
96 ISD::ArgFlagsTy Flags) override {
97 assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
98 "Unsupported size");
99
100 LLT p0 = LLT::pointer(0, 32);
101 LLT s32 = LLT::scalar(32);
102 auto SPReg = MIRBuilder.buildCopy(p0, Register(ARM::SP));
103
104 auto OffsetReg = MIRBuilder.buildConstant(s32, Offset);
105
106 auto AddrReg = MIRBuilder.buildPtrAdd(p0, SPReg, OffsetReg);
107
108 MPO = MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset);
109 return AddrReg.getReg(0);
110 }
111
112 void assignValueToReg(Register ValVReg, Register PhysReg,
113 CCValAssign VA) override {
114 assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
115 assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
116
117 assert(VA.getValVT().getSizeInBits() <= 64 && "Unsupported value size");
118 assert(VA.getLocVT().getSizeInBits() <= 64 && "Unsupported location size");
119
120 Register ExtReg = extendRegister(ValVReg, VA);
121 MIRBuilder.buildCopy(PhysReg, ExtReg);
122 MIB.addUse(PhysReg, RegState::Implicit);
123 }
124
125 void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy,
126 MachinePointerInfo &MPO, CCValAssign &VA) override {
127 Register ExtReg = extendRegister(ValVReg, VA);
128 auto MMO = MIRBuilder.getMF().getMachineMemOperand(
129 MPO, MachineMemOperand::MOStore, MemTy, Align(1));
130 MIRBuilder.buildStore(ExtReg, Addr, *MMO);
131 }
132
133 unsigned assignCustomValue(CallLowering::ArgInfo &Arg,
135 std::function<void()> *Thunk) override {
136 assert(Arg.Regs.size() == 1 && "Can't handle multple regs yet");
137
138 CCValAssign VA = VAs[0];
139 assert(VA.needsCustom() && "Value doesn't need custom handling");
140
141 // Custom lowering for other types, such as f16, is currently not supported
142 if (VA.getValVT() != MVT::f64)
143 return 0;
144
145 CCValAssign NextVA = VAs[1];
146 assert(NextVA.needsCustom() && "Value doesn't need custom handling");
147 assert(NextVA.getValVT() == MVT::f64 && "Unsupported type");
148
149 assert(VA.getValNo() == NextVA.getValNo() &&
150 "Values belong to different arguments");
151
152 assert(VA.isRegLoc() && "Value should be in reg");
153 assert(NextVA.isRegLoc() && "Value should be in reg");
154
155 Register NewRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)),
156 MRI.createGenericVirtualRegister(LLT::scalar(32))};
157 MIRBuilder.buildUnmerge(NewRegs, Arg.Regs[0]);
158
159 bool IsLittle = MIRBuilder.getMF().getSubtarget<ARMSubtarget>().isLittle();
160 if (!IsLittle)
161 std::swap(NewRegs[0], NewRegs[1]);
162
163 if (Thunk) {
164 *Thunk = [=]() {
165 assignValueToReg(NewRegs[0], VA.getLocReg(), VA);
166 assignValueToReg(NewRegs[1], NextVA.getLocReg(), NextVA);
167 };
168 return 1;
169 }
170 assignValueToReg(NewRegs[0], VA.getLocReg(), VA);
171 assignValueToReg(NewRegs[1], NextVA.getLocReg(), NextVA);
172 return 1;
173 }
174
176};
177
178} // end anonymous namespace
179
180/// Lower the return value for the already existing \p Ret. This assumes that
181/// \p MIRBuilder's insertion point is correct.
182bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder,
183 const Value *Val, ArrayRef<Register> VRegs,
184 MachineInstrBuilder &Ret) const {
185 if (!Val)
186 // Nothing to do here.
187 return true;
188
189 auto &MF = MIRBuilder.getMF();
190 const auto &F = MF.getFunction();
191
192 const auto &DL = MF.getDataLayout();
193 auto &TLI = *getTLI<ARMTargetLowering>();
194 if (!isSupportedType(DL, TLI, Val->getType()))
195 return false;
196
197 ArgInfo OrigRetInfo(VRegs, Val->getType(), 0);
199
200 SmallVector<ArgInfo, 4> SplitRetInfos;
201 splitToValueTypes(OrigRetInfo, SplitRetInfos, DL, F.getCallingConv());
202
203 CCAssignFn *AssignFn =
204 TLI.CCAssignFnForReturn(F.getCallingConv(), F.isVarArg());
205
206 OutgoingValueAssigner RetAssigner(AssignFn);
207 ARMOutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret);
208 return determineAndHandleAssignments(RetHandler, RetAssigner, SplitRetInfos,
209 MIRBuilder, F.getCallingConv(),
210 F.isVarArg());
211}
212
214 const Value *Val, ArrayRef<Register> VRegs,
215 FunctionLoweringInfo &FLI) const {
216 assert(!Val == VRegs.empty() && "Return value without a vreg");
217
218 auto const &ST = MIRBuilder.getMF().getSubtarget<ARMSubtarget>();
219 unsigned Opcode = ST.getReturnOpcode();
220 auto Ret = MIRBuilder.buildInstrNoInsert(Opcode).add(predOps(ARMCC::AL));
221
222 if (!lowerReturnVal(MIRBuilder, Val, VRegs, Ret))
223 return false;
224
225 MIRBuilder.insertInstr(Ret);
226 return true;
227}
228
229namespace {
230
231/// Helper class for values coming in through an ABI boundary (used for handling
232/// formal arguments and call return values).
233struct ARMIncomingValueHandler : public CallLowering::IncomingValueHandler {
234 ARMIncomingValueHandler(MachineIRBuilder &MIRBuilder,
236 : IncomingValueHandler(MIRBuilder, MRI) {}
237
238 Register getStackAddress(uint64_t Size, int64_t Offset,
240 ISD::ArgFlagsTy Flags) override {
241 assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
242 "Unsupported size");
243
244 auto &MFI = MIRBuilder.getMF().getFrameInfo();
245
246 // Byval is assumed to be writable memory, but other stack passed arguments
247 // are not.
248 const bool IsImmutable = !Flags.isByVal();
249
250 int FI = MFI.CreateFixedObject(Size, Offset, IsImmutable);
251 MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
252
253 return MIRBuilder.buildFrameIndex(LLT::pointer(MPO.getAddrSpace(), 32), FI)
254 .getReg(0);
255 }
256
257 void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy,
258 MachinePointerInfo &MPO, CCValAssign &VA) override {
259 if (VA.getLocInfo() == CCValAssign::SExt ||
261 // If the value is zero- or sign-extended, its size becomes 4 bytes, so
262 // that's what we should load.
263 MemTy = LLT::scalar(32);
264 assert(MRI.getType(ValVReg).isScalar() && "Only scalars supported atm");
265
266 auto LoadVReg = buildLoad(LLT::scalar(32), Addr, MemTy, MPO);
267 MIRBuilder.buildTrunc(ValVReg, LoadVReg);
268 } else {
269 // If the value is not extended, a simple load will suffice.
270 buildLoad(ValVReg, Addr, MemTy, MPO);
271 }
272 }
273
274 MachineInstrBuilder buildLoad(const DstOp &Res, Register Addr, LLT MemTy,
275 MachinePointerInfo &MPO) {
276 MachineFunction &MF = MIRBuilder.getMF();
277
278 auto MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, MemTy,
279 inferAlignFromPtrInfo(MF, MPO));
280 return MIRBuilder.buildLoad(Res, Addr, *MMO);
281 }
282
283 void assignValueToReg(Register ValVReg, Register PhysReg,
284 CCValAssign VA) override {
285 assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
286 assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
287
288 uint64_t ValSize = VA.getValVT().getFixedSizeInBits();
289 uint64_t LocSize = VA.getLocVT().getFixedSizeInBits();
290
291 assert(ValSize <= 64 && "Unsupported value size");
292 assert(LocSize <= 64 && "Unsupported location size");
293
294 markPhysRegUsed(PhysReg);
295 if (ValSize == LocSize) {
296 MIRBuilder.buildCopy(ValVReg, PhysReg);
297 } else {
298 assert(ValSize < LocSize && "Extensions not supported");
299
300 // We cannot create a truncating copy, nor a trunc of a physical register.
301 // Therefore, we need to copy the content of the physical register into a
302 // virtual one and then truncate that.
303 auto PhysRegToVReg = MIRBuilder.buildCopy(LLT::scalar(LocSize), PhysReg);
304 MIRBuilder.buildTrunc(ValVReg, PhysRegToVReg);
305 }
306 }
307
308 unsigned assignCustomValue(ARMCallLowering::ArgInfo &Arg,
310 std::function<void()> *Thunk) override {
311 assert(Arg.Regs.size() == 1 && "Can't handle multple regs yet");
312
313 CCValAssign VA = VAs[0];
314 assert(VA.needsCustom() && "Value doesn't need custom handling");
315
316 // Custom lowering for other types, such as f16, is currently not supported
317 if (VA.getValVT() != MVT::f64)
318 return 0;
319
320 CCValAssign NextVA = VAs[1];
321 assert(NextVA.needsCustom() && "Value doesn't need custom handling");
322 assert(NextVA.getValVT() == MVT::f64 && "Unsupported type");
323
324 assert(VA.getValNo() == NextVA.getValNo() &&
325 "Values belong to different arguments");
326
327 assert(VA.isRegLoc() && "Value should be in reg");
328 assert(NextVA.isRegLoc() && "Value should be in reg");
329
330 Register NewRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)),
331 MRI.createGenericVirtualRegister(LLT::scalar(32))};
332
333 assignValueToReg(NewRegs[0], VA.getLocReg(), VA);
334 assignValueToReg(NewRegs[1], NextVA.getLocReg(), NextVA);
335
336 bool IsLittle = MIRBuilder.getMF().getSubtarget<ARMSubtarget>().isLittle();
337 if (!IsLittle)
338 std::swap(NewRegs[0], NewRegs[1]);
339
340 MIRBuilder.buildMergeLikeInstr(Arg.Regs[0], NewRegs);
341
342 return 1;
343 }
344
345 /// Marking a physical register as used is different between formal
346 /// parameters, where it's a basic block live-in, and call returns, where it's
347 /// an implicit-def of the call instruction.
348 virtual void markPhysRegUsed(unsigned PhysReg) = 0;
349};
350
351struct FormalArgHandler : public ARMIncomingValueHandler {
353 : ARMIncomingValueHandler(MIRBuilder, MRI) {}
354
355 void markPhysRegUsed(unsigned PhysReg) override {
356 MIRBuilder.getMRI()->addLiveIn(PhysReg);
357 MIRBuilder.getMBB().addLiveIn(PhysReg);
358 }
359};
360
361} // end anonymous namespace
362
364 const Function &F,
366 FunctionLoweringInfo &FLI) const {
367 auto &TLI = *getTLI<ARMTargetLowering>();
368 auto Subtarget = TLI.getSubtarget();
369
370 if (Subtarget->isThumb1Only())
371 return false;
372
373 // Quick exit if there aren't any args
374 if (F.arg_empty())
375 return true;
376
377 if (F.isVarArg())
378 return false;
379
380 auto &MF = MIRBuilder.getMF();
381 auto &MBB = MIRBuilder.getMBB();
382 const auto &DL = MF.getDataLayout();
383
384 for (auto &Arg : F.args()) {
385 if (!isSupportedType(DL, TLI, Arg.getType()))
386 return false;
387 if (Arg.hasPassPointeeByValueCopyAttr())
388 return false;
389 }
390
391 CCAssignFn *AssignFn =
392 TLI.CCAssignFnForCall(F.getCallingConv(), F.isVarArg());
393
394 OutgoingValueAssigner ArgAssigner(AssignFn);
395 FormalArgHandler ArgHandler(MIRBuilder, MIRBuilder.getMF().getRegInfo());
396
397 SmallVector<ArgInfo, 8> SplitArgInfos;
398 unsigned Idx = 0;
399 for (auto &Arg : F.args()) {
400 ArgInfo OrigArgInfo(VRegs[Idx], Arg.getType(), Idx);
401
403 splitToValueTypes(OrigArgInfo, SplitArgInfos, DL, F.getCallingConv());
404
405 Idx++;
406 }
407
408 if (!MBB.empty())
409 MIRBuilder.setInstr(*MBB.begin());
410
411 if (!determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgInfos,
412 MIRBuilder, F.getCallingConv(),
413 F.isVarArg()))
414 return false;
415
416 // Move back to the end of the basic block.
417 MIRBuilder.setMBB(MBB);
418 return true;
419}
420
421namespace {
422
423struct CallReturnHandler : public ARMIncomingValueHandler {
426 : ARMIncomingValueHandler(MIRBuilder, MRI), MIB(MIB) {}
427
428 void markPhysRegUsed(unsigned PhysReg) override {
429 MIB.addDef(PhysReg, RegState::Implicit);
430 }
431
433};
434
435// FIXME: This should move to the ARMSubtarget when it supports all the opcodes.
436unsigned getCallOpcode(const MachineFunction &MF, const ARMSubtarget &STI,
437 bool isDirect) {
438 if (isDirect)
439 return STI.isThumb() ? ARM::tBL : ARM::BL;
440
441 if (STI.isThumb())
442 return gettBLXrOpcode(MF);
443
444 if (STI.hasV5TOps())
445 return getBLXOpcode(MF);
446
447 if (STI.hasV4TOps())
448 return ARM::BX_CALL;
449
450 return ARM::BMOVPCRX_CALL;
451}
452} // end anonymous namespace
453
455 MachineFunction &MF = MIRBuilder.getMF();
456 const auto &TLI = *getTLI<ARMTargetLowering>();
457 const auto &DL = MF.getDataLayout();
458 const auto &STI = MF.getSubtarget<ARMSubtarget>();
461
462 if (STI.genLongCalls())
463 return false;
464
465 if (STI.isThumb1Only())
466 return false;
467
468 auto CallSeqStart = MIRBuilder.buildInstr(ARM::ADJCALLSTACKDOWN);
469
470 // Create the call instruction so we can add the implicit uses of arg
471 // registers, but don't insert it yet.
472 bool IsDirect = !Info.Callee.isReg();
473 auto CallOpcode = getCallOpcode(MF, STI, IsDirect);
474 auto MIB = MIRBuilder.buildInstrNoInsert(CallOpcode);
475
476 bool IsThumb = STI.isThumb();
477 if (IsThumb)
478 MIB.add(predOps(ARMCC::AL));
479
480 MIB.add(Info.Callee);
481 if (!IsDirect) {
482 auto CalleeReg = Info.Callee.getReg();
483 if (CalleeReg && !CalleeReg.isPhysical()) {
484 unsigned CalleeIdx = IsThumb ? 2 : 0;
485 MIB->getOperand(CalleeIdx).setReg(constrainOperandRegClass(
486 MF, *TRI, MRI, *STI.getInstrInfo(), *STI.getRegBankInfo(),
487 *MIB.getInstr(), MIB->getDesc(), Info.Callee, CalleeIdx));
488 }
489 }
490
491 MIB.addRegMask(TRI->getCallPreservedMask(MF, Info.CallConv));
492
494 for (auto Arg : Info.OrigArgs) {
495 if (!isSupportedType(DL, TLI, Arg.Ty))
496 return false;
497
498 if (Arg.Flags[0].isByVal())
499 return false;
500
501 splitToValueTypes(Arg, ArgInfos, DL, Info.CallConv);
502 }
503
504 auto ArgAssignFn = TLI.CCAssignFnForCall(Info.CallConv, Info.IsVarArg);
505 OutgoingValueAssigner ArgAssigner(ArgAssignFn);
506 ARMOutgoingValueHandler ArgHandler(MIRBuilder, MRI, MIB);
507 if (!determineAndHandleAssignments(ArgHandler, ArgAssigner, ArgInfos,
508 MIRBuilder, Info.CallConv, Info.IsVarArg))
509 return false;
510
511 // Now we can add the actual call instruction to the correct basic block.
512 MIRBuilder.insertInstr(MIB);
513
514 if (!Info.OrigRet.Ty->isVoidTy()) {
515 if (!isSupportedType(DL, TLI, Info.OrigRet.Ty))
516 return false;
517
518 ArgInfos.clear();
519 splitToValueTypes(Info.OrigRet, ArgInfos, DL, Info.CallConv);
520 auto RetAssignFn = TLI.CCAssignFnForReturn(Info.CallConv, Info.IsVarArg);
521 OutgoingValueAssigner Assigner(RetAssignFn);
522 CallReturnHandler RetHandler(MIRBuilder, MRI, MIB);
523 if (!determineAndHandleAssignments(RetHandler, Assigner, ArgInfos,
524 MIRBuilder, Info.CallConv,
525 Info.IsVarArg))
526 return false;
527 }
528
529 // We now know the size of the stack - update the ADJCALLSTACKDOWN
530 // accordingly.
531 CallSeqStart.addImm(ArgAssigner.StackSize).addImm(0).add(predOps(ARMCC::AL));
532
533 MIRBuilder.buildInstr(ARM::ADJCALLSTACKUP)
534 .addImm(ArgAssigner.StackSize)
535 .addImm(-1ULL)
537
538 return true;
539}
unsigned const MachineRegisterInfo * MRI
static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, bool IsTailCall)
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
static bool isSupportedType(const DataLayout &DL, const ARMTargetLowering &TLI, Type *T)
This file describes how to lower LLVM calls to machine code calls.
This file contains the simple types necessary to represent the attributes associated with functions a...
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
uint64_t Addr
uint64_t Size
Implement a low-level type suitable for MachineInstr level instruction selection.
Implement a low-level type suitable for MachineInstr level instruction selection.
#define F(x, y, z)
Definition: MD5.cpp:55
This file declares the MachineIRBuilder class.
unsigned const TargetRegisterInfo * TRI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
@ Flags
Definition: TextStubV5.cpp:93
ARMCallLowering(const ARMTargetLowering &TLI)
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...
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...
const RegisterBankInfo * getRegBankInfo() const override
const ARMBaseInstrInfo * getInstrInfo() const override
Definition: ARMSubtarget.h:262
bool isThumb1Only() const
Definition: ARMSubtarget.h:419
const ARMBaseRegisterInfo * getRegisterInfo() const override
Definition: ARMSubtarget.h:274
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:158
CCValAssign - Represent assignment of one arg/retval to a location.
bool isRegLoc() const
Register getLocReg() const
LocInfo getLocInfo() const
bool needsCustom() const
unsigned getValNo() const
bool determineAndHandleAssignments(ValueHandler &Handler, ValueAssigner &Assigner, SmallVectorImpl< ArgInfo > &Args, MachineIRBuilder &MIRBuilder, CallingConv::ID CallConv, bool IsVarArg, ArrayRef< Register > ThisReturnRegs=std::nullopt) const
Invoke ValueAssigner::assignArg on each of the given Args and then use Handler to move them to the as...
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.
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:110
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition: LowLevelType.h:42
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
Definition: LowLevelType.h:49
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, 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.
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 DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Helper class to build MachineInstr.
MachineInstrBuilder insertInstr(MachineInstrBuilder MIB)
Insert an existing instruction at the insertion point.
void setInstr(MachineInstr &MI)
Set the insertion point to before MI.
MachineInstrBuilder buildMergeLikeInstr(const DstOp &Res, ArrayRef< Register > Ops)
Build and insert Res = G_MERGE_VALUES Op0, ... or Res = G_BUILD_VECTOR Op0, ... or Res = G_CONCAT_VEC...
MachineInstrBuilder buildLoad(const DstOp &Res, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert Res = G_LOAD 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.
void setMBB(MachineBasicBlock &MBB)
Set the insertion point to the end of MBB.
MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_TRUNC Op.
MachineRegisterInfo * getMRI()
Getter for MRI.
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.
Register getReg(unsigned Idx) const
Get the register for the operand index.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVM Value Representation.
Definition: Value.h:74
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
@ Implicit
Not emitted register (e.g. carry, or temporary result).
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:440
Register constrainOperandRegClass(const MachineFunction &MF, const TargetRegisterInfo &TRI, MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const RegisterBankInfo &RBI, MachineInstr &InsertPt, const TargetRegisterClass &RegClass, MachineOperand &RegMO)
Constrain the Register operand OpIdx, so that it is now constrained to the TargetRegisterClass passed...
Definition: Utils.cpp:53
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
unsigned gettBLXrOpcode(const MachineFunction &MF)
unsigned getBLXOpcode(const MachineFunction &MF)
Align inferAlignFromPtrInfo(MachineFunction &MF, const MachinePointerInfo &MPO)
Definition: Utils.cpp:709
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:860
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
Helper struct shared between Function Specialization and SCCP Solver.
Definition: SCCPSolver.h:43
Base class for ValueHandlers used for arguments coming into the current function, or for return value...
Definition: CallLowering.h:317
Base class for ValueHandlers used for arguments passed to a function call, or for return values.
Definition: CallLowering.h:332
uint64_t StackSize
The size of the currently allocated portion of the stack.
Definition: CallLowering.h:203
MachineRegisterInfo & MRI
Definition: CallLowering.h:230
Extended Value Type.
Definition: ValueTypes.h:34
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
Definition: ValueTypes.h:129
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
Definition: ValueTypes.h:139
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:299
bool isVector() const
Return true if this is a vector value type.
Definition: ValueTypes.h:160
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition: ValueTypes.h:144
This class contains a discriminated union of information about pointers in memory operands,...
unsigned getAddrSpace() const
Return the LLVM IR address space number that this pointer points into.
static MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.