38 {
39 const auto& const_result = am.getResult<ConstPropPass>();
40 const auto& in_stacks = const_result.const_stack_in;
41
42 const auto& block_result = am.getResult<BlockAnalysisPass>();
43 const auto& cfg_blocks = block_result.cfg_blocks;
44
45 std::map<std::string, int> array_alloc_count;
46 for (const auto& token : tokens) {
49 const auto& payload = std::get<TokenPayloadArrayOp>(token.payload);
50 array_alloc_count[payload.name]++;
51 }
52 }
53
54 std::map<int, int> dyn_to_static;
55
56 for (size_t block_idx = 0; block_idx < cfg_blocks.size(); ++block_idx) {
57 const auto& block = cfg_blocks[block_idx];
58
59 auto current_stack = in_stacks[block_idx];
60
61 for (int token_idx = block.start_token_idx;
62 token_idx < block.end_token_idx; ++token_idx) {
63 const auto& token = tokens[token_idx];
65
66 while (current_stack.size() < static_cast<size_t>(behavior.arity)) {
67 current_stack.insert(current_stack.begin(), std::nullopt);
68 }
69
70 std::vector<std::optional<double>> args;
71 for (int k = 0; k < behavior.arity; ++k) {
72 args.push_back(current_stack.back());
73 current_stack.pop_back();
74 }
75 std::ranges::reverse(args);
76
78 const auto& payload =
79 std::get<TokenPayloadArrayOp>(token.payload);
80
81
82
83
84 if (args[0].has_value() &&
85 array_alloc_count[payload.name] == 1) {
86 int size = static_cast<int>(args[0].value());
87 if (size > 0 && size <= SINGLEEXPR_STACK_ALLOC_THRESHOLD) {
88 dyn_to_static[token_idx] = size;
89 }
90 }
91 }
92
93 for (int k = 0; k < behavior.arity + behavior.stack_effect; ++k) {
94 current_stack.emplace_back(std::nullopt);
95 }
96 }
97 }
98
99 std::vector<std::pair<int, Token>> insertions;
100
101 for (auto& it : std::ranges::reverse_view(dyn_to_static)) {
102 int token_idx = it.first;
103 int size = it.second;
104
105 auto& token = tokens[token_idx];
106 auto& payload = std::get<TokenPayloadArrayOp>(token.payload);
107
109 token.text = payload.name + "{}^" + std::to_string(size);
110 payload.static_size = size;
111
113 .text = "drop1",
114 .payload = TokenPayloadStackOp{.n = 1}};
115
116 insertions.emplace_back(token_idx, drop_token);
117 }
118
119 for (const auto& [pos, drop_token] : insertions) {
120 tokens.insert(tokens.begin() + pos, drop_token);
121 }
122
123 if (!dyn_to_static.empty()) {
125 }
126
128}
TokenBehavior get_token_behavior(const Token &token)
static PreservedAnalyses all()
static PreservedAnalyses none()
preprocessor_detail::Token Token