Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomáš Rylek <trylek@microsoft.com>2020-12-08 05:19:44 +0300
committerGitHub <noreply@github.com>2020-12-08 05:19:44 +0300
commit69e114c1abf91241a0eeecf1ecceab4711b8aa62 (patch)
treeb81a0b35748f5e598412bcc504335cdbd322cd43 /src/coreclr/jit/objectalloc.h
parent0ec07945a9759a72a689edbb01e69b232e26e05a (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.h195
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