Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/ARM/ThumbRegisterInfo.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- ThumbRegisterInfo.cpp - Thumb-1 Register Information -------------===//
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
// This file contains the Thumb-1 implementation of the TargetRegisterInfo
11
// class.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#include "ThumbRegisterInfo.h"
16
#include "ARMBaseInstrInfo.h"
17
#include "ARMMachineFunctionInfo.h"
18
#include "ARMSubtarget.h"
19
#include "MCTargetDesc/ARMAddressingModes.h"
20
#include "llvm/CodeGen/MachineConstantPool.h"
21
#include "llvm/CodeGen/MachineFrameInfo.h"
22
#include "llvm/CodeGen/MachineFunction.h"
23
#include "llvm/CodeGen/MachineInstrBuilder.h"
24
#include "llvm/CodeGen/MachineRegisterInfo.h"
25
#include "llvm/CodeGen/RegisterScavenging.h"
26
#include "llvm/IR/Constants.h"
27
#include "llvm/IR/DerivedTypes.h"
28
#include "llvm/IR/Function.h"
29
#include "llvm/IR/LLVMContext.h"
30
#include "llvm/Support/CommandLine.h"
31
#include "llvm/Support/ErrorHandling.h"
32
#include "llvm/Target/TargetFrameLowering.h"
33
#include "llvm/Target/TargetMachine.h"
34
35
namespace llvm {
36
extern cl::opt<bool> ReuseFrameIndexVals;
37
}
38
39
using namespace llvm;
40
41
3.35k
ThumbRegisterInfo::ThumbRegisterInfo() : ARMBaseRegisterInfo() {}
42
43
const TargetRegisterClass *
44
ThumbRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
45
32.5k
                                              const MachineFunction &MF) const {
46
32.5k
  if (!MF.getSubtarget<ARMSubtarget>().isThumb1Only())
47
28.5k
    return ARMBaseRegisterInfo::getLargestLegalSuperClass(RC, MF);
48
3.94k
49
3.94k
  
if (3.94k
ARM::tGPRRegClass.hasSubClassEq(RC)3.94k
)
50
3.94k
    return &ARM::tGPRRegClass;
51
2
  return ARMBaseRegisterInfo::getLargestLegalSuperClass(RC, MF);
52
2
}
53
54
const TargetRegisterClass *
55
ThumbRegisterInfo::getPointerRegClass(const MachineFunction &MF,
56
261
                                      unsigned Kind) const {
57
261
  if (!MF.getSubtarget<ARMSubtarget>().isThumb1Only())
58
251
    return ARMBaseRegisterInfo::getPointerRegClass(MF, Kind);
59
10
  return &ARM::tGPRRegClass;
60
10
}
61
62
static void emitThumb1LoadConstPool(MachineBasicBlock &MBB,
63
                                    MachineBasicBlock::iterator &MBBI,
64
                                    const DebugLoc &dl, unsigned DestReg,
65
                                    unsigned SubIdx, int Val,
66
                                    ARMCC::CondCodes Pred, unsigned PredReg,
67
81
                                    unsigned MIFlags) {
68
81
  MachineFunction &MF = *MBB.getParent();
69
81
  const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>();
70
81
  const TargetInstrInfo &TII = *STI.getInstrInfo();
71
81
  MachineConstantPool *ConstantPool = MF.getConstantPool();
72
81
  const Constant *C = ConstantInt::get(
73
81
          Type::getInt32Ty(MBB.getParent()->getFunction()->getContext()), Val);
74
81
  unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
75
81
76
81
  BuildMI(MBB, MBBI, dl, TII.get(ARM::tLDRpci))
77
81
    .addReg(DestReg, getDefRegState(true), SubIdx)
78
81
    .addConstantPoolIndex(Idx).addImm(Pred).addReg(PredReg)
79
81
    .setMIFlags(MIFlags);
80
81
}
81
82
static void emitThumb2LoadConstPool(MachineBasicBlock &MBB,
83
                                    MachineBasicBlock::iterator &MBBI,
84
                                    const DebugLoc &dl, unsigned DestReg,
85
                                    unsigned SubIdx, int Val,
86
                                    ARMCC::CondCodes Pred, unsigned PredReg,
87
0
                                    unsigned MIFlags) {
88
0
  MachineFunction &MF = *MBB.getParent();
89
0
  const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
90
0
  MachineConstantPool *ConstantPool = MF.getConstantPool();
91
0
  const Constant *C = ConstantInt::get(
92
0
           Type::getInt32Ty(MBB.getParent()->getFunction()->getContext()), Val);
93
0
  unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
94
0
95
0
  BuildMI(MBB, MBBI, dl, TII.get(ARM::t2LDRpci))
96
0
      .addReg(DestReg, getDefRegState(true), SubIdx)
97
0
      .addConstantPoolIndex(Idx)
98
0
      .add(predOps(ARMCC::AL))
99
0
      .setMIFlags(MIFlags);
100
0
}
101
102
/// emitLoadConstPool - Emits a load from constpool to materialize the
103
/// specified immediate.
104
void ThumbRegisterInfo::emitLoadConstPool(
105
    MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
106
    const DebugLoc &dl, unsigned DestReg, unsigned SubIdx, int Val,
107
81
    ARMCC::CondCodes Pred, unsigned PredReg, unsigned MIFlags) const {
108
81
  MachineFunction &MF = *MBB.getParent();
109
81
  const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>();
110
81
  if (
STI.isThumb1Only()81
) {
111
81
    assert((isARMLowRegister(DestReg) || isVirtualRegister(DestReg)) &&
112
81
           "Thumb1 does not have ldr to high register");
113
81
    return emitThumb1LoadConstPool(MBB, MBBI, dl, DestReg, SubIdx, Val, Pred,
114
81
                                   PredReg, MIFlags);
115
81
  }
116
0
  return emitThumb2LoadConstPool(MBB, MBBI, dl, DestReg, SubIdx, Val, Pred,
117
0
                                 PredReg, MIFlags);
118
0
}
119
120
/// emitThumbRegPlusImmInReg - Emits a series of instructions to materialize
121
/// a destreg = basereg + immediate in Thumb code. Materialize the immediate
122
/// in a register using mov / mvn sequences or load the immediate from a
123
/// constpool entry.
124
static void emitThumbRegPlusImmInReg(
125
    MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
126
    const DebugLoc &dl, unsigned DestReg, unsigned BaseReg, int NumBytes,
127
    bool CanChangeCC, const TargetInstrInfo &TII,
128
85
    const ARMBaseRegisterInfo &MRI, unsigned MIFlags = MachineInstr::NoFlags) {
129
85
  MachineFunction &MF = *MBB.getParent();
130
85
  const ARMSubtarget &ST = MF.getSubtarget<ARMSubtarget>();
131
85
  bool isHigh = !isARMLowRegister(DestReg) ||
132
16
                
(BaseReg != 0 && 16
!isARMLowRegister(BaseReg)16
);
133
85
  bool isSub = false;
134
85
  // Subtract doesn't have high register version. Load the negative value
135
85
  // if either base or dest register is a high register. Also, if do not
136
85
  // issue sub as part of the sequence if condition register is to be
137
85
  // preserved.
138
85
  if (
NumBytes < 0 && 85
!isHigh34
&&
CanChangeCC0
) {
139
0
    isSub = true;
140
0
    NumBytes = -NumBytes;
141
0
  }
142
85
  unsigned LdReg = DestReg;
143
85
  if (DestReg == ARM::SP)
144
85
    assert(BaseReg == ARM::SP && "Unexpected!");
145
85
  if (
!isARMLowRegister(DestReg) && 85
!MRI.isVirtualRegister(DestReg)69
)
146
58
    LdReg = MF.getRegInfo().createVirtualRegister(&ARM::tGPRRegClass);
147
85
148
85
  if (
NumBytes <= 255 && 85
NumBytes >= 034
&&
CanChangeCC0
) {
149
0
    BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg)
150
0
        .add(t1CondCodeOp())
151
0
        .addImm(NumBytes)
152
0
        .setMIFlags(MIFlags);
153
85
  } else 
