Skip to content

Commit fe03904

Browse files
EgorBojakobbotsch
andauthored
JIT: Intrinsify UTF16->UTF8 conversion for string literals (Encoding.UTF8.TryGetBytes) (#85328)
Co-authored-by: Jakob Botsch Nielsen <[email protected]>
1 parent 65536eb commit fe03904

File tree

11 files changed

+695
-15
lines changed

11 files changed

+695
-15
lines changed

src/coreclr/jit/compiler.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4877,6 +4877,7 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
48774877
bool doBranchOpt = true;
48784878
bool doCse = true;
48794879
bool doAssertionProp = true;
4880+
bool doVNBasedIntrinExpansion = true;
48804881
bool doRangeAnalysis = true;
48814882
bool doVNBasedDeadStoreRemoval = true;
48824883
int iterations = 1;
@@ -4890,6 +4891,7 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
48904891
doBranchOpt = doValueNum && (JitConfig.JitDoRedundantBranchOpts() != 0);
48914892
doCse = doValueNum;
48924893
doAssertionProp = doValueNum && (JitConfig.JitDoAssertionProp() != 0);
4894+
doVNBasedIntrinExpansion = doValueNum;
48934895
doRangeAnalysis = doAssertionProp && (JitConfig.JitDoRangeAnalysis() != 0);
48944896
doVNBasedDeadStoreRemoval = doValueNum && (JitConfig.JitDoVNBasedDeadStoreRemoval() != 0);
48954897

@@ -4973,6 +4975,13 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
49734975
DoPhase(this, PHASE_ASSERTION_PROP_MAIN, &Compiler::optAssertionPropMain);
49744976
}
49754977

4978+
if (doVNBasedIntrinExpansion)
4979+
{
4980+
// Expand some intrinsics based on VN data
4981+
//
4982+
DoPhase(this, PHASE_VN_BASED_INTRINSIC_EXPAND, &Compiler::fgVNBasedIntrinsicExpansion);
4983+
}
4984+
49764985
if (doRangeAnalysis)
49774986
{
49784987
// Bounds check elimination via range analysis

src/coreclr/jit/compiler.h

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5214,6 +5214,8 @@ class Compiler
52145214
}
52155215
}
52165216

5217+
bool GetObjectHandleAndOffset(GenTree* tree, ssize_t* byteOffset, CORINFO_OBJECT_HANDLE* pObj);
5218+
52175219
// Convert a BYTE which represents the VM's CorInfoGCtype to the JIT's var_types
52185220
var_types getJitGCType(BYTE gcType);
52195221

@@ -5357,6 +5359,10 @@ class Compiler
53575359
PhaseStatus fgExpandStaticInit();
53585360
bool fgExpandStaticInitForCall(BasicBlock** pBlock, Statement* stmt, GenTreeCall* call);
53595361

5362+
PhaseStatus fgVNBasedIntrinsicExpansion();
5363+
bool fgVNBasedIntrinsicExpansionForCall(BasicBlock** pBlock, Statement* stmt, GenTreeCall* call);
5364+
bool fgVNBasedIntrinsicExpansionForCall_ReadUtf8(BasicBlock** pBlock, Statement* stmt, GenTreeCall* call);
5365+
53605366
PhaseStatus fgInsertGCPolls();
53615367
BasicBlock* fgCreateGCPoll(GCPollType pollType, BasicBlock* block);
53625368

@@ -7087,6 +7093,7 @@ class Compiler
70877093
#define OMF_HAS_MDARRAYREF 0x00004000 // Method contains multi-dimensional intrinsic array element loads or stores.
70887094
#define OMF_HAS_STATIC_INIT 0x00008000 // Method has static initializations we might want to partially inline
70897095
#define OMF_HAS_TLS_FIELD 0x00010000 // Method contains TLS field access
7096+
#define OMF_HAS_SPECIAL_INTRINSICS 0x00020000 // Method contains special intrinsics expanded in late phases
70907097

70917098
// clang-format on
70927099

@@ -7147,6 +7154,16 @@ class Compiler
71477154
optMethodFlags |= OMF_HAS_TLS_FIELD;
71487155
}
71497156

7157+
bool doesMethodHaveSpecialIntrinsics()
7158+
{
7159+
return (optMethodFlags & OMF_HAS_SPECIAL_INTRINSICS) != 0;
7160+
}
7161+
7162+
void setMethodHasSpecialIntrinsics()
7163+
{
7164+
optMethodFlags |= OMF_HAS_SPECIAL_INTRINSICS;
7165+
}
7166+
71507167
void pickGDV(GenTreeCall* call,
71517168
IL_OFFSET ilOffset,
71527169
bool isInterface,
@@ -8947,7 +8964,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
89478964

89488965
public:
89498966
// Similar to roundUpSIMDSize, but for General Purpose Registers (GPR)
8950-
unsigned int roundUpGPRSize(unsigned size)
8967+
unsigned roundUpGPRSize(unsigned size)
89518968
{
89528969
if (size > 4 && (REGSIZE_BYTES == 8))
89538970
{
@@ -8960,6 +8977,33 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
89608977
return size; // 2, 1, 0
89618978
}
89628979

8980+
var_types roundDownMaxType(unsigned size)
8981+
{
8982+
assert(size > 0);
8983+
var_types result = TYP_UNDEF;
8984+
#ifdef FEATURE_SIMD
8985+
if (IsBaselineSimdIsaSupported() && (roundDownSIMDSize(size) > 0))
8986+
{
8987+
return getSIMDTypeForSize(roundDownSIMDSize(size));
8988+
}
8989+
#endif
8990+
int nearestPow2 = 1 << BitOperations::Log2((unsigned)size);
8991+
switch (min(nearestPow2, REGSIZE_BYTES))
8992+
{
8993+
case 1:
8994+
return TYP_UBYTE;
8995+
case 2:
8996+
return TYP_USHORT;
8997+
case 4:
8998+
return TYP_INT;
8999+
case 8:
9000+
assert(REGSIZE_BYTES == 8);
9001+
return TYP_LONG;
9002+
default:
9003+
unreached();
9004+
}
9005+
}
9006+
89639007
enum UnrollKind
89649008
{
89659009
Memset,

src/coreclr/jit/compphases.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ CompPhaseNameMacro(PHASE_VALUE_NUMBER, "Do value numbering",
8686
CompPhaseNameMacro(PHASE_OPTIMIZE_INDEX_CHECKS, "Optimize index checks", false, -1, false)
8787
CompPhaseNameMacro(PHASE_OPTIMIZE_VALNUM_CSES, "Optimize Valnum CSEs", false, -1, false)
8888
CompPhaseNameMacro(PHASE_VN_COPY_PROP, "VN based copy prop", false, -1, false)
89+
CompPhaseNameMacro(PHASE_VN_BASED_INTRINSIC_EXPAND, "VN based intrinsic expansion", false, -1, false)
8990
CompPhaseNameMacro(PHASE_OPTIMIZE_BRANCHES, "Redundant branch opts", false, -1, false)
9091
CompPhaseNameMacro(PHASE_ASSERTION_PROP_MAIN, "Assertion prop", false, -1, false)
9192
CompPhaseNameMacro(PHASE_IF_CONVERSION, "If conversion", false, -1, false)

0 commit comments

Comments
 (0)