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