if (85
NumBytes < 0 && 85
NumBytes >= -25534
&&
CanChangeCC0
) {
154
0
    BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg)
155
0
        .add(t1CondCodeOp())
156
0
        .addImm(NumBytes)
157
0
        .setMIFlags(MIFlags);
158
0
    BuildMI(MBB, MBBI, dl, TII.get(ARM::tRSB), LdReg)
159
0
        .add(t1CondCodeOp())
160
0
        .addReg(LdReg, RegState::Kill)
161
0
        .setMIFlags(MIFlags);
162
85
  } else 
if (85
ST.genExecuteOnly()85
) {
163
4
    BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi32imm), LdReg)
164
4
      .addImm(NumBytes).setMIFlags(MIFlags);
165
4
  } else
166
81
    MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, 0, NumBytes, ARMCC::AL, 0,
167
81
                          MIFlags);
168
85
169
85
  // Emit add / sub.
170
0
  int Opc = (isSub) ? ARM::tSUBrr
171
85
                    : 
((isHigh || 85
!CanChangeCC0
) ?
ARM::tADDhirr85
:
ARM::tADDrr0
);
172
85
  MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg);
173
85
  if (Opc != ARM::tADDhirr)
174
0
    MIB = MIB.add(t1CondCodeOp());
175
85
  if (
DestReg == ARM::SP || 85
isSub27
)
176
58
    MIB.addReg(BaseReg).addReg(LdReg, RegState::Kill);
