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 "X86ISelLowering.h" 18 #include "X86InstrInfo.h" 19 #include "X86TargetMachine.h" 20 #include "X86CallingConv.h" 21 22 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 23 #include "llvm/CodeGen/MachineValueType.h" 24 #include "llvm/CodeGen/MachineRegisterInfo.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 SplitArgs.push_back(OrigArg); 51 return; 52 } 53 54 SmallVector<uint64_t, 4> BitOffsets; 55 SmallVector<unsigned, 8> SplitRegs; 56 57 EVT PartVT = TLI.getRegisterType(Context, VT); 58 Type *PartTy = PartVT.getTypeForEVT(Context); 59 60 for (unsigned i = 0; i < NumParts; ++i) { 61 ArgInfo Info = ArgInfo{MRI.createGenericVirtualRegister(LLT{*PartTy, DL}), 62 PartTy, OrigArg.Flags}; 63 SplitArgs.push_back(Info); 64 BitOffsets.push_back(PartVT.getSizeInBits() * i); 65 SplitRegs.push_back(Info.Reg); 66 } 67 68 PerformArgSplit(SplitRegs, BitOffsets); 69 } 70 71 namespace { 72 struct FuncReturnHandler : public CallLowering::ValueHandler { 73 FuncReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, 74 MachineInstrBuilder &MIB, CCAssignFn *AssignFn) 75 : ValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {} 76 77 unsigned getStackAddress(uint64_t Size, int64_t Offset, 78 MachinePointerInfo &MPO) override { 79 llvm_unreachable("Don't know how to get a stack address yet"); 80 } 81 82 void assignValueToReg(unsigned ValVReg, unsigned PhysReg, 83 CCValAssign &VA) override { 84 MIB.addUse(PhysReg, RegState::Implicit); 85 unsigned ExtReg = extendRegister(ValVReg, VA); 86 MIRBuilder.buildCopy(PhysReg, ExtReg); 87 } 88 89 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size, 90 MachinePointerInfo &MPO, CCValAssign &VA) override { 91 llvm_unreachable("Don't know how to assign a value to an address yet"); 92 } 93 94 MachineInstrBuilder &MIB; 95 }; 96 } // End anonymous namespace. 97 98 bool X86CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, 99 const Value *Val, unsigned VReg) const { 100 101 assert(((Val && VReg) || (!Val && !VReg)) && "Return value without a vreg"); 102 103 auto MIB = MIRBuilder.buildInstrNoInsert(X86::RET).addImm(0); 104 105 if (VReg) { 106 MachineFunction &MF = MIRBuilder.getMF(); 107 MachineRegisterInfo &MRI = MF.getRegInfo(); 108 auto &DL = MF.getDataLayout(); 109 const Function &F = *MF.getFunction(); 110 111 ArgInfo OrigArg{VReg, Val->getType()}; 112 setArgFlags(OrigArg, AttributeSet::ReturnIndex, DL, F); 113 114 SmallVector<ArgInfo, 8> SplitArgs; 115 splitToValueTypes(OrigArg, SplitArgs, DL, MRI, 116 [&](ArrayRef<unsigned> Regs, ArrayRef<uint64_t> Offsets) { 117 MIRBuilder.buildExtract(Regs, Offsets, VReg); 118 }); 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 = 143 MRI.createGenericVirtualRegister(LLT::pointer(0, 144 DL.getPointerSizeInBits(0))); 145 MIRBuilder.buildFrameIndex(AddrReg, FI); 146 return AddrReg; 147 } 148 149 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size, 150 MachinePointerInfo &MPO, CCValAssign &VA) override { 151 152 auto MMO = MIRBuilder.getMF().getMachineMemOperand( 153 MPO, MachineMemOperand::MOLoad | MachineMemOperand::MOInvariant, Size, 154 0); 155 MIRBuilder.buildLoad(ValVReg, Addr, *MMO); 156 } 157 158 void assignValueToReg(unsigned ValVReg, unsigned PhysReg, 159 CCValAssign &VA) override { 160 MIRBuilder.getMBB().addLiveIn(PhysReg); 161 MIRBuilder.buildCopy(ValVReg, PhysReg); 162 } 163 164 const DataLayout &DL; 165 }; 166 } 167 168 bool X86CallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, 169 const Function &F, 170 ArrayRef<unsigned> VRegs) const { 171 if (F.arg_empty()) 172 return true; 173 174 //TODO: handle variadic function 175 if (F.isVarArg()) 176 return false; 177 178 MachineFunction &MF = MIRBuilder.getMF(); 179 MachineRegisterInfo &MRI = MF.getRegInfo(); 180 auto DL = MF.getDataLayout(); 181 182 SmallVector<ArgInfo, 8> SplitArgs; 183 unsigned Idx = 0; 184 for (auto &Arg : F.getArgumentList()) { 185 ArgInfo OrigArg(VRegs[Idx], Arg.getType()); 186 setArgFlags(OrigArg, Idx + 1, DL, F); 187 splitToValueTypes(OrigArg, SplitArgs, DL, MRI, 188 [&](ArrayRef<unsigned> Regs, ArrayRef<uint64_t> Offsets) { 189 MIRBuilder.buildSequence(VRegs[Idx], Regs, Offsets); 190 }); 191 Idx++; 192 } 193 194 MachineBasicBlock &MBB = MIRBuilder.getMBB(); 195 if (!MBB.empty()) 196 MIRBuilder.setInstr(*MBB.begin()); 197 198 FormalArgHandler Handler(MIRBuilder, MRI, CC_X86, DL); 199 if (!handleAssignments(MIRBuilder, SplitArgs, Handler)) 200 return false; 201 202 // Move back to the end of the basic block. 203 MIRBuilder.setMBB(MBB); 204 205 return true; 206 } 207