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