177
85
  else
178
27
    MIB.addReg(LdReg).addReg(BaseReg, RegState::Kill);
179
85
  MIB.add(predOps(ARMCC::AL));
180
85
}
181
182
/// emitThumbRegPlusImmediate - Emits a series of instructions to materialize
183
/// a destreg = basereg + immediate in Thumb code. Tries a series of ADDs or
184
/// SUBs first, and uses a constant pool value if the instruction sequence would
185
/// be too long. This is allowed to modify the condition flags.
186
void llvm::emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
187
                                     MachineBasicBlock::iterator &MBBI,
188
                                     const DebugLoc &dl, unsigned DestReg,
189
                                     unsigned BaseReg, int NumBytes,
190
                                     const TargetInstrInfo &TII,
191
                                     const ARMBaseRegisterInfo &MRI,
192
1.44k
                                     unsigned MIFlags) {
193
1.44k
  bool isSub = NumBytes < 0;
194
1.44k
  unsigned Bytes = (unsigned)NumBytes;
195
1.44k
  if (
isSub1.44k
)
Bytes = -NumBytes388
;
196
1.44k
197
1.44k
  int CopyOpc = 0;
198
1.44k
  unsigned CopyBits = 0;
199
1.44k
  unsigned CopyScale = 1;
200
1.44k
  bool CopyNeedsCC = false;
201
1.44k
  int ExtraOpc = 0;
202
1.44k
  unsigned ExtraBits = 0;
203
1.44k
  unsigned ExtraScale = 1;
204
1.44k
  bool ExtraNeedsCC = false;
205
1.44k
206
1.44k
  // Strategy:
207
1.44k
  // We need to select two types of instruction, maximizing the available
208
1.44k
  // immediate range of each. The instructions we use will depend on whether
209
1.44k
  // DestReg and BaseReg are low, high or the stack pointer.
210
1.44k
  // * CopyOpc  - DestReg = BaseReg + imm
211
1.44k
  //              This will be emitted once if DestReg != BaseReg, and never if
212
1.44k
  //              DestReg == BaseReg.
213
1.44k
  // * ExtraOpc - DestReg = DestReg + imm
214
1.44k
  //              This will be emitted as many times as necessary to add the
215
1.44k
  //              full immediate.
216
1.44k
  // If the immediate ranges of these instructions are not large enough to cover
217
1.44k
  // NumBytes with a reasonable number of instructions, we fall back to using a
218
1.44k
  // value loaded from a constant pool.
219
1.44k
  if (
DestReg == ARM::SP1.44k
) {
220
1.13k
    if (
BaseReg == ARM::SP1.13k
) {
221
1.13k
      // sp -> sp
222
1.13k
      // Already in right reg, no copy needed
223
1.13k
    } else {
224
0
      // low -> sp or high -> sp
225
0
      CopyOpc = ARM::tMOVr;
226
0
      CopyBits = 0;
227
0
    }
228
1.13k
    ExtraOpc = isSub ? 
ARM::tSUBspi350
:
ARM::tADDspi780
;
229
1.13k
    ExtraBits = 7;
230
1.13k
    ExtraScale = 4;
231
1.44k
  } else 
if (316
isARMLowRegister(DestReg)316
) {
232
316
    if (
BaseReg == ARM::SP316
) {
233
275
      // sp -> low
234
275
      assert(!isSub && "Thumb1 does not have tSUBrSPi");
235
275
      CopyOpc = ARM::tADDrSPi;
236
275
      CopyBits = 8;
237
275
      CopyScale = 4;
238
316
    } else 
if (41
DestReg == BaseReg41
) {
239
0
      // low -> same low
240
0
      // Already in right reg, no copy needed
241
41
    } else 
if (41
isARMLowRegister(BaseReg)41
) {
242
41
      // low -> different low
243
41
      CopyOpc = isSub ? 
ARM::tSUBi338
:
ARM::tADDi33
;
244
41
      CopyBits = 3;
245
41
      CopyNeedsCC = true;
246
0
    } else {
247
0
      // high -> low
248
0
      CopyOpc = ARM::tMOVr;
249
0
      CopyBits = 0;
250
0
    }
251
316
    ExtraOpc = isSub ? 
ARM::tSUBi838
:
ARM::tADDi8278
;
252
316
    ExtraBits = 8;
253
316
    ExtraNeedsCC = true;
254
0
  } else /* DestReg is high */ {
255
0
    if (
DestReg == BaseReg0
) {
256
0
      // high -> same high
257
0
      // Already in right reg, no copy needed
258
0
    } else {
259
0
      // {low,high,sp} -> high
260
0
      CopyOpc = ARM::tMOVr;
261
0
      CopyBits = 0;
262
0
    }
263
316
    ExtraOpc = 0;
264
316
  }
265
1.44k
266
1.44k
  // We could handle an unaligned immediate with an unaligned copy instruction
267
1.44k
  // and an aligned extra instruction, but this case is not currently needed.
268
1.44k
  assert(((Bytes & 3) == 0 || ExtraScale == 1) &&
269
1.44k
         "Unaligned offset, but all instructions require alignment");
270
1.44k
271
1.44k
  unsigned CopyRange = ((1 << CopyBits) - 1) * CopyScale;
272
1.44k
  // If we would emit the copy with an immediate of 0, just use tMOVr.
273
1.44k
  if (
CopyOpc && 1.44k
Bytes < CopyScale316
) {
274
49
    CopyOpc = ARM::tMOVr;
275
49
    CopyScale = 1;
276
49
    CopyNeedsCC = false;
277
49
    CopyRange = 0;
278
49
  }
279
1.44k
  unsigned ExtraRange = ((1 << ExtraBits) - 1) * ExtraScale; // per instruction
280
1.44k
  unsigned RequiredCopyInstrs = CopyOpc ? 
1316
:
01.13k
;
281
1.44k
  unsigned RangeAfterCopy = (CopyRange > Bytes) ? 
0215
:
(Bytes - CopyRange)1.23k
;
282
1.44k
283
1.44k
  // We could handle this case when the copy instruction does not require an
284
1.44k
  // aligned immediate, but we do not currently do this.
285
1.44k
  assert(RangeAfterCopy % ExtraScale == 0 &&
286
1.44k
         "Extra instruction requires immediate to be aligned");
287
1.44k
288
1.44k
  unsigned RequiredExtraInstrs;
289
1.44k
  if (ExtraRange)
290
1.44k
    RequiredExtraInstrs = alignTo(RangeAfterCopy, ExtraRange) / ExtraRange;
291
0
  else 
if (0
RangeAfterCopy > 00
)
292
0
    // We need an extra instruction but none is available
293
0
    RequiredExtraInstrs = 1000000;
294
0
  else
295
0
    RequiredExtraInstrs = 0;
296
1.44k
  unsigned RequiredInstrs = RequiredCopyInstrs + RequiredExtraInstrs;
297
1.44k
  unsigned Threshold = (DestReg == ARM::SP) ? 
31.13k
:
2316
;
298
1.44k
299
1.44k
  // Use a constant pool, if the sequence of ADDs/SUBs is too expensive.
300
1.44k
  if (
RequiredInstrs > Threshold1.44k
) {
301
61
    emitThumbRegPlusImmInReg(MBB, MBBI, dl,
302
61
                             DestReg, BaseReg, NumBytes, true,
303
61
                             TII, MRI, MIFlags);
304
61
    return;
305
61
  }
306
1.38k
307
1.38k
  // Emit zero or one copy instructions
308
1.38k
  
if (1.38k
CopyOpc1.38k
) {
309
313
    unsigned CopyImm = std::min(Bytes, CopyRange) / CopyScale;
310
313
    Bytes -= CopyImm * CopyScale;
311
313
312
313
    MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(CopyOpc), DestReg);
313
313
    if (CopyNeedsCC)
314
38
      MIB = MIB.add(t1CondCodeOp());
315
313
    MIB.addReg(BaseReg, RegState::Kill);
316
313
    if (
CopyOpc != ARM::tMOVr313
) {
317
264
      MIB.addImm(CopyImm);
318
264
    }
319
313
    MIB.setMIFlags(MIFlags).add(predOps(ARMCC::AL));
320
313
321
313
    BaseReg = DestReg;
322
313
  }
