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