LLVM  4.0.0
ARMCallLowering.cpp
Go to the documentation of this file.
1 //===-- llvm/lib/Target/ARM/ARMCallLowering.cpp - Call lowering -----------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// This file implements the lowering of LLVM calls to machine code calls for
12 /// GlobalISel.
13 ///
14 //===----------------------------------------------------------------------===//
15 
16 #include "ARMCallLowering.h"
17 
18 #include "ARMBaseInstrInfo.h"
19 #include "ARMISelLowering.h"
20 
23 
24 using namespace llvm;
25 
26 #ifndef LLVM_BUILD_GLOBAL_ISEL
27 #error "This shouldn't be built without GISel"
28 #endif
29 
31  : CallLowering(&TLI) {}
32 
33 static bool isSupportedType(const DataLayout DL, const ARMTargetLowering &TLI,
34  Type *T) {
35  EVT VT = TLI.getValueType(DL, T);
36  if (!VT.isSimple() || !VT.isInteger() || VT.isVector())
37  return false;
38 
39  unsigned VTSize = VT.getSimpleVT().getSizeInBits();
40  return VTSize == 8 || VTSize == 16 || VTSize == 32;
41 }
42 
43 namespace {
44 struct FuncReturnHandler : public CallLowering::ValueHandler {
45  FuncReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
47  : ValueHandler(MIRBuilder, MRI), MIB(MIB) {}
48 
49  unsigned getStackAddress(uint64_t Size, int64_t Offset,
50  MachinePointerInfo &MPO) override {
51  llvm_unreachable("Don't know how to get a stack address yet");
52  }
53 
54  void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
55  CCValAssign &VA) override {
56  assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
57  assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
58 
59  assert(VA.getValVT().getSizeInBits() <= 32 && "Unsupported value size");
60  assert(VA.getLocVT().getSizeInBits() == 32 && "Unsupported location size");
61 
63  VA.getLocInfo() != CCValAssign::ZExt &&
64  "ABI extensions not supported yet");
65 
66  MIRBuilder.buildCopy(PhysReg, ValVReg);
67  MIB.addUse(PhysReg, RegState::Implicit);
68  }
69 
70  void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
71  MachinePointerInfo &MPO, CCValAssign &VA) override {
72  llvm_unreachable("Don't know how to assign a value to an address yet");
73  }
74 
76 };
77 } // End anonymous namespace.
78 
79 /// Lower the return value for the already existing \p Ret. This assumes that
80 /// \p MIRBuilder's insertion point is correct.
81 bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder,
82  const Value *Val, unsigned VReg,
83  MachineInstrBuilder &Ret) const {
84  if (!Val)
85  // Nothing to do here.
86  return true;
87 
88  auto &MF = MIRBuilder.getMF();
89  const auto &F = *MF.getFunction();
90 
91  auto DL = MF.getDataLayout();
92  auto &TLI = *getTLI<ARMTargetLowering>();
93  if (!isSupportedType(DL, TLI, Val->getType()))
94  return false;
95 
96  CCAssignFn *AssignFn =
97  TLI.CCAssignFnForReturn(F.getCallingConv(), F.isVarArg());
98 
99  ArgInfo RetInfo(VReg, Val->getType());
100  setArgFlags(RetInfo, AttributeSet::ReturnIndex, DL, F);
101 
102  FuncReturnHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret);
103  return handleAssignments(MIRBuilder, AssignFn, RetInfo, RetHandler);
104 }
105 
107  const Value *Val, unsigned VReg) const {
108  assert(!Val == !VReg && "Return value without a vreg");
109 
110  auto Ret = AddDefaultPred(MIRBuilder.buildInstrNoInsert(ARM::BX_RET));
111 
112  if (!lowerReturnVal(MIRBuilder, Val, VReg, Ret))
113  return false;
114 
115  MIRBuilder.insertInstr(Ret);
116  return true;
117 }
118 
119 namespace {
121  FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
122  : ValueHandler(MIRBuilder, MRI) {}
123 
124  unsigned getStackAddress(uint64_t Size, int64_t Offset,
125  MachinePointerInfo &MPO) override {
126  assert(Size == 4 && "Unsupported size");
127 
128  auto &MFI = MIRBuilder.getMF().getFrameInfo();
129 
130  int FI = MFI.CreateFixedObject(Size, Offset, true);
131  MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
132 
133  unsigned AddrReg =
134  MRI.createGenericVirtualRegister(LLT::pointer(MPO.getAddrSpace(), 32));
135  MIRBuilder.buildFrameIndex(AddrReg, FI);
136 
137  return AddrReg;
138  }
139 
140  void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
141  MachinePointerInfo &MPO, CCValAssign &VA) override {
142  assert(Size == 4 && "Unsupported size");
143 
144  auto MMO = MIRBuilder.getMF().getMachineMemOperand(
145  MPO, MachineMemOperand::MOLoad, Size, /* Alignment */ 0);
146  MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
147  }
148 
149  void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
150  CCValAssign &VA) override {
151  assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
152  assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
153 
154  assert(VA.getValVT().getSizeInBits() <= 32 && "Unsupported value size");
155  assert(VA.getLocVT().getSizeInBits() == 32 && "Unsupported location size");
156 
157  MIRBuilder.getMBB().addLiveIn(PhysReg);
158  MIRBuilder.buildCopy(ValVReg, PhysReg);
159  }
160 };
161 } // End anonymous namespace
162 
164  const Function &F,
165  ArrayRef<unsigned> VRegs) const {
166  // Quick exit if there aren't any args
167  if (F.arg_empty())
168  return true;
169 
170  if (F.isVarArg())
171  return false;
172 
173  auto DL = MIRBuilder.getMF().getDataLayout();
174  auto &TLI = *getTLI<ARMTargetLowering>();
175 
176  auto &Args = F.getArgumentList();
177  unsigned ArgIdx = 0;
178  for (auto &Arg : Args) {
179  ArgIdx++;
180  if (!isSupportedType(DL, TLI, Arg.getType()))
181  return false;
182 
183  // FIXME: This check as well as ArgIdx are going away as soon as we support
184  // loading values < 32 bits.
185  if (ArgIdx > 4 && Arg.getType()->getIntegerBitWidth() != 32)
186  return false;
187  }
188 
189  CCAssignFn *AssignFn =
190  TLI.CCAssignFnForCall(F.getCallingConv(), F.isVarArg());
191 
192  SmallVector<ArgInfo, 8> ArgInfos;
193  unsigned Idx = 0;
194  for (auto &Arg : Args) {
195  ArgInfo AInfo(VRegs[Idx], Arg.getType());
196  setArgFlags(AInfo, Idx + 1, DL, F);
197  ArgInfos.push_back(AInfo);
198  Idx++;
199  }
200 
201  FormalArgHandler ArgHandler(MIRBuilder, MIRBuilder.getMF().getRegInfo());
202  return handleAssignments(MIRBuilder, AssignFn, ArgInfos, ArgHandler);
203 }
MachineBasicBlock & getMBB()
Getter for the basic block we currently build.
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:102
MVT getValVT() const
LocInfo getLocInfo() const
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 getSizeInBits() const
static const MCPhysReg VRegs[32]
bool isRegLoc() const
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition: Function.h:165
bool isVector() const
isVector - Return true if this is a vector value type.
Definition: ValueTypes.h:133
static const MachineInstrBuilder & AddDefaultPred(const MachineInstrBuilder &MIB)
bool lowerReturn(MachineIRBuilder &MIRBuiler, const Value *Val, unsigned VReg) const override
This hook must be implemented to lower outgoing return values, described by Val, into the specified v...
ARMCallLowering(const ARMTargetLowering &TLI)
bool isInteger() const
isInteger - Return true if this is an integer, or a vector integer type.
Definition: ValueTypes.h:123
unsigned getLocReg() const
#define F(x, y, z)
Definition: MD5.cpp:51
MachineInstrBuilder buildInstrNoInsert(unsigned Opcode)
Build but don't insert <empty> = Opcode <empty>.
MachineFunction & getMF()
Getter for the function we currently build.
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F, ArrayRef< unsigned > VRegs) const override
This hook must be implemented to lower the incoming (formal) arguments, described by Args...
FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
void addLiveIn(MCPhysReg PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
unsigned const MachineRegisterInfo * MRI
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
MVT getLocVT() const
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Helper class to build MachineInstr.
uint32_t Offset
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool Immutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
EVT - Extended Value Type.
Definition: ValueTypes.h:31
Argument handling is mostly uniform between the four places that make these decisions: function forma...
Definition: CallLowering.h:49
This class contains a discriminated union of information about pointers in memory operands...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
MachineInstrBuilder buildFrameIndex(unsigned Res, int Idx)
Build and insert Res<def> = G_FRAME_INDEX Idx.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:843
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:230
MachineInstrBuilder buildCopy(unsigned Res, unsigned Op)
Build and insert Res<def> = COPY Op.
CCValAssign - Represent assignment of one arg/retval to a location.
unsigned getAddrSpace() const
Return the LLVM IR address space number that this pointer points into.
This file declares the MachineIRBuilder class.
bool arg_empty() const
Definition: Function.cpp:330
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SynchronizationScope SynchScope=CrossThread, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
The memory access reads data.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
void setArgFlags(ArgInfo &Arg, unsigned OpNum, const DataLayout &DL, const FuncInfoTy &FuncInfo) const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isSimple() const
isSimple - Test if the given EVT is simple (as opposed to being extended).
Definition: ValueTypes.h:107
MachineInstrBuilder insertInstr(MachineInstrBuilder MIB)
Insert an existing instruction at the insertion point.
LLVM Value Representation.
Definition: Value.h:71
static LLT pointer(uint16_t AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space (defaulting to 0).
Definition: LowLevelType.h:57
const ArgumentListType & getArgumentList() const
Get the underlying elements of the Function...
Definition: Function.h:499
MachineInstrBuilder buildLoad(unsigned Res, unsigned Addr, MachineMemOperand &MMO)
Build and insert Res<def> = G_LOAD Addr, MMO.
static bool isSupportedType(const DataLayout DL, const ARMTargetLowering &TLI, Type *T)
This file describes how to lower LLVM calls to machine code calls.
bool handleAssignments(MachineIRBuilder &MIRBuilder, CCAssignFn *AssignFn, ArrayRef< ArgInfo > Args, ValueHandler &Callback) const
Invoke the AssignFn on each of the given Args and then use Callback to move them to the assigned loca...
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition: Function.cpp:234
MVT getSimpleVT() const
getSimpleVT - Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:226