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 #include "ARMSubtarget.h"
21 
22 #include "llvm/CodeGen/Analysis.h"
23 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
24 #include "llvm/CodeGen/MachineRegisterInfo.h"
25 
26 using namespace llvm;
27 
28 #ifndef LLVM_BUILD_GLOBAL_ISEL
29 #error "This shouldn't be built without GISel"
30 #endif
31 
32 ARMCallLowering::ARMCallLowering(const ARMTargetLowering &TLI)
33     : CallLowering(&TLI) {}
34 
35 static bool isSupportedType(const DataLayout &DL, const ARMTargetLowering &TLI,
36                             Type *T) {
37   EVT VT = TLI.getValueType(DL, T, true);
38   if (!VT.isSimple() || VT.isVector())
39     return false;
40 
41   unsigned VTSize = VT.getSimpleVT().getSizeInBits();
42 
43   if (VTSize == 64)
44     // FIXME: Support i64 too
45     return VT.isFloatingPoint();
46 
47   return VTSize == 1 || VTSize == 8 || VTSize == 16 || VTSize == 32;
48 }
49 
50 namespace {
51 /// Helper class for values going out through an ABI boundary (used for handling
52 /// function return values and call parameters).
53 struct OutgoingValueHandler : public CallLowering::ValueHandler {
54   OutgoingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
55                        MachineInstrBuilder &MIB, CCAssignFn *AssignFn)
56       : ValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB), StackSize(0) {}
57 
58   unsigned getStackAddress(uint64_t Size, int64_t Offset,
59                            MachinePointerInfo &MPO) override {
60     assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
61            "Unsupported size");
62 
63     LLT p0 = LLT::pointer(0, 32);
64     LLT s32 = LLT::scalar(32);
65     unsigned SPReg = MRI.createGenericVirtualRegister(p0);
66     MIRBuilder.buildCopy(SPReg, ARM::SP);
67 
68     unsigned OffsetReg = MRI.createGenericVirtualRegister(s32);
69     MIRBuilder.buildConstant(OffsetReg, Offset);
70 
71     unsigned AddrReg = MRI.createGenericVirtualRegister(p0);
72     MIRBuilder.buildGEP(AddrReg, SPReg, OffsetReg);
73 
74     MPO = MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset);
75     return AddrReg;
76   }
77 
78   void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
79                         CCValAssign &VA) override {
80     assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
81     assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
82 
83     assert(VA.getValVT().getSizeInBits() <= 64 && "Unsupported value size");
84     assert(VA.getLocVT().getSizeInBits() <= 64 && "Unsupported location size");
85 
86     unsigned ExtReg = extendRegister(ValVReg, VA);
87     MIRBuilder.buildCopy(PhysReg, ExtReg);
88     MIB.addUse(PhysReg, RegState::Implicit);
89   }
90 
91   void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
92                             MachinePointerInfo &MPO, CCValAssign &VA) override {
93     assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
94            "Unsupported size");
95 
96     unsigned ExtReg = extendRegister(ValVReg, VA);
97     auto MMO = MIRBuilder.getMF().getMachineMemOperand(
98         MPO, MachineMemOperand::MOStore, VA.getLocVT().getStoreSize(),
99         /* Alignment */ 0);
100     MIRBuilder.buildStore(ExtReg, Addr, *MMO);
101   }
102 
103   unsigned assignCustomValue(const CallLowering::ArgInfo &Arg,
104                              ArrayRef<CCValAssign> VAs) override {
105     CCValAssign VA = VAs[0];
106     assert(VA.needsCustom() && "Value doesn't need custom handling");
107     assert(VA.getValVT() == MVT::f64 && "Unsupported type");
108 
109     CCValAssign NextVA = VAs[1];
110     assert(NextVA.needsCustom() && "Value doesn't need custom handling");
111     assert(NextVA.getValVT() == MVT::f64 && "Unsupported type");
112 
113     assert(VA.getValNo() == NextVA.getValNo() &&
114            "Values belong to different arguments");
115 
116     assert(VA.isRegLoc() && "Value should be in reg");
117     assert(NextVA.isRegLoc() && "Value should be in reg");
118 
119     unsigned NewRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)),
120                           MRI.createGenericVirtualRegister(LLT::scalar(32))};
121 
122     MIRBuilder.buildExtract(NewRegs, {0, 32}, Arg.Reg);
123 
124     bool IsLittle = MIRBuilder.getMF().getSubtarget<ARMSubtarget>().isLittle();
125     if (!IsLittle)
126       std::swap(NewRegs[0], NewRegs[1]);
127 
128     assignValueToReg(NewRegs[0], VA.getLocReg(), VA);
129     assignValueToReg(NewRegs[1], NextVA.getLocReg(), NextVA);
130 
131     return 1;
132   }
133 
134   bool assignArg(unsigned ValNo, MVT ValVT, MVT LocVT,
135                  CCValAssign::LocInfo LocInfo,
136                  const CallLowering::ArgInfo &Info, CCState &State) override {
137     if (AssignFn(ValNo, ValVT, LocVT, LocInfo, Info.Flags, State))
138       return true;
139 
140     StackSize =
141         std::max(StackSize, static_cast<uint64_t>(State.getNextStackOffset()));
142     return false;
143   }
144 
145   MachineInstrBuilder &MIB;
146   uint64_t StackSize;
147 };
148 } // End anonymous namespace.
149 
150 void ARMCallLowering::splitToValueTypes(const ArgInfo &OrigArg,
151                                         SmallVectorImpl<ArgInfo> &SplitArgs,
152                                         const DataLayout &DL,
153                                         MachineRegisterInfo &MRI) const {
154   const ARMTargetLowering &TLI = *getTLI<ARMTargetLowering>();
155   LLVMContext &Ctx = OrigArg.Ty->getContext();
156 
157   SmallVector<EVT, 4> SplitVTs;
158   SmallVector<uint64_t, 4> Offsets;
159   ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0);
160 
161   assert(SplitVTs.size() == 1 && "Unsupported type");
162 
163   // Even if there is no splitting to do, we still want to replace the original
164   // type (e.g. pointer type -> integer).
165   SplitArgs.emplace_back(OrigArg.Reg, SplitVTs[0].getTypeForEVT(Ctx),
166                          OrigArg.Flags, OrigArg.IsFixed);
167 }
168 
169 /// Lower the return value for the already existing \p Ret. This assumes that
170 /// \p MIRBuilder's insertion point is correct.
171 bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder,
172                                      const Value *Val, unsigned VReg,
173                                      MachineInstrBuilder &Ret) const {
174   if (!Val)
175     // Nothing to do here.
176     return true;
177 
178   auto &MF = MIRBuilder.getMF();
179   const auto &F = *MF.getFunction();
180 
181   auto DL = MF.getDataLayout();
182   auto &TLI = *getTLI<ARMTargetLowering>();
183   if (!isSupportedType(DL, TLI, Val->getType()))
184     return false;
185 
186   SmallVector<ArgInfo, 4> SplitVTs;
187   ArgInfo RetInfo(VReg, Val->getType());
188   setArgFlags(RetInfo, AttributeSet::ReturnIndex, DL, F);
189   splitToValueTypes(RetInfo, SplitVTs, DL, MF.getRegInfo());
190 
191   CCAssignFn *AssignFn =
192       TLI.CCAssignFnForReturn(F.getCallingConv(), F.isVarArg());
193 
194   OutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret, AssignFn);
195   return handleAssignments(MIRBuilder, SplitVTs, RetHandler);
196 }
197 
198 bool ARMCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
199                                   const Value *Val, unsigned VReg) const {
200   assert(!Val == !VReg && "Return value without a vreg");
201 
202   auto Ret = MIRBuilder.buildInstrNoInsert(ARM::BX_RET).add(predOps(ARMCC::AL));
203 
204   if (!lowerReturnVal(MIRBuilder, Val, VReg, Ret))
205     return false;
206 
207   MIRBuilder.insertInstr(Ret);
208   return true;
209 }
210 
211 namespace {
212 /// Helper class for values coming in through an ABI boundary (used for handling
213 /// formal arguments and call return values).
214 struct IncomingValueHandler : public CallLowering::ValueHandler {
215   IncomingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
216                        CCAssignFn AssignFn)
217       : ValueHandler(MIRBuilder, MRI, AssignFn) {}
218 
219   unsigned getStackAddress(uint64_t Size, int64_t Offset,
220                            MachinePointerInfo &MPO) override {
221     assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
222            "Unsupported size");
223 
224     auto &MFI = MIRBuilder.getMF().getFrameInfo();
225 
226     int FI = MFI.CreateFixedObject(Size, Offset, true);
227     MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
228 
229     unsigned AddrReg =
230         MRI.createGenericVirtualRegister(LLT::pointer(MPO.getAddrSpace(), 32));
231     MIRBuilder.buildFrameIndex(AddrReg, FI);
232 
233     return AddrReg;
234   }
235 
236   void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
237                             MachinePointerInfo &MPO, CCValAssign &VA) override {
238     assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
239            "Unsupported size");
240 
241     if (VA.getLocInfo() == CCValAssign::SExt ||
242         VA.getLocInfo() == CCValAssign::ZExt) {
243       // If the value is zero- or sign-extended, its size becomes 4 bytes, so
244       // that's what we should load.
245       Size = 4;
246       assert(MRI.getType(ValVReg).isScalar() && "Only scalars supported atm");
247       MRI.setType(ValVReg, LLT::scalar(32));
248     }
249 
250     auto MMO = MIRBuilder.getMF().getMachineMemOperand(
251         MPO, MachineMemOperand::MOLoad, Size, /* Alignment */ 0);
252     MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
253   }
254 
255   void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
256                         CCValAssign &VA) override {
257     assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
258     assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
259 
260     assert(VA.getValVT().getSizeInBits() <= 64 && "Unsupported value size");
261     assert(VA.getLocVT().getSizeInBits() <= 64 && "Unsupported location size");
262 
263     // The necesary extensions are handled on the other side of the ABI
264     // boundary.
265     markPhysRegUsed(PhysReg);
266     MIRBuilder.buildCopy(ValVReg, PhysReg);
267   }
268 
269   unsigned assignCustomValue(const ARMCallLowering::ArgInfo &Arg,
270                              ArrayRef<CCValAssign> VAs) override {
271     CCValAssign VA = VAs[0];
272     assert(VA.needsCustom() && "Value doesn't need custom handling");
273     assert(VA.getValVT() == MVT::f64 && "Unsupported type");
274 
275     CCValAssign NextVA = VAs[1];
276     assert(NextVA.needsCustom() && "Value doesn't need custom handling");
277     assert(NextVA.getValVT() == MVT::f64 && "Unsupported type");
278 
279     assert(VA.getValNo() == NextVA.getValNo() &&
280            "Values belong to different arguments");
281 
282     assert(VA.isRegLoc() && "Value should be in reg");
283     assert(NextVA.isRegLoc() && "Value should be in reg");
284 
285     unsigned NewRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)),
286                           MRI.createGenericVirtualRegister(LLT::scalar(32))};
287 
288     assignValueToReg(NewRegs[0], VA.getLocReg(), VA);
289     assignValueToReg(NewRegs[1], NextVA.getLocReg(), NextVA);
290 
291     bool IsLittle = MIRBuilder.getMF().getSubtarget<ARMSubtarget>().isLittle();
292     if (!IsLittle)
293       std::swap(NewRegs[0], NewRegs[1]);
294 
295     MIRBuilder.buildSequence(Arg.Reg, NewRegs, {0, 32});
296 
297     return 1;
298   }
299 
300   /// Marking a physical register as used is different between formal
301   /// parameters, where it's a basic block live-in, and call returns, where it's
302   /// an implicit-def of the call instruction.
303   virtual void markPhysRegUsed(unsigned PhysReg) = 0;
304 };
305 
306 struct FormalArgHandler : public IncomingValueHandler {
307   FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
308                    CCAssignFn AssignFn)
309       : IncomingValueHandler(MIRBuilder, MRI, AssignFn) {}
310 
311   void markPhysRegUsed(unsigned PhysReg) override {
312     MIRBuilder.getMBB().addLiveIn(PhysReg);
313   }
314 };
315 } // End anonymous namespace
316 
317 bool ARMCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
318                                            const Function &F,
319                                            ArrayRef<unsigned> VRegs) const {
320   // Quick exit if there aren't any args
321   if (F.arg_empty())
322     return true;
323 
324   if (F.isVarArg())
325     return false;
326 
327   auto &MF = MIRBuilder.getMF();
328   auto DL = MF.getDataLayout();
329   auto &TLI = *getTLI<ARMTargetLowering>();
330 
331   auto Subtarget = TLI.getSubtarget();
332 
333   if (Subtarget->isThumb())
334     return false;
335 
336   // FIXME: Support soft float (when we're ready to generate libcalls)
337   if (Subtarget->useSoftFloat() || !Subtarget->hasVFP2())
338     return false;
339 
340   auto &Args = F.getArgumentList();
341   for (auto &Arg : Args)
342     if (!isSupportedType(DL, TLI, Arg.getType()))
343       return false;
344 
345   CCAssignFn *AssignFn =
346       TLI.CCAssignFnForCall(F.getCallingConv(), F.isVarArg());
347 
348   SmallVector<ArgInfo, 8> ArgInfos;
349   unsigned Idx = 0;
350   for (auto &Arg : Args) {
351     ArgInfo AInfo(VRegs[Idx], Arg.getType());
352     setArgFlags(AInfo, Idx + 1, DL, F);
353     splitToValueTypes(AInfo, ArgInfos, DL, MF.getRegInfo());
354     Idx++;
355   }
356 
357   FormalArgHandler ArgHandler(MIRBuilder, MIRBuilder.getMF().getRegInfo(),
358                               AssignFn);
359   return handleAssignments(MIRBuilder, ArgInfos, ArgHandler);
360 }
361 
362 namespace {
363 struct CallReturnHandler : public IncomingValueHandler {
364   CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
365                     MachineInstrBuilder MIB, CCAssignFn *AssignFn)
366       : IncomingValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
367 
368   void markPhysRegUsed(unsigned PhysReg) override {
369     MIB.addDef(PhysReg, RegState::Implicit);
370   }
371 
372   MachineInstrBuilder MIB;
373 };
374 } // End anonymous namespace.
375 
376 bool ARMCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
377                                 const MachineOperand &Callee,
378                                 const ArgInfo &OrigRet,
379                                 ArrayRef<ArgInfo> OrigArgs) const {
380   MachineFunction &MF = MIRBuilder.getMF();
381   const auto &TLI = *getTLI<ARMTargetLowering>();
382   const auto &DL = MF.getDataLayout();
383   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
384   MachineRegisterInfo &MRI = MF.getRegInfo();
385 
386   if (MF.getSubtarget<ARMSubtarget>().genLongCalls())
387     return false;
388 
389   auto CallSeqStart = MIRBuilder.buildInstr(ARM::ADJCALLSTACKDOWN);
390 
391   // FIXME: This is the calling convention of the caller - we should use the
392   // calling convention of the callee instead.
393   auto CallConv = MF.getFunction()->getCallingConv();
394 
395   // Create the call instruction so we can add the implicit uses of arg
396   // registers, but don't insert it yet.
397   auto MIB = MIRBuilder.buildInstrNoInsert(ARM::BLX).add(Callee).addRegMask(
398       TRI->getCallPreservedMask(MF, CallConv));
399 
400   SmallVector<ArgInfo, 8> ArgInfos;
401   for (auto Arg : OrigArgs) {
402     if (!isSupportedType(DL, TLI, Arg.Ty))
403       return false;
404 
405     if (!Arg.IsFixed)
406       return false;
407 
408     splitToValueTypes(Arg, ArgInfos, DL, MRI);
409   }
410 
411   auto ArgAssignFn = TLI.CCAssignFnForCall(CallConv, /*IsVarArg=*/false);
412   OutgoingValueHandler ArgHandler(MIRBuilder, MRI, MIB, ArgAssignFn);
413   if (!handleAssignments(MIRBuilder, ArgInfos, ArgHandler))
414     return false;
415 
416   // Now we can add the actual call instruction to the correct basic block.
417   MIRBuilder.insertInstr(MIB);
418 
419   if (!OrigRet.Ty->isVoidTy()) {
420     if (!isSupportedType(DL, TLI, OrigRet.Ty))
421       return false;
422 
423     ArgInfos.clear();
424     splitToValueTypes(OrigRet, ArgInfos, DL, MRI);
425 
426     auto RetAssignFn = TLI.CCAssignFnForReturn(CallConv, /*IsVarArg=*/false);
427     CallReturnHandler RetHandler(MIRBuilder, MRI, MIB, RetAssignFn);
428     if (!handleAssignments(MIRBuilder, ArgInfos, RetHandler))
429       return false;
430   }
431 
432   // We now know the size of the stack - update the ADJCALLSTACKDOWN
433   // accordingly.
434   CallSeqStart.addImm(ArgHandler.StackSize).add(predOps(ARMCC::AL));
435 
436   MIRBuilder.buildInstr(ARM::ADJCALLSTACKUP)
437       .addImm(ArgHandler.StackSize)
438       .addImm(0)
439       .add(predOps(ARMCC::AL));
440 
441   return true;
442 }
443