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/MachineRegisterInfo.h" 25 #include "llvm/CodeGen/MachineValueType.h" 26 #include "llvm/Target/TargetSubtargetInfo.h" 27 28 using namespace llvm; 29 30 #include "X86GenCallingConv.inc" 31 32 #ifndef LLVM_BUILD_GLOBAL_ISEL 33 #error "This shouldn't be built without GISel" 34 #endif 35 36 X86CallLowering::X86CallLowering(const X86TargetLowering &TLI) 37 : CallLowering(&TLI) {} 38 39 bool X86CallLowering::splitToValueTypes(const ArgInfo &OrigArg, 40 SmallVectorImpl<ArgInfo> &SplitArgs, 41 const DataLayout &DL, 42 MachineRegisterInfo &MRI, 43 SplitArgTy PerformArgSplit) const { 44 45 const X86TargetLowering &TLI = *getTLI<X86TargetLowering>(); 46 LLVMContext &Context = OrigArg.Ty->getContext(); 47 48 SmallVector<EVT, 4> SplitVTs; 49 SmallVector<uint64_t, 4> Offsets; 50 ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0); 51 52 if (SplitVTs.size() != 1) { 53 // TODO: support struct/array split 54 return false; 55 } 56 57 EVT VT = SplitVTs[0]; 58 unsigned NumParts = TLI.getNumRegisters(Context, VT); 59 60 if (NumParts == 1) { 61 // replace the original type ( pointer -> GPR ). 62 SplitArgs.emplace_back(OrigArg.Reg, VT.getTypeForEVT(Context), 63 OrigArg.Flags, OrigArg.IsFixed); 64 return true; 65 } 66 67 SmallVector<unsigned, 8> SplitRegs; 68 69 EVT PartVT = TLI.getRegisterType(Context, VT); 70 Type *PartTy = PartVT.getTypeForEVT(Context); 71 72 for (unsigned i = 0; i < NumParts; ++i) { 73 ArgInfo Info = 74 ArgInfo{MRI.createGenericVirtualRegister(getLLTForType(*PartTy, DL)), 75 PartTy, OrigArg.Flags}; 76 SplitArgs.push_back(Info); 77 SplitRegs.push_back(Info.Reg); 78 } 79 80 PerformArgSplit(SplitRegs); 81 return true; 82 } 83 84 namespace { 85 struct FuncReturnHandler : public CallLowering::ValueHandler { 86 FuncReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, 87 MachineInstrBuilder &MIB, CCAssignFn *AssignFn) 88 : ValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {} 89 90 unsigned getStackAddress(uint64_t Size, int64_t Offset, 91 MachinePointerInfo &MPO) override { 92 llvm_unreachable("Don't know how to get a stack address yet"); 93 } 94 95 void assignValueToReg(unsigned ValVReg, unsigned PhysReg, 96 CCValAssign &VA) override { 97 MIB.addUse(PhysReg, RegState::Implicit); 98 unsigned ExtReg = extendRegister(ValVReg, VA); 99 MIRBuilder.buildCopy(PhysReg, ExtReg); 100 } 101 102 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size, 103 MachinePointerInfo &MPO, CCValAssign &VA) override { 104 llvm_unreachable("Don't know how to assign a value to an address yet"); 105 } 106 107 MachineInstrBuilder &MIB; 108 }; 109 } // End anonymous namespace. 110 111 bool X86CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, 112 const Value *Val, unsigned VReg) const { 113 114 assert(((Val && VReg) || (!Val && !VReg)) && "Return value without a vreg"); 115 116 auto MIB = MIRBuilder.buildInstrNoInsert(X86::RET).addImm(0); 117 118 if (VReg) { 119 MachineFunction &MF = MIRBuilder.getMF(); 120 MachineRegisterInfo &MRI = MF.getRegInfo(); 121 auto &DL = MF.getDataLayout(); 122 const Function &F = *MF.getFunction(); 123 124 ArgInfo OrigArg{VReg, Val->getType()}; 125 setArgFlags(OrigArg, AttributeList::ReturnIndex, DL, F); 126 127 SmallVector<ArgInfo, 8> SplitArgs; 128 if (!splitToValueTypes(OrigArg, SplitArgs, DL, MRI, 129 [&](ArrayRef<unsigned> Regs) { 130 MIRBuilder.buildUnmerge(Regs, VReg); 131 })) 132 return false; 133 134 FuncReturnHandler Handler(MIRBuilder, MRI, MIB, RetCC_X86); 135 if (!handleAssignments(MIRBuilder, SplitArgs, Handler)) 136 return false; 137 } 138 139 MIRBuilder.insertInstr(MIB); 140 return true; 141 } 142 143 namespace { 144 struct FormalArgHandler : public CallLowering::ValueHandler { 145 FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, 146 CCAssignFn *AssignFn, const DataLayout &DL) 147 : ValueHandler(MIRBuilder, MRI, AssignFn), DL(DL) {} 148 149 unsigned getStackAddress(uint64_t Size, int64_t Offset, 150 MachinePointerInfo &MPO) override { 151 152 auto &MFI = MIRBuilder.getMF().getFrameInfo(); 153 int FI = MFI.CreateFixedObject(Size, Offset, true); 154 MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI); 155 156 unsigned AddrReg = MRI.createGenericVirtualRegister( 157 LLT::pointer(0, DL.getPointerSizeInBits(0))); 158 MIRBuilder.buildFrameIndex(AddrReg, FI); 159 return AddrReg; 160 } 161 162 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size, 163 MachinePointerInfo &MPO, CCValAssign &VA) override { 164 165 auto MMO = MIRBuilder.getMF().getMachineMemOperand( 166 MPO, MachineMemOperand::MOLoad | MachineMemOperand::MOInvariant, Size, 167 0); 168 MIRBuilder.buildLoad(ValVReg, Addr, *MMO); 169 } 170 171 void assignValueToReg(unsigned ValVReg, unsigned PhysReg, 172 CCValAssign &VA) override { 173 MIRBuilder.getMBB().addLiveIn(PhysReg); 174 MIRBuilder.buildCopy(ValVReg, PhysReg); 175 } 176 177 const DataLayout &DL; 178 }; 179 } // namespace 180 181 bool X86CallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, 182 const Function &F, 183 ArrayRef<unsigned> VRegs) const { 184 if (F.arg_empty()) 185 return true; 186 187 // TODO: handle variadic function 188 if (F.isVarArg()) 189 return false; 190 191 MachineFunction &MF = MIRBuilder.getMF(); 192 MachineRegisterInfo &MRI = MF.getRegInfo(); 193 auto DL = MF.getDataLayout(); 194 195 SmallVector<ArgInfo, 8> SplitArgs; 196 unsigned Idx = 0; 197 for (auto &Arg : F.args()) { 198 199 // TODO: handle not simple cases. 200 if (Arg.hasAttribute(Attribute::ByVal) || 201 Arg.hasAttribute(Attribute::InReg) || 202 Arg.hasAttribute(Attribute::StructRet) || 203 Arg.hasAttribute(Attribute::SwiftSelf) || 204 Arg.hasAttribute(Attribute::SwiftError) || 205 Arg.hasAttribute(Attribute::Nest)) 206 return false; 207 208 ArgInfo OrigArg(VRegs[Idx], Arg.getType()); 209 setArgFlags(OrigArg, Idx + AttributeList::FirstArgIndex, DL, F); 210 if (!splitToValueTypes(OrigArg, SplitArgs, DL, MRI, 211 [&](ArrayRef<unsigned> Regs) { 212 MIRBuilder.buildMerge(VRegs[Idx], Regs); 213 })) 214 return false; 215 Idx++; 216 } 217 218 MachineBasicBlock &MBB = MIRBuilder.getMBB(); 219 if (!MBB.empty()) 220 MIRBuilder.setInstr(*MBB.begin()); 221 222 FormalArgHandler Handler(MIRBuilder, MRI, CC_X86, DL); 223 if (!handleAssignments(MIRBuilder, SplitArgs, Handler)) 224 return false; 225 226 // Move back to the end of the basic block. 227 MIRBuilder.setMBB(MBB); 228 229 return true; 230 } 231