Skip to content

feat: extend LiteralDict lowering with runtime support (constant-path tests)#213

Open
m-akhil-reddy wants to merge 12 commits intoarxlang:mainfrom
m-akhil-reddy:feat/literal-dict-runtime-211
Open

feat: extend LiteralDict lowering with runtime support (constant-path tests)#213
m-akhil-reddy wants to merge 12 commits intoarxlang:mainfrom
m-akhil-reddy:feat/literal-dict-runtime-211

Conversation

@m-akhil-reddy
Copy link
Contributor

Notes

  • This repository uses an AI bot for reviews. Keep your PR in Draft while
    you work. When you’re ready for a review, change the status to Ready for
    review
    to trigger a new review round. If you make additional changes and
    don’t want to trigger the bot, switch the PR back to Draft.
  • AI-bot comments may not always be accurate. Please review them critically and
    share your feedback; it helps us improve the tool.
  • Avoid changing code that is unrelated to your proposal. Keep your PR as short
    as possible to increase the chances of a timely review. Large PRs may not be
    reviewed and may be closed.
  • Don’t add unnecessary comments. Your code should be readable and
    self-documenting
    (guidance).
  • Don’t change core features without prior discussion with the community. Use
    our Discord to discuss ideas, blockers, or issues
    (https://discord.gg/Nu4MdGj9jB).
  • Do not include secrets (API keys, tokens, passwords), credentials, or
    sensitive data/PII in code, configs, logs, screenshots, or commit history. If
    something leaks, rotate the credentials immediately, invalidate the old key,
    and note it in the PR so maintainers can assist.
  • Do not commit large binaries or generated artifacts. If large datasets are
    needed for tests, prefer small fixtures or programmatic downloads declared in
    makim.yaml (e.g., a task that fetches data at test time). If a large binary is
    unavoidable, discuss first and consider Git LFS.

Pull Request description

#30 #211

How to test these changes

  • ...

Pull Request checklists

This PR is a:

  • bug-fix
  • new feature
  • maintenance

About this PR:

  • it includes tests.
  • the tests are executed on CI.
  • the tests generate log file(s) (path).
  • pre-commit hooks were executed locally.
  • this PR requires a project documentation update.

Author's checklist:

  • I have reviewed the changes and it contains no misspelling.
  • The code is well commented, especially in the parts that contain more
    complexity.
  • New and old tests passed locally.

Additional information

Reviewer's checklist

Copy and paste this template for your review's note:

## Reviewer's Checklist

- [ ] I managed to reproduce the problem locally from the `main` branch
- [ ] I managed to test the new changes locally
- [ ] I confirm that the issues mentioned were fixed/resolved .

@m-akhil-reddy
Copy link
Contributor Author

Hi @yuvimittal , can you review the PR and suggest any changes if needed .

This PR extends the existing LiteralDict lowering by adding support for the runtime (non-constant) dictionary path.

Approach

The implementation first checks whether all keys and values lower to LLVM Constant values.

If all elements are constants, the dictionary is lowered using the existing constant fast-path to a constant LLVM array [N x {K, V}].

If non-constant values appear, the visitor switches to runtime lowering:

  • The key/value LLVM types are inferred from the first pair.
  • Homogeneity of types is enforced for runtime dictionaries.
  • A struct type {K, V} is created to represent each dictionary entry.
  • An array [N x {K, V}] is allocated in the function entry block.
  • Each key/value pair is stored using GEP indexing and store instructions.
  • The resulting pointer to the allocated array is pushed onto the result stack.

Safety Handling

  • Runtime lowering requires a valid LLVM function context.
  • If the visitor is executed outside a function (as in unit tests), the implementation falls back to constant lowering to avoid invalid IR generation.

Tests

  • Added a test covering the runtime-lowering path behavior.
  • Since tests run outside a function context, the test verifies the fallback to constant lowering.

Renamed test from 'test_literal_dict_runtime_lowering_fallback' to 'test_literal_dict_const_lowering'.


@pytest.mark.parametrize("builder_class", [LLVMLiteIR])
def test_literal_dict_const_lowering(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i have changed the test name as test never enters runtime lowering.Because
LiteralInt32 -> ir.Constant so this condition is always true: `all_constants = True
meaning all tests actually executes constant fast path , not run time lowering

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right that this path always hits the constant fast-path since LiteralInt32 lowers to ir.Constant. I updated the test name to test_literal_dict_const_lowering.
thanks.

result = visitor.result_stack.pop()

# When no function context exists, runtime lowering falls back to constant
assert isinstance(result, ir.Constant)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better test assert result.type.count == 1
this verifies dictionary layout

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added assert result.type.count == 1 so the test also verifies the dictionary layout.
thank.



@pytest.mark.parametrize("builder_class", [LLVMLiteIR])
def test_literal_dict_const_lowering(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should ideally test a non-constant key/value. uh for example
x = 1 { x: 2 }
like the code functionality

Copy link
Contributor Author

@m-akhil-reddy m-akhil-reddy Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestions, @yuvimittal

Currently the tests run outside a function context, so runtime lowering cannot safely emit IR (no builder block). Because of that, the implementation falls back to constant lowering in tests.

I agree that ideally we should test a true non-constant case (e.g., using a variable like {x: 2} inside a function). I can add a function-based test for that in a follow-up PR's.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@m-akhil-reddy , but the PR title and description doesnt align with existing tests

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yuvimittal ,
thanks for pointing that out.

I'll update the PR title/description to clarify that the implementation includes the runtime lowering path, while the current tests cover the constant fast-path due to running outside a function context.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have updated the PR title and description to clarify that the implementation includes the runtime lowering path while the current tests cover the constant fast-path due to running outside a function context.

builder.position_at_end(current_bb)

# i32 type used for GEP indexing
i32 = ir.IntType(32)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LLVM actually expects target pointer-sized integers for GEP indices on some targets. so the safer approach would be i32 = self._llvm.INT32_TYPE

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I replaced ir.IntType(32) with self._llvm.INT32_TYPE to follow the project's LLVM type definitions.
thanks.

@m-akhil-reddy
Copy link
Contributor Author

@yuvimittal , i have made the changes according to your suggestion.

@m-akhil-reddy m-akhil-reddy changed the title feat: extend LiteralDict lowering with runtime construction feat: extend LiteralDict lowering with runtime construction support Mar 11, 2026
@m-akhil-reddy m-akhil-reddy changed the title feat: extend LiteralDict lowering with runtime construction support feat: extend LiteralDict lowering with runtime support (constant-path tests) Mar 11, 2026
@m-akhil-reddy
Copy link
Contributor Author

This PR extends LiteralDict lowering with runtime construction support when keys/values are non-constant.
Current tests run outside a function context, so they cover the constant fast-path; a function-based runtime test can be added in a follow-up.

@yuvimittal
Copy link
Member

This PR extends LiteralDict lowering with runtime construction support when keys/values are non-constant. Current tests run outside a function context, so they cover the constant fast-path; a function-based runtime test can be added in a follow-up.

uh i am not sure, how do we verify the current implenmentation

@m-akhil-reddy
Copy link
Contributor Author

Thanks for the feedback.

I updated the tests to better reflect the current implementation. Since LiteralDict requires both keys and values to be Literal nodes, using identifiers like {1: x} is rejected during AST construction. Because of this constraint, the runtime path cannot be directly triggered in a literal-only test.

The test now verifies the fallback behavior when no function context exists (i.e., builder.block is None), ensuring that the implementation safely falls back to constant lowering. All CI checks are passing after the update.

Please let me know if you would prefer a different testing approach.
@yuvimittal

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