Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Hexagon/HexagonGenPredicate.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- HexagonGenPredicate.cpp --------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "HexagonInstrInfo.h"
10
#include "HexagonSubtarget.h"
11
#include "llvm/ADT/SetVector.h"
12
#include "llvm/ADT/StringRef.h"
13
#include "llvm/CodeGen/MachineBasicBlock.h"
14
#include "llvm/CodeGen/MachineDominators.h"
15
#include "llvm/CodeGen/MachineFunction.h"
16
#include "llvm/CodeGen/MachineFunctionPass.h"
17
#include "llvm/CodeGen/MachineInstr.h"
18
#include "llvm/CodeGen/MachineInstrBuilder.h"
19
#include "llvm/CodeGen/MachineOperand.h"
20
#include "llvm/CodeGen/MachineRegisterInfo.h"
21
#include "llvm/CodeGen/TargetRegisterInfo.h"
22
#include "llvm/IR/DebugLoc.h"
23
#include "llvm/Pass.h"
24
#include "llvm/Support/Compiler.h"
25
#include "llvm/Support/Debug.h"
26
#include "llvm/Support/ErrorHandling.h"
27
#include "llvm/Support/raw_ostream.h"
28
#include <cassert>
29
#include <iterator>
30
#include <map>
31
#include <queue>
32
#include <set>
33
#include <utility>
34
35
#define DEBUG_TYPE "gen-pred"
36
37
using namespace llvm;
38
39
namespace llvm {
40
41
  void initializeHexagonGenPredicatePass(PassRegistry& Registry);
42
  FunctionPass *createHexagonGenPredicate();
43
44
} // end namespace llvm
45
46
namespace {
47
48
  // FIXME: Use TargetInstrInfo::RegSubRegPair
49
  struct RegisterSubReg {
50
    unsigned R, S;
51
52
1
    RegisterSubReg(unsigned r = 0, unsigned s = 0) : R(r), S(s) {}
53
26.2k
    RegisterSubReg(const MachineOperand &MO) : R(MO.getReg()), S(MO.getSubReg()) {}
54
1
    RegisterSubReg(const Register &Reg) : R(Reg), S(0) {}
55
56
0
    bool operator== (const RegisterSubReg &Reg) const {
57
0
      return R == Reg.R && S == Reg.S;
58
0
    }
59
60
32
    bool operator< (const RegisterSubReg &Reg) const {
61
32
      return R < Reg.R || 
(17
R == Reg.R17
&&
S < Reg.S6
);
62
32
    }
63
  };
64
65
  struct PrintRegister {
66
    friend raw_ostream &operator<< (raw_ostream &OS, const PrintRegister &PR);
67
68
0
    PrintRegister(RegisterSubReg R, const TargetRegisterInfo &I) : Reg(R), TRI(I) {}
69
70
  private:
71
    RegisterSubReg Reg;
72
    const TargetRegisterInfo &TRI;
73
  };
74
75
  raw_ostream &operator<< (raw_ostream &OS, const PrintRegister &PR)
76
    LLVM_ATTRIBUTE_UNUSED;
77
0
  raw_ostream &operator<< (raw_ostream &OS, const PrintRegister &PR) {
78
0
    return OS << printReg(PR.Reg.R, &PR.TRI, PR.Reg.S);
79
0
  }
80
81
  class HexagonGenPredicate : public MachineFunctionPass {
82
  public:
83
    static char ID;
84
85
862
    HexagonGenPredicate() : MachineFunctionPass(ID) {
86
862
      initializeHexagonGenPredicatePass(*PassRegistry::getPassRegistry());
87
862
    }
88
89
3.36k
    StringRef getPassName() const override {
90
3.36k
      return "Hexagon generate predicate operations";
91
3.36k
    }
92
93
855
    void getAnalysisUsage(AnalysisUsage &AU) const override {
94
855
      AU.addRequired<MachineDominatorTree>();
95
855
      AU.addPreserved<MachineDominatorTree>();
96
855
      MachineFunctionPass::getAnalysisUsage(AU);
97
855
    }
98
99
    bool runOnMachineFunction(MachineFunction &MF) override;
100
101
  private:
102
    using VectOfInst = SetVector<MachineInstr *>;
103
    using SetOfReg = std::set<RegisterSubReg>;
104
    using RegToRegMap = std::map<RegisterSubReg, RegisterSubReg>;
105
106
    const HexagonInstrInfo *TII = nullptr;
107
    const HexagonRegisterInfo *TRI = nullptr;
108
    MachineRegisterInfo *MRI = nullptr;
109
    SetOfReg PredGPRs;
110
    VectOfInst PUsers;
111
    RegToRegMap G2P;
112
113
    bool isPredReg(unsigned R);
114
    void collectPredicateGPR(MachineFunction &MF);
115
    void processPredicateGPR(const RegisterSubReg &Reg);
116
    unsigned getPredForm(unsigned Opc);
117
    bool isConvertibleToPredForm(const MachineInstr *MI);
118
    bool isScalarCmp(unsigned Opc);
119
    bool isScalarPred(RegisterSubReg PredReg);
120
    RegisterSubReg getPredRegFor(const RegisterSubReg &Reg);
121
    bool convertToPredForm(MachineInstr *MI);
122
    bool eliminatePredCopies(MachineFunction &MF);
123
  };
124
125
} // end anonymous namespace
126
127
char HexagonGenPredicate::ID = 0;
128
129
862
INITIALIZE_PASS_BEGIN(HexagonGenPredicate, "hexagon-gen-pred",
130
862
  "Hexagon generate predicate operations", false, false)
