Skip to content

Commit bfe5ebb

Browse files
[NativeAOT-LLVM] Avoid unnecessary zeroing in LSSA (#3125)
* Avoid zeroing more than necessary in LSSA * Add a few tests --------- Co-authored-by: yowl <scott.waye@hubse.com>
1 parent c7b7245 commit bfe5ebb

File tree

9 files changed

+936
-165
lines changed

9 files changed

+936
-165
lines changed

src/coreclr/jit/compiler.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2680,6 +2680,10 @@ void Compiler::compInitOptions(JitFlags* jitFlags)
26802680
{
26812681
verboseDump = true;
26822682
}
2683+
2684+
#ifdef TARGET_WASM
2685+
verboseDump |= m_llvm->EnableVerboseDump();
2686+
#endif // TARGET_WASM
26832687
}
26842688
}
26852689

src/coreclr/jit/jitconfigvalues.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,7 @@ RELEASE_CONFIG_INTEGER(JitCheckLlvmIR, "JitCheckLlvmIR", 0)
850850
RELEASE_CONFIG_INTEGER(JitRunLssaTests, "JitRunLssaTests", 0)
851851
RELEASE_CONFIG_INTEGER(JitGcStress, "JitGcStress", 0)
852852

853+
CONFIG_STRING(JitDumpSymbol, "JitDumpSymbol")
853854
CONFIG_STRING(JitEnableLssaRange, "JitEnableLssaRange")
854855
#endif // TARGET_WASM
855856

src/coreclr/jit/llvm.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ Llvm::Llvm(Compiler* compiler)
8282
, m_phiPairs(compiler->getAllocator(CMK_Codegen))
8383
, m_ehModel(GetExceptionHandlingModel())
8484
, m_debugVariablesMap(compiler->getAllocator(CMK_Codegen))
85+
#ifdef DEBUG
86+
, m_optimizationRequirements(compiler->getAllocator(CMK_DebugOnly))
87+
#endif // DEBUG
8588
{
8689
}
8790

@@ -108,6 +111,20 @@ Llvm::Llvm(Compiler* compiler)
108111
#endif // HOST_WINDOWS
109112
}
110113

114+
bool Llvm::EnableVerboseDump()
115+
{
116+
#ifdef DEBUG
117+
const char* dumpSymbolName = JitConfig.JitDumpSymbol();
118+
const char* compilingSymbolName = GetMangledMethodName(m_info->compMethodHnd);
119+
if ((dumpSymbolName != nullptr) && (strcmp(dumpSymbolName, compilingSymbolName) == 0))
120+
{
121+
return true;
122+
}
123+
#endif // DEBUG
124+
125+
return false;
126+
}
127+
111128
var_types Llvm::GetArgTypeForStructWasm(CORINFO_CLASS_HANDLE structHnd, structPassingKind* pPassKind)
112129
{
113130
// Note the managed and unmanaged ABIs are the same in terms of values, but do differ w.r.t by-ref
@@ -806,6 +823,44 @@ void Llvm::GetJitTestInfo(CorInfoLlvmJitTestKind kind, CORINFO_LLVM_JIT_TEST_INF
806823
CallEEApi<EEAI_GetJitTestInfo, CORINFO_GENERIC_HANDLE>(m_pEECorInfo, kind, pInfo);
807824
}
808825

826+
void Llvm::ImposeOptimizationRequirement(GenTree* node, NodeOptimizationRequirement requirement)
827+
{
828+
#ifdef DEBUG
829+
assert(node != nullptr);
830+
*m_optimizationRequirements.LookupPointerOrAdd(node, NOR_NONE) |= requirement;
831+
#endif // DEBUG
832+
}
833+
834+
void Llvm::SatisfyOptimizationRequirement(GenTree* node, NodeOptimizationRequirement requirement)
835+
{
836+
#ifdef DEBUG
837+
assert(node != nullptr);
838+
NodeOptimizationRequirement* pRequired = m_optimizationRequirements.LookupPointer(node);
839+
if (pRequired != nullptr)
840+
{
841+
*pRequired &= ~requirement;
842+
if (*pRequired == NOR_NONE)
843+
{
844+
m_optimizationRequirements.Remove(node);
845+
}
846+
}
847+
#endif // DEBUG
848+
}
849+
850+
void Llvm::VerifyAllOptimizationRequirementsSatisfied()
851+
{
852+
#ifdef DEBUG
853+
if (m_optimizationRequirements.GetCount() != 0)
854+
{
855+
for (GenTree* node : decltype(m_optimizationRequirements)::KeyIteration(&m_optimizationRequirements))
856+
{
857+
_compiler->gtDispTree(node, nullptr, nullptr, true);
858+
}
859+
assert(!"Found nodes with unsatisfied optimization requirements");
860+
}
861+
#endif // DEBUG
862+
}
863+
809864
static SingleThreadedCompilationContext* StartSingleThreadedCompilation(
810865
CorInfoLlvmSingleThreadedCompilationContextFlags flags,
811866
const char* path,

src/coreclr/jit/llvm.h

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@
1414
#include "JitEEApi.Shared.cspp"
1515
#include <new>
1616

17-
// this breaks StringMap.h
18-
#undef NumItems
19-
2017
// TODO-LLVM-Upstream: figure out how to fix these warnings in LLVM headers.
2118
#pragma warning(push)
2219
#pragma warning(disable : 4146)
@@ -215,6 +212,27 @@ inline CallSiteFacts& operator |=(CallSiteFacts& a, CallSiteFacts b)
215212
return a = static_cast<CallSiteFacts>(static_cast<int>(a) | static_cast<int>(b));
216213
}
217214

215+
enum NodeOptimizationRequirement
216+
{
217+
NOR_NONE = 0,
218+
NOR_SHADOW_TAILCALL = 1
219+
};
220+
221+
inline NodeOptimizationRequirement& operator |=(NodeOptimizationRequirement& a, NodeOptimizationRequirement b)
222+
{
223+
return a = static_cast<NodeOptimizationRequirement>(static_cast<int>(a) | static_cast<int>(b));
224+
}
225+
226+
inline NodeOptimizationRequirement& operator &=(NodeOptimizationRequirement& a, NodeOptimizationRequirement b)
227+
{
228+
return a = static_cast<NodeOptimizationRequirement>(static_cast<int>(a) & static_cast<int>(b));
229+
}
230+
231+
inline NodeOptimizationRequirement operator ~(NodeOptimizationRequirement a)
232+
{
233+
return static_cast<NodeOptimizationRequirement>(~static_cast<int>(a));
234+
}
235+
218236
struct ThrowHelperKey
219237
{
220238
unsigned ThrowIndex;
@@ -231,6 +249,14 @@ struct ThrowHelperKey
231249
}
232250
};
233251

