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