131
862
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
132
862
INITIALIZE_PASS_END(HexagonGenPredicate, "hexagon-gen-pred",
133
  "Hexagon generate predicate operations", false, false)
134
135
13.1k
bool HexagonGenPredicate::isPredReg(unsigned R) {
136
13.1k
  if (!TargetRegisterInfo::isVirtualRegister(R))
137
5.36k
    return false;
138
7.75k
  const TargetRegisterClass *RC = MRI->getRegClass(R);
139
7.75k
  return RC == &Hexagon::PredRegsRegClass;
140
7.75k
}
141
142
21
unsigned HexagonGenPredicate::getPredForm(unsigned Opc) {
143
21
  using namespace Hexagon;
144
21
145
21
  switch (Opc) {
146
21
    case A2_and:
147
0
    case A2_andp:
148
0
      return C2_and;
149
0
    case A4_andn:
150
0
    case A4_andnp:
151
0
      return C2_andn;
152
0
    case M4_and_and:
153
0
      return C4_and_and;
154
0
    case M4_and_andn:
155
0
      return C4_and_andn;
156
0
    case M4_and_or:
157
0
      return C4_and_or;
158
0
159
0
    case A2_or:
160
0
    case A2_orp:
161
0
      return C2_or;
162
0
    case A4_orn:
163
0
    case A4_ornp:
164
0
      return C2_orn;
165
4
    case M4_or_and:
166
4
      return C4_or_and;
167
0
    case M4_or_andn:
168
0
      return C4_or_andn;
169
0
    case M4_or_or:
170
0
      return C4_or_or;
171
0
172
0
    case A2_xor:
173
0
    case A2_xorp:
174
0
      return C2_xor;
175
0
176
0
    case C2_tfrrp:
177
0
      return COPY;
178
17
  }
179
17
  // The opcode corresponding to 0 is TargetOpcode::PHI. We can use 0 here
180
17
  // to denote "none", but we need to make sure that none of the valid opcodes
181
17
  // that we return will ever be 0.
182
17
  static_assert(PHI == 0, "Use different value for <none>");
183
17
  return 0;
184
17
}
185
186
20
bool HexagonGenPredicate::isConvertibleToPredForm(const MachineInstr *MI) {
187
20
  unsigned Opc = MI->getOpcode();
188
20
  if (getPredForm(Opc) != 0)
189
3
    return true;
190
17
191
17
  // Comparisons against 0 are also convertible. This does not apply to
192
17
  // A4_rcmpeqi or A4_rcmpneqi, since they produce values 0 or 1, which
193
17
  // may not match the value that the predicate register would have if
194
17
  // it was converted to a predicate form.
195
17
  switch (Opc) {
196
17
    case Hexagon::C2_cmpeqi:
197
0
    case Hexagon::C4_cmpneqi:
198
0
      if (MI->getOperand(2).isImm() && MI->getOperand(2).getImm() == 0)
199
0
        return true;
200
0
      break;
201
17
  }
202
17
  return false;
203
17
}
204
205
3.35k
void HexagonGenPredicate::collectPredicateGPR(MachineFunction &MF) {
206
8.33k
  for (MachineFunction::iterator A = MF.begin(), Z = MF.end(); A != Z; 
++A4.98k
) {
207
4.98k
    MachineBasicBlock &B = *A;
208
47.9k
    for (MachineBasicBlock::iterator I = B.begin(), E = B.end(); I != E; 
++I43.0k
) {
209
43.0k
      MachineInstr *MI = &*I;
210
43.0k
      unsigned Opc = MI->getOpcode();
211
43.0k
      switch (Opc) {
212
43.0k
        case Hexagon::C2_tfrpr:
213
13.1k
        case TargetOpcode::COPY:
214
13.1k
          if (isPredReg(MI->getOperand(1).getReg())) {
215
56
            RegisterSubReg RD = MI->getOperand(0);
216
56
            if (TargetRegisterInfo::isVirtualRegister(RD.R))
217
20
              PredGPRs.insert(RD);
218
56
          }
219
13.1k
          break;
220
43.0k
      }
221
43.0k
    }
222
4.98k
  }
223
3.35k
}
224
225
21
void HexagonGenPredicate::processPredicateGPR(const RegisterSubReg &Reg) {
226
21
  LLVM_DEBUG(dbgs() << __func__ << ": " << printReg(Reg.R, TRI, Reg.S) << "\n");
227
21
  using use_iterator = MachineRegisterInfo::use_iterator;
228
21
229
21
  use_iterator I = MRI->use_begin(Reg.R), E = MRI->use_end();
230
21
  if (I == E) {
231
1
    LLVM_DEBUG(dbgs() << "Dead reg: " << printReg(Reg.R, TRI, Reg.S) << '\n');
232
1
    MachineInstr *DefI = MRI->getVRegDef(Reg.R);
233
1
    DefI->eraseFromParent();
234
1
    return;
235
1
  }
236
20
237
40
  
for (; 20
I != E;
++I20
) {
238
20
    MachineInstr *UseI = I->getParent();
239
20
    if (isConvertibleToPredForm(UseI))
240
3
      PUsers.insert(UseI);
241
20
  }
242
20
}
243
244
3
RegisterSubReg HexagonGenPredicate::getPredRegFor(const RegisterSubReg &Reg) {
245
3
  // Create a predicate register for a given Reg. The newly created register
246
3
  // will have its value copied from Reg, so that it can be later used as
247
3
  // an operand in other instructions.
248
3
  assert(TargetRegisterInfo::isVirtualRegister(Reg.R));
249
3
  RegToRegMap::iterator F = G2P.find(Reg);
250
3
  if (F != G2P.end())
251
0
    return F->second;
252
3
253
3
  LLVM_DEBUG(dbgs() << __func__ << ": " << PrintRegister(Reg, *TRI));
254
3
  MachineInstr *DefI = MRI->getVRegDef(Reg.R);
255
3
  assert(DefI);
256
3
  unsigned Opc = DefI->getOpcode();
257
3
  if (Opc == Hexagon::C2_tfrpr || Opc == TargetOpcode::COPY) {
258
3
    assert(DefI->getOperand(0).isDef() && DefI->getOperand(1).isUse());
259
3
    RegisterSubReg PR = DefI->getOperand(1);
260
3
    G2P.insert(std::make_pair(Reg, PR));
261
3
    LLVM_DEBUG(dbgs() << " -> " << PrintRegister(PR, *TRI) << '\n');
262
3
    return PR;
263
3
  }
264
0
265
0
  MachineBasicBlock &B = *DefI->getParent();
266
0
  DebugLoc DL = DefI->getDebugLoc();
267
0
  const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;
268
0
  unsigned NewPR = MRI->createVirtualRegister(PredRC);
269
0
270
0
  // For convertible instructions, do not modify them, so that they can
271
0
  // be converted later.  Generate a copy from Reg to NewPR.
272
0
  if (isConvertibleToPredForm(DefI)) {
273
0
    MachineBasicBlock::iterator DefIt = DefI;
274
0
    BuildMI(B, std::next(DefIt), DL, TII->get(TargetOpcode::COPY), NewPR)
275
0
      .addReg(Reg.R, 0, Reg.S);
276
0
    G2P.insert(std::make_pair(Reg, RegisterSubReg(NewPR)));
277
0
    LLVM_DEBUG(dbgs() << " -> !" << PrintRegister(RegisterSubReg(NewPR), *TRI)
278
0
                      << '\n');
279
0
    return RegisterSubReg(NewPR);
280
0
  }
281
0
282
0
  llvm_unreachable("Invalid argument");
283
0
}
284
285
0
bool HexagonGenPredicate::isScalarCmp(unsigned Opc) {
286
0
  switch (Opc) {
287
0
    case Hexagon::C2_cmpeq:
288
0
    case Hexagon::C2_cmpgt:
289
0
    case Hexagon::C2_cmpgtu:
290
0
    case Hexagon::C2_cmpeqp:
291
0
    case Hexagon::C2_cmpgtp:
292
0
    case Hexagon::C2_cmpgtup:
293
0
    case Hexagon::C2_cmpeqi:
294
0
    case Hexagon::C2_cmpgti:
295
0
    case Hexagon::C2_cmpgtui:
296
0
    case Hexagon::C2_cmpgei:
297
0
    case Hexagon::C2_cmpgeui:
298
0
    case Hexagon::C4_cmpneqi:
299
0
    case Hexagon::C4_cmpltei:
300
0
    case Hexagon::C4_cmplteui:
301
0
    case Hexagon::C4_cmpneq:
302
0
    case Hexagon::C4_cmplte:
303
0
    case Hexagon::C4_cmplteu:
304
0
    case Hexagon::A4_cmpbeq:
305
0
    case Hexagon::A4_cmpbeqi:
306
0
    case Hexagon::A4_cmpbgtu:
307
0
    case Hexagon::A4_cmpbgtui:
308
0
    case Hexagon::A4_cmpbgt:
309
0
    case Hexagon::A4_cmpbgti:
310
0
    case Hexagon::A4_cmpheq:
311
0
    case Hexagon::A4_cmphgt:
312
0
    case Hexagon::A4_cmphgtu:
313
0
    case Hexagon::A4_cmpheqi:
314
0
    case Hexagon::A4_cmphgti:
315
0
    case Hexagon::A4_cmphgtui:
316
0
      return true;
317
0
  }
318
0
  return false;
319
0
}
320
321
0
bool HexagonGenPredicate::isScalarPred(RegisterSubReg PredReg) {
322
0
  std::queue<RegisterSubReg> WorkQ;
323
0
  WorkQ.push(PredReg);
324
0
325
0
  while (!WorkQ.empty()) {
326
0
    RegisterSubReg PR = WorkQ.front();
327
0
    WorkQ.pop();
328
0
    const MachineInstr *DefI = MRI->getVRegDef(PR.R);
329
0
    if (!DefI)
330
0
      return false;
331
0
    unsigned DefOpc = DefI->getOpcode();
332
0
    switch (DefOpc) {
333
0
      case TargetOpcode::COPY: {
334
0
        const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;
335
0
        if (MRI->getRegClass(PR.R) != PredRC)
336
0
          return false;
337
0
        // If it is a copy between two predicate registers, fall through.
338
0
        LLVM_FALLTHROUGH;
339
0
      }
340
0
      case Hexagon::C2_and:
341
0
      case Hexagon::C2_andn:
342
0
      case Hexagon::C4_and_and:
343
0
      case Hexagon::C4_and_andn:
344
0
      case Hexagon::C4_and_or:
345
0
      case Hexagon::C2_or:
346
0
      case Hexagon::C2_orn:
347
0
      case Hexagon::C4_or_and:
348
0
      case Hexagon::C4_or_andn:
349
0
      case Hexagon::C4_or_or:
350
0
      case Hexagon::C4_or_orn:
351
0
      case Hexagon::C2_xor:
352
0
        // Add operands to the queue.
353
0
        for (const MachineOperand &MO : DefI->operands())
354
0
          if (MO.isReg() && MO.isUse())
355
0
            WorkQ.push(RegisterSubReg(MO.getReg()));
356
0
        break;
357
0
358
0
      // All non-vector compares are ok, everything else is bad.
359
0
      default:
360
0
        return isScalarCmp(DefOpc);
361
0
    }
362
0
  }
363
0
364
0
  return true;
365
0
}
366
367
1
bool HexagonGenPredicate::convertToPredForm(MachineInstr *MI) {
368
1
  LLVM_DEBUG(dbgs() << __func__ << ": " << MI << " " << *MI);
369
1
370
1
  unsigned Opc = MI->getOpcode();
371
1
  assert(isConvertibleToPredForm(MI));
372
1
  unsigned NumOps = MI->getNumOperands();
373
5
  for (unsigned i = 0; i < NumOps; 
++i4
) {
374
4
    MachineOperand &MO = MI->getOperand(i);
375
4
    if (!MO.isReg() || !MO.isUse())
376
1
      continue;
377
3
    RegisterSubReg Reg(MO);
378
3
    if (Reg.S && 
Reg.S != Hexagon::isub_lo0
)
379
0
      return false;
380
3
    if (!PredGPRs.count(Reg))
381
0
      return false;
382
3
  }
383
1
384
1
  MachineBasicBlock &B = *MI->getParent();
385
1
  DebugLoc DL = MI->getDebugLoc();
386
1
387
1
  unsigned NewOpc = getPredForm(Opc);
388
1
  // Special case for comparisons against 0.
389
1
  if (NewOpc == 0) {
390
0
    switch (Opc) {
391
0
      case Hexagon::C2_cmpeqi:
392
0
        NewOpc = Hexagon::C2_not;
393
0
        break;
394
0
      case Hexagon::C4_cmpneqi:
395
0
        NewOpc = TargetOpcode::COPY;
396
0
        break;
397
0
      default:
398
0
        return false;
399
0
    }
400
0
401
0
    // If it's a scalar predicate register, then all bits in it are
402
0
    // the same. Otherwise, to determine whether all bits are 0 or not
403
0
    // we would need to use any8.
404
0
    RegisterSubReg PR = getPredRegFor(MI->getOperand(1));
405
0
    if (!isScalarPred(PR))
406
0
      return false;
407
0
    // This will skip the immediate argument when creating the predicate
408
0
    // version instruction.
409
0
    NumOps = 2;
410
0
  }
411
1
412
1
  // Some sanity: check that def is in operand #0.
413
1
  MachineOperand &Op0 = MI->getOperand(0);
414
1
  assert(Op0.isDef());
415
1
  RegisterSubReg OutR(Op0);
416
1
417
1
  // Don't use getPredRegFor, since it will create an association between
418
1
  // the argument and a created predicate register (i.e. it will insert a
419
1
  // copy if a new predicate register is created).
420
1
  const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;
421
1
  RegisterSubReg NewPR = MRI->createVirtualRegister(PredRC);
422
1
  MachineInstrBuilder MIB = BuildMI(B, MI, DL, TII->get(NewOpc), NewPR.R);
423
1
424
1
  // Add predicate counterparts of the GPRs.
425
4
  for (unsigned i = 1; i < NumOps; 
++i3
) {
426
3
    RegisterSubReg GPR = MI->getOperand(i);
427
3
    RegisterSubReg Pred = getPredRegFor(GPR);
428
3
    MIB.addReg(Pred.R, 0, Pred.S);
429
3
  }
430
1
  LLVM_DEBUG(dbgs() << "generated: " << *MIB);
431
1
432
1
  // Generate a copy-out: NewGPR = NewPR, and replace all uses of OutR
433
1
  // with NewGPR.
434
1
  const TargetRegisterClass *RC = MRI->getRegClass(OutR.R);
435
1
  unsigned NewOutR = MRI->createVirtualRegister(RC);
436
1
  BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), NewOutR)