323
1.38k
324
1.38k
  // Emit zero or more in-place add/sub instructions
325
2.28k
  while (
Bytes2.28k
) {
326
897
    unsigned ExtraImm = std::min(Bytes, ExtraRange) / ExtraScale;
327
897
    Bytes -= ExtraImm * ExtraScale;
328
897
329
897
    MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(ExtraOpc), DestReg);
330
897
    if (ExtraNeedsCC)
331
46
      MIB = MIB.add(t1CondCodeOp());
332
897
    MIB.addReg(BaseReg)
333
897
       .addImm(ExtraImm)
334
897
       .add(predOps(ARMCC::AL))
335
897
       .setMIFlags(MIFlags);
336
897
  }
337
1.44k
}
338
339
24
static void removeOperands(MachineInstr &MI, unsigned i) {
340
24
  unsigned Op = i;
341
72
  for (unsigned e = MI.getNumOperands(); 
i != e72
;
++i48
)
342
48
    MI.RemoveOperand(Op);
343
24
}
344
345
/// convertToNonSPOpcode - Change the opcode to the non-SP version, because
346
/// we're replacing the frame index with a non-SP register.
347
3.56k
static unsigned convertToNonSPOpcode(unsigned Opcode) {
348
3.56k
  switch (Opcode) {
349
2.32k
  case ARM::tLDRspi:
350
2.32k
    return ARM::tLDRi;
351
3.56k
352
1.23k
  case ARM::tSTRspi:
353
1.23k
    return ARM::tSTRi;
354
0
  }
355
0
356
0
  return Opcode;
357
0
}
358
359
bool ThumbRegisterInfo::rewriteFrameIndex(MachineBasicBlock::iterator II,
360
                                          unsigned FrameRegIdx,
361
                                          unsigned FrameReg, int &Offset,
362
3.86k
                                          const ARMBaseInstrInfo &TII) const {
363
3.86k
  MachineInstr &MI = *II;
364
3.86k
  MachineBasicBlock &MBB = *MI.getParent();
365
3.86k
  assert(MBB.getParent()->getSubtarget<ARMSubtarget>().isThumb1Only() &&
366
3.86k
         "This isn't needed for thumb2!");
367
3.86k
  DebugLoc dl = MI.getDebugLoc();
368
3.86k
  MachineInstrBuilder MIB(*MBB.getParent(), &MI);
369
3.86k
  unsigned Opcode = MI.getOpcode();
370
3.86k
  const MCInstrDesc &Desc = MI.getDesc();
371
3.86k
  unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
372
3.86k
373
3.86k
  if (
Opcode == ARM::tADDframe3.86k
) {
374
278
    Offset += MI.getOperand(FrameRegIdx+1).getImm();
375
278
    unsigned DestReg = MI.getOperand(0).getReg();
376
278
377
278
    emitThumbRegPlusImmediate(MBB, II, dl, DestReg, FrameReg, Offset, TII,
378
278
                              *this);
379
278
    MBB.erase(II);
380
278
    return true;
381
0
  } else {
382
3.58k
    if (AddrMode != ARMII::AddrModeT1_s)
383
0
      llvm_unreachable("Unsupported addressing mode!");
384
3.58k
385
3.58k
    unsigned ImmIdx = FrameRegIdx + 1;
386
3.58k
    int InstrOffs = MI.getOperand(ImmIdx).getImm();
387
3.58k
    unsigned NumBits = (FrameReg == ARM::SP) ? 
83.55k
:
535
;
388
3.58k
    unsigned Scale = 4;
389
3.58k
390
3.58k
    Offset += InstrOffs * Scale;
391
3.58k
    assert((Offset & (Scale - 1)) == 0 && "Can't encode this offset!");
392
3.58k
393
3.58k
    // Common case: small offset, fits into instruction.
394
3.58k
    MachineOperand &ImmOp = MI.getOperand(ImmIdx);
395
3.58k
    int ImmedOffset = Offset / Scale;
396
3.58k
    unsigned Mask = (1 << NumBits) - 1;
397
3.58k
398
3.58k
    if (
(unsigned)Offset <= Mask * Scale3.58k
) {
399
3.56k
      // Replace the FrameIndex with the frame register (e.g., sp).
400
3.56k
      MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
401
3.56k
      ImmOp.ChangeToImmediate(ImmedOffset);
402
3.56k
403
3.56k
      // If we're using a register where sp was stored, convert the instruction
404
3.56k
      // to the non-SP version.
405
3.56k
      unsigned NewOpc = convertToNonSPOpcode(Opcode);
406
3.56k
      if (
NewOpc != Opcode && 3.56k
FrameReg != ARM::SP3.56k
)
407
35
        MI.setDesc(TII.get(NewOpc));
408
3.56k
409
3.56k
      return true;
410
3.56k
    }
411
24
412
24
    NumBits = 5;
413
24
    Mask = (1 << NumBits) - 1;
414
24
415
24
    // If this is a thumb spill / restore, we will be using a constpool load to
416
24
    // materialize the offset.
417
24
    if (
Opcode == ARM::tLDRspi || 24
Opcode == ARM::tSTRspi11
) {
418
24
      ImmOp.ChangeToImmediate(0);
419
24
    } else {
420
0
      // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
421
0
      ImmedOffset = ImmedOffset & Mask;
422
0
      ImmOp.ChangeToImmediate(ImmedOffset);
423
0
      Offset &= ~(Mask * Scale);
424
0
    }
425
3.58k
  }
426
3.86k
427
24
  return Offset == 0;
428
3.86k
}
429
430
void ThumbRegisterInfo::resolveFrameIndex(MachineInstr &MI, unsigned BaseReg,
431
25
                                           int64_t Offset) const {
432
25
  const MachineFunction &MF = *MI.getParent()->getParent();
433
25
  const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>();
434
25
  if (!STI.isThumb1Only())
435
15
    return ARMBaseRegisterInfo::resolveFrameIndex(MI, BaseReg, Offset);
436
10
437
10
  const ARMBaseInstrInfo &TII = *STI.getInstrInfo();
438
10
  int Off = Offset; // ARM doesn't need the general 64-bit offsets
439
10
  unsigned i = 0;
440
10
441
20
  while (
!MI.getOperand(i).isFI()20
) {
442
10
    ++i;
443
10
    assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
444
10
  }
445
25
  bool Done = rewriteFrameIndex(MI, i, BaseReg, Off, TII);
446
25
  assert (Done && "Unable to resolve frame index!");
447
25
  (void)Done;
448
25
}
449
450
/// saveScavengerRegister - Spill the register so it can be used by the
451
/// register scavenger. Return true.
452
bool ThumbRegisterInfo::saveScavengerRegister(
453
    MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
454
    MachineBasicBlock::iterator &UseMI, const TargetRegisterClass *RC,
455
3
    unsigned Reg) const {
456
3
457
3
  const ARMSubtarget &STI = MBB.getParent()->getSubtarget<ARMSubtarget>();
458
3
  if (!STI.isThumb1Only())
459
1
    return ARMBaseRegisterInfo::saveScavengerRegister(MBB, I, UseMI, RC, Reg);
460
2
461
2
  // Thumb1 can't use the emergency spill slot on the stack because
462
2
  // ldr/str immediate offsets must be positive, and if we're referencing
463
2
  // off the frame pointer (if, for example, there are alloca() calls in
464
2
  // the function, the offset will be negative. Use R12 instead since that's
465
2
  // a call clobbered register that we know won't be used in Thumb1 mode.
466
2
  const TargetInstrInfo &TII = *STI.getInstrInfo();
467
2
  DebugLoc DL;
468
2
  BuildMI(MBB, I, DL, TII.get(ARM::tMOVr))
469
2
      .addReg(ARM::R12, RegState::Define)
470
2
      .addReg(Reg, RegState::Kill)
471
2
      .add(predOps(ARMCC::AL));
472
2
473
2
  // The UseMI is where we would like to restore the register. If there's
474
2
  // interference with R12 before then, however, we'll need to restore it
475
2
  // before that instead and adjust the UseMI.
476
2
  bool done = false;
477
26
  for (MachineBasicBlock::iterator II = I; 
!done && 26
II != UseMI26
;
++II24
) {
478
24
    if (II->isDebugValue())
479
0
      continue;
480
24
    // If this instruction affects R12, adjust our restore point.
481
112
    
for (unsigned i = 0, e = II->getNumOperands(); 24
i != e112
;
++i88
) {
482
88
      const MachineOperand &MO = II->getOperand(i);
483
88
      if (
MO.isRegMask() && 88
MO.clobbersPhysReg(ARM::R12)0
) {
484
0
        UseMI = II;
485
0
        done = true;
486
0
        break;
487
0
      }
488
88
      
if (88
!MO.isReg() || 88
MO.isUndef()64
||
!MO.getReg()64
||
489
48
          TargetRegisterInfo::isVirtualRegister(MO.getReg()))
490
72
        continue;
491
16
      
if (16
MO.getReg() == ARM::R1216
) {
492
0
        UseMI = II;
493
0
        done = true;
494
0
        break;
495
0
      }
496
88
    }
497
24
  }
498
3
  // Restore the register from R12
499
3
  BuildMI(MBB, UseMI, DL, TII.get(ARM::tMOVr))
500
3
      .addReg(Reg, RegState::Define)
501
3
      .addReg(ARM::R12, RegState::Kill)
502
3
      .add(predOps(ARMCC::AL));
503
3
504
3
  return true;
505
3
}
506
507
void ThumbRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
508
                                            int SPAdj, unsigned FIOperandNum,
