Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 3779842

Browse files
authored
Merge pull request #6653 from echesakov/StackAllocation
Work towards objects stack allocation
2 parents 0093a35 + 3c30aa1 commit 3779842

15 files changed

+389
-9
lines changed

src/jit/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ set( JIT_SOURCES
5151
lower.cpp
5252
lsra.cpp
5353
morph.cpp
54+
objectalloc.cpp
5455
optcse.cpp
5556
optimizer.cpp
5657
rangecheck.cpp

src/jit/compiler.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4151,7 +4151,15 @@ void Compiler::compCompile(void * * methodCodePtr,
41514151

41524152
// Compute reachability sets and dominators.
41534153
fgComputeReachability();
4154+
}
4155+
4156+
// Transform each GT_ALLOCOBJ node into either an allocation helper call or
4157+
// local variable allocation on the stack.
4158+
ObjectAllocator objectAllocator(this);
4159+
objectAllocator.Run();
41544160

4161+
if (!opts.MinOpts() && !opts.compDbgCode)
4162+
{
41554163
/* Perform loop inversion (i.e. transform "while" loops into
41564164
"repeat" loops) and discover and classify natural loops
41574165
(e.g. mark iterative loops as such). Also marks loop blocks

src/jit/compiler.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1364,6 +1364,7 @@ class Compiler
13641364
friend class CodeGen;
13651365
friend class LclVarDsc;
13661366
friend class TempDsc;
1367+
friend class ObjectAllocator;
13671368

13681369
#ifndef _TARGET_64BIT_
13691370
friend class DecomposeLongs;
@@ -1930,6 +1931,11 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
19301931
GenTreePtr op1,
19311932
var_types castType);
19321933

1934+
GenTreePtr gtNewAllocObjNode(unsigned int helper,
1935+
CORINFO_CLASS_HANDLE clsHnd,
1936+
var_types type,
1937+
GenTreePtr op1);
1938+
19331939
//------------------------------------------------------------------------
19341940
// Other GenTree functions
19351941

src/jit/compiler.hpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,28 @@ GenTreeCall* Compiler::gtNewHelperCallNode(unsigned helper,
11161116
return result;
11171117
}
11181118

1119+
//------------------------------------------------------------------------
1120+
// gtNewAllocObjNode: A little helper to create an object allocation node.
1121+
//
1122+
// Arguments:
1123+
// helper - Value returned by ICorJitInfo::getNewHelper
1124+
// clsHnd - Corresponding class handle
1125+
// type - Tree return type (e.g. TYP_REF)
1126+
// op1 - Node containing an address of VtablePtr
1127+
//
1128+
// Return Value:
1129+
// Returns GT_ALLOCOBJ node that will be later morphed into an
1130+
// allocation helper call or local variable allocation on the stack.
1131+
inline
1132+
GenTreePtr Compiler::gtNewAllocObjNode(unsigned int helper,
1133+
CORINFO_CLASS_HANDLE clsHnd,
1134+
var_types type,
1135+
GenTreePtr op1)
1136+
{
1137+
GenTreePtr node = new(this, GT_ALLOCOBJ) GenTreeAllocObj(type, helper, clsHnd, op1);
1138+
return node;
1139+
}
1140+
11191141
/*****************************************************************************/
11201142

11211143
inline

src/jit/compphases.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ CompPhaseNameMacro(PHASE_COMPUTE_EDGE_WEIGHTS, "Compute edge weights (1)",
3131
CompPhaseNameMacro(PHASE_CREATE_FUNCLETS, "Create EH funclets", "EH-FUNC", false, -1)
3232
#endif // FEATURE_EH_FUNCLETS
3333
CompPhaseNameMacro(PHASE_OPTIMIZE_LAYOUT, "Optimize layout", "LAYOUT", false, -1)
34+
CompPhaseNameMacro(PHASE_ALLOCATE_OBJECTS, "Allocate Objects", "ALLOC-OBJ",false, -1)
3435
CompPhaseNameMacro(PHASE_OPTIMIZE_LOOPS, "Optimize loops", "LOOP-OPT", false, -1)
3536
CompPhaseNameMacro(PHASE_CLONE_LOOPS, "Clone loops", "LP-CLONE", false, -1)
3637
CompPhaseNameMacro(PHASE_UNROLL_LOOPS, "Unroll loops", "UNROLL", false, -1)

src/jit/gentree.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ void GenTree::InitNodeSize()
272272
GenTree::s_gtNodeSizes[GT_LEA ] = TREE_NODE_SZ_LARGE;
273273
GenTree::s_gtNodeSizes[GT_COPYOBJ ] = TREE_NODE_SZ_LARGE;
274274
GenTree::s_gtNodeSizes[GT_INTRINSIC ] = TREE_NODE_SZ_LARGE;
275+
GenTree::s_gtNodeSizes[GT_ALLOCOBJ ] = TREE_NODE_SZ_LARGE;
275276
#if USE_HELPERS_FOR_INT_DIV
276277
GenTree::s_gtNodeSizes[GT_DIV ] = TREE_NODE_SZ_LARGE;
277278
GenTree::s_gtNodeSizes[GT_UDIV ] = TREE_NODE_SZ_LARGE;
@@ -341,6 +342,7 @@ void GenTree::InitNodeSize()
341342
static_assert_no_msg(sizeof(GenTreeArgPlace) <= TREE_NODE_SZ_SMALL);
342343
static_assert_no_msg(sizeof(GenTreeLabel) <= TREE_NODE_SZ_SMALL);
343344
static_assert_no_msg(sizeof(GenTreePhiArg) <= TREE_NODE_SZ_SMALL);
345+
static_assert_no_msg(sizeof(GenTreeAllocObj) <= TREE_NODE_SZ_LARGE); // *** large node
344346
#ifndef FEATURE_UNIX_AMD64_STRUCT_PASSING
345347
static_assert_no_msg(sizeof(GenTreePutArgStk) <= TREE_NODE_SZ_SMALL);
346348
#else // FEATURE_UNIX_AMD64_STRUCT_PASSING
@@ -2145,7 +2147,10 @@ unsigned Compiler::gtHashValue(GenTree * tree)
21452147
case GT_INDEX:
21462148
hash += tree->gtIndex.gtIndElemSize;
21472149
break;
2148-
2150+
case GT_ALLOCOBJ:
2151+
hash = genTreeHashAdd(hash, static_cast<unsigned>(reinterpret_cast<uintptr_t>(tree->gtAllocObj.gtAllocObjClsHnd)));
2152+
hash = genTreeHashAdd(hash, tree->gtAllocObj.gtNewHelper);
2153+
break;
21492154

21502155
// For the ones below no extra argument matters for comparison.
21512156
case GT_BOX:
@@ -6754,6 +6759,13 @@ GenTreePtr Compiler::gtCloneExpr(GenTree * tree,
67546759
}
67556760
break;
67566761

6762+
case GT_ALLOCOBJ:
6763+
{
6764+
GenTreeAllocObj* asAllocObj = tree->AsAllocObj();
6765+
copy = new (this, GT_ALLOCOBJ) GenTreeAllocObj(tree->TypeGet(), asAllocObj->gtNewHelper, asAllocObj->gtAllocObjClsHnd, asAllocObj->gtOp1);
6766+
}
6767+
break;
6768+
67576769
case GT_ARR_LENGTH:
67586770
copy = new (this, GT_ARR_LENGTH) GenTreeArrLen(tree->TypeGet(), tree->gtOp.gtOp1, tree->gtArrLen.ArrLenOffset());
67596771
break;
@@ -11062,6 +11074,11 @@ GenTreePtr Compiler::gtFoldExprConst(GenTreePtr tree)
1106211074
}
1106311075
#endif // FEATURE_SIMD
1106411076

11077+
if (tree->gtOper == GT_ALLOCOBJ)
11078+
{
11079+
return tree;
11080+
}
11081+
1106511082
if (kind & GTK_UNOP)
1106611083
{
1106711084
assert(op1->OperKind() & GTK_CONST);

src/jit/gentree.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4221,6 +4221,25 @@ struct GenTreeCopyOrReload : public GenTreeUnOp
42214221
#endif
42224222
};
42234223

4224+
// Represents GT_ALLOCOBJ node
4225+
4226+
struct GenTreeAllocObj final : public GenTreeUnOp
4227+
{
4228+
unsigned int gtNewHelper; // Value returned by ICorJitInfo::getNewHelper
4229+
CORINFO_CLASS_HANDLE gtAllocObjClsHnd;
4230+
4231+
GenTreeAllocObj(var_types type, unsigned int helper, CORINFO_CLASS_HANDLE clsHnd, GenTreePtr op) :
4232+
GenTreeUnOp(GT_ALLOCOBJ, type, op
4233+
DEBUGARG(/*largeNode*/TRUE)),// This node in most cases will be changed to a call node
4234+
gtNewHelper(helper),
4235+
gtAllocObjClsHnd(clsHnd)
4236+
{}
4237+
#if DEBUGGABLE_GENTREE
4238+
GenTreeAllocObj() : GenTreeUnOp() {}
4239+
#endif
4240+
};
4241+
4242+
42244243
//------------------------------------------------------------------------
42254244
// Deferred inline functions of GenTree -- these need the subtypes above to
42264245
// be defined already.

src/jit/gtlist.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ GTNODE(SIMD_CHK , "simdChk" ,0,GTK_SPECIAL) // Compare wheth
8585
// does the compare, so that it can be more easily optimized. But that involves generating qmarks at import time...
8686
#endif // FEATURE_SIMD
8787

88+
GTNODE(ALLOCOBJ , "allocObj" ,0,GTK_UNOP|GTK_EXOP) // object allocator
89+
8890
//-----------------------------------------------------------------------------
8991
// Binary operators (2 operands):
9092
//-----------------------------------------------------------------------------

src/jit/gtstructs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ GTSTRUCT_1(CpBlk , GT_COPYBLK)
101101
#ifdef FEATURE_SIMD
102102
GTSTRUCT_1(SIMD , GT_SIMD)
103103
#endif // FEATURE_SIMD
104+
GTSTRUCT_1(AllocObj , GT_ALLOCOBJ)
104105
/*****************************************************************************/
105106
#undef GTSTRUCT_0
106107
#undef GTSTRUCT_1

src/jit/importer.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11852,18 +11852,22 @@ MATH_MAYBE_CALL_NO_OVF: ovfl = false;
1185211852
// 3) Allocate and return the new object
1185311853
// Reason: performance (today, we'll always use the slow helper for the R2R generics case)
1185411854

11855-
op1 = gtNewHelperCallNode( info.compCompHnd->getNewHelper(&resolvedToken, info.compMethodHnd),
11856-
TYP_REF, 0,
11857-
gtNewArgList(op1));
11855+
op1 = gtNewAllocObjNode( info.compCompHnd->getNewHelper(&resolvedToken, info.compMethodHnd),
11856+
resolvedToken.hClass, TYP_REF, op1 );
1185811857
}
1185911858

11860-
/* Remember that this basic block contains 'new' of an object */
11859+
// Remember that this basic block contains 'new' of an object
1186111860
block->bbFlags |= BBF_HAS_NEWOBJ;
1186211861
optMethodFlags |= OMF_HAS_NEWOBJ;
1186311862

11864-
/* Append the assignment to the temp/local. Dont need to spill
11865-
at all as we are just calling an EE-Jit helper which can only
11866-
cause an (async) OutOfMemoryException */
11863+
// Append the assignment to the temp/local. Dont need to spill
11864+
// at all as we are just calling an EE-Jit helper which can only
11865+
// cause an (async) OutOfMemoryException.
11866+
11867+
// We assign the newly allocated object (by a GT_ALLOCOBJ node)
11868+
// to a temp. Note that the pattern "temp = allocObj" is required
11869+
// by ObjectAllocator phase to be able to determine GT_ALLOCOBJ nodes
11870+
// without exhaustive walk over all expressions.
1186711871

1186811872
impAssignTempGen(lclNum, op1, (unsigned)CHECK_SPILL_NONE);
1186911873

src/jit/jit.settings.targets

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
<CppCompile Include="..\inlinepolicy.cpp" />
8585
<CppCompile Include="..\jitconfig.cpp" />
8686
<CppCompile Include="..\hostallocator.cpp" />
87+
<CppCompile Include="..\objectalloc.cpp" />
8788
<CppCompile Condition="'$(ClDefines.Contains(`LEGACY_BACKEND`))'=='True'" Include="..\CodeGenLegacy.cpp" />
8889
<CppCompile Condition="'$(ClDefines.Contains(`LEGACY_BACKEND`))'=='False'" Include="..\Lower.cpp" />
8990
<CppCompile Condition="'$(ClDefines.Contains(`LEGACY_BACKEND`))'=='False'" Include="..\LSRA.cpp" />

src/jit/jitpch.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,4 @@
3434
#include "blockset.h"
3535
#include "bitvec.h"
3636
#include "inline.h"
37-
37+
#include "objectalloc.h"

src/jit/morph.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ GenTreePtr Compiler::fgMorphIntoHelperCall(GenTreePtr tree,
6464
tree->ChangeOper(GT_CALL);
6565

6666
tree->gtFlags |= GTF_CALL;
67+
if (args)
68+
tree->gtFlags |= (args->gtFlags & GTF_ALL_EFFECT);
6769
tree->gtCall.gtCallType = CT_HELPER;
6870
tree->gtCall.gtCallMethHnd = eeFindHelper(helper);
6971
tree->gtCall.gtCallArgs = args;
@@ -79,6 +81,12 @@ GenTreePtr Compiler::fgMorphIntoHelperCall(GenTreePtr tree,
7981
tree->gtCall.gtCallRegUsedMask = RBM_NONE;
8082
#endif // LEGACY_BACKEND
8183

84+
#if DEBUG
85+
// Helper calls are never candidates.
86+
87+
tree->gtCall.gtInlineObservation = InlineObservation::CALLSITE_IS_CALL_TO_HELPER;
88+
#endif // DEBUG
89+
8290
#ifdef FEATURE_READYTORUN_COMPILER
8391
tree->gtCall.gtEntryPoint.addr = nullptr;
8492
#endif

0 commit comments

Comments
 (0)