llvm.org GIT mirror llvm / 88d7249
In preparation for moving ARM's TargetRegisterInfo to the TargetMachine merge Thumb1RegisterInfo and Thumb2RegisterInfo. This will enable us to match the TargetMachine for our TargetRegisterInfo classes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@232117 91177308-0d34-0410-b5e6-96231b3b80d8 Eric Christopher 5 years ago
14 changed file(s) with 707 addition(s) and 748 deletion(s). Raw diff Collapse all Expand all
19901990 if (isCalleeStructRet || isCallerStructRet)
19911991 return false;
19921992
1993 // FIXME: Completely disable sibcall for Thumb1 since Thumb1RegisterInfo::
1993 // FIXME: Completely disable sibcall for Thumb1 since ThumbRegisterInfo::
19941994 // emitEpilogue is not ready for them. Thumb tail calls also use t2B, as
19951995 // the Thumb1 16-bit unconditional branch doesn't have sufficient relocation
19961996 // support in the assembler and linker to be used. This would need to be
1818 #include "ARMMachineFunctionInfo.h"
1919 #include "ARMSubtarget.h"
2020 #include "MCTargetDesc/ARMAddressingModes.h"
21 #include "Thumb1RegisterInfo.h"
21 #include "ThumbRegisterInfo.h"
2222 #include "llvm/ADT/DenseMap.h"
2323 #include "llvm/ADT/STLExtras.h"
2424 #include "llvm/ADT/SmallPtrSet.h"
3939 MLxExpansionPass.cpp
4040 Thumb1FrameLowering.cpp
4141 Thumb1InstrInfo.cpp
42 Thumb1RegisterInfo.cpp
42 ThumbRegisterInfo.cpp
4343 Thumb2ITBlockPass.cpp
4444 Thumb2InstrInfo.cpp
45 Thumb2RegisterInfo.cpp
4645 Thumb2SizeReduction.cpp
4746 )
4847
231231 //===---------------------------------------------------------------------===//
232232
233233 Thumb1 immediate field sometimes keep pre-scaled values. See
234 Thumb1RegisterInfo::eliminateFrameIndex. This is inconsistent from ARM and
234 ThumbRegisterInfo::eliminateFrameIndex. This is inconsistent from ARM and
235235 Thumb2.
236236
237237 //===---------------------------------------------------------------------===//
4040 emitSPUpdate(MachineBasicBlock &MBB,
4141 MachineBasicBlock::iterator &MBBI,
4242 const TargetInstrInfo &TII, DebugLoc dl,
43 const Thumb1RegisterInfo &MRI,
43 const ThumbRegisterInfo &MRI,
4444 int NumBytes, unsigned MIFlags = MachineInstr::NoFlags) {
4545 emitThumbRegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes, TII,
4646 MRI, MIFlags);
5252 MachineBasicBlock::iterator I) const {
5353 const Thumb1InstrInfo &TII =
5454 *static_cast(STI.getInstrInfo());
55 const Thumb1RegisterInfo *RegInfo =
56 static_cast(STI.getRegisterInfo());
55 const ThumbRegisterInfo *RegInfo =
56 static_cast(STI.getRegisterInfo());
5757 if (!hasReservedCallFrame(MF)) {
5858 // If we have alloca, convert as follows:
5959 // ADJCALLSTACKDOWN -> sub, sp, sp, amount
8888 ARMFunctionInfo *AFI = MF.getInfo();
8989 MachineModuleInfo &MMI = MF.getMMI();
9090 const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
91 const Thumb1RegisterInfo *RegInfo =
92 static_cast(STI.getRegisterInfo());
91 const ThumbRegisterInfo *RegInfo =
92 static_cast(STI.getRegisterInfo());
9393 const Thumb1InstrInfo &TII =
9494 *static_cast(STI.getInstrInfo());
9595
326326 DebugLoc dl = MBBI->getDebugLoc();
327327 MachineFrameInfo *MFI = MF.getFrameInfo();
328328 ARMFunctionInfo *AFI = MF.getInfo();
329 const Thumb1RegisterInfo *RegInfo =
330 static_cast(STI.getRegisterInfo());
329 const ThumbRegisterInfo *RegInfo =
330 static_cast(STI.getRegisterInfo());
331331 const Thumb1InstrInfo &TII =
332332 *static_cast(STI.getInstrInfo());
333333
1515
1616 #include "ARMFrameLowering.h"
1717 #include "Thumb1InstrInfo.h"
18 #include "Thumb1RegisterInfo.h"
18 #include "ThumbRegisterInfo.h"
1919 #include "llvm/Target/TargetFrameLowering.h"
2020
2121 namespace llvm {
1414 #define LLVM_LIB_TARGET_ARM_THUMB1INSTRINFO_H
1515
1616 #include "ARMBaseInstrInfo.h"
17 #include "Thumb1RegisterInfo.h"
17 #include "ThumbRegisterInfo.h"
1818
1919 namespace llvm {
2020 class ARMSubtarget;
2121
2222 class Thumb1InstrInfo : public ARMBaseInstrInfo {
23 Thumb1RegisterInfo RI;
23 ThumbRegisterInfo RI;
2424 public:
2525 explicit Thumb1InstrInfo(const ARMSubtarget &STI);
2626
3535 /// such, whenever a client has an instance of instruction info, it should
3636 /// always be able to get register info as well (through this method).
3737 ///
38 const Thumb1RegisterInfo &getRegisterInfo() const override { return RI; }
38 const ThumbRegisterInfo &getRegisterInfo() const override { return RI; }
3939
4040 void copyPhysReg(MachineBasicBlock &MBB,
4141 MachineBasicBlock::iterator I, DebugLoc DL,
+0
-576
lib/Target/ARM/Thumb1RegisterInfo.cpp less more
None //===-- Thumb1RegisterInfo.cpp - Thumb-1 Register Information -------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the Thumb-1 implementation of the TargetRegisterInfo
10 // class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "Thumb1RegisterInfo.h"
15 #include "ARMBaseInstrInfo.h"
16 #include "ARMMachineFunctionInfo.h"
17 #include "ARMSubtarget.h"
18 #include "MCTargetDesc/ARMAddressingModes.h"
19 #include "llvm/CodeGen/MachineConstantPool.h"
20 #include "llvm/CodeGen/MachineFrameInfo.h"
21 #include "llvm/CodeGen/MachineFunction.h"
22 #include "llvm/CodeGen/MachineInstrBuilder.h"
23 #include "llvm/CodeGen/MachineRegisterInfo.h"
24 #include "llvm/CodeGen/RegisterScavenging.h"
25 #include "llvm/IR/Constants.h"
26 #include "llvm/IR/DerivedTypes.h"
27 #include "llvm/IR/Function.h"
28 #include "llvm/IR/LLVMContext.h"
29 #include "llvm/Support/CommandLine.h"
30 #include "llvm/Support/ErrorHandling.h"
31 #include "llvm/Target/TargetFrameLowering.h"
32 #include "llvm/Target/TargetMachine.h"
33
34 namespace llvm {
35 extern cl::opt ReuseFrameIndexVals;
36 }
37
38 using namespace llvm;
39
40 Thumb1RegisterInfo::Thumb1RegisterInfo() : ARMBaseRegisterInfo() {}
41
42 const TargetRegisterClass *
43 Thumb1RegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
44 const MachineFunction &MF) const {
45 if (ARM::tGPRRegClass.hasSubClassEq(RC))
46 return &ARM::tGPRRegClass;
47 return ARMBaseRegisterInfo::getLargestLegalSuperClass(RC, MF);
48 }
49
50 const TargetRegisterClass *
51 Thumb1RegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind)
52 const {
53 return &ARM::tGPRRegClass;
54 }
55
56 /// emitLoadConstPool - Emits a load from constpool to materialize the
57 /// specified immediate.
58 void Thumb1RegisterInfo::emitLoadConstPool(
59 MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl,
60 unsigned DestReg, unsigned SubIdx, int Val, ARMCC::CondCodes Pred,
61 unsigned PredReg, unsigned MIFlags) const {
62 assert((isARMLowRegister(DestReg) ||
63 isVirtualRegister(DestReg)) &&
64 "Thumb1 does not have ldr to high register");
65
66 MachineFunction &MF = *MBB.getParent();
67 const ARMSubtarget &STI = MF.getSubtarget();
68 const TargetInstrInfo &TII = *STI.getInstrInfo();
69 MachineConstantPool *ConstantPool = MF.getConstantPool();
70 const Constant *C = ConstantInt::get(
71 Type::getInt32Ty(MBB.getParent()->getFunction()->getContext()), Val);
72 unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
73
74 BuildMI(MBB, MBBI, dl, TII.get(ARM::tLDRpci))
75 .addReg(DestReg, getDefRegState(true), SubIdx)
76 .addConstantPoolIndex(Idx).addImm(Pred).addReg(PredReg)
77 .setMIFlags(MIFlags);
78 }
79
80
81 /// emitThumbRegPlusImmInReg - Emits a series of instructions to materialize
82 /// a destreg = basereg + immediate in Thumb code. Materialize the immediate
83 /// in a register using mov / mvn sequences or load the immediate from a
84 /// constpool entry.
85 static
86 void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB,
87 MachineBasicBlock::iterator &MBBI,
88 DebugLoc dl,
89 unsigned DestReg, unsigned BaseReg,
90 int NumBytes, bool CanChangeCC,
91 const TargetInstrInfo &TII,
92 const ARMBaseRegisterInfo& MRI,
93 unsigned MIFlags = MachineInstr::NoFlags) {
94 MachineFunction &MF = *MBB.getParent();
95 bool isHigh = !isARMLowRegister(DestReg) ||
96 (BaseReg != 0 && !isARMLowRegister(BaseReg));
97 bool isSub = false;
98 // Subtract doesn't have high register version. Load the negative value
99 // if either base or dest register is a high register. Also, if do not
100 // issue sub as part of the sequence if condition register is to be
101 // preserved.
102 if (NumBytes < 0 && !isHigh && CanChangeCC) {
103 isSub = true;
104 NumBytes = -NumBytes;
105 }
106 unsigned LdReg = DestReg;
107 if (DestReg == ARM::SP)
108 assert(BaseReg == ARM::SP && "Unexpected!");
109 if (!isARMLowRegister(DestReg) && !MRI.isVirtualRegister(DestReg))
110 LdReg = MF.getRegInfo().createVirtualRegister(&ARM::tGPRRegClass);
111
112 if (NumBytes <= 255 && NumBytes >= 0 && CanChangeCC) {
113 AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg))
114 .addImm(NumBytes).setMIFlags(MIFlags);
115 } else if (NumBytes < 0 && NumBytes >= -255 && CanChangeCC) {
116 AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg))
117 .addImm(NumBytes).setMIFlags(MIFlags);
118 AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tRSB), LdReg))
119 .addReg(LdReg, RegState::Kill).setMIFlags(MIFlags);
120 } else
121 MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, 0, NumBytes,
122 ARMCC::AL, 0, MIFlags);
123
124 // Emit add / sub.
125 int Opc = (isSub) ? ARM::tSUBrr : ((isHigh || !CanChangeCC) ? ARM::tADDhirr
126 : ARM::tADDrr);
127 MachineInstrBuilder MIB =
128 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg);
129 if (Opc != ARM::tADDhirr)
130 MIB = AddDefaultT1CC(MIB);
131 if (DestReg == ARM::SP || isSub)
132 MIB.addReg(BaseReg).addReg(LdReg, RegState::Kill);
133 else
134 MIB.addReg(LdReg).addReg(BaseReg, RegState::Kill);
135 AddDefaultPred(MIB);
136 }
137
138 /// emitThumbRegPlusImmediate - Emits a series of instructions to materialize
139 /// a destreg = basereg + immediate in Thumb code. Tries a series of ADDs or
140 /// SUBs first, and uses a constant pool value if the instruction sequence would
141 /// be too long. This is allowed to modify the condition flags.
142 void llvm::emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
143 MachineBasicBlock::iterator &MBBI,
144 DebugLoc dl,
145 unsigned DestReg, unsigned BaseReg,
146 int NumBytes, const TargetInstrInfo &TII,
147 const ARMBaseRegisterInfo& MRI,
148 unsigned MIFlags) {
149 bool isSub = NumBytes < 0;
150 unsigned Bytes = (unsigned)NumBytes;
151 if (isSub) Bytes = -NumBytes;
152
153 int CopyOpc = 0;
154 unsigned CopyBits = 0;
155 unsigned CopyScale = 1;
156 bool CopyNeedsCC = false;
157 int ExtraOpc = 0;
158 unsigned ExtraBits = 0;
159 unsigned ExtraScale = 1;
160 bool ExtraNeedsCC = false;
161
162 // Strategy:
163 // We need to select two types of instruction, maximizing the available
164 // immediate range of each. The instructions we use will depend on whether
165 // DestReg and BaseReg are low, high or the stack pointer.
166 // * CopyOpc - DestReg = BaseReg + imm
167 // This will be emitted once if DestReg != BaseReg, and never if
168 // DestReg == BaseReg.
169 // * ExtraOpc - DestReg = DestReg + imm
170 // This will be emitted as many times as necessary to add the
171 // full immediate.
172 // If the immediate ranges of these instructions are not large enough to cover
173 // NumBytes with a reasonable number of instructions, we fall back to using a
174 // value loaded from a constant pool.
175 if (DestReg == ARM::SP) {
176 if (BaseReg == ARM::SP) {
177 // sp -> sp
178 // Already in right reg, no copy needed
179 } else {
180 // low -> sp or high -> sp
181 CopyOpc = ARM::tMOVr;
182 CopyBits = 0;
183 }
184 ExtraOpc = isSub ? ARM::tSUBspi : ARM::tADDspi;
185 ExtraBits = 7;
186 ExtraScale = 4;
187 } else if (isARMLowRegister(DestReg)) {
188 if (BaseReg == ARM::SP) {
189 // sp -> low
190 assert(!isSub && "Thumb1 does not have tSUBrSPi");
191 CopyOpc = ARM::tADDrSPi;
192 CopyBits = 8;
193 CopyScale = 4;
194 } else if (DestReg == BaseReg) {
195 // low -> same low
196 // Already in right reg, no copy needed
197 } else if (isARMLowRegister(BaseReg)) {
198 // low -> different low
199 CopyOpc = isSub ? ARM::tSUBi3 : ARM::tADDi3;
200 CopyBits = 3;
201 CopyNeedsCC = true;
202 } else {
203 // high -> low
204 CopyOpc = ARM::tMOVr;
205 CopyBits = 0;
206 }
207 ExtraOpc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
208 ExtraBits = 8;
209 ExtraNeedsCC = true;
210 } else /* DestReg is high */ {
211 if (DestReg == BaseReg) {
212 // high -> same high
213 // Already in right reg, no copy needed
214 } else {
215 // {low,high,sp} -> high
216 CopyOpc = ARM::tMOVr;
217 CopyBits = 0;
218 }
219 ExtraOpc = 0;
220 }
221
222 // We could handle an unaligned immediate with an unaligned copy instruction
223 // and an aligned extra instruction, but this case is not currently needed.
224 assert(((Bytes & 3) == 0 || ExtraScale == 1) &&
225 "Unaligned offset, but all instructions require alignment");
226
227 unsigned CopyRange = ((1 << CopyBits) - 1) * CopyScale;
228 // If we would emit the copy with an immediate of 0, just use tMOVr.
229 if (CopyOpc && Bytes < CopyScale) {
230 CopyOpc = ARM::tMOVr;
231 CopyScale = 1;
232 CopyNeedsCC = false;
233 CopyRange = 0;
234 }
235 unsigned ExtraRange = ((1 << ExtraBits) - 1) * ExtraScale; // per instruction
236 unsigned RequiredCopyInstrs = CopyOpc ? 1 : 0;
237 unsigned RangeAfterCopy = (CopyRange > Bytes) ? 0 : (Bytes - CopyRange);
238
239 // We could handle this case when the copy instruction does not require an
240 // aligned immediate, but we do not currently do this.
241 assert(RangeAfterCopy % ExtraScale == 0 &&
242 "Extra instruction requires immediate to be aligned");
243
244 unsigned RequiredExtraInstrs;
245 if (ExtraRange)
246 RequiredExtraInstrs = RoundUpToAlignment(RangeAfterCopy, ExtraRange) / ExtraRange;
247 else if (RangeAfterCopy > 0)
248 // We need an extra instruction but none is available
249 RequiredExtraInstrs = 1000000;
250 else
251 RequiredExtraInstrs = 0;
252 unsigned RequiredInstrs = RequiredCopyInstrs + RequiredExtraInstrs;
253 unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2;
254
255 // Use a constant pool, if the sequence of ADDs/SUBs is too expensive.
256 if (RequiredInstrs > Threshold) {
257 emitThumbRegPlusImmInReg(MBB, MBBI, dl,
258 DestReg, BaseReg, NumBytes, true,
259 TII, MRI, MIFlags);
260 return;
261 }
262
263 // Emit zero or one copy instructions
264 if (CopyOpc) {
265 unsigned CopyImm = std::min(Bytes, CopyRange) / CopyScale;
266 Bytes -= CopyImm * CopyScale;
267
268 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(CopyOpc), DestReg);
269 if (CopyNeedsCC)
270 MIB = AddDefaultT1CC(MIB);
271 MIB.addReg(BaseReg, RegState::Kill);
272 if (CopyOpc != ARM::tMOVr) {
273 MIB.addImm(CopyImm);
274 }
275 AddDefaultPred(MIB.setMIFlags(MIFlags));
276
277 BaseReg = DestReg;
278 }
279
280 // Emit zero or more in-place add/sub instructions
281 while (Bytes) {
282 unsigned ExtraImm = std::min(Bytes, ExtraRange) / ExtraScale;
283 Bytes -= ExtraImm * ExtraScale;
284
285 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(ExtraOpc), DestReg);
286 if (ExtraNeedsCC)
287 MIB = AddDefaultT1CC(MIB);
288 MIB.addReg(BaseReg).addImm(ExtraImm);
289 MIB = AddDefaultPred(MIB);
290 MIB.setMIFlags(MIFlags);
291 }
292 }
293
294 static void removeOperands(MachineInstr &MI, unsigned i) {
295 unsigned Op = i;
296 for (unsigned e = MI.getNumOperands(); i != e; ++i)
297 MI.RemoveOperand(Op);
298 }
299
300 /// convertToNonSPOpcode - Change the opcode to the non-SP version, because
301 /// we're replacing the frame index with a non-SP register.
302 static unsigned convertToNonSPOpcode(unsigned Opcode) {
303 switch (Opcode) {
304 case ARM::tLDRspi:
305 return ARM::tLDRi;
306
307 case ARM::tSTRspi:
308 return ARM::tSTRi;
309 }
310
311 return Opcode;
312 }
313
314 bool Thumb1RegisterInfo::
315 rewriteFrameIndex(MachineBasicBlock::iterator II, unsigned FrameRegIdx,
316 unsigned FrameReg, int &Offset,
317 const ARMBaseInstrInfo &TII) const {
318 MachineInstr &MI = *II;
319 MachineBasicBlock &MBB = *MI.getParent();
320 DebugLoc dl = MI.getDebugLoc();
321 MachineInstrBuilder MIB(*MBB.getParent(), &MI);
322 unsigned Opcode = MI.getOpcode();
323 const MCInstrDesc &Desc = MI.getDesc();
324 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
325
326 if (Opcode == ARM::tADDframe) {
327 Offset += MI.getOperand(FrameRegIdx+1).getImm();
328 unsigned DestReg = MI.getOperand(0).getReg();
329
330 emitThumbRegPlusImmediate(MBB, II, dl, DestReg, FrameReg, Offset, TII,
331 *this);
332 MBB.erase(II);
333 return true;
334 } else {
335 if (AddrMode != ARMII::AddrModeT1_s)
336 llvm_unreachable("Unsupported addressing mode!");
337
338 unsigned ImmIdx = FrameRegIdx + 1;
339 int InstrOffs = MI.getOperand(ImmIdx).getImm();
340 unsigned NumBits = (FrameReg == ARM::SP) ? 8 : 5;
341 unsigned Scale = 4;
342
343 Offset += InstrOffs * Scale;
344 assert((Offset & (Scale - 1)) == 0 && "Can't encode this offset!");
345
346 // Common case: small offset, fits into instruction.
347 MachineOperand &ImmOp = MI.getOperand(ImmIdx);
348 int ImmedOffset = Offset / Scale;
349 unsigned Mask = (1 << NumBits) - 1;
350
351 if ((unsigned)Offset <= Mask * Scale) {
352 // Replace the FrameIndex with the frame register (e.g., sp).
353 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
354 ImmOp.ChangeToImmediate(ImmedOffset);
355
356 // If we're using a register where sp was stored, convert the instruction
357 // to the non-SP version.
358 unsigned NewOpc = convertToNonSPOpcode(Opcode);
359 if (NewOpc != Opcode && FrameReg != ARM::SP)
360 MI.setDesc(TII.get(NewOpc));
361
362 return true;
363 }
364
365 NumBits = 5;
366 Mask = (1 << NumBits) - 1;
367
368 // If this is a thumb spill / restore, we will be using a constpool load to
369 // materialize the offset.
370 if (Opcode == ARM::tLDRspi || Opcode == ARM::tSTRspi) {
371 ImmOp.ChangeToImmediate(0);
372 } else {
373 // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
374 ImmedOffset = ImmedOffset & Mask;
375 ImmOp.ChangeToImmediate(ImmedOffset);
376 Offset &= ~(Mask * Scale);
377 }
378 }
379
380 return Offset == 0;
381 }
382
383 void Thumb1RegisterInfo::resolveFrameIndex(MachineInstr &MI, unsigned BaseReg,
384 int64_t Offset) const {
385 const MachineFunction &MF = *MI.getParent()->getParent();
386 const ARMSubtarget &STI = MF.getSubtarget();
387 const ARMBaseInstrInfo &TII = *STI.getInstrInfo();
388 int Off = Offset; // ARM doesn't need the general 64-bit offsets
389 unsigned i = 0;
390
391 while (!MI.getOperand(i).isFI()) {
392 ++i;
393 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
394 }
395 bool Done = rewriteFrameIndex(MI, i, BaseReg, Off, TII);
396 assert (Done && "Unable to resolve frame index!");
397 (void)Done;
398 }
399
400 /// saveScavengerRegister - Spill the register so it can be used by the
401 /// register scavenger. Return true.
402 bool
403 Thumb1RegisterInfo::saveScavengerRegister(MachineBasicBlock &MBB,
404 MachineBasicBlock::iterator I,
405 MachineBasicBlock::iterator &UseMI,
406 const TargetRegisterClass *RC,
407 unsigned Reg) const {
408 // Thumb1 can't use the emergency spill slot on the stack because
409 // ldr/str immediate offsets must be positive, and if we're referencing
410 // off the frame pointer (if, for example, there are alloca() calls in
411 // the function, the offset will be negative. Use R12 instead since that's
412 // a call clobbered register that we know won't be used in Thumb1 mode.
413 const ARMSubtarget &STI = MBB.getParent()->getSubtarget();
414 const TargetInstrInfo &TII = *STI.getInstrInfo();
415 DebugLoc DL;
416 AddDefaultPred(BuildMI(MBB, I, DL, TII.get(ARM::tMOVr))
417 .addReg(ARM::R12, RegState::Define)
418 .addReg(Reg, RegState::Kill));
419
420 // The UseMI is where we would like to restore the register. If there's
421 // interference with R12 before then, however, we'll need to restore it
422 // before that instead and adjust the UseMI.
423 bool done = false;
424 for (MachineBasicBlock::iterator II = I; !done && II != UseMI ; ++II) {
425 if (II->isDebugValue())
426 continue;
427 // If this instruction affects R12, adjust our restore point.
428 for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) {
429 const MachineOperand &MO = II->getOperand(i);
430 if (MO.isRegMask() && MO.clobbersPhysReg(ARM::R12)) {
431 UseMI = II;
432 done = true;
433 break;
434 }
435 if (!MO.isReg() || MO.isUndef() || !MO.getReg() ||
436 TargetRegisterInfo::isVirtualRegister(MO.getReg()))
437 continue;
438 if (MO.getReg() == ARM::R12) {
439 UseMI = II;
440 done = true;
441 break;
442 }
443 }
444 }
445 // Restore the register from R12
446 AddDefaultPred(BuildMI(MBB, UseMI, DL, TII.get(ARM::tMOVr)).
447 addReg(Reg, RegState::Define).addReg(ARM::R12, RegState::Kill));
448
449 return true;
450 }
451
452 void
453 Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
454 int SPAdj, unsigned FIOperandNum,
455 RegScavenger *RS) const {
456 unsigned VReg = 0;
457 MachineInstr &MI = *II;
458 MachineBasicBlock &MBB = *MI.getParent();
459 MachineFunction &MF = *MBB.getParent();
460 const ARMSubtarget &STI = MF.getSubtarget();
461 const ARMBaseInstrInfo &TII = *STI.getInstrInfo();
462 ARMFunctionInfo *AFI = MF.getInfo();
463 DebugLoc dl = MI.getDebugLoc();
464 MachineInstrBuilder MIB(*MBB.getParent(), &MI);
465
466 unsigned FrameReg = ARM::SP;
467 int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
468 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
469 MF.getFrameInfo()->getStackSize() + SPAdj;
470
471 if (MF.getFrameInfo()->hasVarSizedObjects()) {
472 assert(SPAdj == 0 && STI.getFrameLowering()->hasFP(MF) && "Unexpected");
473 // There are alloca()'s in this function, must reference off the frame
474 // pointer or base pointer instead.
475 if (!hasBasePointer(MF)) {
476 FrameReg = getFrameRegister(MF);
477 Offset -= AFI->getFramePtrSpillOffset();
478 } else
479 FrameReg = BasePtr;
480 }
481
482 // PEI::scavengeFrameVirtualRegs() cannot accurately track SPAdj because the
483 // call frame setup/destroy instructions have already been eliminated. That
484 // means the stack pointer cannot be used to access the emergency spill slot
485 // when !hasReservedCallFrame().
486 #ifndef NDEBUG
487 if (RS && FrameReg == ARM::SP && RS->isScavengingFrameIndex(FrameIndex)){
488 assert(STI.getFrameLowering()->hasReservedCallFrame(MF) &&
489 "Cannot use SP to access the emergency spill slot in "
490 "functions without a reserved call frame");
491 assert(!MF.getFrameInfo()->hasVarSizedObjects() &&
492 "Cannot use SP to access the emergency spill slot in "
493 "functions with variable sized frame objects");
494 }
495 #endif // NDEBUG
496
497 // Special handling of dbg_value instructions.
498 if (MI.isDebugValue()) {
499 MI.getOperand(FIOperandNum). ChangeToRegister(FrameReg, false /*isDef*/);
500 MI.getOperand(FIOperandNum+1).ChangeToImmediate(Offset);
501 return;
502 }
503
504 // Modify MI as necessary to handle as much of 'Offset' as possible
505 assert(AFI->isThumbFunction() &&
506 "This eliminateFrameIndex only supports Thumb1!");
507 if (rewriteFrameIndex(MI, FIOperandNum, FrameReg, Offset, TII))
508 return;
509
510 // If we get here, the immediate doesn't fit into the instruction. We folded
511 // as much as possible above, handle the rest, providing a register that is
512 // SP+LargeImm.
513 assert(Offset && "This code isn't needed if offset already handled!");
514
515 unsigned Opcode = MI.getOpcode();
516
517 // Remove predicate first.
518 int PIdx = MI.findFirstPredOperandIdx();
519 if (PIdx != -1)
520 removeOperands(MI, PIdx);
521
522 if (MI.mayLoad()) {
523 // Use the destination register to materialize sp + offset.
524 unsigned TmpReg = MI.getOperand(0).getReg();
525 bool UseRR = false;
526 if (Opcode == ARM::tLDRspi) {
527 if (FrameReg == ARM::SP)
528 emitThumbRegPlusImmInReg(MBB, II, dl, TmpReg, FrameReg,
529 Offset, false, TII, *this);
530 else {
531 emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset);
532 UseRR = true;
533 }
534 } else {
535 emitThumbRegPlusImmediate(MBB, II, dl, TmpReg, FrameReg, Offset, TII,
536 *this);
537 }
538
539 MI.setDesc(TII.get(UseRR ? ARM::tLDRr : ARM::tLDRi));
540 MI.getOperand(FIOperandNum).ChangeToRegister(TmpReg, false, false, true);
541 if (UseRR)
542 // Use [reg, reg] addrmode. Replace the immediate operand w/ the frame
543 // register. The offset is already handled in the vreg value.
544 MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg, false, false,
545 false);
546 } else if (MI.mayStore()) {
547 VReg = MF.getRegInfo().createVirtualRegister(&ARM::tGPRRegClass);
548 bool UseRR = false;
549
550 if (Opcode == ARM::tSTRspi) {
551 if (FrameReg == ARM::SP)
552 emitThumbRegPlusImmInReg(MBB, II, dl, VReg, FrameReg,
553 Offset, false, TII, *this);
554 else {
555 emitLoadConstPool(MBB, II, dl, VReg, 0, Offset);
556 UseRR = true;
557 }
558 } else
559 emitThumbRegPlusImmediate(MBB, II, dl, VReg, FrameReg, Offset, TII,
560 *this);
561 MI.setDesc(TII.get(UseRR ? ARM::tSTRr : ARM::tSTRi));
562 MI.getOperand(FIOperandNum).ChangeToRegister(VReg, false, false, true);
563 if (UseRR)
564 // Use [reg, reg] addrmode. Replace the immediate operand w/ the frame
565 // register. The offset is already handled in the vreg value.
566 MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg, false, false,
567 false);
568 } else {
569 llvm_unreachable("Unexpected opcode!");
570 }
571
572 // Add predicate back if it's needed.
573 if (MI.isPredicable())
574 AddDefaultPred(MIB);
575 }
+0
-64
lib/Target/ARM/Thumb1RegisterInfo.h less more
None //===- Thumb1RegisterInfo.h - Thumb-1 Register Information Impl -*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the Thumb-1 implementation of the TargetRegisterInfo
10 // class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_LIB_TARGET_ARM_THUMB1REGISTERINFO_H
15 #define LLVM_LIB_TARGET_ARM_THUMB1REGISTERINFO_H
16
17 #include "ARMBaseRegisterInfo.h"
18 #include "llvm/Target/TargetRegisterInfo.h"
19
20 namespace llvm {
21 class ARMSubtarget;
22 class ARMBaseInstrInfo;
23
24 struct Thumb1RegisterInfo : public ARMBaseRegisterInfo {
25 public:
26 Thumb1RegisterInfo();
27
28 const TargetRegisterClass *
29 getLargestLegalSuperClass(const TargetRegisterClass *RC,
30 const MachineFunction &MF) const override;
31
32 const TargetRegisterClass *
33 getPointerRegClass(const MachineFunction &MF,
34 unsigned Kind = 0) const override;
35
36 /// emitLoadConstPool - Emits a load from constpool to materialize the
37 /// specified immediate.
38 void
39 emitLoadConstPool(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
40 DebugLoc dl, unsigned DestReg, unsigned SubIdx, int Val,
41 ARMCC::CondCodes Pred = ARMCC::AL, unsigned PredReg = 0,
42 unsigned MIFlags = MachineInstr::NoFlags) const override;
43
44 // rewrite MI to access 'Offset' bytes from the FP. Update Offset to be
45 // however much remains to be handled. Return 'true' if no further
46 // work is required.
47 bool rewriteFrameIndex(MachineBasicBlock::iterator II, unsigned FrameRegIdx,
48 unsigned FrameReg, int &Offset,
49 const ARMBaseInstrInfo &TII) const;
50 void resolveFrameIndex(MachineInstr &MI, unsigned BaseReg,
51 int64_t Offset) const override;
52 bool saveScavengerRegister(MachineBasicBlock &MBB,
53 MachineBasicBlock::iterator I,
54 MachineBasicBlock::iterator &UseMI,
55 const TargetRegisterClass *RC,
56 unsigned Reg) const override;
57 void eliminateFrameIndex(MachineBasicBlock::iterator II,
58 int SPAdj, unsigned FIOperandNum,
59 RegScavenger *RS = nullptr) const override;
60 };
61 }
62
63 #endif
1414 #define LLVM_LIB_TARGET_ARM_THUMB2INSTRINFO_H
1515
1616 #include "ARMBaseInstrInfo.h"
17 #include "Thumb2RegisterInfo.h"
17 #include "ThumbRegisterInfo.h"
1818
1919 namespace llvm {
2020 class ARMSubtarget;
2121 class ScheduleHazardRecognizer;
2222
2323 class Thumb2InstrInfo : public ARMBaseInstrInfo {
24 Thumb2RegisterInfo RI;
24 ThumbRegisterInfo RI;
2525 public:
2626 explicit Thumb2InstrInfo(const ARMSubtarget &STI);
2727
5959 /// such, whenever a client has an instance of instruction info, it should
6060 /// always be able to get register info as well (through this method).
6161 ///
62 const Thumb2RegisterInfo &getRegisterInfo() const override { return RI; }
62 const ThumbRegisterInfo &getRegisterInfo() const override { return RI; }
6363
6464 private:
6565 void expandLoadStackGuard(MachineBasicBlock::iterator MI,
+0
-51
lib/Target/ARM/Thumb2RegisterInfo.cpp less more
None //===-- Thumb2RegisterInfo.cpp - Thumb-2 Register Information -------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the Thumb-2 implementation of the TargetRegisterInfo
10 // class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "Thumb2RegisterInfo.h"
15 #include "ARM.h"
16 #include "ARMSubtarget.h"
17 #include "llvm/CodeGen/MachineConstantPool.h"
18 #include "llvm/CodeGen/MachineFunction.h"
19 #include "llvm/CodeGen/MachineInstrBuilder.h"
20 #include "llvm/IR/Constants.h"
21 #include "llvm/IR/DerivedTypes.h"
22 #include "llvm/IR/Function.h"
23 #include "llvm/Target/TargetInstrInfo.h"
24 #include "llvm/Target/TargetMachine.h"
25 using namespace llvm;
26
27 Thumb2RegisterInfo::Thumb2RegisterInfo() : ARMBaseRegisterInfo() {}
28
29 /// emitLoadConstPool - Emits a load from constpool to materialize the
30 /// specified immediate.
31 void
32 Thumb2RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
33 MachineBasicBlock::iterator &MBBI,
34 DebugLoc dl,
35 unsigned DestReg, unsigned SubIdx,
36 int Val,
37 ARMCC::CondCodes Pred, unsigned PredReg,
38 unsigned MIFlags) const {
39 MachineFunction &MF = *MBB.getParent();
40 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
41 MachineConstantPool *ConstantPool = MF.getConstantPool();
42 const Constant *C = ConstantInt::get(
43 Type::getInt32Ty(MBB.getParent()->getFunction()->getContext()), Val);
44 unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
45
46 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2LDRpci))
47 .addReg(DestReg, getDefRegState(true), SubIdx)
48 .addConstantPoolIndex(Idx).addImm((int64_t)ARMCC::AL).addReg(0)
49 .setMIFlags(MIFlags);
50 }
+0
-38
lib/Target/ARM/Thumb2RegisterInfo.h less more
None //===- Thumb2RegisterInfo.h - Thumb-2 Register Information Impl -*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the Thumb-2 implementation of the TargetRegisterInfo
10 // class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_LIB_TARGET_ARM_THUMB2REGISTERINFO_H
15 #define LLVM_LIB_TARGET_ARM_THUMB2REGISTERINFO_H
16
17 #include "ARMBaseRegisterInfo.h"
18
19 namespace llvm {
20
21 class ARMSubtarget;
22
23 struct Thumb2RegisterInfo : public ARMBaseRegisterInfo {
24 public:
25 Thumb2RegisterInfo();
26
27 /// emitLoadConstPool - Emits a load from constpool to materialize the
28 /// specified immediate.
29 void
30 emitLoadConstPool(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
31 DebugLoc dl, unsigned DestReg, unsigned SubIdx, int Val,
32 ARMCC::CondCodes Pred = ARMCC::AL, unsigned PredReg = 0,
33 unsigned MIFlags = MachineInstr::NoFlags) const override;
34 };
35 }
36
37 #endif
0 //===-- ThumbRegisterInfo.cpp - Thumb-1 Register Information -------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the Thumb-1 implementation of the TargetRegisterInfo
10 // class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "ThumbRegisterInfo.h"
15 #include "ARMBaseInstrInfo.h"
16 #include "ARMMachineFunctionInfo.h"
17 #include "ARMSubtarget.h"
18 #include "MCTargetDesc/ARMAddressingModes.h"
19 #include "llvm/CodeGen/MachineConstantPool.h"
20 #include "llvm/CodeGen/MachineFrameInfo.h"
21 #include "llvm/CodeGen/MachineFunction.h"
22 #include "llvm/CodeGen/MachineInstrBuilder.h"
23 #include "llvm/CodeGen/MachineRegisterInfo.h"
24 #include "llvm/CodeGen/RegisterScavenging.h"
25 #include "llvm/IR/Constants.h"
26 #include "llvm/IR/DerivedTypes.h"
27 #include "llvm/IR/Function.h"
28 #include "llvm/IR/LLVMContext.h"
29 #include "llvm/Support/CommandLine.h"
30 #include "llvm/Support/ErrorHandling.h"
31 #include "llvm/Target/TargetFrameLowering.h"
32 #include "llvm/Target/TargetMachine.h"
33
34 namespace llvm {
35 extern cl::opt ReuseFrameIndexVals;
36 }
37
38 using namespace llvm;
39
40 ThumbRegisterInfo::ThumbRegisterInfo() : ARMBaseRegisterInfo() {}
41
42 const TargetRegisterClass *
43 ThumbRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
44 const MachineFunction &MF) const {
45 if (!MF.getSubtarget().isThumb1Only())
46 return ARMBaseRegisterInfo::getLargestLegalSuperClass(RC, MF);
47
48 if (ARM::tGPRRegClass.hasSubClassEq(RC))
49 return &ARM::tGPRRegClass;
50 return ARMBaseRegisterInfo::getLargestLegalSuperClass(RC, MF);
51 }
52
53 const TargetRegisterClass *
54 ThumbRegisterInfo::getPointerRegClass(const MachineFunction &MF,
55 unsigned Kind) const {
56 if (!MF.getSubtarget().isThumb1Only())
57 return ARMBaseRegisterInfo::getPointerRegClass(MF, Kind);
58 return &ARM::tGPRRegClass;
59 }
60
61 static void emitThumb1LoadConstPool(MachineBasicBlock &MBB,
62 MachineBasicBlock::iterator &MBBI,
63 DebugLoc dl, unsigned DestReg,
64 unsigned SubIdx, int Val,
65 ARMCC::CondCodes Pred, unsigned PredReg,
66 unsigned MIFlags) {
67 MachineFunction &MF = *MBB.getParent();
68 const ARMSubtarget &STI = MF.getSubtarget();
69 const TargetInstrInfo &TII = *STI.getInstrInfo();
70 MachineConstantPool *ConstantPool = MF.getConstantPool();
71 const Constant *C = ConstantInt::get(
72 Type::getInt32Ty(MBB.getParent()->getFunction()->getContext()), Val);
73 unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
74
75 BuildMI(MBB, MBBI, dl, TII.get(ARM::tLDRpci))
76 .addReg(DestReg, getDefRegState(true), SubIdx)
77 .addConstantPoolIndex(Idx).addImm(Pred).addReg(PredReg)
78 .setMIFlags(MIFlags);
79 }
80
81 static void emitThumb2LoadConstPool(MachineBasicBlock &MBB,
82 MachineBasicBlock::iterator &MBBI,
83 DebugLoc dl, unsigned DestReg,
84 unsigned SubIdx, int Val,
85 ARMCC::CondCodes Pred, unsigned PredReg,
86 unsigned MIFlags) {
87 MachineFunction &MF = *MBB.getParent();
88 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
89 MachineConstantPool *ConstantPool = MF.getConstantPool();
90 const Constant *C = ConstantInt::get(
91 Type::getInt32Ty(MBB.getParent()->getFunction()->getContext()), Val);
92 unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
93
94 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2LDRpci))
95 .addReg(DestReg, getDefRegState(true), SubIdx)
96 .addConstantPoolIndex(Idx).addImm((int64_t)ARMCC::AL).addReg(0)
97 .setMIFlags(MIFlags);
98 }
99
100 /// emitLoadConstPool - Emits a load from constpool to materialize the
101 /// specified immediate.
102 void ThumbRegisterInfo::emitLoadConstPool(
103 MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl,
104 unsigned DestReg, unsigned SubIdx, int Val, ARMCC::CondCodes Pred,
105 unsigned PredReg, unsigned MIFlags) const {
106 MachineFunction &MF = *MBB.getParent();
107 const ARMSubtarget &STI = MF.getSubtarget();
108 if (STI.isThumb1Only()) {
109 assert((isARMLowRegister(DestReg) || isVirtualRegister(DestReg)) &&
110 "Thumb1 does not have ldr to high register");
111 return emitThumb1LoadConstPool(MBB, MBBI, dl, DestReg, SubIdx, Val, Pred,
112 PredReg, MIFlags);
113 }
114 return emitThumb2LoadConstPool(MBB, MBBI, dl, DestReg, SubIdx, Val, Pred,
115 PredReg, MIFlags);
116 }
117
118 /// emitThumbRegPlusImmInReg - Emits a series of instructions to materialize
119 /// a destreg = basereg + immediate in Thumb code. Materialize the immediate
120 /// in a register using mov / mvn sequences or load the immediate from a
121 /// constpool entry.
122 static
123 void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB,
124 MachineBasicBlock::iterator &MBBI,
125 DebugLoc dl,
126 unsigned DestReg, unsigned BaseReg,
127 int NumBytes, bool CanChangeCC,
128 const TargetInstrInfo &TII,
129 const ARMBaseRegisterInfo& MRI,
130 unsigned MIFlags = MachineInstr::NoFlags) {
131 MachineFunction &MF = *MBB.getParent();
132 bool isHigh = !isARMLowRegister(DestReg) ||
133 (BaseReg != 0 && !isARMLowRegister(BaseReg));
134 bool isSub = false;
135 // Subtract doesn't have high register version. Load the negative value
136 // if either base or dest register is a high register. Also, if do not
137 // issue sub as part of the sequence if condition register is to be
138 // preserved.
139 if (NumBytes < 0 && !isHigh && CanChangeCC) {
140 isSub = true;
141 NumBytes = -NumBytes;
142 }
143 unsigned LdReg = DestReg;
144 if (DestReg == ARM::SP)
145 assert(BaseReg == ARM::SP && "Unexpected!");
146 if (!isARMLowRegister(DestReg) && !MRI.isVirtualRegister(DestReg))
147 LdReg = MF.getRegInfo().createVirtualRegister(&ARM::tGPRRegClass);
148
149 if (NumBytes <= 255 && NumBytes >= 0 && CanChangeCC) {
150 AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg))
151 .addImm(NumBytes).setMIFlags(MIFlags);
152 } else if (NumBytes < 0 && NumBytes >= -255 && CanChangeCC) {
153 AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg))
154 .addImm(NumBytes).setMIFlags(MIFlags);
155 AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tRSB), LdReg))
156 .addReg(LdReg, RegState::Kill).setMIFlags(MIFlags);
157 } else
158 MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, 0, NumBytes,
159 ARMCC::AL, 0, MIFlags);
160
161 // Emit add / sub.
162 int Opc = (isSub) ? ARM::tSUBrr : ((isHigh || !CanChangeCC) ? ARM::tADDhirr
163 : ARM::tADDrr);
164 MachineInstrBuilder MIB =
165 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg);
166 if (Opc != ARM::tADDhirr)
167 MIB = AddDefaultT1CC(MIB);
168 if (DestReg == ARM::SP || isSub)
169 MIB.addReg(BaseReg).addReg(LdReg, RegState::Kill);
170 else
171 MIB.addReg(LdReg).addReg(BaseReg, RegState::Kill);
172 AddDefaultPred(MIB);
173 }
174
175 /// emitThumbRegPlusImmediate - Emits a series of instructions to materialize
176 /// a destreg = basereg + immediate in Thumb code. Tries a series of ADDs or
177 /// SUBs first, and uses a constant pool value if the instruction sequence would
178 /// be too long. This is allowed to modify the condition flags.
179 void llvm::emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
180 MachineBasicBlock::iterator &MBBI,
181 DebugLoc dl,
182 unsigned DestReg, unsigned BaseReg,
183 int NumBytes, const TargetInstrInfo &TII,
184 const ARMBaseRegisterInfo& MRI,
185 unsigned MIFlags) {
186 bool isSub = NumBytes < 0;
187 unsigned Bytes = (unsigned)NumBytes;
188 if (isSub) Bytes = -NumBytes;
189
190 int CopyOpc = 0;
191 unsigned CopyBits = 0;
192 unsigned CopyScale = 1;
193 bool CopyNeedsCC = false;
194 int ExtraOpc = 0;
195 unsigned ExtraBits = 0;
196 unsigned ExtraScale = 1;
197 bool ExtraNeedsCC = false;
198
199 // Strategy:
200 // We need to select two types of instruction, maximizing the available
201 // immediate range of each. The instructions we use will depend on whether
202 // DestReg and BaseReg are low, high or the stack pointer.
203 // * CopyOpc - DestReg = BaseReg + imm
204 // This will be emitted once if DestReg != BaseReg, and never if
205 // DestReg == BaseReg.
206 // * ExtraOpc - DestReg = DestReg + imm
207 // This will be emitted as many times as necessary to add the
208 // full immediate.
209 // If the immediate ranges of these instructions are not large enough to cover
210 // NumBytes with a reasonable number of instructions, we fall back to using a
211 // value loaded from a constant pool.
212 if (DestReg == ARM::SP) {
213 if (BaseReg == ARM::SP) {
214 // sp -> sp
215 // Already in right reg, no copy needed
216 } else {
217 // low -> sp or high -> sp
218 CopyOpc = ARM::tMOVr;
219 CopyBits = 0;
220 }
221 ExtraOpc = isSub ? ARM::tSUBspi : ARM::tADDspi;
222 ExtraBits = 7;
223 ExtraScale = 4;
224 } else if (isARMLowRegister(DestReg)) {
225 if (BaseReg == ARM::SP) {
226 // sp -> low
227 assert(!isSub && "Thumb1 does not have tSUBrSPi");
228 CopyOpc = ARM::tADDrSPi;
229 CopyBits = 8;
230 CopyScale = 4;
231 } else if (DestReg == BaseReg) {
232 // low -> same low
233 // Already in right reg, no copy needed
234 } else if (isARMLowRegister(BaseReg)) {
235 // low -> different low
236 CopyOpc = isSub ? ARM::tSUBi3 : ARM::tADDi3;
237 CopyBits = 3;
238 CopyNeedsCC = true;
239 } else {
240 // high -> low
241 CopyOpc = ARM::tMOVr;
242 CopyBits = 0;
243 }
244 ExtraOpc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
245 ExtraBits = 8;
246 ExtraNeedsCC = true;
247 } else /* DestReg is high */ {
248 if (DestReg == BaseReg) {
249 // high -> same high
250 // Already in right reg, no copy needed
251 } else {
252 // {low,high,sp} -> high
253 CopyOpc = ARM::tMOVr;
254 CopyBits = 0;
255 }
256 ExtraOpc = 0;
257 }
258
259 // We could handle an unaligned immediate with an unaligned copy instruction
260 // and an aligned extra instruction, but this case is not currently needed.
261 assert(((Bytes & 3) == 0 || ExtraScale == 1) &&
262 "Unaligned offset, but all instructions require alignment");
263
264 unsigned CopyRange = ((1 << CopyBits) - 1) * CopyScale;
265 // If we would emit the copy with an immediate of 0, just use tMOVr.
266 if (CopyOpc && Bytes < CopyScale) {
267 CopyOpc = ARM::tMOVr;
268 CopyScale = 1;
269 CopyNeedsCC = false;
270 CopyRange = 0;
271 }
272 unsigned ExtraRange = ((1 << ExtraBits) - 1) * ExtraScale; // per instruction
273 unsigned RequiredCopyInstrs = CopyOpc ? 1 : 0;
274 unsigned RangeAfterCopy = (CopyRange > Bytes) ? 0 : (Bytes - CopyRange);
275
276 // We could handle this case when the copy instruction does not require an
277 // aligned immediate, but we do not currently do this.
278 assert(RangeAfterCopy % ExtraScale == 0 &&
279 "Extra instruction requires immediate to be aligned");
280
281 unsigned RequiredExtraInstrs;
282 if (ExtraRange)
283 RequiredExtraInstrs = RoundUpToAlignment(RangeAfterCopy, ExtraRange) / ExtraRange;
284 else if (RangeAfterCopy > 0)
285 // We need an extra instruction but none is available
286 RequiredExtraInstrs = 1000000;
287 else
288 RequiredExtraInstrs = 0;
289 unsigned RequiredInstrs = RequiredCopyInstrs + RequiredExtraInstrs;
290 unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2;
291
292 // Use a constant pool, if the sequence of ADDs/SUBs is too expensive.
293 if (RequiredInstrs > Threshold) {
294 emitThumbRegPlusImmInReg(MBB, MBBI, dl,
295 DestReg, BaseReg, NumBytes, true,
296 TII, MRI, MIFlags);
297 return;
298 }
299
300 // Emit zero or one copy instructions
301 if (CopyOpc) {
302 unsigned CopyImm = std::min(Bytes, CopyRange) / CopyScale;
303 Bytes -= CopyImm * CopyScale;
304
305 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(CopyOpc), DestReg);
306 if (CopyNeedsCC)
307 MIB = AddDefaultT1CC(MIB);
308 MIB.addReg(BaseReg, RegState::Kill);
309 if (CopyOpc != ARM::tMOVr) {
310 MIB.addImm(CopyImm);
311 }
312 AddDefaultPred(MIB.setMIFlags(MIFlags));
313
314 BaseReg = DestReg;
315 }
316
317 // Emit zero or more in-place add/sub instructions
318 while (Bytes) {
319 unsigned ExtraImm = std::min(Bytes, ExtraRange) / ExtraScale;
320 Bytes -= ExtraImm * ExtraScale;
321
322 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(ExtraOpc), DestReg);
323 if (ExtraNeedsCC)
324 MIB = AddDefaultT1CC(MIB);
325 MIB.addReg(BaseReg).addImm(ExtraImm);
326 MIB = AddDefaultPred(MIB);
327 MIB.setMIFlags(MIFlags);
328 }
329 }
330
331 static void removeOperands(MachineInstr &MI, unsigned i) {
332 unsigned Op = i;
333 for (unsigned e = MI.getNumOperands(); i != e; ++i)
334 MI.RemoveOperand(Op);
335 }
336
337 /// convertToNonSPOpcode - Change the opcode to the non-SP version, because
338 /// we're replacing the frame index with a non-SP register.
339 static unsigned convertToNonSPOpcode(unsigned Opcode) {
340 switch (Opcode) {
341 case ARM::tLDRspi:
342 return ARM::tLDRi;
343
344 case ARM::tSTRspi:
345 return ARM::tSTRi;
346 }
347
348 return Opcode;
349 }
350
351 bool ThumbRegisterInfo::rewriteFrameIndex(MachineBasicBlock::iterator II,
352 unsigned FrameRegIdx,
353 unsigned FrameReg, int &Offset,
354 const ARMBaseInstrInfo &TII) const {
355 MachineInstr &MI = *II;
356 MachineBasicBlock &MBB = *MI.getParent();
357 const MachineFunction &MF = *MBB.getParent();
358 assert(MF.getSubtarget().isThumb1Only() &&
359 "This isn't needed for thumb2!");
360 DebugLoc dl = MI.getDebugLoc();
361 MachineInstrBuilder MIB(*MBB.getParent(), &MI);
362 unsigned Opcode = MI.getOpcode();
363 const MCInstrDesc &Desc = MI.getDesc();
364 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
365
366 if (Opcode == ARM::tADDframe) {
367 Offset += MI.getOperand(FrameRegIdx+1).getImm();
368 unsigned DestReg = MI.getOperand(0).getReg();
369
370 emitThumbRegPlusImmediate(MBB, II, dl, DestReg, FrameReg, Offset, TII,
371 *this);
372 MBB.erase(II);
373 return true;
374 } else {
375 if (AddrMode != ARMII::AddrModeT1_s)
376 llvm_unreachable("Unsupported addressing mode!");
377
378 unsigned ImmIdx = FrameRegIdx + 1;
379 int InstrOffs = MI.getOperand(ImmIdx).getImm();
380 unsigned NumBits = (FrameReg == ARM::SP) ? 8 : 5;
381 unsigned Scale = 4;
382
383 Offset += InstrOffs * Scale;
384 assert((Offset & (Scale - 1)) == 0 && "Can't encode this offset!");
385
386 // Common case: small offset, fits into instruction.
387 MachineOperand &ImmOp = MI.getOperand(ImmIdx);
388 int ImmedOffset = Offset / Scale;
389 unsigned Mask = (1 << NumBits) - 1;
390
391 if ((unsigned)Offset <= Mask * Scale) {
392 // Replace the FrameIndex with the frame register (e.g., sp).
393 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
394 ImmOp.ChangeToImmediate(ImmedOffset);
395
396 // If we're using a register where sp was stored, convert the instruction
397 // to the non-SP version.
398 unsigned NewOpc = convertToNonSPOpcode(Opcode);
399 if (NewOpc != Opcode && FrameReg != ARM::SP)
400 MI.setDesc(TII.get(NewOpc));
401
402 return true;
403 }
404
405 NumBits = 5;
406 Mask = (1 << NumBits) - 1;
407
408 // If this is a thumb spill / restore, we will be using a constpool load to
409 // materialize the offset.
410 if (Opcode == ARM::tLDRspi || Opcode == ARM::tSTRspi) {
411 ImmOp.ChangeToImmediate(0);
412 } else {
413 // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
414 ImmedOffset = ImmedOffset & Mask;
415 ImmOp.ChangeToImmediate(ImmedOffset);
416 Offset &= ~(Mask * Scale);
417 }
418 }
419
420 return Offset == 0;
421 }
422
423 void ThumbRegisterInfo::resolveFrameIndex(MachineInstr &MI, unsigned BaseReg,
424 int64_t Offset) const {
425 const MachineFunction &MF = *MI.getParent()->getParent();
426 const ARMSubtarget &STI = MF.getSubtarget();
427 if (!STI.isThumb1Only())
428 return ARMBaseRegisterInfo::resolveFrameIndex(MI, BaseReg, Offset);
429
430 const ARMBaseInstrInfo &TII = *STI.getInstrInfo();
431 int Off = Offset; // ARM doesn't need the general 64-bit offsets
432 unsigned i = 0;
433
434 while (!MI.getOperand(i).isFI()) {
435 ++i;
436 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
437 }
438 bool Done = rewriteFrameIndex(MI, i, BaseReg, Off, TII);
439 assert (Done && "Unable to resolve frame index!");
440 (void)Done;
441 }
442
443 /// saveScavengerRegister - Spill the register so it can be used by the
444 /// register scavenger. Return true.
445 bool ThumbRegisterInfo::saveScavengerRegister(
446 MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
447 MachineBasicBlock::iterator &UseMI, const TargetRegisterClass *RC,
448 unsigned Reg) const {
449
450 const ARMSubtarget &STI = MBB.getParent()->getSubtarget();
451 if (!STI.isThumb1Only())
452 return ARMBaseRegisterInfo::saveScavengerRegister(MBB, I, UseMI, RC, Reg);
453
454 // Thumb1 can't use the emergency spill slot on the stack because
455 // ldr/str immediate offsets must be positive, and if we're referencing
456 // off the frame pointer (if, for example, there are alloca() calls in
457 // the function, the offset will be negative. Use R12 instead since that's
458 // a call clobbered register that we know won't be used in Thumb1 mode.
459 const TargetInstrInfo &TII = *STI.getInstrInfo();
460 DebugLoc DL;
461 AddDefaultPred(BuildMI(MBB, I, DL, TII.get(ARM::tMOVr))
462 .addReg(ARM::R12, RegState::Define)
463 .addReg(Reg, RegState::Kill));
464
465 // The UseMI is where we would like to restore the register. If there's
466 // interference with R12 before then, however, we'll need to restore it
467 // before that instead and adjust the UseMI.
468 bool done = false;
469 for (MachineBasicBlock::iterator II = I; !done && II != UseMI ; ++II) {
470 if (II->isDebugValue())
471 continue;
472 // If this instruction affects R12, adjust our restore point.
473 for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) {
474 const MachineOperand &MO = II->getOperand(i);
475 if (MO.isRegMask() && MO.clobbersPhysReg(ARM::R12)) {
476 UseMI = II;
477 done = true;
478 break;
479 }
480 if (!MO.isReg() || MO.isUndef() || !MO.getReg() ||
481 TargetRegisterInfo::isVirtualRegister(MO.getReg()))
482 continue;
483 if (MO.getReg() == ARM::R12) {
484 UseMI = II;
485 done = true;
486 break;
487 }
488 }
489 }
490 // Restore the register from R12
491 AddDefaultPred(BuildMI(MBB, UseMI, DL, TII.get(ARM::tMOVr)).
492 addReg(Reg, RegState::Define).addReg(ARM::R12, RegState::Kill));
493
494 return true;
495 }
496
497 void ThumbRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
498 int SPAdj, unsigned FIOperandNum,
499 RegScavenger *RS) const {
500 MachineInstr &MI = *II;
501 MachineBasicBlock &MBB = *MI.getParent();
502 MachineFunction &MF = *MBB.getParent();
503 const ARMSubtarget &STI = MF.getSubtarget();
504 if (!STI.isThumb1Only())
505 return ARMBaseRegisterInfo::eliminateFrameIndex(II, SPAdj, FIOperandNum,
506 RS);
507
508 unsigned VReg = 0;
509 const ARMBaseInstrInfo &TII = *STI.getInstrInfo();
510 ARMFunctionInfo *AFI = MF.getInfo();
511 DebugLoc dl = MI.getDebugLoc();
512 MachineInstrBuilder MIB(*MBB.getParent(), &MI);
513
514 unsigned FrameReg = ARM::SP;
515 int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
516 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
517 MF.getFrameInfo()->getStackSize() + SPAdj;
518
519 if (MF.getFrameInfo()->hasVarSizedObjects()) {
520 assert(SPAdj == 0 && STI.getFrameLowering()->hasFP(MF) && "Unexpected");
521 // There are alloca()'s in this function, must reference off the frame
522 // pointer or base pointer instead.
523 if (!hasBasePointer(MF)) {
524 FrameReg = getFrameRegister(MF);
525 Offset -= AFI->getFramePtrSpillOffset();
526 } else
527 FrameReg = BasePtr;
528 }
529
530 // PEI::scavengeFrameVirtualRegs() cannot accurately track SPAdj because the
531 // call frame setup/destroy instructions have already been eliminated. That
532 // means the stack pointer cannot be used to access the emergency spill slot
533 // when !hasReservedCallFrame().
534 #ifndef NDEBUG
535 if (RS && FrameReg == ARM::SP && RS->isScavengingFrameIndex(FrameIndex)){
536 assert(STI.getFrameLowering()->hasReservedCallFrame(MF) &&
537 "Cannot use SP to access the emergency spill slot in "
538 "functions without a reserved call frame");
539 assert(!MF.getFrameInfo()->hasVarSizedObjects() &&
540 "Cannot use SP to access the emergency spill slot in "
541 "functions with variable sized frame objects");
542 }
543 #endif // NDEBUG
544
545 // Special handling of dbg_value instructions.
546 if (MI.isDebugValue()) {
547 MI.getOperand(FIOperandNum). ChangeToRegister(FrameReg, false /*isDef*/);
548 MI.getOperand(FIOperandNum+1).ChangeToImmediate(Offset);
549 return;
550 }
551
552 // Modify MI as necessary to handle as much of 'Offset' as possible
553 assert(AFI->isThumbFunction() &&
554 "This eliminateFrameIndex only supports Thumb1!");
555 if (rewriteFrameIndex(MI, FIOperandNum, FrameReg, Offset, TII))
556 return;
557
558 // If we get here, the immediate doesn't fit into the instruction. We folded
559 // as much as possible above, handle the rest, providing a register that is
560 // SP+LargeImm.
561 assert(Offset && "This code isn't needed if offset already handled!");
562
563 unsigned Opcode = MI.getOpcode();
564
565 // Remove predicate first.
566 int PIdx = MI.findFirstPredOperandIdx();
567 if (PIdx != -1)
568 removeOperands(MI, PIdx);
569
570 if (MI.mayLoad()) {
571 // Use the destination register to materialize sp + offset.
572 unsigned TmpReg = MI.getOperand(0).getReg();
573 bool UseRR = false;
574 if (Opcode == ARM::tLDRspi) {
575 if (FrameReg == ARM::SP)
576 emitThumbRegPlusImmInReg(MBB, II, dl, TmpReg, FrameReg,
577 Offset, false, TII, *this);
578 else {
579 emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset);
580 UseRR = true;
581 }
582 } else {
583 emitThumbRegPlusImmediate(MBB, II, dl, TmpReg, FrameReg, Offset, TII,
584 *this);
585 }
586
587 MI.setDesc(TII.get(UseRR ? ARM::tLDRr : ARM::tLDRi));
588 MI.getOperand(FIOperandNum).ChangeToRegister(TmpReg, false, false, true);
589 if (UseRR)
590 // Use [reg, reg] addrmode. Replace the immediate operand w/ the frame
591 // register. The offset is already handled in the vreg value.
592 MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg, false, false,
593 false);
594 } else if (MI.mayStore()) {
595 VReg = MF.getRegInfo().createVirtualRegister(&ARM::tGPRRegClass);
596 bool UseRR = false;
597
598 if (Opcode == ARM::tSTRspi) {
599 if (FrameReg == ARM::SP)
600 emitThumbRegPlusImmInReg(MBB, II, dl, VReg, FrameReg,
601 Offset, false, TII, *this);
602 else {
603 emitLoadConstPool(MBB, II, dl, VReg, 0, Offset);
604 UseRR = true;
605 }
606 } else
607 emitThumbRegPlusImmediate(MBB, II, dl, VReg, FrameReg, Offset, TII,
608 *this);
609 MI.setDesc(TII.get(UseRR ? ARM::tSTRr : ARM::tSTRi));
610 MI.getOperand(FIOperandNum).ChangeToRegister(VReg, false, false, true);
611 if (UseRR)
612 // Use [reg, reg] addrmode. Replace the immediate operand w/ the frame
613 // register. The offset is already handled in the vreg value.
614 MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg, false, false,
615 false);
616 } else {
617 llvm_unreachable("Unexpected opcode!");
618 }
619
620 // Add predicate back if it's needed.
621 if (MI.isPredicable())
622 AddDefaultPred(MIB);
623 }
0 //===- ThumbRegisterInfo.h - Thumb Register Information Impl -*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the Thumb implementation of the TargetRegisterInfo
10 // class. With the exception of emitLoadConstPool Thumb2 tracks
11 // ARMBaseRegisterInfo, Thumb1 overloads the functions below.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_LIB_TARGET_ARM_THUMB1REGISTERINFO_H
16 #define LLVM_LIB_TARGET_ARM_THUMB1REGISTERINFO_H
17
18 #include "ARMBaseRegisterInfo.h"
19 #include "llvm/Target/TargetRegisterInfo.h"
20
21 namespace llvm {
22 class ARMSubtarget;
23 class ARMBaseInstrInfo;
24
25 struct ThumbRegisterInfo : public ARMBaseRegisterInfo {
26 public:
27 ThumbRegisterInfo();
28
29 const TargetRegisterClass *
30 getLargestLegalSuperClass(const TargetRegisterClass *RC,
31 const MachineFunction &MF) const override;
32
33 const TargetRegisterClass *
34 getPointerRegClass(const MachineFunction &MF,
35 unsigned Kind = 0) const override;
36
37 /// emitLoadConstPool - Emits a load from constpool to materialize the
38 /// specified immediate.
39 void
40 emitLoadConstPool(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
41 DebugLoc dl, unsigned DestReg, unsigned SubIdx, int Val,
42 ARMCC::CondCodes Pred = ARMCC::AL, unsigned PredReg = 0,
43 unsigned MIFlags = MachineInstr::NoFlags) const override;
44
45 // rewrite MI to access 'Offset' bytes from the FP. Update Offset to be
46 // however much remains to be handled. Return 'true' if no further
47 // work is required.
48 bool rewriteFrameIndex(MachineBasicBlock::iterator II, unsigned FrameRegIdx,
49 unsigned FrameReg, int &Offset,
50 const ARMBaseInstrInfo &TII) const;
51 void resolveFrameIndex(MachineInstr &MI, unsigned BaseReg,
52 int64_t Offset) const override;
53 bool saveScavengerRegister(MachineBasicBlock &MBB,
54 MachineBasicBlock::iterator I,
55 MachineBasicBlock::iterator &UseMI,
56 const TargetRegisterClass *RC,
57 unsigned Reg) const override;
58 void eliminateFrameIndex(MachineBasicBlock::iterator II,
59 int SPAdj, unsigned FIOperandNum,
60 RegScavenger *RS = nullptr) const override;
61 };
62 }
63
64 #endif