blob: de40dd0db0e26754927be5cb8616d0fe956fc46e [file] [log] [blame]
Diana Picus22274932016-11-11 08:27:37 +00001//===-- 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
21#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
Diana Picus1437f6d2016-12-19 11:55:41 +000022#include "llvm/CodeGen/MachineRegisterInfo.h"
Diana Picus22274932016-11-11 08:27:37 +000023
24using namespace llvm;
25
26#ifndef LLVM_BUILD_GLOBAL_ISEL
27#error "This shouldn't be built without GISel"
28#endif
29
30ARMCallLowering::ARMCallLowering(const ARMTargetLowering &TLI)
31 : CallLowering(&TLI) {}
32
Diana Picus812caee2016-12-16 12:54:46 +000033static bool isSupportedType(const DataLayout DL, const ARMTargetLowering &TLI,
34 Type *T) {
35 EVT VT = TLI.getValueType(DL, T);
36 return VT.isSimple() && VT.isInteger() &&
37 VT.getSimpleVT().getSizeInBits() == 32;
38}
39
40namespace {
41struct FuncReturnHandler : public CallLowering::ValueHandler {
42 FuncReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
43 MachineInstrBuilder &MIB)
44 : ValueHandler(MIRBuilder, MRI), MIB(MIB) {}
45
46 unsigned getStackAddress(uint64_t Size, int64_t Offset,
47 MachinePointerInfo &MPO) override {
48 llvm_unreachable("Don't know how to get a stack address yet");
49 }
50
51 void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
52 CCValAssign &VA) override {
53 assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
54 assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
55
56 assert(VA.getValVT().getSizeInBits() == 32 && "Unsupported value size");
57 assert(VA.getLocVT().getSizeInBits() == 32 && "Unsupported location size");
58
59 MIRBuilder.buildCopy(PhysReg, ValVReg);
60 MIB.addUse(PhysReg, RegState::Implicit);
61 }
62
63 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
64 MachinePointerInfo &MPO, CCValAssign &VA) override {
65 llvm_unreachable("Don't know how to assign a value to an address yet");
66 }
67
68 MachineInstrBuilder &MIB;
69};
70} // End anonymous namespace.
71
72/// Lower the return value for the already existing \p Ret. This assumes that
73/// \p MIRBuilder's insertion point is correct.
74bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder,
75 const Value *Val, unsigned VReg,
76 MachineInstrBuilder &Ret) const {
77 if (!Val)
78 // Nothing to do here.
79 return true;
80
81 auto &MF = MIRBuilder.getMF();
82 const auto &F = *MF.getFunction();
83
84 auto DL = MF.getDataLayout();
85 auto &TLI = *getTLI<ARMTargetLowering>();
86 if (!isSupportedType(DL, TLI, Val->getType()))
Diana Picus22274932016-11-11 08:27:37 +000087 return false;
88
Diana Picus812caee2016-12-16 12:54:46 +000089 CCAssignFn *AssignFn =
90 TLI.CCAssignFnForReturn(F.getCallingConv(), F.isVarArg());
Diana Picus22274932016-11-11 08:27:37 +000091
Diana Picus812caee2016-12-16 12:54:46 +000092 ArgInfo RetInfo(VReg, Val->getType());
93 setArgFlags(RetInfo, AttributeSet::ReturnIndex, DL, F);
94
95 FuncReturnHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret);
96 return handleAssignments(MIRBuilder, AssignFn, RetInfo, RetHandler);
97}
98
99bool ARMCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
100 const Value *Val, unsigned VReg) const {
101 assert(!Val == !VReg && "Return value without a vreg");
102
103 auto Ret = AddDefaultPred(MIRBuilder.buildInstrNoInsert(ARM::BX_RET));
104
105 if (!lowerReturnVal(MIRBuilder, Val, VReg, Ret))
106 return false;
107
108 MIRBuilder.insertInstr(Ret);
Diana Picus22274932016-11-11 08:27:37 +0000109 return true;
110}
111
Diana Picus812caee2016-12-16 12:54:46 +0000112namespace {
113struct FormalArgHandler : public CallLowering::ValueHandler {
114 FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
115 : ValueHandler(MIRBuilder, MRI) {}
116
117 unsigned getStackAddress(uint64_t Size, int64_t Offset,
118 MachinePointerInfo &MPO) override {
Diana Picus1437f6d2016-12-19 11:55:41 +0000119 assert(Size == 4 && "Unsupported size");
120
121 auto &MFI = MIRBuilder.getMF().getFrameInfo();
122
123 int FI = MFI.CreateFixedObject(Size, Offset, true);
124 MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
125
126 unsigned AddrReg =
127 MRI.createGenericVirtualRegister(LLT::pointer(MPO.getAddrSpace(), 32));
128 MIRBuilder.buildFrameIndex(AddrReg, FI);
129
130 return AddrReg;
131 }
132
133 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
134 MachinePointerInfo &MPO, CCValAssign &VA) override {
135 assert(Size == 4 && "Unsupported size");
136
137 auto MMO = MIRBuilder.getMF().getMachineMemOperand(
138 MPO, MachineMemOperand::MOLoad, Size, /* Alignment */ 0);
139 MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
Diana Picus812caee2016-12-16 12:54:46 +0000140 }
141
142 void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
143 CCValAssign &VA) override {
144 assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
145 assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
146
147 assert(VA.getValVT().getSizeInBits() == 32 && "Unsupported value size");
148 assert(VA.getLocVT().getSizeInBits() == 32 && "Unsupported location size");
149
150 MIRBuilder.getMBB().addLiveIn(PhysReg);
151 MIRBuilder.buildCopy(ValVReg, PhysReg);
152 }
Diana Picus812caee2016-12-16 12:54:46 +0000153};
154} // End anonymous namespace
155
Diana Picus22274932016-11-11 08:27:37 +0000156bool ARMCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
157 const Function &F,
158 ArrayRef<unsigned> VRegs) const {
Diana Picus812caee2016-12-16 12:54:46 +0000159 // Quick exit if there aren't any args
160 if (F.arg_empty())
161 return true;
162
Diana Picus812caee2016-12-16 12:54:46 +0000163 if (F.isVarArg())
164 return false;
165
166 auto DL = MIRBuilder.getMF().getDataLayout();
167 auto &TLI = *getTLI<ARMTargetLowering>();
168
169 auto &Args = F.getArgumentList();
170 for (auto &Arg : Args)
171 if (!isSupportedType(DL, TLI, Arg.getType()))
172 return false;
173
174 CCAssignFn *AssignFn =
175 TLI.CCAssignFnForCall(F.getCallingConv(), F.isVarArg());
176
177 SmallVector<ArgInfo, 8> ArgInfos;
178 unsigned Idx = 0;
179 for (auto &Arg : Args) {
180 ArgInfo AInfo(VRegs[Idx], Arg.getType());
181 setArgFlags(AInfo, Idx + 1, DL, F);
182 ArgInfos.push_back(AInfo);
183 Idx++;
184 }
185
186 FormalArgHandler ArgHandler(MIRBuilder, MIRBuilder.getMF().getRegInfo());
187 return handleAssignments(MIRBuilder, AssignFn, ArgInfos, ArgHandler);
Diana Picus22274932016-11-11 08:27:37 +0000188}