509
18.9k
                                            RegScavenger *RS) const {
510
18.9k
  MachineInstr &MI = *II;
511
18.9k
  MachineBasicBlock &MBB = *MI.getParent();
512
18.9k
  MachineFunction &MF = *MBB.getParent();
513
18.9k
  const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>();
514
18.9k
  if (!STI.isThumb1Only())
515
15.1k
    return ARMBaseRegisterInfo::eliminateFrameIndex(II, SPAdj, FIOperandNum,
516
15.1k
                                                    RS);
517
3.85k
518
3.85k
  unsigned VReg = 0;
519
3.85k
  const ARMBaseInstrInfo &TII = *STI.getInstrInfo();
520
3.85k
  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
521
3.85k
  DebugLoc dl = MI.getDebugLoc();
522
3.85k
  MachineInstrBuilder MIB(*MBB.getParent(), &MI);
523
3.85k
524
3.85k
  unsigned FrameReg = ARM::SP;
525
3.85k
  int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
526
3.85k
  int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex) +
527
3.85k
               MF.getFrameInfo().getStackSize() + SPAdj;
528
3.85k
529
3.85k
  if (
MF.getFrameInfo().hasVarSizedObjects()3.85k
) {
530
28
    assert(SPAdj == 0 && STI.getFrameLowering()->hasFP(MF) && "Unexpected");
531
28
    // There are alloca()'s in this function, must reference off the frame
532
28
    // pointer or base pointer instead.
533
28
    if (
!hasBasePointer(MF)28
) {
534
0
      FrameReg = getFrameRegister(MF);
535
0
      Offset -= AFI->getFramePtrSpillOffset();
536
0
    } else
537
28
      FrameReg = BasePtr;
538
28
  }
