Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/X86/X86ExpandPseudo.cpp
Line
Count
Source (jump to first uncovered line)
1
//===------- X86ExpandPseudo.cpp - Expand pseudo instructions -------------===//
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 a pass that expands pseudo instructions into target
11
// instructions to allow proper scheduling, if-conversion, other late
12
// optimizations, or simply the encoding of the instructions.
13
//
14
//===----------------------------------------------------------------------===//
15
16
#include "X86.h"
17
#include "X86FrameLowering.h"
18
#include "X86InstrBuilder.h"
19
#include "X86InstrInfo.h"
20
#include "X86MachineFunctionInfo.h"
21
#include "X86Subtarget.h"
22
#include "llvm/Analysis/EHPersonalities.h"
23
#include "llvm/CodeGen/MachineFunctionPass.h"
24
#include "llvm/CodeGen/MachineInstrBuilder.h"
25
#include "llvm/CodeGen/Passes.h" // For IDs of passes that are preserved.
26
#include "llvm/IR/GlobalValue.h"
27
using namespace llvm;
28
29
#define DEBUG_TYPE "x86-pseudo"
30
31
namespace {
32
class X86ExpandPseudo : public MachineFunctionPass {
33
public:
34
  static char ID;
35
8.54k
  X86ExpandPseudo() : MachineFunctionPass(ID) {}
36
37
8.52k
  void getAnalysisUsage(AnalysisUsage &AU) const override {
38
8.52k
    AU.setPreservesCFG();
39
8.52k
    AU.addPreservedID(MachineLoopInfoID);
40
8.52k
    AU.addPreservedID(MachineDominatorsID);
41
8.52k
    MachineFunctionPass::getAnalysisUsage(AU);
42
8.52k
  }
43
44
  const X86Subtarget *STI;
45
  const X86InstrInfo *TII;
46
  const X86RegisterInfo *TRI;
47
  const X86MachineFunctionInfo *X86FI;
48
  const X86FrameLowering *X86FL;
49
50
  bool runOnMachineFunction(MachineFunction &Fn) override;
51
52
8.52k
  MachineFunctionProperties getRequiredProperties() const override {
53
8.52k
    return MachineFunctionProperties().set(
54
8.52k
        MachineFunctionProperties::Property::NoVRegs);
55
8.52k
  }
56
57
8.52k
  StringRef getPassName() const override {
58
8.52k
    return "X86 pseudo instruction expansion pass";
59
8.52k
  }
60
61
private:
62
  bool ExpandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI);
63
  bool ExpandMBB(MachineBasicBlock &MBB);
64
};
65
char X86ExpandPseudo::ID = 0;
66
} // End anonymous namespace.
67
68
/// If \p MBBI is a pseudo instruction, this method expands
69
/// it to the corresponding (sequence of) actual instruction(s).
70
/// \returns true if \p MBBI has been expanded.
71
bool X86ExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
72
889k
                               MachineBasicBlock::iterator MBBI) {
73
889k
  MachineInstr &MI = *MBBI;
74
889k
  unsigned Opcode = MI.getOpcode();
75
889k
  DebugLoc DL = MBBI->getDebugLoc();
76
889k
  switch (Opcode) {
77
820k
  default:
78
820k
    return false;
79
1.88k
  case X86::TCRETURNdi:
80
1.88k
  case X86::TCRETURNdicc:
81
1.88k
  case X86::TCRETURNri:
82
1.88k
  case X86::TCRETURNmi:
83
1.88k
  case X86::TCRETURNdi64:
84
1.88k
  case X86::TCRETURNdi64cc:
85
1.88k
  case X86::TCRETURNri64:
86
1.88k
  case X86::TCRETURNmi64: {
87
1.88k
    bool isMem = Opcode == X86::TCRETURNmi || Opcode == X86::TCRETURNmi64;
88
1.88k
    MachineOperand &JumpTarget = MBBI->getOperand(0);
89
1.88k
    MachineOperand &StackAdjust = MBBI->getOperand(isMem ? 
545
:
11.84k
);
90
1.88k
    assert(StackAdjust.isImm() && "Expecting immediate value.");
91
1.88k
92
1.88k
    // Adjust stack pointer.
93
1.88k
    int StackAdj = StackAdjust.getImm();
94
1.88k
    int MaxTCDelta = X86FI->getTCReturnAddrDelta();
95
1.88k
    int Offset = 0;
96
1.88k
    assert(MaxTCDelta <= 0 && "MaxTCDelta should never be positive");
97
1.88k
98
1.88k
    // Incoporate the retaddr area.
99
1.88k
    Offset = StackAdj - MaxTCDelta;
100
1.88k
    assert(Offset >= 0 && "Offset should never be negative");
101
1.88k
102
1.88k
    if (
Opcode == X86::TCRETURNdicc || 1.88k
Opcode == X86::TCRETURNdi64cc1.88k
) {
103
26
      assert(Offset == 0 && "Conditional tail call cannot adjust the stack.");
104
26
    }
105
1.88k
106
1.88k
    if (
Offset1.88k
) {
107
1
      // Check for possible merge with preceding ADD instruction.
108
1
      Offset += X86FL->mergeSPUpdates(MBB, MBBI, true);
109
1
      X86FL->emitSPUpdate(MBB, MBBI, Offset, /*InEpilogue=*/true);
110
1
    }
111
1.88k
112
1.88k
    // Jump to label or value in register.
113
1.88k
    bool IsWin64 = STI->isTargetWin64();
114
1.88k
    if (
Opcode == X86::TCRETURNdi || 1.88k
Opcode == X86::TCRETURNdicc1.56k
||
115
1.88k
        
Opcode == X86::TCRETURNdi641.56k
||
Opcode == X86::TCRETURNdi64cc263
) {
116
1.65k
      unsigned Op;
117
1.65k
      switch (Opcode) {
118
326
      case X86::TCRETURNdi:
119
326
        Op = X86::TAILJMPd;
120
326
        break;
121
2
      case X86::TCRETURNdicc:
122
2
        Op = X86::TAILJMPd_CC;
123
2
        break;
124
24
      case X86::TCRETURNdi64cc:
125
24
        assert(!MBB.getParent()->hasWinCFI() &&
126
24
               "Conditional tail calls confuse "
127
24
               "the Win64 unwinder.");
128
24
        Op = X86::TAILJMPd64_CC;
129
24
        break;
130
1.29k
      default:
131
1.29k
        // Note: Win64 uses REX prefixes indirect jumps out of functions, but
132
1.29k
        // not direct ones.
133
1.29k
        Op = X86::TAILJMPd64;
134
1.29k
        break;
135
1.65k
      }
136
1.65k
      MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(Op));
137
1.65k
      if (
JumpTarget.isGlobal()1.65k
) {
138
1.57k
        MIB.addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(),
139
1.57k
                             JumpTarget.getTargetFlags());
140
1.65k
      } else {
141
73
        assert(JumpTarget.isSymbol());
142
73
        MIB.addExternalSymbol(JumpTarget.getSymbolName(),
143
73
                              JumpTarget.getTargetFlags());
144
73
      }
145
1.65k
      if (
Op == X86::TAILJMPd_CC || 1.65k
Op == X86::TAILJMPd64_CC1.64k
) {
146
26
        MIB.addImm(MBBI->getOperand(2).getImm());
147
26
      }
148
1.65k
149
1.88k
    } else 
if (239
Opcode == X86::TCRETURNmi || 239
Opcode == X86::TCRETURNmi64232
) {
150
45
      unsigned Op = (Opcode == X86::TCRETURNmi)
151
7
                        ? X86::TAILJMPm
152
38
                        : 
(IsWin64 ? 38
X86::TAILJMPm64_REX3
:
X86::TAILJMPm6435
);
153
45
      MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(Op));
154
270
      for (unsigned i = 0; 
i != 5270
;
++i225
)
155
225
        MIB.add(MBBI->getOperand(i));
156
239
    } else 
