Go to the documentation of this file.
30 #ifndef LLVM_BITCODE_BITCODECONVENIENCE_H
31 #define LLVM_BITCODE_BITCODECONVENIENCE_H
42 template <
bool Compound = false>
class BCField {
47 template <
typename T>
static void assertValid(
const T &data) {}
51 template <
typename T>
static T convert(T rawValue) {
return rawValue; }
69 template <
typename T>
static void assertValid(
const T &data) {
70 assert(data ==
Value &&
"data value does not match declared literal value");
79 static_assert(
Width <= 64,
"fixed-width field is too large");
86 assert(llvm::isUInt<Width>(data) &&
87 "data value does not fit in the given bit width");
90 template <
typename T>
static void assertValid(
const T &data) {
91 assert(data >= 0 &&
"cannot encode signed integers");
92 assert(llvm::isUInt<Width>(data) &&
93 "data value does not fit in the given bit width");
103 static_assert(
Width >= 2,
"width does not have room for continuation bit");
111 assert(data >= 0 &&
"cannot encode signed integers");
131 template <
typename T>
char convert(T rawValue) {
132 return static_cast<char>(rawValue);
150 static_assert(!ElementTy::IsCompound,
"arrays can only contain scalar types");
155 ElementTy::emitOp(abbrev);
166 FieldTy::emitOp(abbrev);
174 template <
typename FieldTy,
typename Next,
typename... Rest>
176 static_assert(!FieldTy::IsCompound,
177 "arrays and blobs may not appear in the middle of a record");
178 FieldTy::emitOp(abbrev);
179 emitOps<Next, Rest...>(abbrev);
187 template <
typename BufferTy,
typename ElementDataTy,
typename... DataTy>
189 unsigned code, ElementDataTy element, DataTy &&...data) {
190 static_assert(!ElementTy::IsCompound,
191 "arrays and blobs may not appear in the middle of a record");
192 ElementTy::assertValid(element);
193 buffer.push_back(element);
195 std::forward<DataTy>(data)...);
198 template <
typename T,
typename ElementDataTy,
typename... DataTy>
201 assert(!buffer.
empty() &&
"too few elements in buffer");
202 element = ElementTy::convert(buffer.
front());
204 std::forward<DataTy>(data)...);
207 template <
typename T,
typename... DataTy>
209 assert(!buffer.
empty() &&
"too few elements in buffer");
211 std::forward<DataTy>(data)...);
224 template <
typename BufferTy,
typename DataTy>
226 unsigned code,
const DataTy &data) {
227 static_assert(!ElementTy::IsCompound,
228 "arrays and blobs need special handling");
229 ElementTy::assertValid(data);
230 buffer.push_back(data);
234 template <
typename T,
typename DataTy>
236 assert(buffer.
size() == 1 &&
"record data does not match layout");
237 data = ElementTy::convert(buffer.
front());
241 assert(buffer.
size() == 1 &&
"record data does not match layout");
253 template <
typename BufferTy>
260 template <
typename BufferTy,
typename ArrayTy>
262 unsigned code,
const ArrayTy &array) {
264 for (
auto &element : array)
265 ElementTy::assertValid(element);
267 buffer.reserve(buffer.size() + std::distance(array.begin(), array.end()));
268 std::copy(array.begin(), array.end(), std::back_inserter(buffer));
272 template <
typename BufferTy,
typename ElementDataTy,
typename... DataTy>
274 unsigned code, ElementDataTy element, DataTy... data) {
275 std::array<ElementDataTy, 1 +
sizeof...(data)> array{{element, data...}};
279 template <
typename BufferTy>
285 template <
typename T>
290 template <
typename T,
typename ArrayTy>
308 template <
typename BufferTy>
318 template <
typename T,
typename DataTy>
330 template <
typename... Types>
337 template <
typename E>
static bool check(
BCArray<E> *);
338 static int check(...);
342 static constexpr
bool value = !std::is_same<decltype(check((T *)
nullptr)),
343 decltype(check(
false))>
::value;
348 template <
typename... Types>
374 template <
typename BufferTy,
typename...
Data>
375 void emit(BufferTy &buffer,
unsigned id,
Data &&...data)
const {
383 auto Abbrev = std::make_shared<llvm::BitCodeAbbrev>();
395 template <
typename BufferTy,
typename...
Data>
397 unsigned abbrCode,
unsigned recordID,
Data &&...data) {
398 static_assert(
sizeof...(data) <=
sizeof...(Fields) ||
400 "Too many record elements");
401 static_assert(
sizeof...(data) >=
sizeof...(Fields),
402 "Too few record elements");
405 Stream, buffer, abbrCode, recordID, std::forward<Data>(data)...);
413 template <
typename ElementTy,
typename...
Data>
415 static_assert(
sizeof...(data) <=
sizeof...(Fields),
416 "Too many record elements");
417 static_assert(
sizeof...(Fields) <=
419 "Too few record elements");
421 std::forward<Data>(data)...);
429 template <
typename BufferTy,
typename...
Data>
436 template <
unsigned RecordCode,
typename... Fields>
454 template <
typename BufferTy,
typename...
Data>
455 void emit(BufferTy &buffer,
Data &&...data)
const {
456 Base::emit(buffer, RecordCode, std::forward<Data>(data)...);
464 template <
typename BufferTy,
typename...
Data>
466 unsigned abbrCode,
Data &&...data) {
468 std::forward<Data>(data)...);
we get the following basic block
Represents an untyped blob of bytes.
static void assertValid(const T &data)
static constexpr bool value
void EmitRecordWithBlob(unsigned Abbrev, const Container &Vals, StringRef Blob)
EmitRecordWithBlob - Emit the specified record to the stream, using an abbrev that includes a blob at...
This class represents lattice values for constants.
static void readRecord(ArrayRef< ElementTy > buffer, Data &&...data)
Extract record data from buffer into the given data fields.
static void emit(llvm::BitstreamWriter &Stream, BufferTy &buffer, unsigned code, const DataTy &data)
static void assertValid(const T &data)
void Add(const BitCodeAbbrevOp &OpInfo)
const unsigned AbbrevCode
The abbreviation code used for this record in the current block.
static bool isChar6(char C)
isChar6 - Return true if this character is legal in the Char6 encoding.
static void assertValid(const T &data)
Convenience base for all kinds of bitcode abbreviation fields.
static void emitOp(llvm::BitCodeAbbrev &abbrev)
BCGenericRecordLayout(llvm::BitstreamWriter &Stream)
Create a layout and register it with the given bitstream writer.
bool empty() const
empty - Check if the array is empty.
mapped_iterator< ItTy, FuncTy > map_iterator(ItTy I, FuncTy F)
static void emitOp(llvm::BitCodeAbbrev &abbrev)
static void emit(llvm::BitstreamWriter &Stream, BufferTy &buffer, unsigned code, ElementDataTy element, DataTy... data)
void emit(BufferTy &buffer, unsigned id, Data &&...data) const
Emit a record to the bitstream writer, using the given buffer for scratch space.
void EnterSubblock(unsigned BlockID, unsigned CodeLen)
Represents an array of some other type.
std::is_same< BCBlob, typename last_type< int, Types... >::type > has_blob
A type trait whose value field is true if the last type is BCBlob.
Clang compiles this i1 i64 store i64 i64 store i64 i64 store i64 i64 store i64 align Which gets codegen d xmm0 movaps rbp movaps rbp movaps rbp movaps rbp rbp rbp rbp rbp It would be better to have movq s of instead of the movaps s LLVM produces ret int
static void read(ArrayRef< T > buffer, NoneType)
BCRecordLayout(llvm::BitstreamWriter &Stream)
Create a layout and register it with the given bitstream writer.
static void assertValid(const bool &data)
static void emitRecord(llvm::BitstreamWriter &Stream, BufferTy &buffer, unsigned abbrCode, Data &&...data)
Emit a record identified by abbrCode to bitstream reader Stream, using buffer for scratch space.
Represents a single bitcode record type.
unsigned EmitAbbrev(std::shared_ptr< BitCodeAbbrev > Abbv)
Emits the abbreviation Abbv to the stream.
static void emitOps(llvm::BitCodeAbbrev &abbrev)
Attaches the last field to an abbreviation.
BCBlockRAII(llvm::BitstreamWriter &Stream, unsigned block, unsigned abbrev)
void EmitRecordWithArray(unsigned Abbrev, const Container &Vals, StringRef Array)
EmitRecordWithArray - Just like EmitRecordWithBlob, works with records that end with an array.
static T convert(T rawValue)
Converts a raw numeric representation of this value to its preferred type.
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
static void read(ArrayRef< T > buffer)
A type trait whose type field is the last of its template parameters.
static void read(ArrayRef< T > buffer, NoneType, DataTy &&...data)
Represents a character encoded in LLVM's Char6 encoding.
AMD64 Optimization Manual has some nice information about optimizing integer multiplication by a constant How much of it applies to Intel s X86 implementation There are definite trade offs to xmm0 cvttss2siq rdx jb L3 subss xmm0 rax cvttss2siq rdx xorq rdx rax ret instead of xmm1 cvttss2siq rcx movaps xmm2 subss xmm2 cvttss2siq rax rdx xorq rax ucomiss xmm0 cmovb rax ret Seems like the jb branch has high likelihood of being taken It would have saved a few instructions It s not possible to reference and DH registers in an instruction requiring REX prefix divb and mulb both produce results in AH If isel emits a CopyFromReg which gets turned into a movb and that can be allocated a r8b r15b To get around isel emits a CopyFromReg from AX and then right shift it down by and truncate it It s not pretty but it works We need some register allocation magic to make the hack go which would often require a callee saved register Callees usually need to keep this value live for most of their body so it doesn t add a significant burden on them We currently implement this in however this is suboptimal because it means that it would be quite awkward to implement the optimization for callers A better implementation would be to relax the LLVM IR rules for sret arguments to allow a function with an sret argument to have a non void return type
static void emit(llvm::BitstreamWriter &Stream, BufferTy &buffer, unsigned code, StringRef data)
static void read(ArrayRef< T > buffer, NoneType)
static void read(ArrayRef< T > buffer, ElementDataTy &element, DataTy &&...data)
static void emitOp(llvm::BitCodeAbbrev &abbrev)
static void assertValid(const T &data)
Asserts that the given data is a valid value for this field.
NoneType
A simple null object to allow implicit construction of Optional<T> and similar types without having t...
static void readRecord(BufferTy &buffer, Data &&...data)
Extract record data from buffer into the given data fields.
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
static void emit(llvm::BitstreamWriter &Stream, BufferTy &buffer, unsigned code, ElementDataTy element, DataTy &&...data)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Represents a fixed-width value in a bitcode record.
static void emit(llvm::BitstreamWriter &Stream, BufferTy &Buffer, unsigned code, NoneType)
Helper class for dealing with a scalar element in the middle of a record.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
StringRef - Represent a constant reference to a string, i.e.
static void assertValid(const T &data)
static const bool IsCompound
const T & front() const
front - Get the first element.
RAII object to pair entering and exiting a sub-block.
void emit(BufferTy &buffer, Data &&...data) const
Emit a record to the bitstream writer, using the given buffer for scratch space.
@ Tail
Tail - This calling convention attemps to make calls as fast as possible while guaranteeing that tail...
static void emit(llvm::BitstreamWriter &Stream, BufferTy &buffer, unsigned code, StringRef data)
static void emitOp(llvm::BitCodeAbbrev &abbrev)
*Add support for compiling functions in both ARM and Thumb then taking the smallest *Add support for compiling individual basic blocks in thumb when in a larger ARM function This can be used for presumed cold code
static void emitOp(llvm::BitCodeAbbrev &abbrev)
static void read(ArrayRef< T > buffer, ArrayTy &array)
static void emitOp(llvm::BitCodeAbbrev &abbrev)
Represents a variable-width value in a bitcode record.
static void emit(llvm::BitstreamWriter &Stream, BufferTy &buffer, unsigned code, const ArrayTy &array)
Represents a literal operand in a bitcode record.
void EmitRecordWithAbbrev(unsigned Abbrev, const Container &Vals)
EmitRecordWithAbbrev - Emit a record with the specified abbreviation.
A type trait whose value field is true if the given type is a BCArray (of any element kind).
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
BitCodeAbbrevOp - This describes one or more operands in an abbreviation.
static void read(ArrayRef< T > buffer, DataTy &data)
BitCodeAbbrev - This class represents an abbreviation record.
static void read(ArrayRef< T > Buffer, ArrayRef< T > &rawData)
size_t size() const
size - Get the array size.
typename last_type< Tail... >::type type
A record with a fixed record code.
static void emitRecord(llvm::BitstreamWriter &Stream, BufferTy &buffer, unsigned abbrCode, unsigned recordID, Data &&...data)
Emit a record identified by abbrCode to bitstream reader Stream, using buffer for scratch space.
we should consider alternate ways to model stack dependencies Lots of things could be done in WebAssemblyTargetTransformInfo cpp there are numerous optimization related hooks that can be overridden in WebAssemblyTargetLowering Instead of the OptimizeReturned which should consider preserving the returned attribute through to MachineInstrs and extending the MemIntrinsicResults pass to do this optimization on calls too That would also let the WebAssemblyPeephole pass clean up dead defs for such as it does for stores Consider implementing and or getMachineCombinerPatterns Find a clean way to fix the problem which leads to the Shrink Wrapping pass being run after the WebAssembly PEI pass When setting multiple variables to the same we currently get code like const It could be done with a smaller encoding like local tee $pop5 local copy
@ Code
The record code associated with this layout.
LLVM Value Representation.
static unsigned emitAbbrev(llvm::BitstreamWriter &Stream)
Registers this record's layout with the bitstream reader.