539
3.85k
540
3.85k
  // PEI::scavengeFrameVirtualRegs() cannot accurately track SPAdj because the
541
3.85k
  // call frame setup/destroy instructions have already been eliminated.  That
542
3.85k
  // means the stack pointer cannot be used to access the emergency spill slot
543
3.85k
  // when !hasReservedCallFrame().
544
#ifndef NDEBUG
545
  if (RS && FrameReg == ARM::SP && RS->isScavengingFrameIndex(FrameIndex)){
546
    assert(STI.getFrameLowering()->hasReservedCallFrame(MF) &&
547
           "Cannot use SP to access the emergency spill slot in "
548
           "functions without a reserved call frame");
549
    assert(!MF.getFrameInfo().hasVarSizedObjects() &&
550
           "Cannot use SP to access the emergency spill slot in "
551
           "functions with variable sized frame objects");
552
  }
553
#endif // NDEBUG
554
555
3.85k
  // Special handling of dbg_value instructions.
556
3.85k
  if (
MI.isDebugValue()3.85k
) {
557
0
    MI.getOperand(FIOperandNum).  ChangeToRegister(FrameReg, false /*isDef*/);
558
0
    MI.getOperand(FIOperandNum+1).ChangeToImmediate(Offset);
559
0
    return;
560
0
  }
