Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCShuffler.cpp
Line
Count
Source (jump to first uncovered line)
1
//===----- HexagonMCShuffler.cpp - MC bundle shuffling --------------------===//
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
// This implements the shuffling of insns inside a bundle according to the
10
// packet formation rules of the Hexagon ISA.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#define DEBUG_TYPE "hexagon-shuffle"
15
16
#include "MCTargetDesc/HexagonMCShuffler.h"
17
#include "MCTargetDesc/HexagonMCInstrInfo.h"
18
#include "MCTargetDesc/HexagonShuffler.h"
19
#include "llvm/MC/MCInst.h"
20
#include "llvm/MC/MCInstrDesc.h"
21
#include "llvm/MC/MCInstrInfo.h"
22
#include "llvm/Support/CommandLine.h"
23
#include "llvm/Support/Debug.h"
24
#include "llvm/Support/raw_ostream.h"
25
#include <cassert>
26
27
using namespace llvm;
28
29
static cl::opt<bool>
30
    DisableShuffle("disable-hexagon-shuffle", cl::Hidden, cl::init(false),
31
                   cl::desc("Disable Hexagon instruction shuffling"));
32
33
100k
void HexagonMCShuffler::init(MCInst &MCB) {
34
100k
  if (HexagonMCInstrInfo::isBundle(MCB)) {
35
100k
    MCInst const *Extender = nullptr;
36
100k
    // Copy the bundle for the shuffling.
37
160k
    for (const auto &I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
38
160k
      MCInst &MI = *const_cast<MCInst *>(I.getInst());
39
160k
      LLVM_DEBUG(dbgs() << "Shuffling: " << MCII.getName(MI.getOpcode())
40
160k
                        << '\n');
41
160k
      assert(!HexagonMCInstrInfo::getDesc(MCII, MI).isPseudo());
42
160k
43
160k
      if (!HexagonMCInstrInfo::isImmext(MI)) {
44
152k
        append(MI, Extender, HexagonMCInstrInfo::getUnits(MCII, STI, MI));
45
152k
        Extender = nullptr;
46
152k
      } else
47
8.61k
        Extender = &MI;
48
160k
    }
49
100k
  }
50
100k
51
100k
  Loc = MCB.getLoc();
52
100k
  BundleFlags = MCB.getOperand(0).getImm();
53
100k
}
54
55
void HexagonMCShuffler::init(MCInst &MCB, MCInst const &AddMI,
56
0
                             bool bInsertAtFront) {
57
0
  if (HexagonMCInstrInfo::isBundle(MCB)) {
58
0
    if (bInsertAtFront)
59
0
      append(AddMI, nullptr, HexagonMCInstrInfo::getUnits(MCII, STI, AddMI));
60
0
    MCInst const *Extender = nullptr;
61
0
    // Copy the bundle for the shuffling.
62
0
    for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
63
0
      assert(!HexagonMCInstrInfo::getDesc(MCII, *I.getInst()).isPseudo());
64
0
      MCInst &MI = *const_cast<MCInst *>(I.getInst());
65
0
      if (!HexagonMCInstrInfo::isImmext(MI)) {
66
0
        append(MI, Extender, HexagonMCInstrInfo::getUnits(MCII, STI, MI));
67
0
        Extender = nullptr;
68
0
      } else
69
0
        Extender = &MI;
70
0
    }
71
0
    if (!bInsertAtFront)
72
0
      append(AddMI, nullptr, HexagonMCInstrInfo::getUnits(MCII, STI, AddMI));
73
0
  }
74
0
75
0
  Loc = MCB.getLoc();
76
0
  BundleFlags = MCB.getOperand(0).getImm();
