Go to the documentation of this file.
9 #ifndef LLVM_OBJECT_STACKMAPPARSER_H
10 #define LLVM_OBJECT_STACKMAPPARSER_H
24 template <support::endianness Endianness>
27 template <
typename AccessorT>
40 return A.P ==
Other.A.P;
44 return !(*
this ==
Other);
61 return read<uint64_t>(
P);
66 return read<uint64_t>(
P +
sizeof(
uint64_t));
71 return read<uint64_t>(
P + (2 *
sizeof(
uint64_t)));
77 const static int FunctionAccessorSize = 3 *
sizeof(
uint64_t);
79 FunctionAccessor next()
const {
80 return FunctionAccessor(
P + FunctionAccessorSize);
97 const static int ConstantAccessorSize =
sizeof(
uint64_t);
99 ConstantAccessor next()
const {
100 return ConstantAccessor(
P + ConstantAccessorSize);
123 return read<uint16_t>(
P + SizeOffset);
129 return read<uint16_t>(
P + DwarfRegNumOffset);
135 return read<uint32_t>(
P + SmallConstantOffset);
141 "Not a constant-index.");
142 return read<uint32_t>(
P + SmallConstantOffset);
149 "Not direct or indirect.");
150 return read<int32_t>(
P + SmallConstantOffset);
156 LocationAccessor next()
const {
157 return LocationAccessor(
P + LocationAccessorSize);
160 static const int KindOffset = 0;
161 static const int SizeOffset = KindOffset +
sizeof(
uint16_t);
162 static const int DwarfRegNumOffset = SizeOffset +
sizeof(
uint16_t);
163 static const int SmallConstantOffset = DwarfRegNumOffset +
sizeof(
uint32_t);
164 static const int LocationAccessorSize =
sizeof(
uint64_t) +
sizeof(
uint32_t);
177 return read<uint16_t>(
P + DwarfRegNumOffset);
182 return read<uint8_t>(
P + SizeOffset);
188 LiveOutAccessor next()
const {
189 return LiveOutAccessor(
P + LiveOutAccessorSize);
192 static const int DwarfRegNumOffset = 0;
193 static const int SizeOffset =
194 DwarfRegNumOffset +
sizeof(
uint16_t) +
sizeof(uint8_t);
195 static const int LiveOutAccessorSize =
sizeof(
uint32_t);
210 return read<uint64_t>(
P + PatchpointIDOffset);
216 return read<uint32_t>(
P + InstructionOffsetOffset);
221 return read<uint16_t>(
P + NumLocationsOffset);
226 unsigned LocationOffset =
248 return read<uint16_t>(
P + getNumLiveOutsOffset());
253 unsigned LiveOutOffset =
254 getNumLiveOutsOffset() +
sizeof(
uint16_t) + LiveOutIndex * LiveOutSize;
276 unsigned getNumLiveOutsOffset()
const {
279 return LocOffset +
sizeof(
uint16_t);
283 unsigned RecordSize =
285 return (RecordSize + 7) & ~0x7;
288 RecordAccessor next()
const {
292 static const unsigned PatchpointIDOffset = 0;
293 static const unsigned InstructionOffsetOffset =
294 PatchpointIDOffset +
sizeof(
uint64_t);
295 static const unsigned NumLocationsOffset =
297 static const unsigned LocationListOffset =
298 NumLocationsOffset +
sizeof(
uint16_t);
300 static const unsigned LiveOutSize =
sizeof(
uint32_t);
308 : StackMapSection(StackMapSection) {
309 ConstantsListOffset = FunctionListOffset +
getNumFunctions() * FunctionSize;
311 assert(StackMapSection[0] == 3 &&
312 "StackMapParser can only parse version 3 stackmaps");
314 unsigned CurrentRecordOffset =
318 StackMapRecordOffsets.push_back(CurrentRecordOffset);
319 CurrentRecordOffset +=
320 RecordAccessor(&StackMapSection[CurrentRecordOffset]).getSizeInBytes();
327 if (StackMapSection.
size() < 16)
329 "the stack map section size (" +
Twine(StackMapSection.
size()) +
330 ") is less than the minimum possible size of its header (16)");
332 unsigned Version = StackMapSection[0];
336 ") of the stack map section is unsupported, the "
337 "supported version is 3");
350 return read<uint32_t>(&StackMapSection[NumFunctionsOffset]);
355 return read<uint32_t>(&StackMapSection[NumConstantsOffset]);
360 return read<uint32_t>(&StackMapSection[NumRecordsOffset]);
366 getFunctionOffset(FunctionIndex));
389 getConstantOffset(ConstantIndex));
411 std::size_t RecordOffset = StackMapRecordOffsets[RecordIndex];
438 template <
typename T>
439 static T read(
const uint8_t *
P) {
440 return support::endian::read<T, Endianness, 1>(
P);
443 static const unsigned HeaderOffset = 0;
444 static const unsigned NumFunctionsOffset = HeaderOffset +
sizeof(
uint32_t);
445 static const unsigned NumConstantsOffset = NumFunctionsOffset +
sizeof(
uint32_t);
446 static const unsigned NumRecordsOffset = NumConstantsOffset +
sizeof(
uint32_t);
447 static const unsigned FunctionListOffset = NumRecordsOffset +
sizeof(
uint32_t);
449 static const unsigned FunctionSize = 3 *
sizeof(
uint64_t);
450 static const unsigned ConstantSize =
sizeof(
uint64_t);
452 std::size_t getFunctionOffset(
unsigned FunctionIndex)
const {
453 return FunctionListOffset + FunctionIndex * FunctionSize;
456 std::size_t getConstantOffset(
unsigned ConstantIndex)
const {
457 return ConstantsListOffset + ConstantIndex * ConstantSize;
460 ArrayRef<uint8_t> StackMapSection;
461 unsigned ConstantsListOffset;
462 std::vector<unsigned> StackMapRecordOffsets;
467 #endif // LLVM_OBJECT_STACKMAPPARSER_H
This is an optimization pass for GlobalISel generic memory operations.
uint64_t getRecordCount() const
Get the number of callsite records.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
AccessorIterator< ConstantAccessor > constant_iterator
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
constant_iterator constants_end() const
End iterator for constants.
static ErrorSuccess success()
Create a success value.
unsigned getVersion() const
Get the version number of this stackmap. (Always returns 3).
uint16_t getDwarfRegNum() const
Get the Dwarf register number for this live-out.
FunctionAccessor getFunction(unsigned FunctionIndex) const
Return an FunctionAccessor for the given function index.
StackMapParser(ArrayRef< uint8_t > StackMapSection)
Construct a parser for a version-3 stackmap.
uint64_t getValue() const
Return the value of this constant.
alloca< 16 x float >, align 16 %tmp2=alloca< 16 x float >, align 16 store< 16 x float > %A,< 16 x float > *%tmp %s=bitcast< 16 x float > *%tmp to i8 *%s2=bitcast< 16 x float > *%tmp2 to i8 *call void @llvm.memcpy.i64(i8 *%s, i8 *%s2, i64 64, i32 16) %R=load< 16 x float > *%tmp2 ret< 16 x float > %R } declare void @llvm.memcpy.i64(i8 *nocapture, i8 *nocapture, i64, i32) nounwind which compiles to:_foo:subl $140, %esp movaps %xmm3, 112(%esp) movaps %xmm2, 96(%esp) movaps %xmm1, 80(%esp) movaps %xmm0, 64(%esp) movl 60(%esp), %eax movl %eax, 124(%esp) movl 56(%esp), %eax movl %eax, 120(%esp) movl 52(%esp), %eax< many many more 32-bit copies > movaps(%esp), %xmm0 movaps 16(%esp), %xmm1 movaps 32(%esp), %xmm2 movaps 48(%esp), %xmm3 addl $140, %esp ret On Nehalem, it may even be cheaper to just use movups when unaligned than to fall back to lower-granularity chunks. Implement processor-specific optimizations for parity with GCC on these processors. GCC does two optimizations:1. ix86_pad_returns inserts a noop before ret instructions if immediately preceded by a conditional branch or is the target of a jump. 2. ix86_avoid_jump_misspredicts inserts noops in cases where a 16-byte block of code contains more than 3 branches. The first one is done for all AMDs, Core2, and "Generic" The second one is done for:Atom, Pentium Pro, all AMDs, Pentium 4, Nocona, Core 2, and "Generic" Testcase:int x(int a) { return(a &0xf0)> >4 tmp
uint64_t getID() const
Get the patchpoint/stackmap ID for this record.
uint32_t getNumConstants() const
Get the number of large constants in the stack map.
int32_t getOffset() const
Get the offset for this location. (Kind must be Direct or Indirect).
AccessorIterator(AccessorT A)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
liveout_iterator liveouts_end() const
End iterator for live-outs.
uint16_t getDwarfRegNum() const
Get the Dwarf register number for this location.
Accessor for stackmap records.
bool operator==(const AccessorIterator &Other) const
iterator_range< function_iterator > functions() const
Iterator range for functions.
function_iterator functions_begin() const
Begin iterator for functions.
AccessorIterator & operator++()
uint32_t getNumFunctions() const
Get the number of functions in the stack map.
This is an important base class in LLVM.
function_iterator functions_end() const
End iterator for functions.
liveout_iterator liveouts_begin() const
Begin iterator for live-outs.
uint32_t getInstructionOffset() const
Get the instruction offset (from the start of the containing function) for this record.
AccessorIterator operator++(int)
Accessor for function records.
unsigned getSizeInBytes() const
Get the Size for this location.
location_iterator location_end() const
End iterator for locations.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
iterator_range< constant_iterator > constants() const
Iterator range for constants.
unsigned getSizeInBytes() const
Get the size in bytes of live [sub]register.
constant_iterator constants_begin() const
Begin iterator for constants.
uint32_t getNumRecords() const
Get the number of stackmap records in the stackmap.
RecordAccessor getRecord(unsigned RecordIndex) const
Return a RecordAccessor for the given record index.
AccessorIterator< LiveOutAccessor > liveout_iterator
uint32_t getConstantIndex() const
Get the constant-index for this location. (Kind must be ConstantIndex).
uint64_t getStackSize() const
Get the function's stack size.
iterator_range< record_iterator > records() const
Iterator range for records.
Wrapper class representing virtual and physical registers.
Accessor for stackmap live-out fields.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
iterator_range< location_iterator > locations() const
Iterator range for locations.
value_type read(const void *memory, endianness endian)
Read a value of a particular endianness from memory.
Lightweight error class with error context and mandatory checking.
ConstantAccessor getConstant(unsigned ConstantIndex) const
Return the large constant at the given index.
uint64_t getFunctionAddress() const
Get the function address.
LocationAccessor getLocation(unsigned LocationIndex) const
Get the location with the given index.
uint16_t getNumLiveOuts() const
Get the number of liveouts contained in this record.
AccessorIterator< FunctionAccessor > function_iterator
uint32_t getSmallConstant() const
Get the small-constant for this location. (Kind must be Constant).
bool operator!=(const AccessorIterator &Other) const
AccessorIterator< RecordAccessor > record_iterator
size_t size() const
size - Get the array size.
uint16_t getNumLocations() const
Get the number of locations contained in this record.
A range adaptor for a pair of iterators.
LiveOutAccessor getLiveOut(unsigned LiveOutIndex) const
Get the live-out with the given index.
Error createError(const Twine &Err)
Accessor for location records.
A parser for the latest stackmap format. At the moment, latest=V3.
static Error validateHeader(ArrayRef< uint8_t > StackMapSection)
Validates the header of the specified stack map section.
AccessorIterator< LocationAccessor > location_iterator
record_iterator records_begin() const
Begin iterator for records.
LocationKind getKind() const
Get the Kind for this location.
record_iterator records_end() const
End iterator for records.
Optional< std::vector< StOtherPiece > > Other
iterator_range< liveout_iterator > liveouts() const
Iterator range for live-outs.
location_iterator location_begin() const
Begin iterator for locations.