diff options
author | Tomáš Rylek <trylek@microsoft.com> | 2020-12-08 05:19:44 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-08 05:19:44 +0300 |
commit | 69e114c1abf91241a0eeecf1ecceab4711b8aa62 (patch) | |
tree | b81a0b35748f5e598412bcc504335cdbd322cd43 /src/coreclr/jit/objectalloc.h | |
parent | 0ec07945a9759a72a689edbb01e69b232e26e05a (diff) |
December infra rollout - remove duplicated 'src' from coreclr subrepo (src/coreclr/src becomes src/coreclr) (#44973)
* Move src/coreclr/src/Directory.Build.targets to src/coreclr
Merge src/coreclr/src/CMakeLists.txt into src/coreclr/CMakeLists.txt
* Mechanical move of src/coreclr/src to src/coreclr
* Scripts adjustments to reflect the changed paths
Diffstat (limited to 'src/coreclr/jit/objectalloc.h')
-rw-r--r-- | src/coreclr/jit/objectalloc.h | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/src/coreclr/jit/objectalloc.h b/src/coreclr/jit/objectalloc.h new file mode 100644 index 00000000000..7a03320b46e --- /dev/null +++ b/src/coreclr/jit/objectalloc.h @@ -0,0 +1,195 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +/*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +XX XX +XX ObjectAllocator XX +XX XX +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +*/ + +/*****************************************************************************/ +#ifndef OBJECTALLOC_H +#define OBJECTALLOC_H +/*****************************************************************************/ + +//=============================================================================== +#include "phase.h" +#include "smallhash.h" + +class ObjectAllocator final : public Phase +{ + typedef SmallHashTable<unsigned int, unsigned int, 8U> LocalToLocalMap; + + //=============================================================================== + // Data members + bool m_IsObjectStackAllocationEnabled; + bool m_AnalysisDone; + BitVecTraits m_bitVecTraits; + BitVec m_EscapingPointers; + // We keep the set of possibly-stack-pointing pointers as a superset of the set of + // definitely-stack-pointing pointers. All definitely-stack-pointing pointers are in both sets. + BitVec m_PossiblyStackPointingPointers; + BitVec m_DefinitelyStackPointingPointers; + LocalToLocalMap m_HeapLocalToStackLocalMap; + BitSetShortLongRep* m_ConnGraphAdjacencyMatrix; + + //=============================================================================== + // Methods +public: + ObjectAllocator(Compiler* comp); + bool IsObjectStackAllocationEnabled() const; + void EnableObjectStackAllocation(); + +protected: + virtual PhaseStatus DoPhase() override; + +private: + bool CanAllocateLclVarOnStack(unsigned int lclNum, CORINFO_CLASS_HANDLE clsHnd); + bool CanLclVarEscape(unsigned int lclNum); + void MarkLclVarAsPossiblyStackPointing(unsigned int lclNum); + void MarkLclVarAsDefinitelyStackPointing(unsigned int lclNum); + bool MayLclVarPointToStack(unsigned int lclNum); + bool DoesLclVarPointToStack(unsigned int lclNum); + void DoAnalysis(); + void MarkLclVarAsEscaping(unsigned int lclNum); + void MarkEscapingVarsAndBuildConnGraph(); + void AddConnGraphEdge(unsigned int sourceLclNum, unsigned int targetLclNum); + void ComputeEscapingNodes(BitVecTraits* bitVecTraits, BitVec& escapingNodes); + void ComputeStackObjectPointers(BitVecTraits* bitVecTraits); + bool MorphAllocObjNodes(); + void RewriteUses(); + GenTree* MorphAllocObjNodeIntoHelperCall(GenTreeAllocObj* allocObj); + unsigned int MorphAllocObjNodeIntoStackAlloc(GenTreeAllocObj* allocObj, BasicBlock* block, Statement* stmt); + struct BuildConnGraphVisitorCallbackData; + bool CanLclVarEscapeViaParentStack(ArrayStack<GenTree*>* parentStack, unsigned int lclNum); + void UpdateAncestorTypes(GenTree* tree, ArrayStack<GenTree*>* parentStack, var_types newType); +#ifdef DEBUG + static Compiler::fgWalkResult AssertWhenAllocObjFoundVisitor(GenTree** pTree, Compiler::fgWalkData* data); +#endif // DEBUG + static const unsigned int s_StackAllocMaxSize = 0x2000U; +}; + +//=============================================================================== + +inline ObjectAllocator::ObjectAllocator(Compiler* comp) + : Phase(comp, PHASE_ALLOCATE_OBJECTS) + , m_IsObjectStackAllocationEnabled(false) + , m_AnalysisDone(false) + , m_bitVecTraits(comp->lvaCount, comp) + , m_HeapLocalToStackLocalMap(comp->getAllocator()) +{ + m_EscapingPointers = BitVecOps::UninitVal(); + m_PossiblyStackPointingPointers = BitVecOps::UninitVal(); + m_DefinitelyStackPointingPointers = BitVecOps::UninitVal(); + m_ConnGraphAdjacencyMatrix = nullptr; +} + +//------------------------------------------------------------------------ +// IsObjectStackAllocationEnabled: Returns true iff object stack allocation is enabled +// +// Return Value: +// Returns true iff object stack allocation is enabled + +inline bool ObjectAllocator::IsObjectStackAllocationEnabled() const +{ + return m_IsObjectStackAllocationEnabled; +} + +//------------------------------------------------------------------------ +// EnableObjectStackAllocation: Enable object stack allocation. + +inline void ObjectAllocator::EnableObjectStackAllocation() +{ + m_IsObjectStackAllocationEnabled = true; +} + +//------------------------------------------------------------------------ +// CanAllocateLclVarOnStack: Returns true iff local variable can be +// allocated on the stack. +// +// Arguments: +// lclNum - Local variable number +// clsHnd - Class handle of the variable class +// +// Return Value: +// Returns true iff local variable can be allocated on the stack. +// +// Notes: +// Stack allocation of objects with gc fields and boxed objects is currently disabled. + +inline bool ObjectAllocator::CanAllocateLclVarOnStack(unsigned int lclNum, CORINFO_CLASS_HANDLE clsHnd) +{ + assert(m_AnalysisDone); + + DWORD classAttribs = comp->info.compCompHnd->getClassAttribs(clsHnd); + + if ((classAttribs & CORINFO_FLG_VALUECLASS) != 0) + { + // TODO-ObjectStackAllocation: enable stack allocation of boxed structs + return false; + } + + if (!comp->info.compCompHnd->canAllocateOnStack(clsHnd)) + { + return false; + } + + const unsigned int classSize = comp->info.compCompHnd->getHeapClassSize(clsHnd); + + return !CanLclVarEscape(lclNum) && (classSize <= s_StackAllocMaxSize); +} + +//------------------------------------------------------------------------ +// CanLclVarEscape: Returns true iff local variable can +// potentially escape from the method +// +// Arguments: +// lclNum - Local variable number +// +// Return Value: +// Returns true iff local variable can potentially escape from the method + +inline bool ObjectAllocator::CanLclVarEscape(unsigned int lclNum) +{ + return BitVecOps::IsMember(&m_bitVecTraits, m_EscapingPointers, lclNum); +} + +//------------------------------------------------------------------------ +// MayLclVarPointToStack: Returns true iff local variable may +// point to a stack-allocated object +// +// Arguments: +// lclNum - Local variable number +// +// Return Value: +// Returns true iff local variable may point to a stack-allocated object + +inline bool ObjectAllocator::MayLclVarPointToStack(unsigned int lclNum) +{ + assert(m_AnalysisDone); + return BitVecOps::IsMember(&m_bitVecTraits, m_PossiblyStackPointingPointers, lclNum); +} + +//------------------------------------------------------------------------ +// DoesLclVarPointToStack: Returns true iff local variable definitely +// points to a stack-allocated object (or is null) +// +// Arguments: +// lclNum - Local variable number +// +// Return Value: +// Returns true iff local variable definitely points to a stack-allocated object +// (or is null) + +inline bool ObjectAllocator::DoesLclVarPointToStack(unsigned int lclNum) +{ + assert(m_AnalysisDone); + return BitVecOps::IsMember(&m_bitVecTraits, m_DefinitelyStackPointingPointers, lclNum); +} + +//=============================================================================== + +#endif // OBJECTALLOC_H |