From 4c9d010ff78126dd6b009ccfaf5e5b48252033c4 Mon Sep 17 00:00:00 2001 From: ZhuangYumin Date: Tue, 22 Oct 2024 07:00:48 +0000 Subject: [PATCH] begin to fix stupid Coalesce --- a.txt | 425 ++++++++++++++++++++++++++++++++++++++++ include/opt/confgraph.h | 1 + src/opt/confgraph.cpp | 12 +- src/opt/regalloc.cpp | 29 +++ 4 files changed, 466 insertions(+), 1 deletion(-) create mode 100644 a.txt diff --git a/a.txt b/a.txt new file mode 100644 index 0000000..b58ccf9 --- /dev/null +++ b/a.txt @@ -0,0 +1,425 @@ + return_type_str=int + recorded return type is [none-array]int + func_name=partition + recorded parameter type is [array]int with dimensions=1 + recorded parameter name is a + recorded parameter type is [none-array]int + recorded parameter name is p + recorded parameter type is [none-array]int + recorded parameter name is r + Adding suite statements + Adding a definition statement + recorded variable type is [none-array]int + Adding a definition statement + recorded variable type is [none-array]int + Adding a definition statement + recorded variable type is [none-array]int + Adding a for statement + initial is an expression statement + condition is an expression + update is an expression statement + Adding suite statements + Adding an if statement + Adding suite statements + Adding an expression statement + Adding a definition statement + recorded variable type is [none-array]int + Adding an expression statement + Adding an expression statement + Adding a definition statement + recorded variable type is [none-array]int + Adding an expression statement + Adding an expression statement + Adding a jmp statement + return_type_str=void + recorded return type is [none-array]void + func_name=quick_sort + recorded parameter type is [array]int with dimensions=1 + recorded parameter name is a + recorded parameter type is [none-array]int + recorded parameter name is p + recorded parameter type is [none-array]int + recorded parameter name is r + Adding suite statements + Adding an if statement + Adding a jmp statement + Adding a definition statement + recorded variable type is [none-array]int + Adding an expression statement + Adding an expression statement + return_type_str=void + recorded return type is [none-array]void + func_name=quick_sort_inf + recorded parameter type is [array]int with dimensions=1 + recorded parameter name is a + Adding suite statements + Adding an expression statement + return_type_str=int + recorded return type is [none-array]int + func_name=main + Adding suite statements + Adding a definition statement + recorded variable type is [none-array]int + Adding a definition statement + recorded variable type is [array]int with dimensions=1 + Adding a new array expression + dim 0 has size + Adding a definition statement + recorded variable type is [none-array]int + Adding a for statement + initial is an expression statement + condition is an expression + update is an expression statement + Adding an expression statement + Adding an expression statement + Adding a for statement + initial is an expression statement + condition is an expression + update is an expression statement + Adding an expression statement + Adding an expression statement + Adding a jmp statement +enter function partition +visit definition statement +visit definition statement +visit definition statement +visit definition statement +visit definition statement +leave function partition +enter function quick_sort +visit definition statement +function to call is partition +function to call is quick_sort +function to call is quick_sort +leave function quick_sort +enter function quick_sort_inf +function to call is quick_sort +leave function quick_sort_inf +enter function main +visit definition statement +function to call is getInt +visit definition statement +visit definition statement +function to call is getInt +function to call is quick_sort_inf +function to call is print +function to call is toString +function to call is println +leave function main +label_init_partition: + dom: label_init_partition + dom_frontier: + cfg pred: + successors_in_dom_tree: label_0 +label_0: + dom: label_init_partition label_0 + idom: label_init_partition + dom_frontier: + cfg pred: label_init_partition + successors_in_dom_tree: label_1 +label_1: + dom: label_init_partition label_0 label_1 + idom: label_0 + dom_frontier: label_1 + cfg pred: label_0 label_3 + successors_in_dom_tree: label_2 label_4 +label_2: + dom: label_init_partition label_0 label_1 label_2 + idom: label_1 + dom_frontier: label_1 + cfg pred: label_1 + successors_in_dom_tree: label_5 label_6 +label_5: + dom: label_init_partition label_0 label_1 label_2 label_5 + idom: label_2 + dom_frontier: label_6 + cfg pred: label_2 + successors_in_dom_tree: +label_6: + dom: label_init_partition label_0 label_1 label_2 label_6 + idom: label_2 + dom_frontier: label_1 + cfg pred: label_2 label_5 + successors_in_dom_tree: label_3 +label_3: + dom: label_init_partition label_0 label_1 label_2 label_6 label_3 + idom: label_6 + dom_frontier: label_1 + cfg pred: label_6 + successors_in_dom_tree: +label_4: + dom: label_init_partition label_0 label_1 label_4 + idom: label_1 + dom_frontier: + cfg pred: label_1 + successors_in_dom_tree: +label_init_quick_sort: + dom: label_init_quick_sort + dom_frontier: + cfg pred: + successors_in_dom_tree: label_7 +label_7: + dom: label_init_quick_sort label_7 + idom: label_init_quick_sort + dom_frontier: + cfg pred: label_init_quick_sort + successors_in_dom_tree: label_8 label_9 +label_8: + dom: label_init_quick_sort label_7 label_8 + idom: label_7 + dom_frontier: + cfg pred: label_7 + successors_in_dom_tree: +label_9: + dom: label_init_quick_sort label_7 label_9 + idom: label_7 + dom_frontier: + cfg pred: label_7 + successors_in_dom_tree: +label_init_quick_sort_inf: + dom: label_init_quick_sort_inf + dom_frontier: + cfg pred: + successors_in_dom_tree: label_10 +label_10: + dom: label_init_quick_sort_inf label_10 + idom: label_init_quick_sort_inf + dom_frontier: + cfg pred: label_init_quick_sort_inf + successors_in_dom_tree: +main_init: + dom: main_init + dom_frontier: + cfg pred: + successors_in_dom_tree: label_11 +label_11: + dom: main_init label_11 + idom: main_init + dom_frontier: + cfg pred: main_init + successors_in_dom_tree: label_12 +label_12: + dom: main_init label_11 label_12 + idom: label_11 + dom_frontier: label_12 + cfg pred: label_11 label_14 + successors_in_dom_tree: label_13 label_15 +label_13: + dom: main_init label_11 label_12 label_13 + idom: label_12 + dom_frontier: label_12 + cfg pred: label_12 + successors_in_dom_tree: label_14 +label_14: + dom: main_init label_11 label_12 label_13 label_14 + idom: label_13 + dom_frontier: label_12 + cfg pred: label_13 + successors_in_dom_tree: +label_15: + dom: main_init label_11 label_12 label_15 + idom: label_12 + dom_frontier: + cfg pred: label_12 + successors_in_dom_tree: label_16 +label_16: + dom: main_init label_11 label_12 label_15 label_16 + idom: label_15 + dom_frontier: label_16 + cfg pred: label_15 label_18 + successors_in_dom_tree: label_17 label_19 +label_17: + dom: main_init label_11 label_12 label_15 label_16 label_17 + idom: label_16 + dom_frontier: label_16 + cfg pred: label_16 + successors_in_dom_tree: label_18 +label_18: + dom: main_init label_11 label_12 label_15 label_16 label_17 label_18 + idom: label_17 + dom_frontier: label_16 + cfg pred: label_17 + successors_in_dom_tree: +label_19: + dom: main_init label_11 label_12 label_15 label_16 label_19 + idom: label_16 + dom_frontier: + cfg pred: label_16 + successors_in_dom_tree: +processing function partition +totally allocating 45 nodes +21 +spilled 0 nodes +define i32 @partition(ptr %.var.local.1.a.val,i32 %.var.local.1.p.val,i32 %.var.local.1.r.val) +{ +label_init_partition: +br label %label_0 +label_0: +$reg.17 = getelementptr i32, ptr $reg.10, i32 $reg.12 +$reg.17 = load i32, ptr $reg.17 +$reg.14 = sub i32 $reg.11, 1 +[Persudo] $reg.15 <-- 0 +br label %label_1 +label_1: +$reg.16 = icmp slt i32 $reg.11, $reg.12 +br i1 $reg.16, label %label_2, label %label_4 +label_2: +$reg.16 = getelementptr i32, ptr $reg.10, i32 $reg.11 +$reg.16 = load i32, ptr $reg.16 +$reg.16 = icmp sle i32 $reg.16, $reg.17 +br i1 $reg.16, label %label_5, label %label_6.phieliminate.0 +label_5: +$reg.14 = add i32 $reg.14, 1 +$reg.16 = getelementptr i32, ptr $reg.10, i32 $reg.14 +$reg.15 = load i32, ptr $reg.16 +$reg.13 = getelementptr i32, ptr $reg.10, i32 $reg.14 +$reg.16 = getelementptr i32, ptr $reg.10, i32 $reg.11 +$reg.16 = load i32, ptr $reg.16 +store i32 $reg.16, ptr $reg.13 +$reg.16 = getelementptr i32, ptr $reg.10, i32 $reg.11 +store i32 $reg.15, ptr $reg.16 +br label %label_6 +label_6: +br label %label_3 +label_3: +$reg.11 = add i32 $reg.11, 1 +br label %label_1 +label_4: +$reg.17 = add i32 $reg.14, 1 +$reg.17 = getelementptr i32, ptr $reg.10, i32 $reg.17 +$reg.17 = load i32, ptr $reg.17 +$reg.16 = add i32 $reg.14, 1 +$reg.16 = getelementptr i32, ptr $reg.10, i32 $reg.16 +$reg.15 = getelementptr i32, ptr $reg.10, i32 $reg.12 +$reg.15 = load i32, ptr $reg.15 +store i32 $reg.15, ptr $reg.16 +$reg.16 = getelementptr i32, ptr $reg.10, i32 $reg.12 +store i32 $reg.17, ptr $reg.16 +$reg.10 = add i32 $reg.14, 1 +ret i32 $reg.10 +label_6.phieliminate.0: +br label %label_6 +} +processing function quick_sort +totally allocating 20 nodes +5 +spilled 4 nodes +define void @quick_sort(ptr %.var.local.6.a.val,i32 %.var.local.6.p.val,i32 %.var.local.6.r.val) +{ +label_init_quick_sort: +[Persudo] #0 <-- $reg.12 +[Persudo] #1 <-- $reg.11 +[Persudo] #2 <-- $reg.10 +br label %label_7 +label_7: +$reg.17 = icmp sge i32 #1, #0 +br i1 $reg.17, label %label_8, label %label_9 +label_8: +ret void +label_9: +[Persudo] $reg.10 <-- #2 +[Persudo] $reg.11 <-- #1 +[Persudo] $reg.12 <-- #0 +$reg.10 = call i32 @partition(ptr $reg.10, i32 $reg.11, i32 $reg.12) +[Persudo] #0 <-- $reg.10 +$reg.12 = sub i32 #0, 1 +[Persudo] $reg.10 <-- #2 +[Persudo] $reg.11 <-- #1 +call void @quick_sort(ptr $reg.10, i32 $reg.11, i32 $reg.12) +$reg.11 = add i32 #0, 1 +[Persudo] $reg.10 <-- #2 +[Persudo] $reg.12 <-- #0 +call void @quick_sort(ptr $reg.10, i32 $reg.11, i32 $reg.12) +ret void +} +processing function quick_sort_inf +totally allocating 16 nodes +2 +spilled 2 nodes +define void @quick_sort_inf(ptr %.var.local.8.a.val) +{ +label_init_quick_sort_inf: +[Persudo] #0 <-- $reg.10 +br label %label_10 +label_10: +[Persudo] $reg.10 <-- #0 +$reg.10 = call i32 @.builtin.GetArrayLength(ptr $reg.10) +[Persudo] #0 <-- $reg.10 +$reg.12 = sub i32 #0, 1 +[Persudo] $reg.10 <-- #0 +[Persudo] $reg.11 <-- 0 +call void @quick_sort(ptr $reg.10, i32 $reg.11, i32 $reg.12) +ret void +} +processing function main +totally allocating 29 nodes +19 +spilled 5 nodes +define i32 @main() +{ +main_init: +[Persudo] #0 <-- $reg.20 +[Persudo] #1 <-- $reg.18 +[Persudo] #2 <-- $reg.4 +[Persudo] #3 <-- $reg.3 +$reg.4 = alloca i32 +br label %label_11 +label_11: +$reg.10 = call i32 @getInt() +[Persudo] $reg.3 <-- $reg.10 +$reg.17 = getelementptr i32, ptr $reg.4, i32 0 +store i32 $reg.3, ptr $reg.17 +[Persudo] $reg.10 <-- 1 +[Persudo] $reg.11 <-- 4 +[Persudo] $reg.12 <-- $reg.4 +$reg.10 = call ptr @.builtin.RecursiveAllocateArray(i32 $reg.10, i32 $reg.11, ptr $reg.12) +[Persudo] $reg.4 <-- $reg.10 +[Persudo] $reg.20 <-- 0 +br label %label_12 +label_12: +$reg.17 = icmp slt i32 $reg.20, $reg.3 +br i1 $reg.17, label %label_13, label %label_15 +label_13: +#0 = getelementptr i32, ptr $reg.4, i32 $reg.20 +$reg.10 = call i32 @getInt() +[Persudo] $reg.18 <-- $reg.10 +store i32 $reg.18, ptr #0 +br label %label_14 +label_14: +$reg.17 = add i32 $reg.20, 1 +[Persudo] $reg.20 <-- $reg.17 +br label %label_12 +label_15: +[Persudo] $reg.10 <-- $reg.4 +call void @quick_sort_inf(ptr $reg.10) +[Persudo] $reg.18 <-- 0 +br label %label_16 +label_16: +$reg.17 = icmp slt i32 $reg.18, $reg.3 +br i1 $reg.17, label %label_17, label %label_19 +label_17: +$reg.17 = getelementptr i32, ptr $reg.4, i32 $reg.18 +$reg.10 = load i32, ptr $reg.17 +$reg.10 = call ptr @toString(i32 $reg.10) +[Persudo] $reg.20 <-- $reg.10 +[Persudo] $reg.10 <-- $reg.20 +[Persudo] $reg.11 <-- @.str.2 +$reg.10 = call ptr @.builtin.strcat(ptr $reg.10, ptr $reg.11) +[Persudo] $reg.20 <-- $reg.10 +[Persudo] $reg.10 <-- $reg.20 +call void @print(ptr $reg.10) +br label %label_18 +label_18: +$reg.17 = add i32 $reg.18, 1 +[Persudo] $reg.18 <-- $reg.17 +br label %label_16 +label_19: +[Persudo] $reg.10 <-- @.str.3 +call void @println(ptr $reg.10) +[Persudo] $reg.3 <-- #3 +[Persudo] $reg.4 <-- #2 +[Persudo] $reg.18 <-- #1 +[Persudo] $reg.20 <-- #0 +[Persudo] $reg.10 <-- 0 +ret i32 $reg.10 +} diff --git a/include/opt/confgraph.h b/include/opt/confgraph.h index f666edf..b11d340 100644 --- a/include/opt/confgraph.h +++ b/include/opt/confgraph.h @@ -39,6 +39,7 @@ class ConfGraph { std::unordered_set pending_moves; std::unordered_set potential_moves; + std::unordered_set awful_moves; std::unordered_map::iterator>> adj_table_half_available; std::unordered_map::iterator>> diff --git a/src/opt/confgraph.cpp b/src/opt/confgraph.cpp index 05e8ce3..fbb0ae3 100644 --- a/src/opt/confgraph.cpp +++ b/src/opt/confgraph.cpp @@ -286,6 +286,7 @@ void Simplify(std::shared_ptr src, CFGType &cfg, ConfGraph &con confgraph.low_degree_and_not_move_related.erase(u); DetachNode(u, confgraph); confgraph.stack.push_back(u); + confgraph.awful_moves.clear(); } void Coalesce(std::shared_ptr src, CFGType &cfg, ConfGraph &confgraph) { @@ -324,8 +325,10 @@ void Coalesce(std::shared_ptr src, CFGType &cfg, ConfGraph &con } if (condition_satisfied) { MergeNodeInto(src_node, dest_node, confgraph); + confgraph.awful_moves.clear(); } else { confgraph.potential_moves.insert(move); + confgraph.awful_moves.insert(move); } } else { // Briggs condition @@ -342,8 +345,10 @@ void Coalesce(std::shared_ptr src, CFGType &cfg, ConfGraph &con } if (dangerous_neighbors.size() < kMaxRegs) { MergeNodeInto(src_node, dest_node, confgraph); + confgraph.awful_moves.clear(); } else { confgraph.potential_moves.insert(move); + confgraph.awful_moves.insert(move); } } } @@ -362,6 +367,7 @@ void PotentailSpill(std::shared_ptr src, CFGType &cfg, ConfGrap confgraph.high_degree_nodes.erase(u); DetachNode(u, confgraph); confgraph.stack.push_back(u); + confgraph.awful_moves.clear(); } void GraphCheck(ConfGraph &confgraph) { @@ -457,6 +463,7 @@ bool ConductColoring(std::shared_ptr src, CFGType &cfg, ConfGra // std::cerr << "confgraph.low_degree_and_move_related.size()=" << confgraph.low_degree_and_move_related.size() // << std::endl; // std::cerr << "confgraph.high_degree_nodes.size()=" << confgraph.high_degree_nodes.size() << std::endl; + // std::cerr << "confgraph.potential_moves.size()=" << confgraph.potential_moves.size() << std::endl; // std::cerr << "pending moves" << std::endl; // for (auto mode : confgraph.pending_moves) { // std::cerr << '\t'; @@ -469,7 +476,7 @@ bool ConductColoring(std::shared_ptr src, CFGType &cfg, ConfGra // mode->RecursivePrint(std::cerr); // } // std::cerr << std::endl; - GraphCheck(confgraph); + // GraphCheck(confgraph); for (auto node : confgraph.low_degree_and_not_move_related) { if (node->is_binded_with_physical_reg) { throw std::runtime_error("something strange happened: node is binded with physical reg"); @@ -494,6 +501,9 @@ bool ConductColoring(std::shared_ptr src, CFGType &cfg, ConfGra if (confgraph.potential_moves.size() > 0) { std::vector removed; for (auto move : confgraph.potential_moves) { + if (confgraph.awful_moves.find(move) != confgraph.awful_moves.end()) { + continue; + } auto src_node = confgraph.id_to_node[cfg.var_to_id[move->src_full]]; auto dest_node = confgraph.id_to_node[cfg.var_to_id[move->dest_full]]; src_node = ConfGraphNode::FindFather(src_node); diff --git a/src/opt/regalloc.cpp b/src/opt/regalloc.cpp index 1b577d7..b03ae45 100644 --- a/src/opt/regalloc.cpp +++ b/src/opt/regalloc.cpp @@ -299,6 +299,34 @@ void TranslateColorResult(std::shared_ptr func, CFGType &cfg, C } } } + +void PairMoveEliminate(std::shared_ptr func, CFGType &cfg, ConfGraph &confgraph) { + for (auto node : cfg.nodes) { + auto block = node->corresponding_block; + auto it = block->actions.begin(); + while (it != block->actions.end()) { + while (it != block->actions.end() && !std::dynamic_pointer_cast(*it)) { + ++it; + } + if (it == block->actions.end()) break; + std::unordered_map>::iterator> defined_by; + do { + auto cur_move = std::dynamic_pointer_cast(*it); + if (defined_by.find(cur_move->src_full) != defined_by.end() && + std::dynamic_pointer_cast(*defined_by[cur_move->src_full])->src_full == + cur_move->dest_full) { + auto it_next = it; + ++it_next; + block->actions.erase(it); + it = it_next; + } else { + defined_by[cur_move->dest_full] = it; + ++it; + } + } while (it != block->actions.end() && std::dynamic_pointer_cast(*it)); + } + } +} void ConductRegAllocForFunction(std::shared_ptr func) { std::cerr << "processing function " << func->func_name_raw << std::endl; CFGType cfg; @@ -314,6 +342,7 @@ void ConductRegAllocForFunction(std::shared_ptr func) { confgraph = BuildConfGraph(cfg); } while (ConductColoring(func, cfg, confgraph)); TranslateColorResult(func, cfg, confgraph); + // PairMoveEliminate(func, cfg, confgraph); func->RecursivePrint(std::cerr); }