77
0
}
78
79
93.3k
void HexagonMCShuffler::copyTo(MCInst &MCB) {
80
93.3k
  MCB.clear();
81
93.3k
  MCB.addOperand(MCOperand::createImm(BundleFlags));
82
93.3k
  MCB.setLoc(Loc);
83
93.3k
  // Copy the results into the bundle.
84
236k
  for (HexagonShuffler::iterator I = begin(); I != end(); 
++I142k
) {
85
142k
86
142k
    MCInst const &MI = I->getDesc();
87
142k
    MCInst const *Extender = I->getExtender();
88
142k
    if (Extender)
89
8.00k
      MCB.addOperand(MCOperand::createInst(Extender));
90
142k
    MCB.addOperand(MCOperand::createInst(&MI));
91
142k
  }
92
93.3k
}
93
94
93.2k
bool HexagonMCShuffler::reshuffleTo(MCInst &MCB) {
95
93.2k
  if (shuffle()) {
96
92.9k
    // Copy the results into the bundle.
97
92.9k
    copyTo(MCB);
98
92.9k
    return true;
99
92.9k
  }
100
309
  LLVM_DEBUG(MCB.dump());
101
309
  return false;
102
309
}
103
104
bool llvm::HexagonMCShuffle(MCContext &Context, bool Fatal,
105
                            MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
106
70.3k
                            MCInst &MCB) {
107
70.3k
  HexagonMCShuffler MCS(Context, Fatal, MCII, STI, MCB);
108
70.3k
109
70.3k
  if (DisableShuffle)
110
213
    // Ignore if user chose so.
111
213
    return false;
112
70.1k
113
70.1k
  if (!HexagonMCInstrInfo::bundleSize(MCB)) {
114
15
    // There once was a bundle:
115
15
    //    BUNDLE implicit-def %d2, implicit-def %r4, implicit-def %r5,
116
15
    //    implicit-def %d7, ...
117
15
    //      * %d2 = IMPLICIT_DEF; flags:
118
15
    //      * %d7 = IMPLICIT_DEF; flags:
119
15
    // After the IMPLICIT_DEFs were removed by the asm printer, the bundle
120
15
    // became empty.
121
15
    LLVM_DEBUG(dbgs() << "Skipping empty bundle");
122
15
    return false;
123
70.0k
  } else if (!HexagonMCInstrInfo::isBundle(MCB)) {
124
0
    LLVM_DEBUG(dbgs() << "Skipping stand-alone insn");
125
0
    return false;
126
0
  }
127
70.0k
128
70.0k
  return MCS.reshuffleTo(MCB);
129
70.0k
}
130
131
bool
132
llvm::HexagonMCShuffle(MCContext &Context, MCInstrInfo const &MCII,
133
                       MCSubtargetInfo const &STI, MCInst &MCB,
134
23.3k
                       SmallVector<DuplexCandidate, 8> possibleDuplexes) {
135
23.3k
  if (DisableShuffle)
136
71
    return false;
137
23.2k
138
23.2k
  if (!HexagonMCInstrInfo::bundleSize(MCB)) {
139
14
    // There once was a bundle:
140
14
    //    BUNDLE implicit-def %d2, implicit-def %r4, implicit-def %r5,
141
14
    //    implicit-def %d7, ...
142
14
    //      * %d2 = IMPLICIT_DEF; flags:
143
14
    //      * %d7 = IMPLICIT_DEF; flags:
144
14
    // After the IMPLICIT_DEFs were removed by the asm printer, the bundle
145
14
    // became empty.
146
14
    LLVM_DEBUG(dbgs() << "Skipping empty bundle");
147
14
    return false;
148
23.2k
  } else if (!HexagonMCInstrInfo::isBundle(MCB)) {
149
0
    LLVM_DEBUG(dbgs() << "Skipping stand-alone insn");
150
0
    return false;
151
0
  }
152
23.2k
153
23.2k
  bool doneShuffling = false;
154
23.5k
  while (possibleDuplexes.size() > 0 && 
(!doneShuffling)1.37k
) {
155
1.37k
    // case of Duplex Found
156
1.37k
    DuplexCandidate duplexToTry = possibleDuplexes.pop_back_val();
157
1.37k
    MCInst Attempt(MCB);
158
1.37k
    HexagonMCInstrInfo::replaceDuplex(Context, Attempt, duplexToTry);
159
1.37k
    HexagonMCShuffler MCS(Context, false, MCII, STI, Attempt); // copy packet to the shuffler
160
1.37k
    if (MCS.size() == 1) {                     // case of one duplex
161
423
      // copy the created duplex in the shuffler to the bundle
162
423
      MCS.copyTo(MCB);
163
423
      return false;
164
423
    }
165
956
    // try shuffle with this duplex
166
956
    doneShuffling = MCS.reshuffleTo(MCB);
167
956
168
956
    if (doneShuffling)
169
652
      break;
170
956
  }
171
23.2k
172
23.2k
  
if (22.8k
!doneShuffling22.8k
) {
173
22.1k
    HexagonMCShuffler MCS(Context, false, MCII, STI, MCB);
174
22.1k
    doneShuffling = MCS.reshuffleTo(MCB); // shuffle
175
22.1k
  }
176
22.8k
  if (!doneShuffling)
177
1
    return true;
178
22.8k
179
22.8k
  return false;
180
22.8k
}
181
182
bool llvm::HexagonMCShuffle(MCContext &Context, MCInstrInfo const &MCII,
183
                            MCSubtargetInfo const &STI, MCInst &MCB,
184
0
                            MCInst const &AddMI, int fixupCount) {
185
0
  if (!HexagonMCInstrInfo::isBundle(MCB))
186
0
    return false;
187
0
188
0
  // if fixups present, make sure we don't insert too many nops that would
189
0
  // later prevent an extender from being inserted.
190
0
  unsigned int bundleSize = HexagonMCInstrInfo::bundleSize(MCB);
191
0
  if (bundleSize >= HEXAGON_PACKET_SIZE)
192
0
    return false;
193
0
  bool bhasDuplex = HexagonMCInstrInfo::hasDuplex(MCII, MCB);
194
0
  if (fixupCount >= 2) {
195
0
    if (bhasDuplex) {
196
0
      if (bundleSize >= HEXAGON_PACKET_SIZE - 1) {
197
0
        return false;
198
0
      }
199
0
    } else {
200
0
      return false;
201
0
    }
202
0
  } else {
203
0
    if (bundleSize == HEXAGON_PACKET_SIZE - 1 && fixupCount)
204
0
      return false;
205
0
  }
206
0
207
0
  if (DisableShuffle)
208
0
    return false;
209
0
210
0
  // mgl: temporary code (shuffler doesn't take into account the fact that
211
0
  // a duplex takes up two slots.  for example, 3 nops can be put into a packet
212
0
  // containing a duplex oversubscribing slots by 1).
213
0
  unsigned maxBundleSize = (HexagonMCInstrInfo::hasImmExt(MCB))
214
0
                               ? HEXAGON_PACKET_SIZE
215
0
                               : HEXAGON_PACKET_SIZE - 1;
216
0
  if (bhasDuplex && bundleSize >= maxBundleSize)
217
0
    return false;
218
0
219
0
  HexagonMCShuffler MCS(Context, false, MCII, STI, MCB, AddMI, false);
220
0
  return MCS.reshuffleTo(MCB);
221
0
}