561
3.85k
562
3.85k
  // Modify MI as necessary to handle as much of 'Offset' as possible
563
3.85k
  assert(AFI->isThumbFunction() &&
564
3.85k
         "This eliminateFrameIndex only supports Thumb1!");
565
3.85k
  if (rewriteFrameIndex(MI, FIOperandNum, FrameReg, Offset, TII))
566
3.83k
    return;
567
24
568
24
  // If we get here, the immediate doesn't fit into the instruction.  We folded
569
24
  // as much as possible above, handle the rest, providing a register that is
570
24
  // SP+LargeImm.
571
3.85k
  assert(Offset && "This code isn't needed if offset already handled!");
572
24
573
24
  unsigned Opcode = MI.getOpcode();
574
24
575
24
  // Remove predicate first.
576
24
  int PIdx = MI.findFirstPredOperandIdx();
577
24
  if (PIdx != -1)
578
24
    removeOperands(MI, PIdx);
579
24
580
24
  if (
MI.mayLoad()24
) {
581
13
    // Use the destination register to materialize sp + offset.
582
13
    unsigned TmpReg = MI.getOperand(0).getReg();
583
13
    bool UseRR = false;
584
13
    if (
Opcode == ARM::tLDRspi13
) {
585
13
      if (
FrameReg == ARM::SP || 13
STI.genExecuteOnly()0
)
586
13
        emitThumbRegPlusImmInReg(MBB, II, dl, TmpReg, FrameReg,
587
13
                                 Offset, false, TII, *this);
588
0
      else {
589
0
        emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset);
590
0
        UseRR = true;
591
0
      }
592
0
    } else {
593
0
      emitThumbRegPlusImmediate(MBB, II, dl, TmpReg, FrameReg, Offset, TII,
594
0
                                *this);
595
0
    }
