1 //===-- llvm/lib/Target/X86/X86CallLowering.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 "X86CallLowering.h" 17 #include "X86CallingConv.h" 18 #include "X86ISelLowering.h" 19 #include "X86InstrInfo.h" 20 #include "X86TargetMachine.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 #include "llvm/CodeGen/MachineValueType.h" 27 #include "llvm/Target/TargetSubtargetInfo.h" 28 29 using namespace llvm; 30 31 #include "X86GenCallingConv.inc" 32 33 X86CallLowering::X86CallLowering(const X86TargetLowering &TLI) 34 : CallLowering(&TLI) {} 35 36 bool X86CallLowering::splitToValueTypes(const ArgInfo &OrigArg, 37 SmallVectorImpl<ArgInfo> &SplitArgs, 38 const DataLayout &DL, 39 MachineRegisterInfo &MRI, 40 SplitArgTy PerformArgSplit) const { 41 42 const X86TargetLowering &TLI = *getTLI<X86TargetLowering>(); 43 LLVMContext &Context = OrigArg.Ty->getContext(); 44 45 SmallVector<EVT, 4> SplitVTs; 46 SmallVector<uint64_t, 4> Offsets; 47 ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0); 48 49 if (SplitVTs.size() != 1) { 50 // TODO: support struct/array split 51 return false; 52 } 53 54 EVT VT = SplitVTs[0]; 55 unsigned NumParts = TLI.getNumRegisters(Context, VT); 56 57 if (NumParts == 1) { 58 // replace the original type ( pointer -> GPR ). 59 SplitArgs.emplace_back(OrigArg.Reg, VT.getTypeForEVT(Context), 60 OrigArg.Flags, OrigArg.IsFixed); 61 return true; 62 } 63 64 SmallVector<unsigned, 8> SplitRegs; 65 66 EVT PartVT = TLI.getRegisterType(Context, VT); 67 Type *PartTy = PartVT.getTypeForEVT(Context); 68 69 for (unsigned i = 0; i < NumParts; ++i) { 70 ArgInfo Info = 71 ArgInfo{MRI.createGenericVirtualRegister(getLLTForType(*PartTy, DL)), 72 PartTy, OrigArg.Flags}; 73 SplitArgs.push_back(Info); 74 SplitRegs.push_back(Info.Reg); 75 } 76 77 PerformArgSplit(SplitRegs); 78 return true; 79 } 80 81 namespace { 82 struct OutgoingValueHandler : public CallLowering::ValueHandler { 83 OutgoingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, 84 MachineInstrBuilder &MIB, CCAssignFn *AssignFn) 85 : ValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB), StackSize(0), 86 DL(MIRBuilder.getMF().getDataLayout()), 87 STI(MIRBuilder.getMF().getSubtarget<X86Subtarget>()), NumXMMRegs(0) {} 88 89 unsigned getStackAddress(uint64_t Size, int64_t Offset, 90 MachinePointerInfo &MPO) override { 91 92 LLT p0 = LLT::pointer(0, DL.getPointerSizeInBits(0)); 93 LLT SType = LLT::scalar(DL.getPointerSizeInBits(0)); 94 unsigned SPReg = MRI.createGenericVirtualRegister(p0); 95 MIRBuilder.buildCopy(SPReg, STI.getRegisterInfo()->getStackRegister()); 96 97 unsigned OffsetReg = MRI.createGenericVirtualRegister(SType); 98 MIRBuilder.buildConstant(OffsetReg, Offset); 99 100 unsigned AddrReg = MRI.createGenericVirtualRegister(p0); 101 MIRBuilder.buildGEP(AddrReg, SPReg, OffsetReg); 102 103 MPO = MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset); 104 return AddrReg; 105 } 106 107 void assignValueToReg(unsigned ValVReg, unsigned PhysReg, 108 CCValAssign &VA) override { 109 MIB.addUse(PhysReg, RegState::Implicit); 110 unsigned ExtReg = extendRegister(ValVReg, VA); 111 MIRBuilder.buildCopy(PhysReg, ExtReg); 112 } 113 114 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size, 115 MachinePointerInfo &MPO, CCValAssign &VA) override { 116 117 unsigned ExtReg = extendRegister(ValVReg, VA); 118 auto MMO = MIRBuilder.getMF().getMachineMemOperand( 119 MPO, MachineMemOperand::MOStore, VA.getLocVT().getStoreSize(), 120 /* Alignment */ 0); 121 MIRBuilder.buildStore(ExtReg, Addr, *MMO); 122 } 123 124 bool assignArg(unsigned ValNo, MVT ValVT, MVT LocVT, 125 CCValAssign::LocInfo LocInfo, 126 const CallLowering::ArgInfo &Info, CCState &State) override { 127 128 bool Res = AssignFn(ValNo, ValVT, LocVT, LocInfo, Info.Flags, State); 129 StackSize = State.getNextStackOffset(); 130 131 static const MCPhysReg XMMArgRegs[] = {X86::XMM0, X86::XMM1, X86::XMM2, 132 X86::XMM3, X86::XMM4, X86::XMM5, 133 X86::XMM6, X86::XMM7}; 134 if (!Info.IsFixed) 135 NumXMMRegs = State.getFirstUnallocated(XMMArgRegs); 136 137 return Res; 138 } 139 140 uint64_t getStackSize() { return StackSize; } 141 uint64_t getNumXmmRegs() { return NumXMMRegs; } 142 143 protected: 144 MachineInstrBuilder &MIB; 145 uint64_t StackSize; 146 const DataLayout &DL; 147 const X86Subtarget &STI; 148 unsigned NumXMMRegs; 149 }; 150 } // End anonymous namespace. 151 152 bool X86CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, 153 const Value *Val, unsigned VReg) const { 154 155 assert(((Val && VReg) || (!Val && !VReg)) && "Return value without a vreg"); 156 157 auto MIB = MIRBuilder.buildInstrNoInsert(X86::RET).addImm(0); 158 159 if (VReg) { 160 MachineFunction &MF = MIRBuilder.getMF(); 161 MachineRegisterInfo &MRI = MF.getRegInfo(); 162 auto &DL = MF.getDataLayout(); 163 const Function &F = *MF.getFunction(); 164 165 ArgInfo OrigArg{VReg, Val->getType()}; 166 setArgFlags(OrigArg, AttributeList::ReturnIndex, DL, F); 167 168 SmallVector<ArgInfo, 8> SplitArgs; 169 if (!splitToValueTypes(OrigArg, SplitArgs, DL, MRI, 170 [&](ArrayRef<unsigned> Regs) { 171 MIRBuilder.buildUnmerge(Regs, VReg); 172 })) 173 return false; 174 175 OutgoingValueHandler Handler(MIRBuilder, MRI, MIB, RetCC_X86); 176 if (!handleAssignments(MIRBuilder, SplitArgs, Handler)) 177 return false; 178 } 179 180 MIRBuilder.insertInstr(MIB); 181 return true; 182 } 183 184 namespace { 185 struct IncomingValueHandler : public CallLowering::ValueHandler { 186 IncomingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, 187 CCAssignFn *AssignFn) 188 : ValueHandler(MIRBuilder, MRI, AssignFn), 189 DL(MIRBuilder.getMF().getDataLayout()) {} 190 191 unsigned getStackAddress(uint64_t Size, int64_t Offset, 192 MachinePointerInfo &MPO) override { 193 194 auto &MFI = MIRBuilder.getMF().getFrameInfo(); 195 int FI = MFI.CreateFixedObject(Size, Offset, true); 196 MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI); 197 198 unsigned AddrReg = MRI.createGenericVirtualRegister( 199 LLT::pointer(0, DL.getPointerSizeInBits(0))); 200 MIRBuilder.buildFrameIndex(AddrReg, FI); 201 return AddrReg; 202 } 203 204 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size, 205 MachinePointerInfo &MPO, CCValAssign &VA) override { 206 207 auto MMO = MIRBuilder.getMF().getMachineMemOperand( 208 MPO, MachineMemOperand::MOLoad | MachineMemOperand::MOInvariant, Size, 209 0); 210 MIRBuilder.buildLoad(ValVReg, Addr, *MMO); 211 } 212 213 protected: 214 const DataLayout &DL; 215 }; 216 217 struct FormalArgHandler : public IncomingValueHandler { 218 FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, 219 CCAssignFn *AssignFn) 220 : IncomingValueHandler(MIRBuilder, MRI, AssignFn) {} 221 222 void assignValueToReg(unsigned ValVReg, unsigned PhysReg, 223 CCValAssign &VA) override { 224 MIRBuilder.getMBB().addLiveIn(PhysReg); 225 MIRBuilder.buildCopy(ValVReg, PhysReg); 226 } 227 }; 228 229 struct CallReturnHandler : public IncomingValueHandler { 230 CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, 231 CCAssignFn *AssignFn, MachineInstrBuilder &MIB) 232 : IncomingValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {} 233 234 void assignValueToReg(unsigned ValVReg, unsigned PhysReg, 235 CCValAssign &VA) override { 236 MIB.addDef(PhysReg, RegState::Implicit); 237 MIRBuilder.buildCopy(ValVReg, PhysReg); 238 } 239 240 protected: 241 MachineInstrBuilder &MIB; 242 }; 243 244 } // namespace 245 246 bool X86CallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, 247 const Function &F, 248 ArrayRef<unsigned> VRegs) const { 249 if (F.arg_empty()) 250 return true; 251 252 // TODO: handle variadic function 253 if (F.isVarArg()) 254 return false; 255 256 MachineFunction &MF = MIRBuilder.getMF(); 257 MachineRegisterInfo &MRI = MF.getRegInfo(); 258 auto DL = MF.getDataLayout(); 259 260 SmallVector<ArgInfo, 8> SplitArgs; 261 unsigned Idx = 0; 262 for (auto &Arg : F.args()) { 263 264 // TODO: handle not simple cases. 265 if (Arg.hasAttribute(Attribute::ByVal) || 266 Arg.hasAttribute(Attribute::InReg) || 267 Arg.hasAttribute(Attribute::StructRet) || 268 Arg.hasAttribute(Attribute::SwiftSelf) || 269 Arg.hasAttribute(Attribute::SwiftError) || 270 Arg.hasAttribute(Attribute::Nest)) 271 return false; 272 273 ArgInfo OrigArg(VRegs[Idx], Arg.getType()); 274 setArgFlags(OrigArg, Idx + AttributeList::FirstArgIndex, DL, F); 275 if (!splitToValueTypes(OrigArg, SplitArgs, DL, MRI, 276 [&](ArrayRef<unsigned> Regs) { 277 MIRBuilder.buildMerge(VRegs[Idx], Regs); 278 })) 279 return false; 280 Idx++; 281 } 282 283 MachineBasicBlock &MBB = MIRBuilder.getMBB(); 284 if (!MBB.empty()) 285 MIRBuilder.setInstr(*MBB.begin()); 286 287 FormalArgHandler Handler(MIRBuilder, MRI, CC_X86); 288 if (!handleAssignments(MIRBuilder, SplitArgs, Handler)) 289 return false; 290 291 // Move back to the end of the basic block. 292 MIRBuilder.setMBB(MBB); 293 294 return true; 295 } 296 297 bool X86CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, 298 CallingConv::ID CallConv, 299 const MachineOperand &Callee, 300 const ArgInfo &OrigRet, 301 ArrayRef<ArgInfo> OrigArgs) const { 302 303 MachineFunction &MF = MIRBuilder.getMF(); 304 const Function &F = *MF.getFunction(); 305 MachineRegisterInfo &MRI = MF.getRegInfo(); 306 auto &DL = F.getParent()->getDataLayout(); 307 const X86Subtarget &STI = MF.getSubtarget<X86Subtarget>(); 308 const TargetInstrInfo &TII = *STI.getInstrInfo(); 309 auto TRI = STI.getRegisterInfo(); 310 311 // Handle only Linux C, X86_64_SysV calling conventions for now. 312 if (!STI.isTargetLinux() || 313 !(CallConv == CallingConv::C || CallConv == CallingConv::X86_64_SysV)) 314 return false; 315 316 unsigned AdjStackDown = TII.getCallFrameSetupOpcode(); 317 auto CallSeqStart = MIRBuilder.buildInstr(AdjStackDown); 318 319 // Create a temporarily-floating call instruction so we can add the implicit 320 // uses of arg registers. 321 bool Is64Bit = STI.is64Bit(); 322 unsigned CallOpc = Callee.isReg() 323 ? (Is64Bit ? X86::CALL64r : X86::CALL32r) 324 : (Is64Bit ? X86::CALL64pcrel32 : X86::CALLpcrel32); 325 326 auto MIB = MIRBuilder.buildInstrNoInsert(CallOpc).add(Callee).addRegMask( 327 TRI->getCallPreservedMask(MF, CallConv)); 328 329 SmallVector<ArgInfo, 8> SplitArgs; 330 for (const auto &OrigArg : OrigArgs) { 331 332 // TODO: handle not simple cases. 333 if (OrigArg.Flags.isByVal()) 334 return false; 335 336 if (!splitToValueTypes(OrigArg, SplitArgs, DL, MRI, 337 [&](ArrayRef<unsigned> Regs) { 338 MIRBuilder.buildUnmerge(Regs, OrigArg.Reg); 339 })) 340 return false; 341 } 342 // Do the actual argument marshalling. 343 OutgoingValueHandler Handler(MIRBuilder, MRI, MIB, CC_X86); 344 if (!handleAssignments(MIRBuilder, SplitArgs, Handler)) 345 return false; 346 347 bool IsFixed = OrigArgs.empty() ? true : OrigArgs.back().IsFixed; 348 if (STI.is64Bit() && !IsFixed && !STI.isCallingConvWin64(CallConv)) { 349 // From AMD64 ABI document: 350 // For calls that may call functions that use varargs or stdargs 351 // (prototype-less calls or calls to functions containing ellipsis (...) in 352 // the declaration) %al is used as hidden argument to specify the number 353 // of SSE registers used. The contents of %al do not need to match exactly 354 // the number of registers, but must be an ubound on the number of SSE 355 // registers used and is in the range 0 - 8 inclusive. 356 357 MIRBuilder.buildInstr(X86::MOV8ri) 358 .addDef(X86::AL) 359 .addImm(Handler.getNumXmmRegs()); 360 MIB.addUse(X86::AL, RegState::Implicit); 361 } 362 363 // Now we can add the actual call instruction to the correct basic block. 364 MIRBuilder.insertInstr(MIB); 365 366 // If Callee is a reg, since it is used by a target specific 367 // instruction, it must have a register class matching the 368 // constraint of that instruction. 369 if (Callee.isReg()) 370 MIB->getOperand(0).setReg(constrainOperandRegClass( 371 MF, *TRI, MRI, *MF.getSubtarget().getInstrInfo(), 372 *MF.getSubtarget().getRegBankInfo(), *MIB, MIB->getDesc(), 373 Callee.getReg(), 0)); 374 375 // Finally we can copy the returned value back into its virtual-register. In 376 // symmetry with the arguments, the physical register must be an 377 // implicit-define of the call instruction. 378 379 if (OrigRet.Reg) { 380 SplitArgs.clear(); 381 SmallVector<unsigned, 8> NewRegs; 382 383 if (!splitToValueTypes(OrigRet, SplitArgs, DL, MRI, 384 [&](ArrayRef<unsigned> Regs) { 385 NewRegs.assign(Regs.begin(), Regs.end()); 386 })) 387 return false; 388 389 CallReturnHandler Handler(MIRBuilder, MRI, RetCC_X86, MIB); 390 if (!handleAssignments(MIRBuilder, SplitArgs, Handler)) 391 return false; 392 393 if (!NewRegs.empty()) 394 MIRBuilder.buildMerge(OrigRet.Reg, NewRegs); 395 } 396 397 CallSeqStart.addImm(Handler.getStackSize()) 398 .addImm(0 /* see getFrameTotalSize */) 399 .addImm(0 /* see getFrameAdjustment */); 400 401 unsigned AdjStackUp = TII.getCallFrameDestroyOpcode(); 402 MIRBuilder.buildInstr(AdjStackUp) 403 .addImm(Handler.getStackSize()) 404 .addImm(0 /* NumBytesForCalleeToPop */); 405 406 return true; 407 } 408