437
1
    .addReg(NewPR.R, 0, NewPR.S);
438
1
  MRI->replaceRegWith(OutR.R, NewOutR);
439
1
  MI->eraseFromParent();
440
1
441
1
  // If the processed instruction was C2_tfrrp (i.e. Rn = Pm; Pk = Rn),
442
1
  // then the output will be a predicate register.  Do not visit the
443
1
  // users of it.
444
1
  if (!isPredReg(NewOutR)) {
445
1
    RegisterSubReg R(NewOutR);
446
1
    PredGPRs.insert(R);
447
1
    processPredicateGPR(R);
448
1
  }
449
1
  return true;
450
1
}
451
452
3.35k
bool HexagonGenPredicate::eliminatePredCopies(MachineFunction &MF) {
453
3.35k
  LLVM_DEBUG(dbgs() << __func__ << "\n");
454
3.35k
  const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;
455
3.35k
  bool Changed = false;
456
3.35k
  VectOfInst Erase;
457
3.35k
458
3.35k
  // First, replace copies
459
3.35k
  //   IntR = PredR1
460
3.35k
  //   PredR2 = IntR
461
3.35k
  // with
462
3.35k
  //   PredR2 = PredR1
463
3.35k
  // Such sequences can be generated when a copy-into-pred is generated from
464
3.35k
  // a gpr register holding a result of a convertible instruction. After
465
3.35k
  // the convertible instruction is converted, its predicate result will be
466
3.35k
  // copied back into the original gpr.
467
3.35k
468
4.98k
  for (MachineBasicBlock &MBB : MF) {
469
43.0k
    for (MachineInstr &MI : MBB) {
470
43.0k
      if (MI.getOpcode() != TargetOpcode::COPY)
471
29.9k
        continue;
472
13.1k
      RegisterSubReg DR = MI.getOperand(0);
473
13.1k
      RegisterSubReg SR = MI.getOperand(1);
474
13.1k
      if (!TargetRegisterInfo::isVirtualRegister(DR.R))
475
3.41k
        continue;
476
9.69k
      if (!TargetRegisterInfo::isVirtualRegister(SR.R))
477
5.36k
        continue;
478
4.33k
      if (MRI->getRegClass(DR.R) != PredRC)
479
4.27k
        continue;
480
56
      if (MRI->getRegClass(SR.R) != PredRC)
481
52
        continue;
482
4
      assert(!DR.S && !SR.S && "Unexpected subregister");
483
4
      MRI->replaceRegWith(DR.R, SR.R);
484
4
      Erase.insert(&MI);
485
4
      Changed = true;
486
4
    }
487
4.98k
  }
488
3.35k
489
3.35k
  for (VectOfInst::iterator I = Erase.begin(), E = Erase.end(); I != E; 
++I4
)
490
4
    (*I)->eraseFromParent();
491
3.35k
492
3.35k
  return Changed;
493
3.35k
}
494
495
3.36k
bool HexagonGenPredicate::runOnMachineFunction(MachineFunction &MF) {
496
3.36k
  if (skipFunction(MF.getFunction()))
497
10
    return false;
498
3.35k
499
3.35k
  TII = MF.getSubtarget<HexagonSubtarget>().getInstrInfo();
500
3.35k
  TRI = MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
501
3.35k
  MRI = &MF.getRegInfo();
502
3.35k
  PredGPRs.clear();
503
3.35k
  PUsers.clear();
504
3.35k
  G2P.clear();
505
3.35k
506
3.35k
  bool Changed = false;
507
3.35k
  collectPredicateGPR(MF);
508
3.37k
  for (SetOfReg::iterator I = PredGPRs.begin(), E = PredGPRs.end(); I != E; 
++I20
)
509
20
    processPredicateGPR(*I);
510
3.35k
511
3.35k
  bool Again;
512
3.35k
  do {
513
3.35k
    Again = false;
514
3.35k
    VectOfInst Processed, Copy;
515
3.35k
516
3.35k
    using iterator = VectOfInst::iterator;
517
3.35k
518
3.35k
    Copy = PUsers;
519
3.35k
    for (iterator I = Copy.begin(), E = Copy.end(); I != E; 
++I1
) {
520
1
      MachineInstr *MI = *I;
521
1
      bool Done = convertToPredForm(MI);
522
1
      if (Done) {
523
1
        Processed.insert(MI);
524
1
        Again = true;
525
1
      }
526
1
    }
527
3.35k
    Changed |= Again;
528
3.35k
529
3.35k
    auto Done = [Processed] (MachineInstr *MI) -> bool {
530
1
      return Processed.count(MI);
531
1
    };
532
3.35k
    PUsers.remove_if(Done);
533
3.35k
  } while (Again);
534
3.35k
535
3.35k
  Changed |= eliminatePredCopies(MF);
536
3.35k
  return Changed;
537
3.35k
}
538
539
862
FunctionPass *llvm::createHexagonGenPredicate() {
540
862
  return new HexagonGenPredicate();
541
862
}