Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix internal errors when for-loop bodies always exit #269

Merged
merged 14 commits into from
Jul 16, 2024

Conversation

achidlow
Copy link
Contributor

This fixes "internal error" issues with code such as the below:

@subroutine
def silly_for_1() -> None:
    for b in Bytes(b"abc"):
        log(b)
        break


@subroutine
def silly_for_2() -> None:
    for x in (UInt64(0), UInt64(1)):
        log(x)
        break


@subroutine
def silly_for_3() -> None:
    for i in urange(10):
        log(i)
        break

Because the loops above always exit the loop on the first iteration, the IR builder attempts to add unreachable code in the footers.

This fix only adds footers if the block can be activated.

It also restructures the tuple iteration builder to remove the singular use of ignore_predecessor_check.

The refactored iteration code for tuples also produces reduced code sizes across the board.

Testing has been improved, with coverage of each valid combination of iteration type (indexable, range, and tuple) against forwards/reversed items and indexes.

Copy link

Coverage

Coverage Report
FileStmtsMissCoverMissing
src/puya
   __main__.py31197%116
   arc4_util.py48296%61, 63
   arc32.py70396%77–78, 103
   client_gen.py1141140%1–202
   compile.py2112091%168–171, 183–184, 193–194, 205, 212–213, 230–240, 250–252, 257, 333–334
   context.py40198%48
   errors.py451762%43–53, 65–71
   log.py2123086%36–39, 72, 74, 92, 126–127, 169–171, 174–176, 178, 191–200, 222, 292–294, 303–304, 338, 355
   parse.py2221195%96, 108, 133, 227, 318–323, 327, 425–426, 429
   utils.py1662088%52, 56, 90, 96, 111, 114–116, 123, 145, 158–159, 163, 167–170, 199, 201, 224, 254
src/puya/awst
   nodes.py9095094%84, 88–91, 131, 135–138, 304, 481, 497, 515, 562, 589–590, 646, 650, 774, 810, 832, 864, 886, 891, 896, 995, 1143, 1196–1197, 1204–1209, 1251, 1331, 1384, 1388, 1438, 1451, 1496, 1539, 1550, 1552, 1557, 1565, 1570, 1575, 1584, 1589, 1594, 1601
   to_code_visitor.py330598%112, 296–297, 339, 525
   txn_fields.py98199%48
   wtypes.py2682690%159–163, 173–176, 191, 206, 234, 270, 294, 299, 340, 368, 370, 470, 497–498, 507–508, 516–517, 536
src/puya/awst_build
   arc4_utils.py3164984%42, 45–46, 48, 80, 92–94, 118, 129–133, 149, 151, 154–155, 178, 216–218, 227, 232, 237–238, 262, 266, 278, 285, 287, 301–302, 305–309, 314–315, 321–324, 332, 350, 362, 370–371, 383, 391, 492, 497, 516
   arc32_client_gen.py69396%35, 131–132
   base_mypy_visitor.py1294069%70–76, 94, 102–115, 129, 131, 133, 145, 150, 154, 157, 160, 166, 187, 192, 195, 198, 205, 209, 212, 215, 219, 237, 241, 245, 249, 253, 257, 261, 265, 269, 273, 277, 281, 285
   context.py2254779%47, 69, 72, 82–83, 109–110, 206, 211, 217–221, 226, 235, 237, 240–242, 244, 251, 253, 259, 264–265, 270–272, 275, 295, 319–320, 332, 346, 349–361
   contract.py1953483%125–126, 128–131, 139–140, 143, 155, 203, 248, 252, 267–271, 279, 288, 291, 303, 311, 314, 317, 320, 323, 326, 329, 332, 335, 346, 356, 364, 370, 395–401
   contract_data.py58297%37–38
   intrinsic_models.py40198%49
   main.py48394%31, 48, 58
   module.py4106085%53–56, 85, 149, 163–165, 180–181, 188, 197–198, 206–210, 228–232, 239, 263–264, 275, 297–300, 310–312, 318, 341–344, 357, 391, 398, 420–421, 444–449, 503–504, 532, 543, 546, 552, 565, 571, 583, 586, 608, 628, 633, 637, 641–644, 671, 729, 737, 739
   pytypes.py4565189%84–86, 100–101, 141, 157–163, 186, 206, 267, 276, 295, 299, 315–316, 348, 440–442, 456–457, 526–527, 604, 615–616, 664–665, 670, 719–720, 741–742, 870–871, 895, 923, 957–959, 985, 1012, 1022–1023, 1059–1061
   subroutine.py6015291%136, 258, 264, 322–325, 331, 383, 390, 393–399, 464, 579, 581–582, 600, 602, 612–613, 622–623, 627, 648, 718, 725, 745–746, 828, 859–860, 877, 899–900, 905, 993, 1001, 1012–1013, 1037, 1150, 1160, 1167, 1180, 1205, 1208, 1211, 1214, 1217, 1237–1240
   utils.py1942587%38, 55–59, 75, 110–111, 115, 159–160, 234, 242, 247, 260–264, 269–272, 280, 307, 315, 358
