|
32 | 32 | #include "wabt/intrusive-list.h"
|
33 | 33 | #include "wabt/opcode.h"
|
34 | 34 |
|
| 35 | +#include <optional> |
| 36 | + |
35 | 37 | namespace wabt {
|
36 | 38 |
|
37 | 39 | struct Module;
|
@@ -702,15 +704,90 @@ class CallIndirectExpr : public ExprMixin<ExprType::CallIndirect> {
|
702 | 704 |
|
703 | 705 | class CodeMetadataExpr : public ExprMixin<ExprType::CodeMetadata> {
|
704 | 706 | public:
|
| 707 | + struct CallTarget { |
| 708 | + Var func; |
| 709 | + uint32_t frequency; |
| 710 | + }; |
| 711 | + struct CompilationPriority { |
| 712 | + uint32_t compilation_priority; |
| 713 | + std::optional<uint32_t> optimization_priority; |
| 714 | + }; |
| 715 | + struct InstructionFrequency { |
| 716 | + uint32_t frequency; |
| 717 | + }; |
| 718 | + enum class Type { |
| 719 | + Binary, |
| 720 | + CompilationHint, |
| 721 | + InstructionFrequency, |
| 722 | + CallTargets |
| 723 | + }; |
| 724 | + |
705 | 725 | explicit CodeMetadataExpr(std::string_view name,
|
706 | 726 | std::vector<uint8_t> data,
|
707 | 727 | const Location& loc = Location())
|
| 728 | + : ExprMixin<ExprType::CodeMetadata>(loc), name(name), type(Type::Binary) { |
| 729 | + new (&hint.data) std::vector<uint8_t>(std::move(data)); |
| 730 | + } |
| 731 | + |
| 732 | + explicit CodeMetadataExpr(std::string_view name, |
| 733 | + CompilationPriority compilation_priority, |
| 734 | + const Location& loc = Location()) |
| 735 | + : ExprMixin<ExprType::CodeMetadata>(loc), |
| 736 | + name(name), |
| 737 | + type(Type::CompilationHint) { |
| 738 | + new (&hint.compilation_priority) CompilationPriority(compilation_priority); |
| 739 | + } |
| 740 | + |
| 741 | + explicit CodeMetadataExpr(std::string_view name, |
| 742 | + InstructionFrequency instruction_frequency, |
| 743 | + const Location& loc = Location()) |
708 | 744 | : ExprMixin<ExprType::CodeMetadata>(loc),
|
709 |
| - name(std::move(name)), |
710 |
| - data(std::move(data)) {} |
| 745 | + name(name), |
| 746 | + type(Type::InstructionFrequency) { |
| 747 | + new (&hint.instruction_frequency) |
| 748 | + InstructionFrequency(instruction_frequency); |
| 749 | + } |
| 750 | + |
| 751 | + explicit CodeMetadataExpr(std::string_view name, |
| 752 | + std::vector<CallTarget> targets, |
| 753 | + const Location& loc = Location()) |
| 754 | + : ExprMixin<ExprType::CodeMetadata>(loc), |
| 755 | + name(name), |
| 756 | + type(Type::CallTargets) { |
| 757 | + new (&hint.call_targets) std::vector<CallTarget>(std::move(targets)); |
| 758 | + } |
| 759 | + |
| 760 | + ~CodeMetadataExpr() override { |
| 761 | + switch (type) { |
| 762 | + case Type::Binary: |
| 763 | + hint.data.~vector(); |
| 764 | + break; |
| 765 | + case Type::CallTargets: |
| 766 | + hint.call_targets.~vector(); |
| 767 | + break; |
| 768 | + default: |
| 769 | + // CompilationHint and InstructionFrequency do not allocate memory.; |
| 770 | + break; |
| 771 | + } |
| 772 | + } |
| 773 | + |
| 774 | + bool is_function_annotation() const { return type == Type::CompilationHint; } |
| 775 | + |
| 776 | + // convert non-binary hints to binary |
| 777 | + std::vector<uint8_t> serialize(const Module&) const; |
711 | 778 |
|
712 | 779 | std::string_view name;
|
713 |
| - std::vector<uint8_t> data; |
| 780 | + Type type; |
| 781 | + |
| 782 | + private: |
| 783 | + union Hint { |
| 784 | + std::vector<uint8_t> data; |
| 785 | + CompilationPriority compilation_priority; |
| 786 | + InstructionFrequency instruction_frequency{}; |
| 787 | + std::vector<CallTarget> call_targets; |
| 788 | + Hint() {} |
| 789 | + ~Hint() {} |
| 790 | + } hint; |
714 | 791 | };
|
715 | 792 |
|
716 | 793 | class ReturnCallIndirectExpr : public ExprMixin<ExprType::ReturnCallIndirect> {
|
|
0 commit comments