Skip to content

Commit

Permalink
Pgo phase3 (#47558)
Browse files Browse the repository at this point in the history
- Fix class type probes (the increment of the count wasn't correct)
- Use the 64bit integer encoders for all the pgo data
- New section for R2R PE Files containing instrumentation data
- R2RDump functionality to display all the data embedded in the file
- Enable BBOPT for optimized builds in a more unconditional fashion

Future PGO work will include
- Move Pgo type handle histogram processing into JIT (which will make type guessing work in crossgen2 as well as in the runtime)
- Triggers for controlling Pgo data extraction
- Size control for pgo instrumentation data

With this checkin, the feature is functional from a crossgen2.exe point of view, but its not polished, and it cannot be used from the Crossgen2 sdk integration yet (as the sdk does not have the ability to pass an extra pair of arguments to the compiler.
  • Loading branch information
davidwrighton committed Feb 2, 2021
1 parent 35f4dad commit afa50f9
Show file tree
Hide file tree
Showing 32 changed files with 1,149 additions and 105 deletions.
1 change: 0 additions & 1 deletion src/coreclr/inc/corjit.h
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,6 @@ class ICorJitInfo : public ICorDynamicInfo
OFFSET_MASK = 0x3FFFFFFF
};

UINT32 ILOffset;
UINT32 Count;
CORINFO_CLASS_HANDLE ClassTable[SIZE];
};
Expand Down
42 changes: 4 additions & 38 deletions src/coreclr/inc/pgo_formatprocessing.h
Original file line number Diff line number Diff line change
Expand Up @@ -381,40 +381,6 @@ inline bool ReadInstrumentationSchemaWithLayoutIntoSArray(const uint8_t *pByte,
return ReadInstrumentationSchemaWithLayout(pByte, cbDataMax, initialOffset, lambda);
}


template<class ByteWriter>
bool WriteCompressedIntToBytes(int32_t value, ByteWriter& byteWriter)
{
uint8_t isSigned = 0;

// This function is modeled on CorSigCompressSignedInt, but differs in that
// it handles arbitrary int32 values, not just a subset
if (value < 0)
isSigned = 1;

if ((value & SIGN_MASK_ONEBYTE) == 0 || (value & SIGN_MASK_ONEBYTE) == SIGN_MASK_ONEBYTE)
{
return byteWriter((uint8_t)((value & ~SIGN_MASK_ONEBYTE) << 1 | isSigned));
}
else if ((value & SIGN_MASK_TWOBYTE) == 0 || (value & SIGN_MASK_TWOBYTE) == SIGN_MASK_TWOBYTE)
{
int32_t iData = (int32_t)((value & ~SIGN_MASK_TWOBYTE) << 1 | isSigned);
_ASSERTE(iData <= 0x3fff);
byteWriter(uint8_t((iData >> 8) | 0x80));
return byteWriter(uint8_t(iData & 0xff));
}
else
{
// Unlike CorSigCompressSignedInt, this just writes a header byte
// then a full 4 bytes, ignoring the whole signed bit detail
byteWriter(0xC0);
byteWriter(uint8_t((value >> 24) & 0xff));
byteWriter(uint8_t((value >> 16) & 0xff));
byteWriter(uint8_t((value >> 8) & 0xff));
return byteWriter(uint8_t((value >> 0) & 0xff));
}
}

#define SIGN_MASK_ONEBYTE_64BIT 0xffffffffffffffc0LL
#define SIGN_MASK_TWOBYTE_64BIT 0xffffffffffffe000LL
#define SIGN_MASK_FOURBYTE_64BIT 0xffffffff80000000LL
Expand Down Expand Up @@ -469,10 +435,10 @@ bool WriteCompressedIntToBytes(int64_t value, ByteWriter& byteWriter)
template<class ByteWriter>
bool WriteIndividualSchemaToBytes(ICorJitInfo::PgoInstrumentationSchema prevSchema, ICorJitInfo::PgoInstrumentationSchema curSchema, ByteWriter& byteWriter)
{
int32_t ilOffsetDiff = curSchema.ILOffset - prevSchema.ILOffset;
int32_t OtherDiff = curSchema.Other - prevSchema.Other;
int32_t CountDiff = curSchema.Count - prevSchema.Count;
int32_t TypeDiff = (int32_t)curSchema.InstrumentationKind - (int32_t)prevSchema.InstrumentationKind;
int64_t ilOffsetDiff = (int64_t)curSchema.ILOffset - (int64_t)prevSchema.ILOffset;
int64_t OtherDiff = (int64_t)curSchema.Other - (int64_t)prevSchema.Other;
int64_t CountDiff = (int64_t)curSchema.Count - (int64_t)prevSchema.Count;
int64_t TypeDiff = (int64_t)curSchema.InstrumentationKind - (int64_t)prevSchema.InstrumentationKind;

InstrumentationDataProcessingState modifyMask = (InstrumentationDataProcessingState)0;

Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/inc/readytorun.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

// Keep these in sync with src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs
#define READYTORUN_MAJOR_VERSION 0x0005
#define READYTORUN_MINOR_VERSION 0x0001
#define READYTORUN_MINOR_VERSION 0x0002

#define MINIMUM_READYTORUN_MAJOR_VERSION 0x003

Expand Down Expand Up @@ -79,6 +79,7 @@ enum class ReadyToRunSectionType : uint32_t
InliningInfo2 = 114, // Added in V4.1
ComponentAssemblies = 115, // Added in V4.1
OwnerCompositeExecutable = 116, // Added in V4.1
PgoInstrumentationData = 117, // Added in 5.2

// If you add a new section consider whether it is a breaking or non-breaking change.
// Usually it is non-breaking, but if it is preferable to have older runtimes fail
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1635,6 +1635,61 @@ internal override void Save(NativeWriter writer)
}
}