src/puya/awst_build/eb
   _base.py1251985%53, 58–60, 65, 72, 77, 82–84, 139, 150, 172, 177, 182, 187, 198, 213, 218–220
   _bytes_backed.py48296%30–31
   _expect.py1251886%25, 36, 77–80, 92–95, 98, 157–158, 219, 232–235
   _literals.py1363078%42–43, 67, 86, 115, 123, 137, 141, 145–151, 161–175, 180
   _utils.py44198%95
   array.py27967%24, 29–34, 44, 50
   biguint.py97694%57, 99, 136, 151–152, 154
   bool.py51884%38–42, 58, 69, 84
   bytes.py1722088%72, 105–106, 133–134, 139–140, 146–147, 150–151, 158, 201, 236, 269, 273, 290–291, 306–307
   conditional_literal.py1173570%76, 80, 134, 138–141, 150–152, 161–164, 175–178, 187, 191, 195–198, 213–225, 234–235
   contracts.py84693%64, 70, 83, 108, 129, 133
   ensure_budget.py33197%49
   interface.py96397%296–298, 302
   intrinsics.py99892%38, 57, 64, 77, 84, 155, 179–180
   log.py43491%46–47, 52, 61
   none.py25388%17, 28, 37
   string.py1451391%72, 115–116, 135, 139, 183, 190, 194, 206, 280–282, 302
   struct.py17571%15–17, 26, 32
   subroutine.py801878%50, 54–57, 72, 75–83, 97, 105–109, 111–114, 119
   template_variables.py37392%30, 58, 67
   tuple.py2661196%75, 149, 184–185, 191, 268–269, 394, 405–406, 469
   uint64.py114596%59, 123–124, 172–173
   uint64_enums.py41295%42, 47
   unsigned_builtins.py1532087%74, 81, 108, 135, 139, 143, 151, 155, 159, 163, 167, 177, 181, 187, 198, 204, 243, 275, 287, 299
src/puya/awst_build/eb/arc4
   _base.py91397%187–190, 201
   _utils.py113992%61–62, 87, 92, 122–125, 165, 169, 183
   abi_call.py159895%90, 96, 99, 121, 179, 195, 248, 320
   address.py77396%57, 117–118
   bool.py57395%44, 86–87
   dynamic_array.py1271092%57, 126–127, 147, 149, 154, 228, 249, 255–258
   dynamic_bytes.py68396%97–99
   emit.py37197%39
   static_array.py66198%41
   string.py100991%54–55, 103, 126, 131–134, 161–162
   struct.py49198%49
   tuple.py941584%50–52, 92–95, 98–99, 135–138, 143, 147–148, 158, 168
   ufixed.py70297%43, 102
   uint.py75495%81–83, 135–136
src/puya/awst_build/eb/reference_types
   _base.py52198%119
   account.py81298%60, 171
   application.py45198%35
   asset.py65198%43
src/puya/awst_build/eb/storage
   _common.py69396%104, 119–120
   _storage.py961683%77, 85, 89, 93, 97, 101, 105, 109, 119, 123, 127, 131, 137, 148, 154, 166
   value_proxy.py55787%39, 43, 51, 55, 92, 100, 104
   box_map.py144199%183
   global_state.py138596%108–109, 115, 171–172
   local_state.py1481193%103–104, 108, 157, 161, 165, 175, 179, 203, 290, 314
