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