Skip to content

Commit d43cd08

Browse files
committed
add support for metadata.code.compilation_order, metadata.code.instr_freq and metadata.code.call_targets annotations and sections
1 parent fde4ca3 commit d43cd08

21 files changed

+1815
-1024
lines changed

include/wabt/binary-reader-logging.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,10 @@ class BinaryReaderLogging : public BinaryReaderDelegate {
414414
Result BeginCodeMetadataSection(std::string_view name, Offset size) override;
415415
Result OnCodeMetadataFuncCount(Index count) override;
416416
Result OnCodeMetadataCount(Index function_index, Index count) override;
417-
Result OnCodeMetadata(Offset offset, const void* data, Address size) override;
417+
Result OnCodeMetadataCodeOffset(Offset offset) override;
418+
Result OnCodeMetadata(const void* data, Address size) override;
419+
Result OnCodeMetadataCallTarget(Index target_index,
420+
uint32_t call_frequency) override;
418421
Result EndCodeMetadataSection() override;
419422

420423
private:

include/wabt/binary-reader-nop.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -489,9 +489,12 @@ class BinaryReaderNop : public BinaryReaderDelegate {
489489
Result OnCodeMetadataCount(Index function_index, Index count) override {
490490
return Result::Ok;
491491
}
492-
Result OnCodeMetadata(Offset offset,
493-
const void* data,
494-
Address size) override {
492+
Result OnCodeMetadata(const void* data, Address size) override {
493+
return Result::Ok;
494+
}
495+
Result OnCodeMetadataCodeOffset(Offset offset) override { return Result::Ok; }
496+
Result OnCodeMetadataCallTarget(Index target_index,
497+
uint32_t call_frequency) override {
495498
return Result::Ok;
496499
}
497500
Result EndCodeMetadataSection() override { return Result::Ok; }

include/wabt/binary-reader.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -498,9 +498,10 @@ class BinaryReaderDelegate {
498498
Offset size) = 0;
499499
virtual Result OnCodeMetadataFuncCount(Index count) = 0;
500500
virtual Result OnCodeMetadataCount(Index function_index, Index count) = 0;
501-
virtual Result OnCodeMetadata(Offset offset,
502-
const void* data,
503-
Address size) = 0;
501+
virtual Result OnCodeMetadata(const void* data, Address size) = 0;
502+
virtual Result OnCodeMetadataCodeOffset(Offset offset) = 0;
503+
virtual Result OnCodeMetadataCallTarget(Index target_index,
504+
uint32_t call_frequency) = 0;
504505
virtual Result EndCodeMetadataSection() = 0;
505506

506507
const State* state = nullptr;

include/wabt/ir.h

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
#include "wabt/intrusive-list.h"
3333
#include "wabt/opcode.h"
3434

35+
#include <optional>
36+
3537
namespace wabt {
3638

3739
struct Module;
@@ -702,15 +704,90 @@ class CallIndirectExpr : public ExprMixin<ExprType::CallIndirect> {
702704

703705
class CodeMetadataExpr : public ExprMixin<ExprType::CodeMetadata> {
704706
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+
705725
explicit CodeMetadataExpr(std::string_view name,
706726
std::vector<uint8_t> data,
707727
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())
708744
: 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;
711778

712779
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;
714791
};
715792

716793
class ReturnCallIndirectExpr : public ExprMixin<ExprType::ReturnCallIndirect> {

include/wabt/token.def

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
/* Tokens with no additional data (i.e. bare). */
2222
WABT_TOKEN(Invalid, "Invalid")
23+
WABT_TOKEN(AlwaysOpt, "always_opt")
2324
WABT_TOKEN(After, "after")
2425
WABT_TOKEN(Array, "array")
2526
WABT_TOKEN(AssertException, "assert_exception")
@@ -31,6 +32,7 @@ WABT_TOKEN(AssertTrap, "assert_trap")
3132
WABT_TOKEN(AssertUnlinkable, "assert_unlinkable")
3233
WABT_TOKEN(Before, "before")
3334
WABT_TOKEN(Bin, "bin")
35+
WABT_TOKEN(Compilation, "compilation")
3436
WABT_TOKEN(Item, "item")
3537
WABT_TOKEN(Data, "data")
3638
WABT_TOKEN(Declare, "declare")
@@ -40,9 +42,11 @@ WABT_TOKEN(Either, "either")
4042
WABT_TOKEN(Elem, "elem")
4143
WABT_TOKEN(Eof, "EOF")
4244
WABT_TOKEN(Tag, "tag")
45+
WABT_TOKEN(Target, "target")
4346
WABT_TOKEN(Export, "export")
4447
WABT_TOKEN(Field, "field")
4548
WABT_TOKEN(Function, "function")
49+
WABT_TOKEN(Freq, "freq")
4650
WABT_TOKEN(Get, "get")
4751
WABT_TOKEN(Global, "global")
4852
WABT_TOKEN(Import, "import")
@@ -55,7 +59,9 @@ WABT_TOKEN(Module, "module")
5559
WABT_TOKEN(Mut, "mut")
5660
WABT_TOKEN(NanArithmetic, "nan:arithmetic")
5761
WABT_TOKEN(NanCanonical, "nan:canonical")
62+
WABT_TOKEN(NeverOpt, "never_opt")
5863
WABT_TOKEN(Offset, "offset")
64+
WABT_TOKEN(Optimization, "optimization")
5965
WABT_TOKEN(Output, "output")
6066
WABT_TOKEN(PageSize, "pagesize")
6167
WABT_TOKEN(Param, "param")
@@ -64,6 +70,7 @@ WABT_TOKEN(Quote, "quote")
6470
WABT_TOKEN(Register, "register")
6571
WABT_TOKEN(Result, "result")
6672
WABT_TOKEN(Rpar, ")")
73+
WABT_TOKEN(RunOnce, "run_once")
6774
WABT_TOKEN(Shared, "shared")
6875
WABT_TOKEN(Start, "start")
6976
WABT_TOKEN(Struct, "struct")

include/wabt/wast-parser.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,15 @@ class WastParser {
217217
Result ParseTerminatingInstrList(ExprList*);
218218
Result ParseInstr(ExprList*);
219219
Result ParseCodeMetadataAnnotation(ExprList*);
220+
Result ParseCodeMetaDataCompilationPriorityAnnotation(ExprList*,
221+
std::string_view,
222+
Location);
223+
Result ParseCodeMetaDataInstrFreqAnnotation(ExprList*,
224+
std::string_view,
225+
Location);
226+
Result ParseCodeMetaDataCallTargetsAnnotation(ExprList*,
227+
std::string_view,
228+
Location);
220229
Result ParsePlainInstr(std::unique_ptr<Expr>*);
221230
Result ParseF32(Const*, ConstType type);
222231
Result ParseF64(Const*, ConstType type);

src/binary-reader-ir.cc

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,8 @@ class BinaryReaderIR : public BinaryReaderNop {
350350
Result BeginCodeMetadataSection(std::string_view name, Offset size) override;
351351
Result OnCodeMetadataFuncCount(Index count) override;
352352
Result OnCodeMetadataCount(Index function_index, Index count) override;
353-
Result OnCodeMetadata(Offset offset, const void* data, Address size) override;
353+
Result OnCodeMetadataCodeOffset(Offset offset) override;
354+
Result OnCodeMetadata(const void* data, Address size) override;
354355

355356
Result OnTagSymbol(Index index,
356357
uint32_t flags,
@@ -398,6 +399,7 @@ class BinaryReaderIR : public BinaryReaderNop {
398399

399400
CodeMetadataExprQueue code_metadata_queue_;
400401
std::string_view current_metadata_name_;
402+
Offset current_metadata_offset_;
401403
};
402404

403405
BinaryReaderIR::BinaryReaderIR(Module* out_module,
@@ -1710,18 +1712,21 @@ Result BinaryReaderIR::OnCodeMetadataCount(Index function_index, Index count) {
17101712
return Result::Error;
17111713
}
17121714

1713-
Result BinaryReaderIR::OnCodeMetadata(Offset offset,
1714-
const void* data,
1715-
Address size) {
1715+
Result BinaryReaderIR::OnCodeMetadata(const void* data, const Address size) {
17161716
std::vector<uint8_t> data_(static_cast<const uint8_t*>(data),
17171717
static_cast<const uint8_t*>(data) + size);
17181718
auto meta = std::make_unique<CodeMetadataExpr>(current_metadata_name_,
17191719
std::move(data_));
1720-
meta->loc.offset = offset;
1720+
meta->loc.offset = current_metadata_offset_;
17211721
code_metadata_queue_.push_metadata(std::move(meta));
17221722
return Result::Ok;
17231723
}
17241724

1725+
Result BinaryReaderIR::OnCodeMetadataCodeOffset(const Offset offset) {
1726+
current_metadata_offset_ = offset;
1727+
return Result::Ok;
1728+
}
1729+
17251730
Result BinaryReaderIR::OnLocalName(Index func_index,
17261731
Index local_index,
17271732
std::string_view name) {

src/binary-reader-logging.cc

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -681,13 +681,23 @@ Result BinaryReaderLogging::BeginCodeMetadataSection(std::string_view name,
681681
Indent();
682682
return reader_->BeginCodeMetadataSection(name, size);
683683
}
684-
Result BinaryReaderLogging::OnCodeMetadata(Offset code_offset,
685-
const void* data,
686-
Address size) {
687-
std::string_view content(static_cast<const char*>(data), size);
688-
LOGF("OnCodeMetadata(offset: %" PRIzd ", data: \"" PRIstringview "\")\n",
689-
code_offset, WABT_PRINTF_STRING_VIEW_ARG(content));
690-
return reader_->OnCodeMetadata(code_offset, data, size);
684+
Result BinaryReaderLogging::OnCodeMetadataCodeOffset(const Offset code_offset) {
685+
LOGF("OnCodeMetadataCodeOffset(offset: %" PRIzd ")\n", code_offset);
686+
return reader_->OnCodeMetadataCodeOffset(code_offset);
687+
}
688+
Result BinaryReaderLogging::OnCodeMetadata(const void* data,
689+
const Address size) {
690+
const std::string_view content(static_cast<const char*>(data), size);
691+
LOGF("OnCodeMetadata(data: \"" PRIstringview "\")\n",
692+
WABT_PRINTF_STRING_VIEW_ARG(content));
693+
return reader_->OnCodeMetadata(data, size);
694+
}
695+
Result BinaryReaderLogging::OnCodeMetadataCallTarget(
696+
const Index target_index,
697+
const uint32_t call_frequency) {
698+
LOGF("OnCodeMetadataCallTarget(target_index: %u, call_frequency: %u)\n",
699+
target_index, call_frequency);
700+
return reader_->OnCodeMetadataCallTarget(target_index, call_frequency);
691701
}
692702

693703
Result BinaryReaderLogging::OnGenericCustomSection(std::string_view name,

src/binary-reader-objdump.cc

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,9 +1286,10 @@ class BinaryReaderObjdump : public BinaryReaderObjdumpBase {
12861286
Result OnRefNullExpr(Type type) override;
12871287
Result OnGlobalGetExpr(Index global_index) override;
12881288
Result OnCodeMetadataCount(Index function_index, Index count) override;
1289-
Result OnCodeMetadata(Offset code_offset,
1290-
const void* data,
1291-
Address size) override;
1289+
Result OnCodeMetadataCodeOffset(Offset code_offset) override;
1290+
Result OnCodeMetadata(const void* data, Address size) override;
1291+
Result OnCodeMetadataCallTarget(Index target_index,
1292+
uint32_t call_frequency) override;
12921293

12931294
private:
12941295
Result EndInitExpr();
@@ -2446,25 +2447,43 @@ Result BinaryReaderObjdump::OnCodeMetadataCount(Index function_index,
24462447
return Result::Ok;
24472448
}
24482449
printf(" - func[%" PRIindex "]", function_index);
2449-
auto name = GetFunctionName(function_index);
2450+
const auto name = GetFunctionName(function_index);
24502451
if (!name.empty()) {
24512452
printf(" <" PRIstringview ">", WABT_PRINTF_STRING_VIEW_ARG(name));
24522453
}
24532454
printf(":\n");
24542455
return Result::Ok;
24552456
}
2456-
Result BinaryReaderObjdump::OnCodeMetadata(Offset code_offset,
2457-
const void* data,
2458-
Address size) {
2457+
Result BinaryReaderObjdump::OnCodeMetadataCodeOffset(const Offset code_offset) {
24592458
if (!ShouldPrintDetails()) {
24602459
return Result::Ok;
24612460
}
24622461
printf(" - meta[%" PRIzx "]:\n", code_offset);
2463-
2462+
return Result::Ok;
2463+
}
2464+
Result BinaryReaderObjdump::OnCodeMetadata(const void* data,
2465+
const Address size) {
2466+
if (!ShouldPrintDetails()) {
2467+
return Result::Ok;
2468+
}
24642469
out_stream_->WriteMemoryDump(data, size, 0, PrintChars::Yes, " - ");
24652470
return Result::Ok;
24662471
}
2472+
Result BinaryReaderObjdump::OnCodeMetadataCallTarget(
2473+
const Index target_index,
2474+
const uint32_t call_frequency) {
2475+
if (!ShouldPrintDetails()) {
2476+
return Result::Ok;
2477+
}
24672478

2479+
printf(" - target [%" PRIindex "]", target_index);
2480+
const auto name = GetFunctionName(target_index);
2481+
if (!name.empty()) {
2482+
printf(" <" PRIstringview ">", WABT_PRINTF_STRING_VIEW_ARG(name));
2483+
}
2484+
printf(": %" PRIu32 "%%\n", call_frequency);
2485+
return Result::Ok;
2486+
}
24682487
} // end anonymous namespace
24692488

24702489
std::string_view ObjdumpNames::Get(Index index) const {

src/binary-reader.cc

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2467,11 +2467,26 @@ Result BinaryReader::ReadCodeMetadataSection(std::string_view name,
24672467
last_code_offset == kInvalidOffset || code_offset > last_code_offset,
24682468
"code offset out of order: %" PRIzx, code_offset);
24692469
last_code_offset = code_offset;
2470-
2471-
Address data_size;
2472-
const void* data;
2473-
CHECK_RESULT(ReadBytes(&data, &data_size, "instance data"));
2474-
CALLBACK(OnCodeMetadata, code_offset, data, data_size);
2470+
CALLBACK(OnCodeMetadataCodeOffset, code_offset);
2471+
2472+
if (name == "call_targets") {
2473+
uint32_t hint_size;
2474+
CHECK_RESULT(ReadU32Leb128(&hint_size, "call targets hint size"));
2475+
Offset end = state_.offset + hint_size;
2476+
while (state_.offset < end) {
2477+
Index target_index;
2478+
CHECK_RESULT(ReadIndex(&target_index, "call target index"));
2479+
uint32_t call_frequency;
2480+
CHECK_RESULT(ReadU32Leb128(&call_frequency, "call frequency"));
2481+
CALLBACK(OnCodeMetadataCallTarget, target_index, call_frequency);
2482+
}
2483+
assert(state_.offset == end);
2484+
} else {
2485+
Address data_size;
2486+
const void* data;
2487+
CHECK_RESULT(ReadBytes(&data, &data_size, "instance data"));
2488+
CALLBACK(OnCodeMetadata, data, data_size);
2489+
}
24752490
}
24762491
}
24772492

0 commit comments

Comments
 (0)