src/puya/awst_build/eb/transaction
   base.py39295%23, 43
   inner.py48296%88–89
   inner_params.py81594%69, 79, 83, 143, 145
   itxn_args.py60198%68
src/puya/awst_build/validation
   base_invoker.py29583%31, 38, 47–52
   inner_transactions.py181199%160
   scratch_slots.py39490%19, 33, 49, 51
src/puya/ir
   arc4_router.py3292393%157, 175, 183, 251–252, 341, 520–521, 535, 579–580, 592, 597, 602, 607, 612, 617, 637–641, 672, 871, 904–905
   avm_ops.py315199%46
   avm_ops_models.py48394%21, 30, 38
   context.py86792%72, 94–100, 105, 128, 136
   main.py230399%438–439, 456
   models.py5192396%67, 176, 183, 313, 383–384, 389, 395–400, 412, 456, 483, 538, 580, 660, 676, 717, 720, 727, 730, 820–821
   ssa.py130298%51–52
   to_text_visitor.py149994%93, 98, 182–183, 189–194
   types.py971288%49–50, 56, 90–95, 103, 140–143
   visitor.py1191587%171, 183, 198, 201, 207, 213, 216, 227, 230, 233, 236, 239, 242, 245, 248
   visitor_mutator.py101298%152–153
   vla.py72199%87
src/puya/ir/builder
   _utils.py76593%78, 204, 240–242
   arc4.py5012795%91, 127–132, 386, 389, 458–461, 725–726, 972, 996, 1085–1102, 1123–1140, 1179–1180, 1232, 1242, 1297, 1342, 1361, 1381, 1445–1452
   assignment.py74791%49, 90, 163, 174, 192, 208–209
   blocks.py90298%162, 170
   bytes.py641478%23–55, 139
   callsub.py57198%93
   flow_control.py96199%72
   iteration.py175498%44, 66, 92, 165
   itxn.py2661395%125–126, 128, 141, 189, 209, 234–235, 563, 587–588, 601–602
   main.py4963793%100, 162, 166, 221, 245, 269–270, 304, 466, 488–491, 507–508, 548, 574, 618–621, 631, 696, 814, 827, 860, 915, 918, 926, 929–930, 937, 968, 1030, 1047, 1097–1098
   storage.py84495%99–100, 151–152
src/puya/ir/destructure
   coalesce_locals.py1022080%119, 128–129, 132–135, 138–147, 163–166
   parcopy.py84298%47, 83
src/puya/ir/optimize
   collapse_blocks.py92595%65–69
   control_op_simplification.py1011090%159–166, 240–247
   inner_txn.py36197%38
   intrinsic_simplification.py4212694%68, 171, 183, 232–233, 253, 320, 384, 458, 486, 507, 509, 524, 579, 609, 615, 617, 619, 624, 626, 628, 630, 632, 684–685, 692
   main.py86397%111–112, 128
src/puya/ir/validation
   _base.py30293%24–25
   min_avm_version_validator.py11191%15
   op_run_mode_validator.py20670%19–30
src/puya/mir
   annotaters.py159299%62, 212
   builder.py136894%139, 248–249, 302, 305, 308, 311, 314
   context.py39197%35
   models.py3281695%40, 52, 68, 77, 88, 99, 110, 150, 260, 291, 328, 340, 365–371
   output.py61297%29, 31
   stack.py2501992%72, 119, 135, 146, 157, 167, 184, 201, 211, 230, 250, 256, 258, 297, 310, 334, 366, 371, 409
src/puya/mir/stack_allocation
   baileys.py205399%31, 330–334
   frame_allocation.py80298%21, 68
   koopmans.py61198%55
   peephole.py100694%75, 89, 99, 101, 103, 145
src/puya/teal/optimize
   peephole.py112397%139, 145, 169
   repeated_rotations.py42198%13
   repeated_rotations_search.py88693%34, 40–41, 57, 67–68
TOTAL19136142093% 

Tests Skipped Failures Errors Time
458 3 💤 0 ❌ 0 🔥 3m 44s ⏱️

@achidlow achidlow merged commit 1b24cd7 into main Jul 16, 2024
4 checks passed
@achidlow achidlow deleted the fix-unreachable-loop-footer branch July 16, 2024 00:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants