VirtualBox

Changeset 100747 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Jul 31, 2023 11:42:58 AM (18 months ago)
Author:
vboxsync
Message:

VMM/IEM: Reworking the recompiler call emitting in the python script - optimize situation where all variants emits the exact same code except for the function number. This saves 4-5 seconds compile time. bugref:10369

Location:
trunk/src/VBox/VMM/VMMAll
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstPython.py

    r100743 r100747  
    18801880        else:
    18811881            sRet = sRet.replace('\n', ' // C++ normal\n');
     1882        return sRet;
     1883
     1884class McCppCall(McCppGeneric):
     1885    """
     1886    A generic C++/C call statement.
     1887
     1888    The sName is still 'C++', so the function name is in the first parameter
     1889    and the the arguments in the subsequent ones.
     1890    """
     1891    def __init__(self, sFnName, asArgs, fDecode = True, cchIndent = 0):
     1892        McCppGeneric.__init__(self, sFnName, fDecode = fDecode, cchIndent = cchIndent);
     1893        self.asParams.extend(asArgs);
     1894
     1895    def renderCode(self, cchIndent = 0):
     1896        cchIndent += self.cchIndent;
     1897        sRet = ' ' * cchIndent + self.asParams[0] + '(' + ','.join(self.asParams[1:]) + ');';
     1898        if self.fDecode:
     1899            sRet += ' // C++ decode\n';
     1900        else:
     1901            sRet += ' // C++ normal\n';
    18821902        return sRet;
    18831903
  • trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py

    r100746 r100747  
    873873        return True;
    874874
    875     def emitThreadedCallStmts(self, cchIndent):
     875    def emitThreadedCallStmts(self, cchIndent, sCallVarNm = None):
    876876        """
    877877        Produces generic C++ statments that emits a call to the thread function
    878878        variation and any subsequent checks that may be necessary after that.
     879
     880        The sCallVarNm is for emitting
    879881        """
    880882        # The call to the threaded function.
    881         sCode = 'IEM_MC2_EMIT_CALL_%s(%s' % (self.cMinParams, self.getIndexName(), );
     883        asCallArgs = [ self.getIndexName() if not sCallVarNm else sCallVarNm, ];
    882884        for iParam in range(self.cMinParams):
    883885            asFrags = [];
     
    893895                        asFrags.append('(%s(%s) << %s)' % (sCast, oRef.sOrgRef, oRef.offNewParam));
    894896            assert asFrags;
    895             sCode += ', ' + ' | '.join(asFrags);
    896         sCode += ');';
     897            asCallArgs.append(' | '.join(asFrags));
    897898
    898899        sCImplFlags = ' | '.join(self.dsCImplFlags.keys());
     
    901902
    902903        aoStmts = [
    903             iai.McCppGeneric('IEM_MC2_BEGIN_EMIT_CALLS();', cchIndent = cchIndent), # Scope and a hook for various stuff.
    904             iai.McCppGeneric(sCode, cchIndent = cchIndent),
     904            iai.McCppCall('IEM_MC2_BEGIN_EMIT_CALLS', [], cchIndent = cchIndent), # Scope and a hook for various stuff.
     905            iai.McCppCall('IEM_MC2_EMIT_CALL_%s' % (len(asCallArgs) - 1,), asCallArgs, cchIndent = cchIndent),
    905906        ];
    906907
     
    908909        # mask and maybe emit additional checks.
    909910        if 'IEM_CIMPL_F_MODE' in self.dsCImplFlags or 'IEM_CIMPL_F_XCPT' in self.dsCImplFlags:
    910             aoStmts.append(iai.McCppGeneric('IEM_MC2_EMIT_CALL_1(kIemThreadedFunc_CheckMode, pVCpu->iem.s.fExec);',
    911                                             cchIndent = cchIndent));
    912 
    913         aoStmts.append(iai.McCppGeneric('IEM_MC2_END_EMIT_CALLS(' + sCImplFlags + ');',
    914                                         cchIndent = cchIndent)); # For closing the scope.
     911            aoStmts.append(iai.McCppCall('IEM_MC2_EMIT_CALL_1', ( 'kIemThreadedFunc_CheckMode', 'pVCpu->iem.s.fExec', ),
     912                                         cchIndent = cchIndent));
     913
     914        aoStmts.append(iai.McCppCall('IEM_MC2_END_EMIT_CALLS', ( sCImplFlags, ), cchIndent = cchIndent)); # For closing the scope.
    915915
    916916        # Emit fEndTb = true or fTbBranched = true if any of the CIMPL flags
     
    10341034            return self.aoVariations[0].emitThreadedCallStmts(0);
    10351035
     1036        #
     1037        # Case statement sub-class.
     1038        #
     1039        dByVari = self.dVariations;
     1040        #fDbg = self.oMcBlock.sFunction == 'iemOpCommonPushSReg';
    10361041        class Case:
    1037             def __init__(self, sCond, aoBody = None):
     1042            def __init__(self, sCond, sVarNm = None):
    10381043                self.sCond  = sCond;
    1039                 self.aoBody = aoBody  # type: list(iai.McCppGeneric)
     1044                self.sVarNm = sVarNm;
     1045                self.oVar   = dByVari[sVarNm] if sVarNm else None;
     1046                self.aoBody = self.oVar.emitThreadedCallStmts(8) if sVarNm else None;
     1047
    10401048            def toCode(self):
    10411049                aoStmts = [ iai.McCppGeneric('case %s:' % (self.sCond), cchIndent = 4), ];
     
    10451053                return aoStmts;
    10461054
    1047         dByVari = self.dVariations;
    1048 
     1055            def toFunctionAssignment(self):
     1056                aoStmts = [ iai.McCppGeneric('case %s:' % (self.sCond), cchIndent = 4), ];
     1057                if self.aoBody:
     1058                    aoStmts.extend([
     1059                        iai.McCppGeneric('enmFunction = %s;' % (self.oVar.getIndexName(),), cchIndent = 8),
     1060                        iai.McCppGeneric('break;', cchIndent = 8),
     1061                    ]);
     1062                return aoStmts;
     1063
     1064            def isSame(self, oThat):
     1065                if not self.aoBody:                 # fall thru always matches.
     1066                    return True;
     1067                if len(self.aoBody) != len(oThat.aoBody):
     1068                    #if fDbg: print('dbg: body len diff: %s vs %s' % (len(self.aoBody), len(oThat.aoBody),));
     1069                    return False;
     1070                for iStmt, oStmt in enumerate(self.aoBody):
     1071                    oThatStmt = oThat.aoBody[iStmt] # type: iai.McStmt
     1072                    assert isinstance(oStmt, iai.McCppGeneric);
     1073                    assert not isinstance(oStmt, iai.McStmtCond);
     1074                    if isinstance(oStmt, iai.McStmtCond):
     1075                        return False;
     1076                    if oStmt.sName != oThatStmt.sName:
     1077                        #if fDbg: print('dbg: stmt #%s name: %s vs %s' % (iStmt, oStmt.sName, oThatStmt.sName,));
     1078                        return False;
     1079                    if len(oStmt.asParams) != len(oThatStmt.asParams):
     1080                        #if fDbg: print('dbg: stmt #%s param count: %s vs %s'
     1081                        #               % (iStmt, len(oStmt.asParams), len(oThatStmt.asParams),));
     1082                        return False;
     1083                    for iParam, sParam in enumerate(oStmt.asParams):
     1084                        if (    sParam != oThatStmt.asParams[iParam]
     1085                            and (   iParam != 1
     1086                                 or not isinstance(oStmt, iai.McCppCall)
     1087                                 or not oStmt.asParams[0].startswith('IEM_MC2_EMIT_CALL_')
     1088                                 or sParam != self.oVar.getIndexName()
     1089                                 or oThatStmt.asParams[iParam] != oThat.oVar.getIndexName() )):
     1090                            #if fDbg: print('dbg: stmt #%s, param #%s: %s vs %s'
     1091                            #               % (iStmt, iParam, sParam, oThatStmt.asParams[iParam],));
     1092                            return False;
     1093                return True;
     1094
     1095        #
    10491096        # Determine what we're switch on.
    10501097        # This ASSUMES that (IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK | IEM_F_MODE_CPUMODE_MASK) == 7!
     1098        #
    10511099        fSimple = True;
    10521100        sSwitchValue = 'pVCpu->iem.s.fExec & IEM_F_MODE_CPUMODE_MASK';
     
    10591107            fSimple       = False;
    10601108
     1109        #
    10611110        # Generate the case statements.
     1111        #
    10621112        # pylintx: disable=x
    10631113        aoCases = [];
     
    10651115            assert not fSimple;
    10661116            aoCases.extend([
    1067                 Case('IEMMODE_64BIT',     dByVari[ThrdFnVar.ksVariation_64].emitThreadedCallStmts(8)),
    1068                 Case('IEMMODE_64BIT | 8', dByVari[ThrdFnVar.ksVariation_64_Addr32].emitThreadedCallStmts(8)),
     1117                Case('IEMMODE_64BIT',     ThrdFnVar.ksVariation_64),
     1118                Case('IEMMODE_64BIT | 8', ThrdFnVar.ksVariation_64_Addr32),
    10691119            ]);
    10701120        elif ThrdFnVar.ksVariation_64 in dByVari:
    10711121            assert fSimple;
    1072             aoCases.append(Case('IEMMODE_64BIT', dByVari[ThrdFnVar.ksVariation_64].emitThreadedCallStmts(8)));
     1122            aoCases.append(Case('IEMMODE_64BIT', ThrdFnVar.ksVariation_64));
    10731123
    10741124        if ThrdFnVar.ksVariation_32_Addr16 in dByVari:
    10751125            assert not fSimple;
    10761126            aoCases.extend([
    1077                 Case('IEMMODE_32BIT | IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK',
    1078                      dByVari[ThrdFnVar.ksVariation_32_Flat].emitThreadedCallStmts(8)),
    1079                 Case('IEMMODE_32BIT',
    1080                      dByVari[ThrdFnVar.ksVariation_32].emitThreadedCallStmts(8)),
    1081                 Case('IEMMODE_32BIT | IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK | 8'), # fall thru
    1082                 Case('IEMMODE_32BIT | 8',
    1083                      dByVari[ThrdFnVar.ksVariation_32_Addr16].emitThreadedCallStmts(8)),
     1127                Case('IEMMODE_32BIT | IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK', ThrdFnVar.ksVariation_32_Flat),
     1128                Case('IEMMODE_32BIT', ThrdFnVar.ksVariation_32),
     1129                Case('IEMMODE_32BIT | IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK | 8', None), # fall thru
     1130                Case('IEMMODE_32BIT | 8', ThrdFnVar.ksVariation_32_Addr16),
    10841131            ]);
    10851132        elif ThrdFnVar.ksVariation_32 in dByVari:
    10861133            assert fSimple;
    1087             aoCases.append(Case('IEMMODE_32BIT', dByVari[ThrdFnVar.ksVariation_32].emitThreadedCallStmts(8)));
     1134            aoCases.append(Case('IEMMODE_32BIT', ThrdFnVar.ksVariation_32));
    10881135
    10891136        if ThrdFnVar.ksVariation_16_Addr32 in dByVari:
    10901137            assert not fSimple;
    10911138            aoCases.extend([
    1092                 Case('IEMMODE_16BIT',     dByVari[ThrdFnVar.ksVariation_16].emitThreadedCallStmts(8)),
    1093                 Case('IEMMODE_16BIT | 8', dByVari[ThrdFnVar.ksVariation_16_Addr32].emitThreadedCallStmts(8)),
     1139                Case('IEMMODE_16BIT',     ThrdFnVar.ksVariation_16),
     1140                Case('IEMMODE_16BIT | 8', ThrdFnVar.ksVariation_16_Addr32),
    10941141            ]);
    10951142        elif ThrdFnVar.ksVariation_16 in dByVari:
    10961143            assert fSimple;
    1097             aoCases.append(Case('IEMMODE_16BIT', dByVari[ThrdFnVar.ksVariation_16].emitThreadedCallStmts(8)));
     1144            aoCases.append(Case('IEMMODE_16BIT', ThrdFnVar.ksVariation_16));
    10981145
    10991146        if ThrdFnVar.ksVariation_16_Pre386 in dByVari:
    1100             aoCases.append(Case('IEMMODE_16BIT | IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK',
    1101                                 dByVari[ThrdFnVar.ksVariation_16_Pre386].emitThreadedCallStmts(8)));
    1102 
    1103         # Generate the switch statement.
    1104         aoStmts = [
    1105             iai.McCppGeneric('switch (%s)' % (sSwitchValue,)),
    1106             iai.McCppGeneric('{'),
    1107         ];
    1108         for oCase in aoCases:
    1109             aoStmts.extend(oCase.toCode());
    1110         aoStmts.extend([
    1111             iai.McCppGeneric('IEM_NOT_REACHED_DEFAULT_CASE_RET();', cchIndent = 4),
    1112             iai.McCppGeneric('}'),
    1113         ]);
     1147            aoCases.append(Case('IEMMODE_16BIT | IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK', ThrdFnVar.ksVariation_16_Pre386));
     1148
     1149        #
     1150        # If the case bodies are all the same, except for the function called,
     1151        # we can reduce the code size and hopefully compile time.
     1152        #
     1153        assert aoCases[0].aoBody;
     1154        fAllSameCases = True
     1155        for iCase in range(1, len(aoCases)):
     1156            fAllSameCases = fAllSameCases and aoCases[iCase].isSame(aoCases[0]);
     1157        #if fDbg: print('fAllSameCases=%s %s' % (fAllSameCases, self.oMcBlock.sFunction,));
     1158        if fAllSameCases:
     1159            aoStmts = [
     1160                iai.McCppGeneric('IEMTHREADEDFUNCS enmFunction;'),
     1161                iai.McCppGeneric('switch (%s)' % (sSwitchValue,)),
     1162                iai.McCppGeneric('{'),
     1163            ];
     1164            for oCase in aoCases:
     1165                aoStmts.extend(oCase.toFunctionAssignment());
     1166            aoStmts.extend([
     1167                iai.McCppGeneric('IEM_NOT_REACHED_DEFAULT_CASE_RET();', cchIndent = 4),
     1168                iai.McCppGeneric('}'),
     1169            ]);
     1170            aoStmts.extend(dByVari[aoCases[0].sVarNm].emitThreadedCallStmts(0, 'enmFunction'));
     1171
     1172        else:
     1173            #
     1174            # Generate the generic switch statement.
     1175            #
     1176            aoStmts = [
     1177                iai.McCppGeneric('switch (%s)' % (sSwitchValue,)),
     1178                iai.McCppGeneric('{'),
     1179            ];
     1180            for oCase in aoCases:
     1181                aoStmts.extend(oCase.toCode());
     1182            aoStmts.extend([
     1183                iai.McCppGeneric('IEM_NOT_REACHED_DEFAULT_CASE_RET();', cchIndent = 4),
     1184                iai.McCppGeneric('}'),
     1185            ]);
    11141186
    11151187        return aoStmts;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette