From 076750fdb85e3272fce18e8ab6c0e3ab8f282cc7 Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Mon, 29 Feb 2016 10:33:23 -0800 Subject: [PATCH] Inliner refactoring: remove the LR sampling mode Remove code that sampled methods and provided data for the linear regresssion (LR) size model used by the inliner. We plan on preserving the current model for legacy behavior and creating new and different models for future work. Addreses one part of dotnet/coreclr#3371. Commit migrated from https://github.com/dotnet/coreclr/commit/563910fef1d865f71cde8244ff7287ffecddb332 --- src/coreclr/src/inc/clrconfigvalues.h | 1 - src/coreclr/src/jit/codegencommon.cpp | 17 -- src/coreclr/src/jit/compiler.cpp | 32 --- src/coreclr/src/jit/compiler.h | 2 - src/coreclr/src/jit/flowgraph.cpp | 16 +- src/coreclr/src/jit/importer.cpp | 1 - src/coreclr/src/jit/lclvars.cpp | 2 +- src/coreclr/src/jit/sm.cpp | 155 +---------- src/coreclr/src/jit/sm.h | 22 +- src/coreclr/src/jit/smgen.cpp | 483 ---------------------------------- src/coreclr/src/jit/smgen.h | 82 ------ 11 files changed, 7 insertions(+), 806 deletions(-) delete mode 100644 src/coreclr/src/jit/smgen.cpp delete mode 100644 src/coreclr/src/jit/smgen.h diff --git a/src/coreclr/src/inc/clrconfigvalues.h b/src/coreclr/src/inc/clrconfigvalues.h index 9a9f74c..e364d3a 100644 --- a/src/coreclr/src/inc/clrconfigvalues.h +++ b/src/coreclr/src/inc/clrconfigvalues.h @@ -436,7 +436,6 @@ CONFIG_DWORD_INFO_EX(INTERNAL_JitInlinePrintStats, W("JitInlinePrintStats"), (DW CONFIG_DWORD_INFO_DIRECT_ACCESS(INTERNAL_JITInlineSize, W("JITInlineSize"), "") CONFIG_STRING_INFO_EX(INTERNAL_JitLateDisasm, W("JitLateDisasm"), "", CLRConfig::REGUTIL_default) CONFIG_STRING_INFO_EX(INTERNAL_JITLateDisasmTo, W("JITLateDisasmTo"), "", CLRConfig::REGUTIL_default) -RETAIL_CONFIG_DWORD_INFO_EX(EXTERNAL_JitLRSampling, W("JitLRSampling"), 0, "", CLRConfig::REGUTIL_default) CONFIG_DWORD_INFO_EX(INTERNAL_JITMaxTempAssert, W("JITMaxTempAssert"), 1, "", CLRConfig::REGUTIL_default) CONFIG_DWORD_INFO_EX(INTERNAL_JitMaxUncheckedOffset, W("JitMaxUncheckedOffset"), (DWORD)8, "", CLRConfig::REGUTIL_default) RETAIL_CONFIG_DWORD_INFO_DIRECT_ACCESS(UNSUPPORTED_JITMinOpts, W("JITMinOpts"), "Forces MinOpts") diff --git a/src/coreclr/src/jit/codegencommon.cpp b/src/coreclr/src/jit/codegencommon.cpp index b8eee4d..fa81516 100644 --- a/src/coreclr/src/jit/codegencommon.cpp +++ b/src/coreclr/src/jit/codegencommon.cpp @@ -3253,23 +3253,6 @@ void CodeGen::genGenerateCode(void * * codePtr, #endif // DISPLAY_SIZES - -#ifdef DEBUG - if (compiler->compIsMethodForLRSampling) - { - // Print this sample. - compiler->fgCodeSeqSm.codeSize = codeSize; - compiler->fgCodeSeqSm.prologSize = prologSize; - compiler->fgCodeSeqSm.epilogSize = epilogSize; - compiler->fgCodeSeqSm.epilogCount = getEmitter()->emitGetEpilogCnt(); - - noway_assert(codeSize >= prologSize + epilogSize * compiler->fgCodeSeqSm.epilogCount); - compiler->fgCodeSeqSm.BBCodeSize = codeSize - prologSize - epilogSize * compiler->fgCodeSeqSm.epilogCount; - - compiler->fgCodeSeqSm.PrintSampleResult(); - } -#endif // DEBUG - compiler->EndPhase(PHASE_EMIT_GCEH); } diff --git a/src/coreclr/src/jit/compiler.cpp b/src/coreclr/src/jit/compiler.cpp index e7ac08f..d9138d9 100644 --- a/src/coreclr/src/jit/compiler.cpp +++ b/src/coreclr/src/jit/compiler.cpp @@ -651,17 +651,6 @@ const bool Compiler::Options::compDbgCode = false; const bool Compiler::Options::compNoPInvokeInlineCB = false; #endif -#if defined(DEBUG) -//static ConfigDWORD fJitLRSampling; -/* static */ -//bool Compiler::s_compInSamplingMode = (fJitLRSampling.val(CLRConfig::EXTERNAL_JitLRSampling) != 0); -bool Compiler::s_compInSamplingMode = false; -#else -/* static */ -bool Compiler::s_compInSamplingMode = false; -#endif - - /***************************************************************************** * * One time initialization code @@ -2043,7 +2032,6 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) #endif opts.compNeedSecurityCheck = false; - compIsMethodForLRSampling = false; opts.altJit = false; #if defined(LATE_DISASM) && !defined(DEBUG) @@ -2555,13 +2543,6 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) if (compIsForInlining() || compIsForImportOnly()) return; - - if (Compiler::s_compInSamplingMode) - { - assert(!compIsForInlining()); - - compIsMethodForLRSampling = true; - } // The rest of the opts fields that we initialize here // should only be used when we generate code for the method @@ -4939,19 +4920,6 @@ int Compiler::compCompileHelper (CORINFO_MODULE_HANDLE clas info.compInitMem = ((methodInfo->options & CORINFO_OPT_INIT_LOCALS) != 0); - if (compIsMethodForLRSampling) - { - // Further trim down our sample set. - - if (info.compILCodeSize > 100 || - info.compXcptnsCount > 0 || // Exclude methods that have EH - instVerInfo != INSTVER_NOT_INSTANTIATION // Exclude generic methods or methods in generic class - ) - { - compIsMethodForLRSampling = false; - } - } - /* Allocate the local variable table */ lvaInitTypeRef(); diff --git a/src/coreclr/src/jit/compiler.h b/src/coreclr/src/jit/compiler.h index e9d5681..39f1e37 100644 --- a/src/coreclr/src/jit/compiler.h +++ b/src/coreclr/src/jit/compiler.h @@ -8554,8 +8554,6 @@ public: #define NATIVE_SIZE_INVALID (-10000) - static bool s_compInSamplingMode; - bool compIsMethodForLRSampling; // Is this the method suitable as a sample for the linear regression? int compNativeSizeEstimate; // The estimated native size of this method. InlineHints compInlineeHints; // Inlining hints from the inline candidate. diff --git a/src/coreclr/src/jit/flowgraph.cpp b/src/coreclr/src/jit/flowgraph.cpp index ddf350a..283c8ea 100644 --- a/src/coreclr/src/jit/flowgraph.cpp +++ b/src/coreclr/src/jit/flowgraph.cpp @@ -4214,19 +4214,11 @@ void Compiler::fgFindJumpTargets(const BYTE * codeAddr, // Keep track of constants and args on the stack. fgStack pushedStack; - // compIsMethodForLRSampling and compIsForInlining() can't both be true. - noway_assert(!compIsMethodForLRSampling || !compIsForInlining()); - // Determine whether to start the state machine to estimate the size of the // native code for this method. bool useSm = false; - if (compIsMethodForLRSampling) - { - // Linear regression sampling requires the estimated native code size. - useSm = true; - } - else if ((codeSize > ALWAYS_INLINE_SIZE) && - !(info.compFlags & CORINFO_FLG_FORCEINLINE)) + if ((codeSize > ALWAYS_INLINE_SIZE) && + !(info.compFlags & CORINFO_FLG_FORCEINLINE)) { // The size of the native code for this method matters for inlining // decisions. @@ -4814,10 +4806,6 @@ _SkipCodeAddrAdjustment: noway_assert(smOpcodeinstrCount; -#endif - pSm->Run(smOpcode DEBUGARG(0)); } diff --git a/src/coreclr/src/jit/importer.cpp b/src/coreclr/src/jit/importer.cpp index a8d3c56..4d063c7 100644 --- a/src/coreclr/src/jit/importer.cpp +++ b/src/coreclr/src/jit/importer.cpp @@ -4875,7 +4875,6 @@ void Compiler::impCheckForPInvokeCall( info.compCallUnmanaged++; assert(!compIsForInlining()); - compIsMethodForLRSampling = false; // Don't sample methods that contain P/I inlining. // AMD64 convention is same for native and managed if (unmanagedCallConv == CORINFO_UNMANAGED_CALLCONV_C) diff --git a/src/coreclr/src/jit/lclvars.cpp b/src/coreclr/src/jit/lclvars.cpp index ae05f01..b401895 100644 --- a/src/coreclr/src/jit/lclvars.cpp +++ b/src/coreclr/src/jit/lclvars.cpp @@ -1130,7 +1130,7 @@ void Compiler::lvaInitVarDsc(LclVarDsc * varDsc, compFloatingPointUsed = true; } - if (tiVerificationNeeded || compIsMethodForLRSampling) + if (tiVerificationNeeded) { varDsc->lvVerTypeInfo = verParseArgSigToTypeInfo(varSig, varList); } diff --git a/src/coreclr/src/jit/sm.cpp b/src/coreclr/src/jit/sm.cpp index a777bad..0154c11 100644 --- a/src/coreclr/src/jit/sm.cpp +++ b/src/coreclr/src/jit/sm.cpp @@ -6,10 +6,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XX XX XX State machine used in the JIT XX -XX To take samples, do XX -XX set complus_JitLRSampling=1 XX -XX set complus_ngenlocalworker=1 XX -XX ngen install mscorlib /nologo /silent /NoDependencies XX XX XX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX @@ -22,15 +18,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #include "smcommon.cpp" -#ifndef FEATURE_CORECLR // ???? Is this right? -#undef printf // We don't want to use logf(). Just print out to the stdout. That simple! -#endif // FEATURE_CORECLR - -#ifdef DEBUG -static LONG g_SMTested = 0; -bool g_HeaderPrinted = false; -#endif // DEBUG - // // The array to map from EE opcodes (i.e. CEE_ ) to state machine opcodes (i.e. SM_ ) // @@ -60,25 +47,7 @@ void CodeSeqSM::Start(Compiler * comp) StateWeights = gp_StateWeights; NativeSize = 0; -#ifdef DEBUG - if (!Compiler::s_compInSamplingMode && // No need to test in the sampling mode. - InterlockedExchange(&g_SMTested, 1) == 0) - { - Test(); - } - - if (Compiler::s_compInSamplingMode) - { - if (!g_HeaderPrinted) - { - PrintSampleHeader(); - g_HeaderPrinted = true; - } - } -#endif - Reset(); - } void CodeSeqSM::Reset() @@ -87,18 +56,9 @@ void CodeSeqSM::Reset() #ifdef DEBUG // Reset the state occurence counts - memset(StateMatchedCounts, 0, sizeof(StateMatchedCounts)); - - b0Args = - b1Args = - b2Args = - b3AndMoreArgs = - bNoLocals = false; - - bNoCalls = true; + memset(StateMatchedCounts, 0, sizeof(StateMatchedCounts)); +#endif - instrCount = 0; -#endif // DEBUG } void CodeSeqSM::End() @@ -107,22 +67,8 @@ void CodeSeqSM::End() { TermStateMatch(curState DEBUGARG(pComp->verbose)); } - -#ifdef DEBUG - if (pComp->info.compILargsCount == 0) - b0Args = true; - else if (pComp->info.compILargsCount == 1) - b1Args = true; - else if (pComp->info.compILargsCount == 2) - b2Args = true; - else - b3AndMoreArgs = true; - - bNoLocals = (pComp->info.compMethodInfo->locals.numArgs == 0); -#endif // DEBUG } - void CodeSeqSM::Run(SM_OPCODE opcode DEBUGARG(int level)) { SM_STATE_ID nextState; @@ -132,16 +78,6 @@ void CodeSeqSM::Run(SM_OPCODE opcode DEBUGARG(int level)) assert(level<=MAX_CODE_SEQUENCE_LENGTH); -#ifdef DEBUG - if (opcode == SM_CALL || - opcode == SM_CALLVIRT || - opcode == SM_CALLI - ) - { - bNoCalls = false; - } -#endif // DEBUG - _Next: nextState = GetDestState(curState, opcode); @@ -252,92 +188,5 @@ const char * CodeSeqSM::StateDesc(SM_STATE_ID stateID) return s_StateDesc; } - -void CodeSeqSM::PrintSampleHeader() -{ - // Output the NUM_SM_STATES here for the linear regression tool to generate the weight array with this size. - printf("# MethodName{NUM_SM_STATES=%d}| NativeSize| ILBytes| ILInstrCount| 0Args| 1Args| 2Args| 3AndMoreArgs| NoLocals| NoCalls", NUM_SM_STATES); - - for (BYTE i=1; iinfo.compFullName, - BBCodeSize, // NativeSize - pComp->info.compILCodeSize, // ILBytes - instrCount); // ILInstrCount - - printf("| %d| %d| %d| %d| %d| %d", b0Args, b1Args, b2Args, b3AndMoreArgs, bNoLocals, bNoCalls); - - for (unsigned i=1; inext = NULL; - States[SM_STATE_ID_START].destStateList = pDestStateListHead; - - lastStateID = 1; - - // - // Process all interesting code sequences - // - - debugprint(("\n======== The code sequences =================\n")); - - SM_OPCODE * CodeSeqs = (SM_OPCODE *)s_CodeSeqs; - - while (*CodeSeqs != CODE_SEQUENCE_END) - { - ProcessSeq(CodeSeqs); - CodeSeqs += MAX_CODE_SEQUENCE_LENGTH; - } - - debugprint(("\n======== The state machine =================\n")); - - for (SM_STATE_ID i=1; i<=lastStateID; ++i) - { - debugprint(("State %-4d : length=%-2d prev=%-4d lngest=%-4d (%c) Desc=[%s]\n", - i, States[i].length, States[i].prevState, States[i].longestTermState, - States[i].term?'*':' ', StateDesc(i))); - - for (unsigned j=0; j %d\n", - smOpcodeNames[(SM_OPCODE)j], - States[i].getDestState((SM_OPCODE)j))); - } - } - } - - debugprint(("\n# MethodName| NativeSize| ILBytes| ILInstrCount| 0Args| 1Args| 2Args| 3AndMoreArgs| NoLocals| NoCalls")); - - unsigned termStateCount = 0; - - for (SM_STATE_ID i=1; i<=lastStateID; ++i) - { - if (States[i].term) - { - ++termStateCount; - debugprint(("| %s[%d]", StateDesc(i), i)); - } - } - - debugprint(("\n\n%d termination states.\n", termStateCount)); -} - -SMGen::~SMGen() -{ -} - -void SMGen::ProcessSeq(SM_OPCODE * CodeSeq) -{ - SM_STATE_ID longestTermState = 0; - - SM_STATE_ID curState = SM_STATE_ID_START; - BYTE curLen = 0; - - SM_OPCODE * pOpcode = CodeSeq; - SM_OPCODE opcode; - - debugprint(("\nCodeSeq : {")); - - do - { - opcode = * pOpcode; - - debugprint(("%s, " , smOpcodeNames[opcode])); - - assert(curLen < MAX_CODE_SEQUENCE_LENGTH); - assert(curLen < 255); - - ++curLen; - - SM_STATE_ID nextState = States[curState].getDestState(opcode); - if (nextState == 0) - { - // Need to create a new state - assert(lastStateID < MAX_NUM_STATES); - ++lastStateID; - - States[curState].setDestState(opcode, lastStateID); - - States[lastStateID].id = lastStateID; - States[lastStateID].longestTermState = longestTermState; - States[lastStateID].prevState = curState; - States[lastStateID].opc = opcode; - States[lastStateID].term = false; - - SMGenDestStateDesc * pDestStateListHead = new SMGenDestStateDesc(); - pDestStateListHead->next = NULL; - States[lastStateID].destStateList = pDestStateListHead; - - curState = lastStateID; - States[curState].length = curLen; - } - else - { - curState = nextState; - if (States[curState].term) - { - longestTermState = curState; - } - } - } - while (* (++pOpcode) != CODE_SEQUENCE_END); - - assert(curState != SM_STATE_ID_START); - assert(!States[curState].term && "Duplicated rule."); - - States[curState].term = true; - - debugprint((" }\n")); -} - -void SMGen::Emit() -{ - // Zero out the entire buffer. - memset(&emitBuffer, 0, sizeof(emitBuffer)); - - BYTE * pBuffer = (BYTE *)&emitBuffer; - pAllStates = (SMState *) pBuffer; - - pBuffer += sizeof(*pAllStates) * (lastStateID+1); - pAllJumpTables = (JumpTableCell *) pBuffer; - - pJumpTableMax = 0; - - // - // Loop through each state and fill in the buffer - // - for (SM_STATE_ID i=1; i<=lastStateID; ++i) - { - SMState * pState = pAllStates+i; - - pState->term = States[i].term; - pState->length = States[i].length; - pState->longestTermState = States[i].longestTermState; - pState->prevState = States[i].prevState; - pState->opc = States[i].opc; - pState->jumpTableByteOffset = JumpTableSet(i); - - } - - debugprint(("pJumpTableMax at starts at cell# %d\n", pJumpTableMax-pAllJumpTables)); - - totalCellNeeded = pJumpTableMax - pAllJumpTables + SM_COUNT; - - debugprint(("MAX_NUM_STATES = %d\n", MAX_NUM_STATES)); - debugprint(("Actual total number of states = %d\n", lastStateID+1)); - assert(lastStateID+1 <= MAX_NUM_STATES); - - debugprint(("Total number of cells = %d\n", totalCellNeeded)); - assert(totalCellNeeded <= MAX_CELL_COUNT); - - debugprint(("sizeof(SMState) = %d\n", sizeof(SMState))); - debugprint(("sizeof(JumpTableCell) = %d\n", sizeof(JumpTableCell))); - debugprint(("sizeof(emitBuffer) = %d\n", sizeof(emitBuffer))); - - EmitDone(); -} - -void SMGen::EmitDone() -{ - printf("// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); - printf("//\n"); - printf("// Automatically generated code. DO NOT MODIFY! \n"); - printf("// To generate this file. Do \"smgen.exe > SMData.cpp\" \n"); - printf("//\n"); - printf("// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n"); - - printf("#include \"jitpch.h\"\n"); - - printf("//\n"); - printf("// States in the state machine\n"); - printf("//\n"); - - printf("const SMState g_SMStates[] = \n{\n"); - - printf(" // {term, len, lng, prev, SMOpcode and SMOpcodeName , offsets } // state ID and name\n"); - - // Print out states - for (SM_STATE_ID id=0; id<=lastStateID; ++id) - { - SMState * pState = pAllStates+id; - printf(" {"); - printf("%4d, ", pState->term); - printf("%3d, ", pState->length); - printf("%3d, ", pState->longestTermState); - printf("%4d, ", pState->prevState); - printf("(SM_OPCODE)%3d /* %-15s */, ", pState->opc, smOpcodeNames[pState->opc]); - printf("%7d" , pState->jumpTableByteOffset); - - printf(" }, // "); - printf("state %d [%s]", id, StateDesc(id)); - - printf("\n"); - } - - printf("};\n\n"); - - printf("static_assert_no_msg(NUM_SM_STATES == sizeof(g_SMStates)/sizeof(g_SMStates[0]));\n\n"); - - printf("const SMState * gp_SMStates = g_SMStates;\n\n"); - - printf("//\n"); - printf("// JumpTableCells in the state machine\n"); - printf("//\n"); - - printf("const JumpTableCell g_SMJumpTableCells[] = \n{\n"); - printf(" // {src, dest }\n"); - - for (unsigned i=0; isrcState); - printf("%4d", cell->destState); - printf(" }, // cell# %d", i); - - if (cell->srcState != 0) - { - JumpTableCell * pThisJumpTable = - (JumpTableCell * )(((PBYTE)pAllJumpTables) + pAllStates[cell->srcState].jumpTableByteOffset); - - assert(cell >= pThisJumpTable); - - SM_OPCODE opcode = (SM_OPCODE) (cell - pThisJumpTable); - - printf(" : state %d [%s]", cell->srcState, StateDesc(cell->srcState)); - - printf(" --(%d %s)--> ", opcode, smOpcodeNames[opcode]); - - printf("state %d [%s]", cell->destState, StateDesc(cell->destState)); - } - printf("\n"); - } - - printf("};\n\n"); - - printf("const JumpTableCell * gp_SMJumpTableCells = g_SMJumpTableCells;\n\n"); -} - - -unsigned short SMGen::JumpTableSet(SM_STATE_ID id) -{ - JumpTableCell * pThisJumpTable = pAllJumpTables; - - while (true) - { - if (bJumpTableFit(pThisJumpTable, id)) - { - JumpTableFill(pThisJumpTable, id); - - if (pThisJumpTable > pJumpTableMax) - pJumpTableMax = pThisJumpTable; - - unsigned offset = ((BYTE*)pThisJumpTable) - ((BYTE*)pAllJumpTables); - - assert(offset == (unsigned short)offset); - - return (unsigned short)offset; - } - - ++pThisJumpTable; - } -} - -bool SMGen::bJumpTableFit(JumpTableCell * pTable, SM_STATE_ID id) -{ - SMGenDestStateDesc * p = States[id].destStateList->next; // Skip the list head. - - while (p) - { - SM_OPCODE opcode = p->opcode; - JumpTableCell * pCell = pTable + opcode; - if (pCell->srcState != 0) - { - // This cell has been occupied. - return false; - } - - p = p->next; - } - - debugprint(("JumpTable for state %d [%s] starts at cell# %d:\n", - id, - StateDesc(id), - pTable-pAllJumpTables)); - return true; -} - -void SMGen::JumpTableFill(JumpTableCell * pTable, SM_STATE_ID id) -{ - SMGenDestStateDesc * p = States[id].destStateList->next; // Skip the list head. - - while (p) - { - SM_OPCODE opcode = p->opcode; - JumpTableCell * pCell = pTable + opcode; - assert(pCell->srcState == 0); - - pCell->srcState = id; - pCell->destState = p->destState; - - debugprint((" cell# %d : [%s (%d)] --> %d\n", - pCell-pAllJumpTables, - smOpcodeNames[opcode], - opcode, - pCell->destState)); - - p = p->next; - } -} - -char * SMGen::StateDesc(SM_STATE_ID stateID) -{ - static char s_StateDesc[500]; - static SM_OPCODE s_StateDescOpcodes[MAX_CODE_SEQUENCE_LENGTH]; - - if (stateID == 0) - return "invalid"; - - if (stateID == SM_STATE_ID_START) - return "start"; - - unsigned i = 0; - - SM_STATE_ID b = stateID; - - while (States[b].prevState != 0) - { - s_StateDescOpcodes[i] = States[b].opc; - b = States[b].prevState; - ++i; - } - - assert(i == States[stateID].length && i>0); - - * s_StateDesc = 0; - - while (--i>0) - { - strcat(s_StateDesc, smOpcodeNames[s_StateDescOpcodes[i]]); - strcat(s_StateDesc, " -> "); - } - - strcat(s_StateDesc, smOpcodeNames[s_StateDescOpcodes[0]]); - - return s_StateDesc; -} - - -SM_STATE_ID SMGenState::getDestState(SM_OPCODE opcode) -{ - assert(opcode < SM_COUNT); - - SMGenDestStateDesc * p = destStateList->next; // Skip the list head. - int lastSeenOpcode = -1; - - while (p) - { - assert(lastSeenOpcode < p->opcode); // opcode should be in accending order. - lastSeenOpcode = p->opcode; - if (p->opcode == opcode) - { - assert(p->destState != 0); - return p->destState; - } - p = p->next; - } - - return 0; -} - -void SMGenState::setDestState(SM_OPCODE opcode, SM_STATE_ID destState) -{ - assert(id != 0); // Should not have come here for the invalid state. - - assert(getDestState(opcode) == 0); // Don't set it twice. - - SMGenDestStateDesc * newSMGenDestStateDesc = new SMGenDestStateDesc(); - - newSMGenDestStateDesc->opcode = opcode; - newSMGenDestStateDesc->destState = destState; - - - // Insert the new entry in accending order - - SMGenDestStateDesc * p = destStateList; - SMGenDestStateDesc * q = p->next; - - while (q) - { - if (q->opcode > opcode) - break; - - p = q; - q = q->next; - } - - newSMGenDestStateDesc->next = p->next; - p->next = newSMGenDestStateDesc; -} - -void Usage() -{ - printf("JIT code sequence state machine generator\n"); - printf("==============================================\n"); - printf("smgen -? : Print usage.\n"); - printf("smgen : Generate static array for the state machine.\n"); - printf("smgen debug: Print debug info.\n"); -} - - -//----------------------------------------------------------------------------- -// main -//----------------------------------------------------------------------------- -extern "C" int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv) -{ - if (argc > 1) - { - if (wcscmp(argv[1], W("-?")) == 0 || wcscmp(argv[1], W("/?")) == 0) - { - Usage(); - return 1; - } - - if (wcscmp(argv[1], W("debug")) == 0) - { - debug = true; - } - } - - // Generate the state machine - SMGen smGen; - smGen.Emit(); - - - - - return 0; -} - - diff --git a/src/coreclr/src/jit/smgen.h b/src/coreclr/src/jit/smgen.h deleted file mode 100644 index 5d254b4..0000000 --- a/src/coreclr/src/jit/smgen.h +++ /dev/null @@ -1,82 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - - -#ifndef __smgen_h__ -#define __smgen_h__ - -#include -#include -#include -#include -#include - -#include "smcommon.h" - -#define MAX_NUM_STATES (1 << (sizeof(SM_STATE_ID)*8)) -#define MAX_CELL_COUNT 420 -#define SM_BUFFER_SIZE (sizeof(SMState)*MAX_NUM_STATES + sizeof(JumpTableCell)*MAX_CELL_COUNT) // Change to a formular of MAX_NUM_STATES and MAX_CELL_COUNT - -class SMGen; // Forward declaration of SMGen - -// The struct representing an edge in the state machine. -struct SMGenDestStateDesc -{ - SMGenDestStateDesc * next; // Linkage - SM_OPCODE opcode; - SM_STATE_ID destState; -}; - -// The struct representing a state in a state machine. -class SMGenState -{ -public: - - SM_STATE_ID id; // the ID of the state - bool term; // does this state terminate a code sequence? - BYTE length; // the length of currently matched opcodes - SM_STATE_ID longestTermState; // the ID of the longest matched terminate state - - SM_STATE_ID prevState; // previous state - SM_OPCODE opc; // opcode that leads from the previous state to current state - - SMGenDestStateDesc * destStateList; // the list of outgoing edges - - // Given an opcode, get the next state the machine will jump to. - SM_STATE_ID getDestState(SM_OPCODE opcode); - - // Given an opcode, set where the next state the machine should jump to. - void setDestState(SM_OPCODE opcode, SM_STATE_ID destState); -}; - -// The state machine generator -class SMGen -{ -public : - - SM_STATE_ID lastStateID; - SMGenState States[MAX_NUM_STATES]; - - SMState * pAllStates; - JumpTableCell * pAllJumpTables; - JumpTableCell * pJumpTableMax; - unsigned totalCellNeeded; - - unsigned emitBufferSize; - BYTE emitBuffer[SM_BUFFER_SIZE]; - - SMGen(); - ~SMGen(); - - void ProcessSeq(SM_OPCODE * CodeSeq); - void Emit(); - void EmitDone(); - unsigned short JumpTableSet(SM_STATE_ID id); - bool bJumpTableFit(JumpTableCell * pTable, SM_STATE_ID id); - void JumpTableFill(JumpTableCell * pTable, SM_STATE_ID id); - char * StateDesc(SM_STATE_ID stateID); -}; - -#endif /* __smgen_h__ */ - -- 2.7.4