ecmascript/compiler/codegen
Translates the optimized Circuit IR into machine code through two pluggable backends: LLVM and Maple/LiteCG. The backend is selected at build time via COMPILE_MAPLE flag.
Primary Language: C++
Design
Both backends implement the same abstract interface (CodeGeneratorImpl) and follow the same flow:
Circuit IR (after optimization passes)
│
▼
CodeGenerator (dispatches to active backend)
│
├──▶ LLVMIRGeneratorImpl path:
│ LLVMIRGeneratorImpl.GenerateCode()
│ └── LLVMIRBuilder → builds LLVM IR
│ LLVMAssembler.Run()
│ └── LLVM JIT engine → machine code
│
└──▶ Maple/LiteCG path:
LiteCGIRGeneratorImpl.GenerateCode()
└── LiteCGIRBuilder → builds Maple LMIR
LiteCGAssembler.Run()
└── LiteCG backend → machine code
Backend abstraction:
CodeGeneratorImpl—GenerateCodeForStub()andGenerateCode()translate Circuit gates to backend IR.Assembler(base class inassembler/) —Run()produces machine code from backend-specific IR.- Target-specific builders (
aarch64_builder,x64_builder) handle architecture differences within each backend.
Key Files
| File | Role |
|---|---|
llvm/llvm_codegen.h |
LLVM backend: LLVMAssembler (IR → machine code) |
llvm/llvm_ir_builder.cpp/.h |
Circuit IR → LLVM IR translation |
llvm/lib/llvm_interface.cpp/.h |
LLVM shared library wrapper (libark_llvmcodegen) |
llvm/aarch64/aarch64_builder.cpp |
ARM64-specific LLVM IR patterns |
llvm/x64/x64_builder.cpp |
x64-specific LLVM IR patterns |
maple/litecg_codegen.cpp/.h |
Maple backend: LiteCGAssembler |
maple/litecg_ir_builder.cpp/.h |
Circuit IR → Maple LMIR translation |
maple/BUILD.gn |
Maple backend build configuration |
How to Modify
Add support for a new Circuit gate in codegen:
- Add the lowering case in
llvm/llvm_ir_builder.cpp(LLVM path) - Add the lowering case in
maple/litecg_ir_builder.cpp(Maple path) - Add target-specific handling in
aarch64_builder/x64_builderif needed - Add test coverage in
compiler/tests/orcodegen/maple/test/
Tune backend compilation options:
- LLVM: Modify
LOptionsinllvm/llvm_codegen.h(opt level, FP elimination, reloc mode) - Maple: Modify
litecgOptionsvector passed toLiteCGAssembler
Building
Standalone repo (from repo root ../../):
python ark.py x64.debug
Full OHOS tree:
./build.sh --product-name <product-name> --build-target ark_js_host_linux_tools_packages
Tests
Standalone repo (from repo root ../../):
python ark.py x64.debug unittest # all unit tests (includes codegen tests)
Full OHOS tree:
# Maple backend tests
./build.sh --product-name <product-name> --build-target ecmascript/compiler/codegen/maple/test:host_unittest
# Full compiler tests (includes backend integration)
./build.sh --product-name <product-name> --build-target ecmascript/compiler/tests:host_unittest
Boundaries
- Keep backend logic strictly inside
maple/orllvm/— no cross-backend coupling. - Both backends must handle the same set of Circuit gates; when adding gates, update both.
- Maintain target portability (
aarch64andx64) in both backends. - Codegen ABI/layout changes must be validated by compiler host unittests.