596
13
597
13
    MI.setDesc(TII.get(UseRR ? 
ARM::tLDRr0
:
ARM::tLDRi13
));
598
13
    MI.getOperand(FIOperandNum).ChangeToRegister(TmpReg, false, false, true);
599
13
    if (UseRR)
600
13
      // Use [reg, reg] addrmode. Replace the immediate operand w/ the frame
601
13
      // register. The offset is already handled in the vreg value.
602
0
      MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg, false, false,
603
0
                                                     false);
604
24
  } else 
if (11
MI.mayStore()11
) {
605
11
      VReg = MF.getRegInfo().createVirtualRegister(&ARM::tGPRRegClass);
606
11
      bool UseRR = false;
607
11
608
11
      if (
Opcode == ARM::tSTRspi11
) {
609
11
        if (
FrameReg == ARM::SP || 11
STI.genExecuteOnly()0
)
610
11
          emitThumbRegPlusImmInReg(MBB, II, dl, VReg, FrameReg,
611
11
                                   Offset, false, TII, *this);
612
0
        else {
613
0
          emitLoadConstPool(MBB, II, dl, VReg, 0, Offset);
614
0
          UseRR = true;
615
0
        }
616
11
      } else
617
0
        emitThumbRegPlusImmediate(MBB, II, dl, VReg, FrameReg, Offset, TII,
618
0
                                  *this);
619
11
      MI.setDesc(TII.get(UseRR ? 
ARM::tSTRr0
:
ARM::tSTRi11
));
620
11
      MI.getOperand(FIOperandNum).ChangeToRegister(VReg, false, false, true);
621
11
      if (UseRR)
622
11
        // Use [reg, reg] addrmode. Replace the immediate operand w/ the frame
623
11
        // register. The offset is already handled in the vreg value.
624
0
        MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg, false, false,
625
0
                                                       false);
626
0
  } else {
627
0
    llvm_unreachable("Unexpected opcode!");
628
11
  }
629
24
630
24
  // Add predicate back if it's needed.
631
24
  
if (24
MI.isPredicable()24
)
632
24
    MIB.add(predOps(ARMCC::AL));
633
18.9k
}