LLVM 19.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 const 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 const MachinePointerInfo &MPO,
127 const CCValAssign &VA) override {
128 Register ExtReg = extendRegister(ValVReg, VA);
129 auto MMO = MIRBuilder.getMF().getMachineMemOperand(
130 MPO, MachineMemOperand::MOStore, MemTy, Align(1));
131 MIRBuilder.buildStore(ExtReg, Addr, *MMO);
132 }
133
134 unsigned assignCustomValue(CallLowering::ArgInfo &Arg,
136 std::function<void()> *Thunk) override {
137 assert(Arg.Regs.size() == 1 && "Can't handle multple regs yet");
138
139 const CCValAssign &VA = VAs[0];
140 assert(VA.needsCustom() && "Value doesn't need custom handling");
141
142 // Custom lowering for other types, such as f16, is currently not supported
143 if (VA.getValVT() != MVT::f64)
144 return 0;
145
146 const CCValAssign &NextVA = VAs[1];
147 assert(NextVA.needsCustom() && "Value doesn't need custom handling");
148 assert(NextVA.getValVT() == MVT::f64 && "Unsupported type");
149
150 assert(VA.getValNo() == NextVA.getValNo() &&
151 "Values belong to different arguments");
152
153 assert(VA.isRegLoc() && "Value should be in reg");
154 assert(NextVA.isRegLoc() && "Value should be in reg");
155
156 Register NewRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)),
157 MRI.createGenericVirtualRegister(LLT::scalar(32))};
158 MIRBuilder.buildUnmerge(NewRegs, Arg.Regs[0]);
159
160 bool IsLittle = MIRBuilder.getMF().getSubtarget<ARMSubtarget>().isLittle();
161 if (!IsLittle)
162 std::swap(NewRegs[0], NewRegs[1]);
163
164 if (Thunk) {
165 *Thunk = [=]() {
166 assignValueToReg(NewRegs[0], VA.getLocReg(), VA);
167 assignValueToReg(NewRegs[1], NextVA.getLocReg(), NextVA);
168 };
169 return 2;
170 }
171 assignValueToReg(NewRegs[0], VA.getLocReg(), VA);
172 assignValueToReg(NewRegs[1], NextVA.getLocReg(), NextVA);
173 return 2;
174 }
175
177};
178
179} // end anonymous namespace
180
181/// Lower the return value for the already existing \p Ret. This assumes that
182/// \p MIRBuilder's insertion point is correct.
183bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder,
184 const Value *Val, ArrayRef<Register> VRegs,
185 MachineInstrBuilder &Ret) const {
186 if (!Val)
187 // Nothing to do here.
188 return true;
189
190 auto &MF = MIRBuilder.getMF();
191 const auto &F = MF.getFunction();
192
193 const auto &DL = MF.getDataLayout();
194 auto &TLI = *getTLI<ARMTargetLowering>();
195 if (!isSupportedType(DL, TLI, Val->getType()))
196 return false;
197
198 ArgInfo OrigRetInfo(VRegs, Val->getType(), 0);
200
201 SmallVector<ArgInfo, 4> SplitRetInfos;
202 splitToValueTypes(OrigRetInfo, SplitRetInfos, DL, F.getCallingConv());
203
204 CCAssignFn *AssignFn =
205 TLI.CCAssignFnForReturn(F.getCallingConv(), F.isVarArg());
206
207 OutgoingValueAssigner RetAssigner(AssignFn);
208 ARMOutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret);
209 return determineAndHandleAssignments(RetHandler, RetAssigner, SplitRetInfos,
210 MIRBuilder, F.getCallingConv(),
211 F.isVarArg());
212}
213
215 const Value *Val, ArrayRef<Register> VRegs,
216 FunctionLoweringInfo &FLI) const {
217 assert(!Val == VRegs.empty() && "Return value without a vreg");
218
219 auto const &ST = MIRBuilder.getMF().getSubtarget<ARMSubtarget>();
220 unsigned Opcode = ST.getReturnOpcode();
221 auto Ret = MIRBuilder.buildInstrNoInsert(Opcode).add(predOps(ARMCC::AL));
222
223 if (!lowerReturnVal(MIRBuilder, Val, VRegs, Ret))
224 return false;
225
226 MIRBuilder.insertInstr(Ret);
227 return true;
228}
229
230namespace {
231
232/// Helper class for values coming in through an ABI boundary (used for handling
233/// formal arguments and call return values).
234struct ARMIncomingValueHandler : public CallLowering::IncomingValueHandler {
235 ARMIncomingValueHandler(MachineIRBuilder &MIRBuilder,
237 : IncomingValueHandler(MIRBuilder, MRI) {}
238
239 Register getStackAddress(uint64_t Size, int64_t Offset,
241 ISD::ArgFlagsTy Flags) override {
242 assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
243 "Unsupported size");
244
245 auto &MFI = MIRBuilder.getMF().getFrameInfo();
246
247 // Byval is assumed to be writable memory, but other stack passed arguments
248 // are not.
249 const bool IsImmutable = !Flags.isByVal();
250
251 int FI = MFI.CreateFixedObject(Size, Offset, IsImmutable);
252 MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
253
254 return MIRBuilder.buildFrameIndex(LLT::pointer(MPO.getAddrSpace(), 32), FI)
255 .getReg(0);
256 }
257
258 void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy,
259 const MachinePointerInfo &MPO,
260 const CCValAssign &VA) override {
261 if (VA.getLocInfo() == CCValAssign::SExt ||
263 // If the value is zero- or sign-extended, its size becomes 4 bytes, so
264 // that's what we should load.
265 MemTy = LLT::scalar(32);
266 assert(MRI.getType(ValVReg).isScalar() && "Only scalars supported atm");
267
268 auto LoadVReg = buildLoad(LLT::scalar(32), Addr, MemTy, MPO);
269 MIRBuilder.buildTrunc(ValVReg, LoadVReg);
270 } else {
271 // If the value is not extended, a simple load will suffice.
272 buildLoad(ValVReg, Addr, MemTy, MPO);
273 }
274 }
275
276 MachineInstrBuilder buildLoad(const DstOp &Res, Register Addr, LLT MemTy,
277 const MachinePointerInfo &MPO) {
278 MachineFunction &MF = MIRBuilder.getMF();
279
280 auto MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, MemTy,
281 inferAlignFromPtrInfo(MF, MPO));
282 return MIRBuilder.buildLoad(Res, Addr, *MMO);
283 }
284
285 void assignValueToReg(Register ValVReg, Register PhysReg,
286 const CCValAssign &VA) override {
287 assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
288 assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
289
290 uint64_t ValSize = VA.getValVT().getFixedSizeInBits();
291 uint64_t LocSize = VA.getLocVT().getFixedSizeInBits();
292
293 assert(ValSize <= 64 && "Unsupported value size");
294 assert(LocSize <= 64 && "Unsupported location size");
295
296 markPhysRegUsed(PhysReg);
297 if (ValSize == LocSize) {
298 MIRBuilder.buildCopy(ValVReg, PhysReg);
299 } else {
300 assert(ValSize < LocSize && "Extensions not supported");
301
302 // We cannot create a truncating copy, nor a trunc of a physical register.
303 // Therefore, we need to copy the content of the physical register into a
304 // virtual one and then truncate that.
305 auto PhysRegToVReg = MIRBuilder.buildCopy(LLT::scalar(LocSize), PhysReg);
306 MIRBuilder.buildTrunc(ValVReg, PhysRegToVReg);
307 }
308 }
309
310 unsigned assignCustomValue(ARMCallLowering::ArgInfo &Arg,
312 std::function<void()> *Thunk) override {
313 assert(Arg.Regs.size() == 1 && "Can't handle multple regs yet");
314
315 const CCValAssign &VA = VAs[0];
316 assert(VA.needsCustom() && "Value doesn't need custom handling");
317
318 // Custom lowering for other types, such as f16, is currently not supported
319 if (VA.getValVT() != MVT::f64)
320 return 0;
321
322 const CCValAssign &NextVA = VAs[1];
323 assert(NextVA.needsCustom() && "Value doesn't need custom handling");
324 assert(NextVA.getValVT() == MVT::f64 && "Unsupported type");
325
326 assert(VA.getValNo() == NextVA.getValNo() &&
327 "Values belong to different arguments");
328
329 assert(VA.isRegLoc() && "Value should be in reg");
330 assert(NextVA.isRegLoc() && "Value should be in reg");
331
332 Register NewRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)),
333 MRI.createGenericVirtualRegister(LLT::scalar(32))};
334
335 assignValueToReg(NewRegs[0], VA.getLocReg(), VA);
336 assignValueToReg(NewRegs[1], NextVA.getLocReg(), NextVA);
337
338 bool IsLittle = MIRBuilder.getMF().getSubtarget<ARMSubtarget>().isLittle();
339 if (!IsLittle)
340 std::swap(NewRegs[0], NewRegs[1]);
341
342 MIRBuilder.buildMergeLikeInstr(Arg.Regs[0], NewRegs);
343
344 return 2;
345 }
346
347 /// Marking a physical register as used is different between formal
348 /// parameters, where it's a basic block live-in, and call returns, where it's
349 /// an implicit-def of the call instruction.
350 virtual void markPhysRegUsed(unsigned PhysReg) = 0;
351};
352
353struct FormalArgHandler : public ARMIncomingValueHandler {
355 : ARMIncomingValueHandler(MIRBuilder, MRI) {}
356
357 void markPhysRegUsed(unsigned PhysReg) override {
358 MIRBuilder.getMRI()->addLiveIn(PhysReg);
359 MIRBuilder.getMBB().addLiveIn(PhysReg);
360 }
361};
362
363} // end anonymous namespace
364
366 const Function &F,
368 FunctionLoweringInfo &FLI) const {
369 auto &TLI = *getTLI<ARMTargetLowering>();
370 auto Subtarget = TLI.getSubtarget();
371
372 if (Subtarget->isThumb1Only())
373 return false;
374
375 // Quick exit if there aren't any args
376 if (F.arg_empty())
377 return true;
378
379 if (F.isVarArg())
380 return false;
381
382 auto &MF = MIRBuilder.getMF();
383 auto &MBB = MIRBuilder.getMBB();
384 const auto &DL = MF.getDataLayout();
385
386 for (auto &Arg : F.args()) {
387 if (!isSupportedType(DL, TLI, Arg.getType()))
388 return false;
389 if (Arg.hasPassPointeeByValueCopyAttr())
390 return false;
391 }
392
393 CCAssignFn *AssignFn =
394 TLI.CCAssignFnForCall(F.getCallingConv(), F.isVarArg());
395
396 OutgoingValueAssigner ArgAssigner(AssignFn);
397 FormalArgHandler ArgHandler(MIRBuilder, MIRBuilder.getMF().getRegInfo());
398
399 SmallVector<ArgInfo, 8> SplitArgInfos;
400 unsigned Idx = 0;
401 for (auto &Arg : F.args()) {
402 ArgInfo OrigArgInfo(VRegs[Idx], Arg.getType(), Idx);
403
405 splitToValueTypes(OrigArgInfo, SplitArgInfos, DL, F.getCallingConv());
406
407 Idx++;
408 }
409
410 if (!MBB.empty())
411 MIRBuilder.setInstr(*MBB.begin());
412
413 if (!determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgInfos,
414 MIRBuilder, F.getCallingConv(),
415 F.isVarArg()))
416 return false;
417
418 // Move back to the end of the basic block.
419 MIRBuilder.setMBB(MBB);
420 return true;
421}
422
423namespace {
424
425struct CallReturnHandler : public ARMIncomingValueHandler {
426 CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
428 : ARMIncomingValueHandler(MIRBuilder, MRI), MIB(MIB) {}
429
430 void markPhysRegUsed(unsigned PhysReg) override {
431 MIB.addDef(PhysReg, RegState::Implicit);
432 }
433
435};
436
437// FIXME: This should move to the ARMSubtarget when it supports all the opcodes.
438unsigned getCallOpcode(const MachineFunction &MF, const ARMSubtarget &STI,
439 bool isDirect) {
440 if (isDirect)
441 return STI.isThumb() ? ARM::tBL : ARM::BL;
442
443 if (STI.isThumb())
444 return gettBLXrOpcode(MF);
445
446 if (STI.hasV5TOps())
447 return getBLXOpcode(MF);
448
449 if (STI.hasV4TOps())
450 return ARM::BX_CALL;
451
452 return ARM::BMOVPCRX_CALL;
453}
454} // end anonymous namespace
455
457 MachineFunction &MF = MIRBuilder.getMF();
458 const auto &TLI = *getTLI<ARMTargetLowering>();
459 const auto &DL = MF.getDataLayout();
460 const auto &STI = MF.getSubtarget<ARMSubtarget>();
463
464 if (STI.genLongCalls())
465 return false;
466
467 if (STI.isThumb1Only())
468 return false;
469
470 auto CallSeqStart = MIRBuilder.buildInstr(ARM::ADJCALLSTACKDOWN);
471
472 // Create the call instruction so we can add the implicit uses of arg
473 // registers, but don't insert it yet.
474 bool IsDirect = !Info.Callee.isReg();
475 auto CallOpcode = getCallOpcode(MF, STI, IsDirect);
476 auto MIB = MIRBuilder.buildInstrNoInsert(CallOpcode);
477
478 bool IsThumb = STI.isThumb();
479 if (IsThumb)
480 MIB.add(predOps(ARMCC::AL));
481
482 MIB.add(Info.Callee);
483 if (!IsDirect) {
484 auto CalleeReg = Info.Callee.getReg();
485 if (CalleeReg && !CalleeReg.isPhysical()) {
486 unsigned CalleeIdx = IsThumb ? 2 : 0;
487 MIB->getOperand(CalleeIdx).setReg(constrainOperandRegClass(
488 MF, *TRI, MRI, *STI.getInstrInfo(), *STI.getRegBankInfo(),
489 *MIB.getInstr(), MIB->getDesc(), Info.Callee, CalleeIdx));
490 }
491 }
492
493 MIB.addRegMask(TRI->getCallPreservedMask(MF, Info.CallConv));
494
496 for (auto Arg : Info.OrigArgs) {
497 if (!isSupportedType(DL, TLI, Arg.Ty))
498 return false;
499
500 if (Arg.Flags[0].isByVal())
501 return false;
502
503 splitToValueTypes(Arg, ArgInfos, DL, Info.CallConv);
504 }
505
506 auto ArgAssignFn = TLI.CCAssignFnForCall(Info.CallConv, Info.IsVarArg);
507 OutgoingValueAssigner ArgAssigner(ArgAssignFn);
508 ARMOutgoingValueHandler ArgHandler(MIRBuilder, MRI, MIB);
509 if (!determineAndHandleAssignments(ArgHandler, ArgAssigner, ArgInfos,
510 MIRBuilder, Info.CallConv, Info.IsVarArg))
511 return false;
512
513 // Now we can add the actual call instruction to the correct basic block.
514 MIRBuilder.insertInstr(MIB);
515
516 if (!Info.OrigRet.Ty->isVoidTy()) {
517 if (!isSupportedType(DL, TLI, Info.OrigRet.Ty))
518 return false;
519
520 ArgInfos.clear();
521 splitToValueTypes(Info.OrigRet, ArgInfos, DL, Info.CallConv);
522 auto RetAssignFn = TLI.CCAssignFnForReturn(Info.CallConv, Info.IsVarArg);
523 OutgoingValueAssigner Assigner(RetAssignFn);
524 CallReturnHandler RetHandler(MIRBuilder, MRI, MIB);
525 if (!determineAndHandleAssignments(RetHandler, Assigner, ArgInfos,
526 MIRBuilder, Info.CallConv,
527 Info.IsVarArg))
528 return false;
529 }
530
531 // We now know the size of the stack - update the ADJCALLSTACKDOWN
532 // accordingly.
533 CallSeqStart.addImm(ArgAssigner.StackSize).addImm(0).add(predOps(ARMCC::AL));
534
535 MIRBuilder.buildInstr(ARM::ADJCALLSTACKUP)
536 .addImm(ArgAssigner.StackSize)
537 .addImm(-1ULL)
539
540 return true;
541}
unsigned const MachineRegisterInfo * MRI
static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, bool IsTailCall)
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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.
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:266
bool isThumb1Only() const
Definition: ARMSubtarget.h:434
const ARMBaseRegisterInfo * getRegisterInfo() const override
Definition: ARMSubtarget.h:278
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:160
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:57
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.
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.
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:1209
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:456
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:54
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:865
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:41
SmallVector< Register, 4 > Regs
Definition: CallLowering.h:63
SmallVector< ISD::ArgFlagsTy, 4 > Flags
Definition: CallLowering.h:51
Base class for ValueHandlers used for arguments coming into the current function, or for return value...
Definition: CallLowering.h:323
Base class for ValueHandlers used for arguments passed to a function call, or for return values.
Definition: CallLowering.h:339
uint64_t StackSize
The size of the currently allocated portion of the stack.
Definition: CallLowering.h:209
MachineRegisterInfo & MRI
Definition: CallLowering.h:236
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:136
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
Definition: ValueTypes.h:146
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:306
bool isVector() const
Return true if this is a vector value type.
Definition: ValueTypes.h:167
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition: ValueTypes.h:151
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.