LLVM  15.0.0git
X86InstrRelaxTables.cpp
Go to the documentation of this file.
1 //===- X86InstrRelaxTables.cpp - X86 Instruction Relaxation Tables -*- C++ -*-//
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 file contains the X86 instruction relaxation tables.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "X86InstrRelaxTables.h"
14 #include "X86InstrInfo.h"
15 #include "llvm/ADT/STLExtras.h"
16 
17 using namespace llvm;
18 
19 // These tables are sorted by their ShortOp value allowing them to be binary
20 // searched at runtime without the need for additional storage. The enum values
21 // are currently emitted in X86GenInstrInfo.inc in alphabetical order. Which
22 // makes sorting these tables a simple matter of alphabetizing the table.
24  // ADC
25  { X86::ADC16mi8, X86::ADC16mi },
26  { X86::ADC16ri8, X86::ADC16ri },
27  { X86::ADC32mi8, X86::ADC32mi },
28  { X86::ADC32ri8, X86::ADC32ri },
29  { X86::ADC64mi8, X86::ADC64mi32 },
30  { X86::ADC64ri8, X86::ADC64ri32 },
31  // ADD
32  { X86::ADD16mi8, X86::ADD16mi },
33  { X86::ADD16ri8, X86::ADD16ri },
34  { X86::ADD32mi8, X86::ADD32mi },
35  { X86::ADD32ri8, X86::ADD32ri },
36  { X86::ADD64mi8, X86::ADD64mi32 },
37  { X86::ADD64ri8, X86::ADD64ri32 },
38  // AND
39  { X86::AND16mi8, X86::AND16mi },
40  { X86::AND16ri8, X86::AND16ri },
41  { X86::AND32mi8, X86::AND32mi },
42  { X86::AND32ri8, X86::AND32ri },
43  { X86::AND64mi8, X86::AND64mi32 },
44  { X86::AND64ri8, X86::AND64ri32 },
45  // CMP
46  { X86::CMP16mi8, X86::CMP16mi },
47  { X86::CMP16ri8, X86::CMP16ri },
48  { X86::CMP32mi8, X86::CMP32mi },
49  { X86::CMP32ri8, X86::CMP32ri },
50  { X86::CMP64mi8, X86::CMP64mi32 },
51  { X86::CMP64ri8, X86::CMP64ri32 },
52  // IMUL
53  { X86::IMUL16rmi8, X86::IMUL16rmi },
54  { X86::IMUL16rri8, X86::IMUL16rri },
55  { X86::IMUL32rmi8, X86::IMUL32rmi },
56  { X86::IMUL32rri8, X86::IMUL32rri },
57  { X86::IMUL64rmi8, X86::IMUL64rmi32 },
58  { X86::IMUL64rri8, X86::IMUL64rri32 },
59  // OR
60  { X86::OR16mi8, X86::OR16mi },
61  { X86::OR16ri8, X86::OR16ri },
62  { X86::OR32mi8, X86::OR32mi },
63  { X86::OR32ri8, X86::OR32ri },
64  { X86::OR64mi8, X86::OR64mi32 },
65  { X86::OR64ri8, X86::OR64ri32 },
66  // PUSH
67  { X86::PUSH16i8, X86::PUSHi16 },
68  { X86::PUSH32i8, X86::PUSHi32 },
69  { X86::PUSH64i8, X86::PUSH64i32 },
70  // SBB
71  { X86::SBB16mi8, X86::SBB16mi },
72  { X86::SBB16ri8, X86::SBB16ri },
73  { X86::SBB32mi8, X86::SBB32mi },
74  { X86::SBB32ri8, X86::SBB32ri },
75  { X86::SBB64mi8, X86::SBB64mi32 },
76  { X86::SBB64ri8, X86::SBB64ri32 },
77  // SUB
78  { X86::SUB16mi8, X86::SUB16mi },
79  { X86::SUB16ri8, X86::SUB16ri },
80  { X86::SUB32mi8, X86::SUB32mi },
81  { X86::SUB32ri8, X86::SUB32ri },
82  { X86::SUB64mi8, X86::SUB64mi32 },
83  { X86::SUB64ri8, X86::SUB64ri32 },
84  // XOR
85  { X86::XOR16mi8, X86::XOR16mi },
86  { X86::XOR16ri8, X86::XOR16ri },
87  { X86::XOR32mi8, X86::XOR32mi },
88  { X86::XOR32ri8, X86::XOR32ri },
89  { X86::XOR64mi8, X86::XOR64mi32 },
90  { X86::XOR64ri8, X86::XOR64ri32 },
91 };
92 
93 static const X86InstrRelaxTableEntry *
95  unsigned ShortOp) {
96 #ifndef NDEBUG
97  // Make sure the tables are sorted.
98  static std::atomic<bool> RelaxTableChecked(false);
99  if (!RelaxTableChecked.load(std::memory_order_relaxed)) {
101  std::adjacent_find(std::begin(InstrRelaxTable),
104  "InstrRelaxTable is not sorted and unique!");
105  RelaxTableChecked.store(true, std::memory_order_relaxed);
106  }
107 #endif
108 
109  const X86InstrRelaxTableEntry *Data = llvm::lower_bound(Table, ShortOp);
110  if (Data != Table.end() && Data->KeyOp == ShortOp)
111  return Data;
112  return nullptr;
113 }
114 
116  return lookupRelaxTableImpl(InstrRelaxTable, ShortOp);
117 }
118 
119 namespace {
120 
121 // This class stores the short form tables. It is instantiated as a
122 // ManagedStatic to lazily init the short form table.
123 struct X86ShortFormTable {
124  // Stores relaxation table entries sorted by relaxed form opcode.
126 
127  X86ShortFormTable() {
128  for (const X86InstrRelaxTableEntry &Entry : InstrRelaxTable)
129  Table.push_back({Entry.DstOp, Entry.KeyOp});
130 
131  llvm::sort(Table);
132 
133  // Now that it's sorted, ensure its unique.
134  assert(std::adjacent_find(Table.begin(), Table.end()) == Table.end() &&
135  "Short form table is not unique!");
136  }
137 };
138 } // namespace
139 
141 
143  auto &Table = ShortTable->Table;
144  auto I = llvm::lower_bound(Table, RelaxOp);
145  if (I != Table.end() && I->KeyOp == RelaxOp)
146  return &*I;
147  return nullptr;
148 }
149 
150 namespace llvm {
151 
152 /// Get the short instruction opcode for a given relaxed opcode.
153 unsigned X86::getShortOpcodeArith(unsigned RelaxOp) {
154  if (const X86InstrRelaxTableEntry *I = lookupShortTable(RelaxOp))
155  return I->DstOp;
156  return RelaxOp;
157 }
158 
159 /// Get the relaxed instruction opcode for a given short opcode.
160 unsigned X86::getRelaxedOpcodeArith(unsigned ShortOp) {
161  if (const X86InstrRelaxTableEntry *I = lookupRelaxTable(ShortOp))
162  return I->DstOp;
163  return ShortOp;
164 }
165 } // namespace llvm
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
X86InstrRelaxTables.h
llvm::lower_bound
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:1736
llvm::X86::getRelaxedOpcodeArith
unsigned getRelaxedOpcodeArith(unsigned ShortOp)
Get the relaxed instruction opcode for a given short opcode.
Definition: X86InstrRelaxTables.cpp:160
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1185
llvm::X86::getShortOpcodeArith
unsigned getShortOpcodeArith(unsigned RelaxOp)
Get the short instruction opcode for a given relaxed opcode.
Definition: X86InstrRelaxTables.cpp:153
ShortTable
static ManagedStatic< X86ShortFormTable > ShortTable
Definition: X86InstrRelaxTables.cpp:140
llvm::sys::path::end
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:235
llvm::lookupShortTable
const X86InstrRelaxTableEntry * lookupShortTable(unsigned RelaxOp)
Look up the short form table entry for a given RelaxOp.
Definition: X86InstrRelaxTables.cpp:142
llvm::sys::path::begin
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:226
STLExtras.h
llvm::lookupRelaxTable
const X86InstrRelaxTableEntry * lookupRelaxTable(unsigned ShortOp)
Look up the relaxed form table entry for a given ShortOp.
Definition: X86InstrRelaxTables.cpp:115
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::ManagedStatic
ManagedStatic - This transparently changes the behavior of global statics to be lazily constructed on...
Definition: ManagedStatic.h:83
lookupRelaxTableImpl
static const X86InstrRelaxTableEntry * lookupRelaxTableImpl(ArrayRef< X86InstrRelaxTableEntry > Table, unsigned ShortOp)
Definition: X86InstrRelaxTables.cpp:94
I
#define I(x, y, z)
Definition: MD5.cpp:58
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
InstrRelaxTable
static const X86InstrRelaxTableEntry InstrRelaxTable[]
Definition: X86InstrRelaxTables.cpp:23
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::X86InstrRelaxTableEntry
Definition: X86InstrRelaxTables.h:23
llvm::sort
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1562
llvm::is_sorted
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
Definition: STLExtras.h:1697
X86InstrInfo.h
llvm::ArrayRef::end
iterator end() const
Definition: ArrayRef.h:153