35int find_block_for_token(
int token_idx,
36 const std::vector<CFGBlock>& cfg_blocks) {
37 for (
size_t i = 0; i < cfg_blocks.size(); ++i) {
38 if (token_idx >= cfg_blocks[i].start_token_idx &&
39 token_idx < cfg_blocks[i].end_token_idx) {
40 return static_cast<int>(i);
46bool is_array_used_in_range(
const std::string& array_name,
47 const std::vector<Token>& tokens,
48 int start_token_idx,
int end_token_idx) {
49 for (
int i = start_token_idx; i < end_token_idx; ++i) {
50 const auto& token = tokens[i];
53 const auto& payload = std::get<TokenPayloadArrayOp>(token.payload);
54 if (payload.name == array_name) {
62bool is_array_used_between(
const std::string& array_name,
63 const std::vector<Token>& tokens,
64 const std::vector<CFGBlock>& cfg_blocks,
65 int start_token_idx,
int end_token_idx) {
66 int start_block = find_block_for_token(start_token_idx, cfg_blocks);
67 int end_block = find_block_for_token(end_token_idx, cfg_blocks);
69 if (start_block == -1 || end_block == -1) {
73 if (start_block == end_block) {
74 return is_array_used_in_range(array_name, tokens, start_token_idx + 1,
78 std::queue<int> to_visit;
79 std::set<int> visited;
81 to_visit.push(start_block);
82 visited.insert(start_block);
84 while (!to_visit.empty()) {
85 int current_block = to_visit.front();
88 const auto& block = cfg_blocks[current_block];
90 int check_start = block.start_token_idx;
91 int check_end = block.end_token_idx;
93 if (current_block == start_block) {
94 check_start = start_token_idx + 1;
97 if (current_block == end_block) {
98 check_end = end_token_idx;
101 if (is_array_used_in_range(array_name, tokens, check_start,
106 if (current_block == end_block) {
110 for (
int successor : block.successors) {
111 if (!visited.contains(successor)) {
112 visited.insert(successor);
113 to_visit.push(successor);
126 const auto& cfg_blocks = block_result.cfg_blocks;
128 std::set<int> allocations_to_remove;
130 std::map<std::string, std::vector<int>> dynamic_allocations;
132 for (
size_t i = 0; i < tokens.size(); ++i) {
133 const auto& token = tokens[i];
135 const auto& payload = std::get<TokenPayloadArrayOp>(token.payload);
136 dynamic_allocations[payload.name].push_back(
static_cast<int>(i));
140 for (
const auto& [array_name, alloc_indices] : dynamic_allocations) {
141 if (alloc_indices.size() < 2) {
145 for (
size_t i = 0; i < alloc_indices.size() - 1; ++i) {
146 int first_alloc = alloc_indices[i];
147 int second_alloc = alloc_indices[i + 1];
149 bool used = is_array_used_between(array_name, tokens, cfg_blocks,
150 first_alloc, second_alloc);
153 allocations_to_remove.insert(first_alloc);
158 if (allocations_to_remove.empty()) {
162 for (
int token_idx : allocations_to_remove) {
163 auto& token = tokens[token_idx];
165 token.text =
"drop1";
PassT::Result & getResult()
PreservedAnalyses run(std::vector< Token > &tokens, AnalysisManager &am) override
static PreservedAnalyses all()
static PreservedAnalyses none()