@@ -71,26 +71,6 @@ int emitLocation::GetInsOffset() const
7171 return emitGetInsOfsFromCodePos (codePos);
7272}
7373
74- // Get the instruction offset in the current instruction region, which must be a funclet prolog.
75- // This is used to find an instruction offset used in unwind data.
76- UNATIVE_OFFSET emitLocation::GetFuncletPrologOffset (emitter* emit) const
77- {
78- assert (ig->igFuncIdx != 0 );
79- assert ((ig->igFlags & IGF_FUNCLET_PROLOG) != 0 );
80- assert ((ig->igFlags & IGF_OUT_OF_ORDER_HEAD) != 0 );
81- assert (GetInsOffset () == 0 );
82-
83- unsigned offset = 0 ;
84- insGroup* lastIG = ig;
85- while (lastIG != emit->emitCurIG )
86- {
87- offset += lastIG->igSize ;
88- lastIG = lastIG->igNext ;
89- }
90- assert ((lastIG->igFlags & IGF_FUNCLET_PROLOG) != 0 );
91-
92- return offset + emit->emitCurIGsize ;
93- }
9474// ------------------------------------------------------------------------
9575// IsPreviousInsNum: Returns true if the emitter is on the next instruction
9676// of the same group as this emitLocation.
@@ -1284,7 +1264,7 @@ insGroup* emitter::emitSavIG(bool emitAdd)
12841264 if (last != nullptr )
12851265 {
12861266 // Append the jump(s) from this IG to the global list
1287- bool prologJump = (ig == emitPrologIG );
1267+ bool prologJump = emitIGisInProlog (ig);
12881268 if ((emitJumpList == nullptr ) || prologJump)
12891269 {
12901270 last->idjNext = emitJumpList;
@@ -1371,6 +1351,8 @@ void emitter::emitBegFN(bool hasFramePtr
13711351 emitChkAlign = chkAlign;
13721352#endif
13731353
1354+ emitPrologEndPos.Init ();
1355+
13741356 /* We have no epilogs yet */
13751357
13761358 emitEpilogSize = 0 ;
@@ -1476,7 +1458,8 @@ void emitter::emitBegFN(bool hasFramePtr
14761458
14771459 emitNxtIGnum = 1 ;
14781460
1479- emitPrologIG = emitIGlist = emitIGlast = emitCurIG = ig = emitAllocIG ();
1461+ emitIGlist = emitIGlast = emitCurIG = ig = emitAllocIG ();
1462+ emitCurIG->igFlags |= (IGF_PROLOG | IGF_OUT_OF_ORDER_HEAD);
14801463
14811464 emitLastIns = nullptr ;
14821465 emitLastInsIG = nullptr ;
@@ -1493,8 +1476,10 @@ void emitter::emitBegFN(bool hasFramePtr
14931476#endif
14941477
14951478 /* Append another group, to start generating the method body */
1496-
14971479 emitNewIG ();
1480+
1481+ /* The group after the placeholder prolog group doesn't get the "propagate" flags */
1482+ emitCurIG->igFlags &= ~IGF_PROPAGATE_MASK;
14981483}
14991484
15001485#ifdef PSEUDORANDOM_NOP_INSERTION
@@ -1741,7 +1726,7 @@ void* emitter::emitAllocAnyInstr(size_t sz, emitAttr opsz)
17411726{
17421727#ifdef DEBUG
17431728 // Under STRESS_EMITTER, put every instruction in its own instruction group.
1744- if (m_compiler->compStressCompile (Compiler::STRESS_EMITTER, 1 ) && emitCurIGinsCnt && ! emitIGisInProlog (emitCurIG ) &&
1729+ if (m_compiler->compStressCompile (Compiler::STRESS_EMITTER, 1 ) && ( emitCurIGinsCnt != 0 ) &&
17451730 !emitCurIG->endsWithAlignInstr ())
17461731 {
17471732 emitNxtIG (true );
@@ -1935,8 +1920,6 @@ void* emitter::emitAllocAnyInstr(size_t sz, emitAttr opsz)
19351920//
19361921void emitter::emitCheckIGList ()
19371922{
1938- assert (emitPrologIG != nullptr );
1939-
19401923#if EMIT_BACKWARDS_NAVIGATION
19411924 struct IGIDPair
19421925 {
@@ -1968,17 +1951,18 @@ void emitter::emitCheckIGList()
19681951 assert ((currIG->igFlags & IGF_EXTEND) == 0 );
19691952
19701953 // First IG must be the function prolog.
1971- assert (currIG == emitPrologIG );
1954+ assert (( currIG-> igFlags & IGF_PROLOG) != 0 );
19721955 }
19731956
1974- if (currIG == emitPrologIG )
1957+ if (( currIG-> igFlags & IGF_PROLOG) != 0 )
19751958 {
19761959 // If we're in the function prolog, we can't be in any other prolog or epilog.
19771960 assert ((currIG->igFlags & (IGF_FUNCLET_PROLOG | IGF_FUNCLET_EPILOG | IGF_EPILOG)) == 0 );
19781961 }
19791962
19801963 // An IG can have at most one of the prolog and epilog flags set.
1981- assert (genCountBits ((unsigned )currIG->igFlags & (IGF_FUNCLET_PROLOG | IGF_FUNCLET_EPILOG | IGF_EPILOG)) <= 1 );
1964+ assert (genCountBits ((unsigned )currIG->igFlags &
1965+ (IGF_PROLOG | IGF_FUNCLET_PROLOG | IGF_FUNCLET_EPILOG | IGF_EPILOG)) <= 1 );
19821966
19831967 // An IG can't have both IGF_HAS_ALIGN and IGF_REMOVED_ALIGN.
19841968 assert (genCountBits ((unsigned )currIG->igFlags & (IGF_HAS_ALIGN | IGF_REMOVED_ALIGN)) <= 1 );
@@ -1994,16 +1978,13 @@ void emitter::emitCheckIGList()
19941978 // not be EXTEND groups, and would there be a benefit to that? Since epilogs are NOGC
19951979 // it would help eliminate NOGC EXTEND groups.
19961980 //
1997- // Note that function prologs must currently exist entirely within one IG and there is
1998- // no flag to indicate a function prolog (the `emitPrologIG` variable points to the single
1999- // unique prolog IG).
2000- //
20011981 // Thus, we can't have this assert:
20021982 // assert((currIG->igFlags & (IGF_FUNCLET_PROLOG | IGF_FUNCLET_EPILOG | IGF_EPILOG)) ==
20031983 // (prevIG->igFlags & (IGF_FUNCLET_PROLOG | IGF_FUNCLET_EPILOG | IGF_EPILOG)));
20041984
2005- // If this is a funclet prolog IG, then it can only extend another funclet prolog IG.
2006- assert ((currIG->igFlags & IGF_FUNCLET_PROLOG) == (prevIG->igFlags & IGF_FUNCLET_PROLOG));
1985+ // If this is a prolog IG, then it can only extend another prolog IG.
1986+ assert ((currIG->igFlags & (IGF_PROLOG | IGF_FUNCLET_PROLOG)) ==
1987+ (prevIG->igFlags & (IGF_PROLOG | IGF_FUNCLET_PROLOG)));
20071988
20081989 // If this is a function epilog IG, it can't extend a funclet prolog or funclet epilog IG.
20091990 if (currIG->igFlags & IGF_EPILOG)
@@ -2102,8 +2083,7 @@ void emitter::emitBegProlog()
21022083 emitForceNewIG = false ;
21032084
21042085 /* Switch to the pre-allocated prolog IG */
2105-
2106- emitGenIG (emitPrologIG);
2086+ emitGenIG (emitGetFirstPrologIG ());
21072087
21082088 /* Nothing is live on entry to the prolog */
21092089
@@ -2116,21 +2096,6 @@ void emitter::emitBegProlog()
21162096 emitPrevByrefRegs = RBM_NONE;
21172097}
21182098
2119- /* ****************************************************************************
2120- *
2121- * Return the code offset of the current location in the prolog.
2122- */
2123-
2124- unsigned emitter::emitGetPrologOffsetEstimate ()
2125- {
2126- /* For now only allow a single prolog ins group */
2127-
2128- assert (emitPrologIG);
2129- assert (emitPrologIG == emitCurIG);
2130-
2131- return emitCurIGsize;
2132- }
2133-
21342099/* ****************************************************************************
21352100 *
21362101 * Mark the code offset of the current location as the end of the prolog,
@@ -2140,13 +2105,7 @@ unsigned emitter::emitGetPrologOffsetEstimate()
21402105void emitter::emitMarkPrologEnd ()
21412106{
21422107 assert (m_compiler->compGeneratingProlog );
2143-
2144- /* For now only allow a single prolog ins group */
2145-
2146- assert (emitPrologIG);
2147- assert (emitPrologIG == emitCurIG);
2148-
2149- emitPrologEndPos = emitCurOffset ();
2108+ emitPrologEndPos.CaptureLocation (this );
21502109}
21512110
21522111/* ****************************************************************************
@@ -2163,7 +2122,7 @@ void emitter::emitEndProlog()
21632122
21642123 /* Save the prolog IG if non-empty or if only one block */
21652124
2166- if (emitCurIGnonEmpty () || emitCurIG == emitPrologIG )
2125+ if (emitCurIGnonEmpty () || ( emitCurIG == emitGetFirstPrologIG ()) )
21672126 {
21682127 emitSavIG ();
21692128 }
@@ -2340,7 +2299,6 @@ void emitter::emitCreatePlaceholderIG(insGroupPlaceholderType igType,
23402299 emitForceStoreGCState = true ;
23412300
23422301 /* The group after the placeholder group doesn't get the "propagate" flags */
2343-
23442302 emitCurIG->igFlags &= ~IGF_PROPAGATE_MASK;
23452303 }
23462304
@@ -2467,6 +2425,11 @@ void emitter::emitFinishPrologEpilogGeneration()
24672425 * Common code for prolog / epilog beginning. Convert the placeholder group to actual code IG,
24682426 * and set it as the current group.
24692427 */
2428+ insGroup* emitter::emitGetFirstPrologIG () const
2429+ {
2430+ assert (emitIGisInProlog (emitIGlist));
2431+ return emitIGlist;
2432+ }
24702433
24712434void emitter::emitBegPrologEpilog (insGroup* igPh)
24722435{
@@ -4119,6 +4082,14 @@ void emitter::emitDispIGflags(unsigned flags)
41194082 {
41204083 printf (" , byref" );
41214084 }
4085+ if (flags & IGF_PROLOG)
4086+ {
4087+ printf (" , prolog" );
4088+ }
4089+ if (flags & IGF_EPILOG)
4090+ {
4091+ printf (" , epilog" );
4092+ }
41224093 if (flags & IGF_FUNCLET_PROLOG)
41234094 {
41244095 printf (" , funclet prolog" );
@@ -4127,10 +4098,6 @@ void emitter::emitDispIGflags(unsigned flags)
41274098 {
41284099 printf (" , funclet epilog" );
41294100 }
4130- if (flags & IGF_EPILOG)
4131- {
4132- printf (" , epilog" );
4133- }
41344101 if (flags & IGF_NOGCINTERRUPT)
41354102 {
41364103 printf (" , nogc" );
@@ -4317,10 +4284,6 @@ void emitter::emitDispIG(insGroup* ig, bool displayFunc, bool displayInstruction
43174284 {
43184285 printf (" <-- Current IG" );
43194286 }
4320- if (ig == emitPrologIG)
4321- {
4322- printf (" <-- Prolog IG" );
4323- }
43244287 }
43254288
43264289 printf (" \n " );
@@ -5002,9 +4965,6 @@ void emitter::emitJumpDistBind()
50024965 UNATIVE_OFFSET adjIG;
50034966 UNATIVE_OFFSET adjLJ;
50044967 insGroup* lstIG;
5005- #ifdef DEBUG
5006- insGroup* prologIG = emitPrologIG;
5007- #endif // DEBUG
50084968
50094969 int jmp_iteration = 1 ;
50104970
@@ -5195,7 +5155,7 @@ void emitter::emitJumpDistBind()
51955155 assert (lastLJ == nullptr || lastIG != jmp->idjIG || lastLJ->idjOffs < jmp->idjOffs );
51965156 lastLJ = (lastIG == jmp->idjIG ) ? jmp : nullptr ;
51975157
5198- assert (lastIG == nullptr || lastIG->IsBeforeOrEqual (jmp->idjIG ) || jmp->idjIG == prologIG );
5158+ assert (lastIG == nullptr || lastIG->IsBeforeOrEqual (jmp->idjIG ) || emitIGisInProlog ( jmp->idjIG ) );
51995159 lastIG = jmp->idjIG ;
52005160#endif // DEBUG
52015161
@@ -7817,7 +7777,7 @@ unsigned emitter::emitEndCodeGen(Compiler* comp,
78177777#endif // DEBUG
78187778
78197779 // Assign the real prolog size
7820- *prologSize = emitCodeOffset (emitPrologIG, emitPrologEndPos);
7780+ *prologSize = emitPrologEndPos. CodeOffset ( this );
78217781
78227782 /* Return the amount of code we've generated */
78237783
@@ -9567,6 +9527,39 @@ UNATIVE_OFFSET emitter::emitCodeOffset(void* blockPtr, unsigned codePos)
95679527 return ig->igOffs + of;
95689528}
95699529
9530+ // ------------------------------------------------------------------------
9531+ // emitGetCurrentCodeOffsetFrom: Get current code offset relative to "ig".
9532+ //
9533+ // This is used to retrieve the current offset within a prolog being generated
9534+ // for unwind info. Thus, the offset we return from here can't later shrink,
9535+ // and overestimating the code size of prolog instructions is fatal.
9536+ //
9537+ // Arguments:
9538+ // ig - IG denoting the start of code, "nullptr" for main function prolog
9539+ //
9540+ // Return Value:
9541+ // Effectively "<current code offset> - ig->igOffs".
9542+ //
9543+ UNATIVE_OFFSET emitter::emitGetCurrentCodeOffsetFrom (insGroup* ig)
9544+ {
9545+ if (ig == nullptr )
9546+ {
9547+ ig = emitGetFirstPrologIG ();
9548+ }
9549+ assert ((ig->igFlags & IGF_OUT_OF_ORDER_HEAD) != 0 );
9550+
9551+ unsigned igKind = ig->igFlags & (IGF_PROLOG | IGF_FUNCLET_PROLOG);
9552+ unsigned offset = 0 ;
9553+ while (ig != emitCurIG)
9554+ {
9555+ offset += ig->igSize ;
9556+ ig = ig->igNext ;
9557+ }
9558+ assert ((ig->igFlags & igKind) == igKind);
9559+
9560+ return offset + emitCurIGsize;
9561+ }
9562+
95709563/* ****************************************************************************
95719564 *
95729565 * Record the fact that the given register now contains a live GC ref.
@@ -9994,12 +9987,7 @@ void emitter::emitInsertIGAfter(insGroup* insertAfterIG, insGroup* ig)
99949987
99959988void emitter::emitNxtIG (bool extend)
99969989{
9997- /* Right now we don't allow multi-IG prologs */
9998-
9999- assert (emitCurIG != emitPrologIG);
10000-
100019990 /* First save the current group */
10002-
100039991 emitSavIG (extend);
100049992
100059993 /* Update the GC live sets for the group's start
0 commit comments