if (194
Opcode == X86::TCRETURNri64194
) {
157
115
      BuildMI(MBB, MBBI, DL,
158
115
              TII->get(IsWin64 ? 
X86::TAILJMPr64_REX6
:
X86::TAILJMPr64109
))
159
115
          .addReg(JumpTarget.getReg(), RegState::Kill);
160
194
    } else {
161
79
      BuildMI(MBB, MBBI, DL, TII->get(X86::TAILJMPr))
162
79
          .addReg(JumpTarget.getReg(), RegState::Kill);
163
79
    }
164
1.88k
165
1.88k
    MachineInstr &NewMI = *std::prev(MBBI);
166
1.88k
    NewMI.copyImplicitOps(*MBBI->getParent()->getParent(), *MBBI);
167
1.88k
168
1.88k
    // Delete the pseudo instruction TCRETURN.
169
1.88k
    MBB.erase(MBBI);
170
1.88k
171
1.88k
    return true;
172
1.88k
  }
173
6
  case X86::EH_RETURN:
174
6
  case X86::EH_RETURN64: {
175
6
    MachineOperand &DestAddr = MBBI->getOperand(0);
176
6
    assert(DestAddr.isReg() && "Offset should be in register!");
177
6
    const bool Uses64BitFramePtr =
178
2
        STI->isTarget64BitLP64() || STI->isTargetNaCl64();
179
6
    unsigned StackPtr = TRI->getStackRegister();
180
6
    BuildMI(MBB, MBBI, DL,
181
6
            TII->get(Uses64BitFramePtr ? 
X86::MOV64rr4
:
X86::MOV32rr2
), StackPtr)
182
6
        .addReg(DestAddr.getReg());
183
6
    // The EH_RETURN pseudo is really removed during the MC Lowering.
184
6
    return true;
185
6
  }
