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

Generated by: LCOV version 1.13