#if NATIVEFORMAT_PUBLICWRITER
public
#else
internal
#endif
class PgoInstrumentedDataVertex : Vertex
{
private uint _version;

private BlobVertex _instrumentationData;

public PgoInstrumentedDataVertex(uint version, BlobVertex instrumentationData)
{
_version = version;
_instrumentationData = instrumentationData;
}

internal override void Save(NativeWriter writer)
{
int existingOffset = _instrumentationData._offset;
if (existingOffset != -1)
{
writer.WriteUnsigned((_version << 2) | 3);
writer.WriteUnsigned((uint)(writer.GetCurrentOffset() - existingOffset));
}
else
{
writer.WriteUnsigned((_version << 2) | 1);
_instrumentationData.Save(writer);
}
}
}

#if NATIVEFORMAT_PUBLICWRITER
public
#else
internal
#endif
class PgoInstrumentedDataWithSignatureBlobVertex : PgoInstrumentedDataVertex
{
private BlobVertex _signatureBlob;

public PgoInstrumentedDataWithSignatureBlobVertex(BlobVertex signaureBlob, uint version, BlobVertex instrumentationData)
: base(version, instrumentationData)
{
_signatureBlob = signaureBlob;
}

internal override void Save(NativeWriter writer)
{
_signatureBlob.Save(writer);
base.Save(writer);
}
}

#if NATIVEFORMAT_PUBLICWRITER
public
#else
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ internal struct ReadyToRunHeaderConstants
public const uint Signature = 0x00525452; // 'RTR'

public const ushort CurrentMajorVersion = 5;
public const ushort CurrentMinorVersion = 1;
public const ushort CurrentMinorVersion = 2;
}

#pragma warning disable 0169
Expand Down Expand Up @@ -65,6 +65,7 @@ public enum ReadyToRunSectionType
InliningInfo2 = 114, // Added in 4.1
ComponentAssemblies = 115, // Added in 4.1
OwnerCompositeExecutable = 116, // Added in 4.1
PgoInstrumentationData = 117, // Added in 5.2

//
// CoreRT ReadyToRun sections
Expand Down
19 changes: 18 additions & 1 deletion src/coreclr/tools/Common/Pgo/TypeSystemEntityOrUnknown.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using Internal.TypeSystem;

namespace Internal.Pgo
{
public struct TypeSystemEntityOrUnknown
public struct TypeSystemEntityOrUnknown : IEquatable<TypeSystemEntityOrUnknown>
{
public TypeSystemEntityOrUnknown(int unknownIndex)
{
Expand All @@ -23,5 +24,21 @@ public TypeSystemEntityOrUnknown(TypeDesc type)
public FieldDesc AsField => _data as FieldDesc;
public int AsUnknown => (!(_data is int)) || _data == null ? 0 : (int)_data;
public bool IsNull => _data == null;

public bool Equals(TypeSystemEntityOrUnknown other)
{
if ((_data is int) && (other._data is int))
{
return other.AsUnknown == AsUnknown;
}
else
{
return object.ReferenceEquals(_data, other._data);
}
}

public override int GetHashCode() => _data.GetHashCode();

public override bool Equals(object obj) => obj is TypeSystemEntityOrUnknown other && other.Equals(this);
}
}
Loading

0 comments on commit afa50f9

Please sign in to comment.