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