Skip to content

Commit 3522d4f

Browse files
Fix
1 parent 16d3d5a commit 3522d4f

File tree

7 files changed

+36
-25
lines changed

7 files changed

+36
-25
lines changed

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ enable_testing()
44

55
option(WARPO_RELEASE "build for release" OFF)
66
option(WARPO_SANITIZE "enable address sanitizer" OFF)
7+
option(WARPO_ENABLE_PERF "enable frame pointer for perf profiling" OFF)
78
option(ENABLE_CLANG_TIDY "Enable clang-tidy static analysis" OFF)
89
option(ENABLE_WERROR "Enable warnings as errors" OFF)
910

@@ -80,6 +81,10 @@ else()
8081
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-warning-option")
8182
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
8283

84+
if(WARPO_ENABLE_PERF)
85+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer")
86+
endif()
87+
8388
if(WARPO_SANITIZE)
8489
add_compile_options(-fsanitize=address)
8590
add_link_options(-fsanitize=address)

passes/ExtractMostFrequentlyUsedGlobals.cpp

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
#include <atomic>
1313
#include <cassert>
1414
#include <fmt/format.h>
15-
#include <map>
1615
#include <memory>
16+
#include <unordered_map>
17+
#include <utility>
18+
#include <vector>
1719

1820
#include "ExtractMostFrequentlyUsedGlobals.hpp"
1921
#include "support/index.h"
@@ -28,7 +30,7 @@ namespace warpo::passes {
2830

2931
namespace {
3032

31-
using Counter = std::map<wasm::Name, std::atomic<wasm::Index>>;
33+
using Counter = std::unordered_map<wasm::Name, std::atomic<wasm::Index>>;
3234
struct Scanner : public wasm::WalkerPass<wasm::PostWalker<Scanner>> {
3335
explicit Scanner(Counter &counter) : counter_(counter) {}
3436

@@ -72,17 +74,20 @@ static Counter createCounter(std::vector<std::unique_ptr<wasm::Global>> const &g
7274
}
7375

7476
static wasm::Name findMostFrequentlyUsed(Counter const &counter) {
75-
wasm::Name maxGlobalName;
76-
wasm::Index maxCount = 0;
77+
std::vector<std::pair<wasm::Name, wasm::Index>> sorted;
78+
sorted.reserve(counter.size());
7779
for (auto const &[name, count] : counter) {
7880
if (support::isDebug(PASS_NAME))
7981
fmt::println("[" PASS_NAME "] '{}' used {} times", name.str, count.load());
80-
if (count.load() >= maxCount) {
81-
maxCount = count.load();
82-
maxGlobalName = name;
83-
}
82+
sorted.emplace_back(name, count.load());
8483
}
85-
return maxGlobalName;
84+
// Sort by count descending, then by name ascending to break ties deterministically.
85+
std::sort(sorted.begin(), sorted.end(), [](auto const &a, auto const &b) {
86+
if (a.second != b.second)
87+
return a.second > b.second;
88+
return a.first < b.first;
89+
});
90+
return sorted.front().first;
8691
}
8792

8893
static void extractGlobal(wasm::Module &m, wasm::Name const name) {

passes/GC/CollectLeafFunction.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
// Copyright (C) 2025 wasm-ecosystem
33
// SPDX-License-Identifier: Apache-2.0
44

5-
#include <set>
5+
#include <unordered_map>
6+
#include <unordered_set>
67

78
#include "CollectLeafFunction.hpp"
89
#include "GCInfo.hpp"
@@ -17,15 +18,15 @@ namespace warpo::passes::gc {
1718

1819
static LeafFunc collectLeafFunctions(const CallGraph &cg) {
1920
LeafFunc leaf{};
20-
std::map<wasm::Name, std::set<wasm::Name>> reservedCallGraph{};
21+
std::unordered_map<wasm::Name, std::unordered_set<wasm::Name>> reservedCallGraph{};
2122

2223
for (auto const &[caller, callees] : cg) {
2324
leaf.insert(caller);
2425
for (wasm::Name const &callee : callees) {
25-
reservedCallGraph.try_emplace(callee, std::set<wasm::Name>{}).first->second.insert(caller);
26+
reservedCallGraph.try_emplace(callee, std::unordered_set<wasm::Name>{}).first->second.insert(caller);
2627
}
2728
}
28-
std::set<wasm::Name> workList{FnITCMSNew, FnITCMSCollect, FnTCMSNew, FnTCMSCollect};
29+
std::unordered_set<wasm::Name> workList{FnITCMSNew, FnITCMSCollect, FnTCMSNew, FnTCMSCollect};
2930
while (!workList.empty()) {
3031
auto it = workList.begin();
3132
if (leaf.erase(*it) == 1) {
@@ -70,7 +71,7 @@ TEST(GCLeafFunctionTest, LeafFunction) {
7071
CG["parent_1"] = {"leaf"};
7172
CG["parent_poison"] = {"leaf", FnITCMSNew};
7273

73-
std::set<wasm::Name> const leaf = collectLeafFunctions(CG);
74+
LeafFunc const leaf = collectLeafFunctions(CG);
7475

7576
EXPECT_THAT(leaf, Contains("leaf"));
7677
EXPECT_THAT(leaf, Contains("parent_1"));

passes/GC/CollectLeafFunction.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#pragma once
66

77
#include <memory>
8-
#include <set>
8+
#include <unordered_set>
99

1010
#include "../helper/BuildCallGraph.hpp"
1111
#include "pass.h"
@@ -14,7 +14,7 @@
1414

1515
namespace warpo::passes::gc {
1616

17-
struct LeafFunc : public std::set<wasm::Name> {};
17+
struct LeafFunc : public std::unordered_set<wasm::Name> {};
1818
/// @brief collect GC leaf functions, i.e., functions that do not call __new / __collect function.
1919
struct LeafFunctionCollector : public wasm::Pass {
2020
std::shared_ptr<CallGraph const> const cg_;

passes/InlinedDecoratorLower.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@
4040
#include <ir/module-utils.h>
4141
#include <memory>
4242
#include <passes/pass-utils.h>
43-
#include <set>
4443
#include <sstream>
44+
#include <unordered_set>
4545
#include <support/name.h>
4646
#include <utility>
4747
#include <vector>
@@ -103,7 +103,7 @@ ChosenActions createChosenActions(wasm::Module &m) {
103103
class ChosenActionsSteps {
104104
ChosenActions actions_;
105105
// functions need to be processed
106-
std::set<wasm::Name> pending_;
106+
std::unordered_set<wasm::Name> pending_;
107107

108108
public:
109109
std::vector<ChosenActions> actionSteps_;
@@ -130,7 +130,7 @@ class ChosenActionsSteps {
130130
if (support::isDebug(PASS_NAME))
131131
for (wasm::Name const &name : pending_)
132132
fmt::println("[" PASS_NAME "] pending inline '{}'", name.str);
133-
std::set<wasm::Name> currentStep;
133+
std::unordered_set<wasm::Name> currentStep;
134134
for (auto &[callerSiteFuncName, actions] : actions_) {
135135
if (support::isDebug(PASS_NAME)) {
136136
fmt::println("[" PASS_NAME "] check '{}' whether can be processed", callerSiteFuncName.str);

passes/helper/BuildCallGraph.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Copyright (C) 2025 wasm-ecosystem
33
// SPDX-License-Identifier: Apache-2.0
44

5-
#include <set>
5+
#include <unordered_set>
66

77
#include "BuildCallGraph.hpp"
88
#include "support/name.h"
@@ -14,7 +14,7 @@ CallGraph CallGraphBuilder::createResults(wasm::Module &m) {
1414
CallGraph ret{};
1515
for (std::unique_ptr<wasm::Function> const &f : m.functions) {
1616
// we treat imported function as leaf function because in wasm-compiler, nest wasm call is not allowed.
17-
ret.insert_or_assign(f->name, std::set<wasm::Name>{});
17+
ret.insert_or_assign(f->name, std::unordered_set<wasm::Name>{});
1818
}
1919
return ret;
2020
}
@@ -23,7 +23,7 @@ void CallGraphBuilder::visitCall(wasm::Call *expr) { cg_.at(getFunction()->name)
2323

2424
void CallGraphBuilder::visitCallIndirect(wasm::CallIndirect *expr) {
2525
wasm::Module *m = getModule();
26-
std::set<wasm::Name> &call = cg_.at(getFunction()->name);
26+
std::unordered_set<wasm::Name> &call = cg_.at(getFunction()->name);
2727
std::vector<wasm::Expression *> const &potentialTargets = m->getElementSegment(expr->table)->data;
2828
for (wasm::Expression *target : potentialTargets) {
2929
wasm::Name const refFunc = target->cast<wasm::RefFunc>()->func;

passes/helper/BuildCallGraph.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@
44

55
#pragma once
66

7-
#include <map>
87
#include <memory>
9-
#include <set>
8+
#include <unordered_map>
9+
#include <unordered_set>
1010

1111
#include "pass.h"
1212
#include "support/name.h"
1313
#include "wasm.h"
1414

1515
namespace warpo::passes {
1616

17-
using CallGraph = std::map<wasm::Name, std::set<wasm::Name>>;
17+
using CallGraph = std::unordered_map<wasm::Name, std::unordered_set<wasm::Name>>;
1818
struct CallGraphBuilder : public wasm::WalkerPass<wasm::PostWalker<CallGraphBuilder>> {
1919
static CallGraph createResults(wasm::Module &m);
2020

0 commit comments

Comments
 (0)