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