252+
struct ThrowHelperCode
253+
{
254+
llvm::BasicBlock* LlvmBlock;
255+
#ifdef DEBUG
256+
bool ShadowTailCalledThrowHelper;
257+
#endif // DEBUG
258+
};
259+
234260
struct PhiPair
235261
{
236262
GenTreeLclVar* StoreNode;
@@ -330,7 +356,7 @@ class Llvm
330356
llvm::IRBuilder<> _builder;
331357
JitHashTable<GenTree*, JitPtrKeyFuncs<GenTree>, Value*> _sdsuMap;
332358
JitHashTable<SSAName, SSAName, Value*> _localsMap;
333-
JitHashTable<ThrowHelperKey, ThrowHelperKey, llvm::BasicBlock*> m_throwHelperBlocksMap;
359+
JitHashTable<ThrowHelperKey, ThrowHelperKey, ThrowHelperCode> m_throwHelperBlocksMap;
334360
jitstd::vector<PhiPair> m_phiPairs;
335361
FunctionInfo* m_functions;
336362

@@ -361,6 +387,10 @@ class Llvm
361387
unsigned m_preciseVirtualUnwindFrameLclNum = BAD_VAR_NUM;
362388
unsigned _llvmArgCount = 0;
363389

390+
#ifdef DEBUG
391+
JitHashTable<GenTree*, JitPtrKeyFuncs<GenTree>, NodeOptimizationRequirement> m_optimizationRequirements;
392+
#endif // DEBUG
393+
364394
// ================================================================================================================
365395
// | General |
366396
// ================================================================================================================
@@ -369,6 +399,7 @@ class Llvm
369399
Llvm(Compiler* compiler);
370400

371401
static void ConfigureDiagnosticOutput();
402+
bool EnableVerboseDump();
372403

373404
var_types GetArgTypeForStructWasm(CORINFO_CLASS_HANDLE structHnd, structPassingKind* pPassKind);
374405
var_types GetReturnTypeForStructWasm(CORINFO_CLASS_HANDLE structHnd, structPassingKind* pPassKind);
@@ -425,6 +456,10 @@ class Llvm
425456
bool IsVirtualUnwindFrameVisible();
426457
void GetJitTestInfo(CorInfoLlvmJitTestKind kind, CORINFO_LLVM_JIT_TEST_INFO* pInfo);
427458

459+
void ImposeOptimizationRequirement(GenTree* node, NodeOptimizationRequirement requirement);
460+
void SatisfyOptimizationRequirement(GenTree* node, NodeOptimizationRequirement requirement);
461+
void VerifyAllOptimizationRequirementsSatisfied();
462+
428463
// ================================================================================================================
429464
// | Type system |
430465
// ================================================================================================================
@@ -495,9 +530,8 @@ class Llvm
495530
void lowerDissolveDependentlyPromotedLocals();
496531
void dissolvePromotedLocal(unsigned lclNum);
497532

498-
void lowerCanonicalizeFirstBlock();
499533
bool isFirstBlockCanonical();
500-
void lowerAndInsertIntoFirstBlock(LIR::Range& range, GenTree* insertAfter = nullptr);
534+
GenTree* lowerAndInsertIntoFirstBlock(LIR::Range& range, GenTree* insertAfter = nullptr);
501535

502536
public:
503537
PhaseStatus AddVirtualUnwindFrame();
@@ -543,7 +577,8 @@ class Llvm
543577

544578
unsigned getShadowFrameSize(unsigned funcIdx) const;
545579
unsigned getCalleeShadowStackOffset(unsigned funcIdx, bool isTailCall) const;
546-
bool canEmitCallAsShadowTailCall(bool callIsInTry, bool callIsInFilter DEBUGARG(const char** pReasonWhyNot)) const;
580+
bool canEmitCallAsShadowTailCall(
581+
bool callIsInTry, bool callIsInFilter DEBUGARG(const char** pReasonWhyNot = nullptr)) const;
547582
bool isPotentialGcSafePoint(GenTree* node) const;
548583
bool isShadowFrameLocal(LclVarDsc* varDsc) const;
549584
bool isShadowStackLocal(unsigned lclNum) const;
@@ -621,19 +656,21 @@ class Llvm
621656
void buildCallFinally(BasicBlock* block);
622657

623658
Value* consumeAddressAndEmitNullCheck(GenTreeIndir* indir);
624-
void emitNullCheckForAddress(GenTree* addr, Value* addrValue);
625-
void emitAlignmentCheckForAddress(GenTree* addr, Value* addrValue, unsigned alignment);
659+
void emitNullCheckForAddress(GenTree* addr, Value* addrValue DEBUGARG(GenTree* indir));
660+
void emitAlignmentCheckForAddress(GenTree* addr, Value* addrValue, unsigned alignment DEBUGARG(GenTree* indir));
626661
bool isAddressAligned(GenTree* addr, unsigned alignment);
627662

628663
Value* consumeInitVal(GenTree* initVal);
629664
void storeObjAtAddress(Value* baseAddress, Value* data, StructDesc* structDesc);
630665
unsigned buildMemCpy(Value* baseAddress, unsigned startOffset, unsigned endOffset, Value* srcAddress);
631666

632-
void emitJumpToThrowHelper(Value* jumpCondValue, CorInfoHelpFunc helperFunc);
633-
Value* emitCheckedArithmeticOperation(llvm::Intrinsic::ID intrinsicId, Value* op1Value, Value* op2Value);
667+
void emitJumpToThrowHelper(Value* jumpCondValue, CorInfoHelpFunc helperFunc DEBUGARG(GenTree* nodeThrowing));
668+
Value* emitCheckedArithmeticOperation(
669+
llvm::Intrinsic::ID intrinsicId, Value* op1Value, Value* op2Value DEBUGARG(GenTree* opNode));
634670

635671
llvm::CallBase* emitGcStressCall(GenTreeCall* call, llvm::CallBase* callValue);
636-
llvm::CallBase* emitHelperCall(CorInfoHelpFunc helperFunc, ArrayRef<Value*> sigArgs = {});
672+
llvm::CallBase* emitHelperCall(
673+
CorInfoHelpFunc helperFunc, ArrayRef<Value*> sigArgs = {} DEBUGARG(bool* pIsShadowTailCall = nullptr));
637674
bool canEmitHelperCallAsShadowTailCall(CorInfoHelpFunc helperFunc);
638675
llvm::CallBase* emitCallOrInvoke(llvm::FunctionCallee callee, ArrayRef<Value*> args, CallSiteFacts facts);
639676

0 commit comments

Comments
 (0)