Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | new INST_LMAP_COLLECT, speeds up lmap and eliminates the need for a temp var |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
58ebb297000cbc64a593e1950fdfc573 |
User & Date: | mig 2013-12-10 11:38:17 |
Context
2013-12-10
| ||
12:05 | fix stack computations for lmap check-in: e4212fccc3 user: mig tags: trunk | |
11:55 | fix stack computations for lmap check-in: 8aa6e6e51b user: mig tags: mistake | |
11:40 | get INST_LMAP_COLLECT from trunk check-in: 72fd8739c8 user: mig tags: mig-optimize | |
11:38 | new INST_LMAP_COLLECT, speeds up lmap and eliminates the need for a temp var check-in: 58ebb29700 user: mig tags: trunk | |
2013-12-06
| ||
15:58 | change NULL to INT2PTR(0), for clarity check-in: 6cfea930ff user: mig tags: trunk | |
Changes
Changes to generic/tclCompCmds.c.
︙ | ︙ | |||
2454 2455 2456 2457 2458 2459 2460 | int collect) /* Select collecting or accumulating mode * (TCL_EACH_*) */ { Proc *procPtr = envPtr->procPtr; ForeachInfo *infoPtr; /* Points to the structure describing this * foreach command. Stored in a AuxData * record in the ByteCode. */ | < < | 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 | int collect) /* Select collecting or accumulating mode * (TCL_EACH_*) */ { Proc *procPtr = envPtr->procPtr; ForeachInfo *infoPtr; /* Points to the structure describing this * foreach command. Stored in a AuxData * record in the ByteCode. */ Tcl_Token *tokenPtr, *bodyTokenPtr; int jumpBackOffset, infoIndex, range; int numWords, numLists, numVars, loopIndex, i, j, code; DefineLineInformation; /* TIP #280 */ /* |
︙ | ︙ | |||
2571 2572 2573 2574 2575 2576 2577 | loopIndex++; } /* * We will compile the foreach command. */ | < < < < < < < | 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 | loopIndex++; } /* * We will compile the foreach command. */ code = TCL_OK; /* * Create and initialize the ForeachInfo and ForeachVarList data * structures describing this command. Then create a AuxData record * pointing to the ForeachInfo structure. */ |
︙ | ︙ | |||
2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 | varListPtr->varIndexes[j] = TclFindCompiledLocal(varName, nameChars, /*create*/ 1, envPtr); } infoPtr->varLists[loopIndex] = varListPtr; } infoIndex = TclCreateAuxData(infoPtr, &tclNewForeachInfoType, envPtr); /* * Evaluate each value list and leave it on stack. */ for (i = 0, tokenPtr = parsePtr->tokenPtr; i < numWords-1; i++, tokenPtr = TokenAfter(tokenPtr)) { if ((i%2 == 0) && (i > 0)) { CompileWord(envPtr, tokenPtr, interp, i); } } | > > > > > > > > < < < < < < < < < < | | | > | 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 | varListPtr->varIndexes[j] = TclFindCompiledLocal(varName, nameChars, /*create*/ 1, envPtr); } infoPtr->varLists[loopIndex] = varListPtr; } infoIndex = TclCreateAuxData(infoPtr, &tclNewForeachInfoType, envPtr); /* * Create the collecting object, unshared. */ if (collect == TCL_EACH_COLLECT) { TclEmitInstInt4(INST_LIST, 0, envPtr); } /* * Evaluate each value list and leave it on stack. */ for (i = 0, tokenPtr = parsePtr->tokenPtr; i < numWords-1; i++, tokenPtr = TokenAfter(tokenPtr)) { if ((i%2 == 0) && (i > 0)) { CompileWord(envPtr, tokenPtr, interp, i); } } TclEmitInstInt4(INST_FOREACH_START, infoIndex, envPtr); /* * Inline compile the loop body. */ range = TclCreateExceptRange(LOOP_EXCEPTION_RANGE, envPtr); ExceptionRangeStarts(envPtr, range); BODY(bodyTokenPtr, numWords - 1); ExceptionRangeEnds(envPtr, range); if (collect == TCL_EACH_COLLECT) { TclEmitOpcode(INST_LMAP_COLLECT, envPtr); } else { TclEmitOpcode( INST_POP, envPtr); } /* * Bottom of loop code: assign each loop variable and check whether * to terminate the loop. Set the loop's break target. */ ExceptionRangeTarget(envPtr, range, continueOffset); |
︙ | ︙ | |||
2668 2669 2670 2671 2672 2673 2674 | */ jumpBackOffset = envPtr->exceptArrayPtr[range].continueOffset - envPtr->exceptArrayPtr[range].codeOffset; infoPtr->loopCtTemp = -jumpBackOffset; /* | | | | < < < < | 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 | */ jumpBackOffset = envPtr->exceptArrayPtr[range].continueOffset - envPtr->exceptArrayPtr[range].codeOffset; infoPtr->loopCtTemp = -jumpBackOffset; /* * The command's result is an empty string if not collecting. If * collecting, it is automatically left on stack after FOREACH_END. */ if (collect != TCL_EACH_COLLECT) { PushStringLiteral(envPtr, ""); } done: for (loopIndex = 0; loopIndex < numLists; loopIndex++) { if (varvList[loopIndex] != NULL) { ckfree(varvList[loopIndex]); |
︙ | ︙ |
Changes to generic/tclCompile.c.
︙ | ︙ | |||
550 551 552 553 554 555 556 557 558 559 560 561 562 563 | /* Initialize execution of a foreach loop. Operand is aux data index * of the ForeachInfo structure for the foreach command. It pushes 2 * elements which hold runtime params for foreach_step, they are later * dropped by foreach_end together with the value lists. */ {"foreach_step", 1, 0, 0, {OPERAND_NONE}}, /* "Step" or begin next iteration of foreach loop. */ {"foreach_end", 1, 0, 0, {OPERAND_NONE}}, {NULL, 0, 0, 0, {OPERAND_NONE}} }; /* * Prototypes for procedures defined later in this file: */ | > | 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 | /* Initialize execution of a foreach loop. Operand is aux data index * of the ForeachInfo structure for the foreach command. It pushes 2 * elements which hold runtime params for foreach_step, they are later * dropped by foreach_end together with the value lists. */ {"foreach_step", 1, 0, 0, {OPERAND_NONE}}, /* "Step" or begin next iteration of foreach loop. */ {"foreach_end", 1, 0, 0, {OPERAND_NONE}}, {"lmap_collect", 1, 0, 0, {OPERAND_NONE}}, {NULL, 0, 0, 0, {OPERAND_NONE}} }; /* * Prototypes for procedures defined later in this file: */ |
︙ | ︙ |
Changes to generic/tclCompile.h.
︙ | ︙ | |||
769 770 771 772 773 774 775 776 777 | #define INST_EXPAND_DROP 165 /* New foreach implementation */ #define INST_FOREACH_START 166 #define INST_FOREACH_STEP 167 #define INST_FOREACH_END 168 /* The last opcode */ | > | | 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 | #define INST_EXPAND_DROP 165 /* New foreach implementation */ #define INST_FOREACH_START 166 #define INST_FOREACH_STEP 167 #define INST_FOREACH_END 168 #define INST_LMAP_COLLECT 169 /* The last opcode */ #define LAST_INST_OPCODE 169 /* * Table describing the Tcl bytecode instructions: their name (for displaying * code), total number of code bytes required (including operand bytes), and a * description of the type of each operand. These operand types include signed * and unsigned integers of length one and four bytes. The unsigned integers * are used for indexes or for, e.g., the count of objects to push in a "push" |
︙ | ︙ |
Changes to generic/tclExecute.c.
︙ | ︙ | |||
6341 6342 6343 6344 6345 6346 6347 6348 6349 6350 6351 6352 6353 6354 | case INST_FOREACH_END: /* THIS INSTRUCTION IS ONLY CALLED AS A BREAK TARGET */ tmpPtr = OBJ_AT_TOS; infoPtr = tmpPtr->internalRep.otherValuePtr; numLists = infoPtr->numLists; NEXT_INST_V(1, numLists+2, 0); } case INST_BEGIN_CATCH4: /* * Record start of the catch command with exception range index equal * to the operand. Push the current stack depth onto the special catch * stack. | > > > > > > > > > > > > > > > > > > > | 6341 6342 6343 6344 6345 6346 6347 6348 6349 6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 | case INST_FOREACH_END: /* THIS INSTRUCTION IS ONLY CALLED AS A BREAK TARGET */ tmpPtr = OBJ_AT_TOS; infoPtr = tmpPtr->internalRep.otherValuePtr; numLists = infoPtr->numLists; NEXT_INST_V(1, numLists+2, 0); case INST_LMAP_COLLECT: /* * This instruction is only issued by lmap. The stack is: * - result * - infoPtr * - loop counters * - valLists * - collecting obj (unshared) * The instruction lappends the result to the collecting obj. */ tmpPtr = OBJ_AT_DEPTH(1); infoPtr = tmpPtr->internalRep.otherValuePtr; numLists = infoPtr->numLists; objPtr = OBJ_AT_DEPTH(3 + numLists); Tcl_ListObjAppendElement(NULL, objPtr, OBJ_AT_TOS); NEXT_INST_F(1, 1, 0); } case INST_BEGIN_CATCH4: /* * Record start of the catch command with exception range index equal * to the operand. Push the current stack depth onto the special catch * stack. |
︙ | ︙ |