186
25
  case X86::IRET: {
187
25
    // Adjust stack to erase error code
188
25
    int64_t StackAdj = MBBI->getOperand(0).getImm();
189
25
    X86FL->emitSPUpdate(MBB, MBBI, StackAdj, true);
190
25
    // Replace pseudo with machine iret
191
25
    BuildMI(MBB, MBBI, DL,
192
25
            TII->get(STI->is64Bit() ? 
X86::IRET6414
:
X86::IRET3211
));
193
25
    MBB.erase(MBBI);
194
25
    return true;
195
6
  }
196
67.4k
  case X86::RET: {
197
67.4k
    // Adjust stack to erase error code
198
67.4k
    int64_t StackAdj = MBBI->getOperand(0).getImm();
199
67.4k
    MachineInstrBuilder MIB;
200
67.4k
    if (
StackAdj == 067.4k
) {
201
67.0k
      MIB = BuildMI(MBB, MBBI, DL,
202
67.0k
                    TII->get(STI->is64Bit() ? 
X86::RETQ54.9k
:
X86::RETL12.1k
));
203
67.4k
    } else 
if (385
isUInt<16>(StackAdj)385
) {
204
381
      MIB = BuildMI(MBB, MBBI, DL,
205
381
                    TII->get(STI->is64Bit() ? 
X86::RETIQ1
:
X86::RETIL380
))
206
381
                .addImm(StackAdj);
207
385
    } else {
208
4
      assert(!STI->is64Bit() &&
209
4
             "shouldn't need to do this for x86_64 targets!");
210
4
      // A ret can only handle immediates as big as 2**16-1.  If we need to pop
211
4
      // off bytes before the return address, we must do it manually.
212
4
      BuildMI(MBB, MBBI, DL, TII->get(X86::POP32r)).addReg(X86::ECX, RegState::Define);
213
4
      X86FL->emitSPUpdate(MBB, MBBI, StackAdj, /*InEpilogue=*/true);
214
4
      BuildMI(MBB, MBBI, DL, TII->get(X86::PUSH32r)).addReg(X86::ECX);
215
4
      MIB = BuildMI(MBB, MBBI, DL, TII->get(X86::RETL));
216
4
    }
217
127k
    for (unsigned I = 1, E = MBBI->getNumOperands(); 
I != E127k
;
++I60.2k
)
218
60.2k
      MIB.add(MBBI->getOperand(I));
219
67.4k
    MBB.erase(MBBI);
220
67.4k
    return true;
221
6
  }
222
34
  case X86::EH_RESTORE: {
223
34
    // Restore ESP and EBP, and optionally ESI if required.
224
34
    bool IsSEH = isAsynchronousEHPersonality(classifyEHPersonality(
225
34
        MBB.getParent()->getFunction()->getPersonalityFn()));
226
34
    X86FL->restoreWin32EHStackPointers(MBB, MBBI, DL, /*RestoreSP=*/IsSEH);
227
34
    MBBI->eraseFromParent();
228
34
    return true;
229
6
  }
230
2
  case X86::LCMPXCHG8B_SAVE_EBX:
231
2
  case X86::LCMPXCHG16B_SAVE_RBX: {
232
2
    // Perform the following transformation.
233
2
    // SaveRbx = pseudocmpxchg Addr, <4 opds for the address>, InArg, SaveRbx
234
2
    // =>
235
2
    // [E|R]BX = InArg
236
2
    // actualcmpxchg Addr
237
2
    // [E|R]BX = SaveRbx
238
2
    const MachineOperand &InArg = MBBI->getOperand(6);
239
2
    unsigned SaveRbx = MBBI->getOperand(7).getReg();
240
2
241
2
    unsigned ActualInArg =
242
2
        Opcode == X86::LCMPXCHG8B_SAVE_EBX ? 
X86::EBX0
:
X86::RBX2
;
243
2
    // Copy the input argument of the pseudo into the argument of the
244
2
    // actual instruction.
245
2
    TII->copyPhysReg(MBB, MBBI, DL, ActualInArg, InArg.getReg(),
246
2
                     InArg.isKill());
247
2
    // Create the actual instruction.
248
2
    unsigned ActualOpc =
249
2
        Opcode == X86::LCMPXCHG8B_SAVE_EBX ? 
X86::LCMPXCHG8B0
:
X86::LCMPXCHG16B2
;
250
2
    MachineInstr *NewInstr = BuildMI(MBB, MBBI, DL, TII->get(ActualOpc));
251
2
    // Copy the operands related to the address.
252
12
    for (unsigned Idx = 1; 
Idx < 612
;
++Idx10
)
253
10
      NewInstr->addOperand(MBBI->getOperand(Idx));
254
2
    // Finally, restore the value of RBX.
255
2
    TII->copyPhysReg(MBB, MBBI, DL, ActualInArg, SaveRbx,
256
2
                     /*SrcIsKill*/ true);
257
2
258
2
    // Delete the pseudo.
259
2
    MBBI->eraseFromParent();
260
2
    return true;
261
0
  }
262
0
  }
263
0
  
llvm_unreachable0
("Previous switch has a fallthrough?");
264
0
}
265
266
/// Expand all pseudo instructions contained in \p MBB.
267
/// \returns true if any expansion occurred for \p MBB.
268
138k
bool X86ExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) {
269
138k
  bool Modified = false;
270
138k
271
138k
  // MBBI may be invalidated by the expansion.
272
138k
  MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
273
1.02M
  while (
MBBI != E1.02M
) {
274
889k
    MachineBasicBlock::iterator NMBBI = std::next(MBBI);
275
889k
    Modified |= ExpandMI(MBB, MBBI);
276
889k
    MBBI = NMBBI;
277
889k
  }
278
138k
279
138k
  return Modified;
280
138k
}
281
282
72.7k
bool X86ExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
283
72.7k
  STI = &static_cast<const X86Subtarget &>(MF.getSubtarget());
284
72.7k
  TII = STI->getInstrInfo();
285
72.7k
  TRI = STI->getRegisterInfo();
286
72.7k
  X86FI = MF.getInfo<X86MachineFunctionInfo>();
287
72.7k
  X86FL = STI->getFrameLowering();
288
72.7k
289
72.7k
  bool Modified = false;
290
72.7k
  for (MachineBasicBlock &MBB : MF)
291
138k
    Modified |= ExpandMBB(MBB);
292
72.7k
  return Modified;
293
72.7k
}
294
295
/// Returns an instance of the pseudo instruction expansion pass.
296
8.54k
FunctionPass *llvm::createX86ExpandPseudoPass() {
297
8.54k
  return new X86ExpandPseudo();
298
8.54k
}