LCOV - code coverage report
Current view: top level - lib/Target/ARM - ARMCallLowering.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 239 239 100.0 %
Date: 2017-09-14 15:23:50 Functions: 19 25 76.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13