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 return VTSize == 1 || VTSize == 8 || VTSize == 16 || VTSize == 32; 43 } 44 45 namespace { 46 struct FuncReturnHandler : public CallLowering::ValueHandler { 47 FuncReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, 48 MachineInstrBuilder &MIB, CCAssignFn *AssignFn) 49 : ValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {} 50 51 unsigned getStackAddress(uint64_t Size, int64_t Offset, 52 MachinePointerInfo &MPO) override { 53 llvm_unreachable("Don't know how to get a stack address yet"); 54 } 55 56 void assignValueToReg(unsigned ValVReg, unsigned PhysReg, 57 CCValAssign &VA) override { 58 assert(VA.isRegLoc() && "Value shouldn't be assigned to reg"); 59 assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?"); 60 61 assert(VA.getValVT().getSizeInBits() <= 32 && "Unsupported value size"); 62 assert(VA.getLocVT().getSizeInBits() == 32 && "Unsupported location size"); 63 64 unsigned ExtReg = extendRegister(ValVReg, VA); 65 MIRBuilder.buildCopy(PhysReg, ExtReg); 66 MIB.addUse(PhysReg, RegState::Implicit); 67 } 68 69 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size, 70 MachinePointerInfo &MPO, CCValAssign &VA) override { 71 llvm_unreachable("Don't know how to assign a value to an address yet"); 72 } 73 74 MachineInstrBuilder &MIB; 75 }; 76 } // End anonymous namespace. 77 78 void ARMCallLowering::splitToValueTypes(const ArgInfo &OrigArg, 79 SmallVectorImpl<ArgInfo> &SplitArgs, 80 const DataLayout &DL, 81 MachineRegisterInfo &MRI) const { 82 const ARMTargetLowering &TLI = *getTLI<ARMTargetLowering>(); 83 LLVMContext &Ctx = OrigArg.Ty->getContext(); 84 85 SmallVector<EVT, 4> SplitVTs; 86 SmallVector<uint64_t, 4> Offsets; 87 ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0); 88 89 assert(SplitVTs.size() == 1 && "Unsupported type"); 90 91 // Even if there is no splitting to do, we still want to replace the original 92 // type (e.g. pointer type -> integer). 93 SplitArgs.emplace_back(OrigArg.Reg, SplitVTs[0].getTypeForEVT(Ctx), 94 OrigArg.Flags, OrigArg.IsFixed); 95 } 96 97 /// Lower the return value for the already existing \p Ret. This assumes that 98 /// \p MIRBuilder's insertion point is correct. 99 bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder, 100 const Value *Val, unsigned VReg, 101 MachineInstrBuilder &Ret) const { 102 if (!Val) 103 // Nothing to do here. 104 return true; 105 106 auto &MF = MIRBuilder.getMF(); 107 const auto &F = *MF.getFunction(); 108 109 auto DL = MF.getDataLayout(); 110 auto &TLI = *getTLI<ARMTargetLowering>(); 111 if (!isSupportedType(DL, TLI, Val->getType())) 112 return false; 113 114 SmallVector<ArgInfo, 4> SplitVTs; 115 ArgInfo RetInfo(VReg, Val->getType()); 116 setArgFlags(RetInfo, AttributeSet::ReturnIndex, DL, F); 117 splitToValueTypes(RetInfo, SplitVTs, DL, MF.getRegInfo()); 118 119 CCAssignFn *AssignFn = 120 TLI.CCAssignFnForReturn(F.getCallingConv(), F.isVarArg()); 121 122 FuncReturnHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret, AssignFn); 123 return handleAssignments(MIRBuilder, SplitVTs, RetHandler); 124 } 125 126 bool ARMCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, 127 const Value *Val, unsigned VReg) const { 128 assert(!Val == !VReg && "Return value without a vreg"); 129 130 auto Ret = MIRBuilder.buildInstrNoInsert(ARM::BX_RET).add(predOps(ARMCC::AL)); 131 132 if (!lowerReturnVal(MIRBuilder, Val, VReg, Ret)) 133 return false; 134 135 MIRBuilder.insertInstr(Ret); 136 return true; 137 } 138 139 namespace { 140 struct FormalArgHandler : public CallLowering::ValueHandler { 141 FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, 142 CCAssignFn AssignFn) 143 : ValueHandler(MIRBuilder, MRI, AssignFn) {} 144 145 unsigned getStackAddress(uint64_t Size, int64_t Offset, 146 MachinePointerInfo &MPO) override { 147 assert((Size == 1 || Size == 2 || Size == 4) && "Unsupported size"); 148 149 auto &MFI = MIRBuilder.getMF().getFrameInfo(); 150 151 int FI = MFI.CreateFixedObject(Size, Offset, true); 152 MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI); 153 154 unsigned AddrReg = 155 MRI.createGenericVirtualRegister(LLT::pointer(MPO.getAddrSpace(), 32)); 156 MIRBuilder.buildFrameIndex(AddrReg, FI); 157 158 return AddrReg; 159 } 160 161 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size, 162 MachinePointerInfo &MPO, CCValAssign &VA) override { 163 assert((Size == 1 || Size == 2 || Size == 4) && "Unsupported size"); 164 165 if (VA.getLocInfo() == CCValAssign::SExt || 166 VA.getLocInfo() == CCValAssign::ZExt) { 167 // If the argument is zero- or sign-extended by the caller, its size 168 // becomes 4 bytes, so that's what we should load. 169 Size = 4; 170 assert(MRI.getType(ValVReg).isScalar() && "Only scalars supported atm"); 171 MRI.setType(ValVReg, LLT::scalar(32)); 172 } 173 174 auto MMO = MIRBuilder.getMF().getMachineMemOperand( 175 MPO, MachineMemOperand::MOLoad, Size, /* Alignment */ 0); 176 MIRBuilder.buildLoad(ValVReg, Addr, *MMO); 177 } 178 179 void assignValueToReg(unsigned ValVReg, unsigned PhysReg, 180 CCValAssign &VA) override { 181 assert(VA.isRegLoc() && "Value shouldn't be assigned to reg"); 182 assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?"); 183 184 assert(VA.getValVT().getSizeInBits() <= 32 && "Unsupported value size"); 185 assert(VA.getLocVT().getSizeInBits() == 32 && "Unsupported location size"); 186 187 // The caller should handle all necesary extensions. 188 MIRBuilder.getMBB().addLiveIn(PhysReg); 189 MIRBuilder.buildCopy(ValVReg, PhysReg); 190 } 191 }; 192 } // End anonymous namespace 193 194 bool ARMCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, 195 const Function &F, 196 ArrayRef<unsigned> VRegs) const { 197 // Quick exit if there aren't any args 198 if (F.arg_empty()) 199 return true; 200 201 if (F.isVarArg()) 202 return false; 203 204 auto &MF = MIRBuilder.getMF(); 205 auto DL = MF.getDataLayout(); 206 auto &TLI = *getTLI<ARMTargetLowering>(); 207 208 auto Subtarget = TLI.getSubtarget(); 209 210 if (Subtarget->isThumb()) 211 return false; 212 213 // FIXME: Support soft float (when we're ready to generate libcalls) 214 if (Subtarget->useSoftFloat() || !Subtarget->hasVFP2()) 215 return false; 216 217 auto &Args = F.getArgumentList(); 218 for (auto &Arg : Args) 219 if (!isSupportedType(DL, TLI, Arg.getType())) 220 return false; 221 222 CCAssignFn *AssignFn = 223 TLI.CCAssignFnForCall(F.getCallingConv(), F.isVarArg()); 224 225 SmallVector<ArgInfo, 8> ArgInfos; 226 unsigned Idx = 0; 227 for (auto &Arg : Args) { 228 ArgInfo AInfo(VRegs[Idx], Arg.getType()); 229 setArgFlags(AInfo, Idx + 1, DL, F); 230 splitToValueTypes(AInfo, ArgInfos, DL, MF.getRegInfo()); 231 Idx++; 232 } 233 234 FormalArgHandler ArgHandler(MIRBuilder, MIRBuilder.getMF().getRegInfo(), 235 AssignFn); 236 return handleAssignments(MIRBuilder, ArgInfos, ArgHandler); 237 } 238