63 _stk(arena(), 8, 0, NULL), // scratch stack of nodes |
63 _stk(arena(), 8, 0, NULL), // scratch stack of nodes |
64 _nlist(arena(), 8, 0, NULL), // scratch list of nodes |
64 _nlist(arena(), 8, 0, NULL), // scratch list of nodes |
65 _lpt(NULL), // loop tree node |
65 _lpt(NULL), // loop tree node |
66 _lp(NULL), // LoopNode |
66 _lp(NULL), // LoopNode |
67 _bb(NULL), // basic block |
67 _bb(NULL), // basic block |
68 _iv(NULL) // induction var |
68 _iv(NULL), // induction var |
|
69 _race_possible(false) // cases where SDMU is true |
69 {} |
70 {} |
70 |
71 |
71 //------------------------------transform_loop--------------------------- |
72 //------------------------------transform_loop--------------------------- |
72 void SuperWord::transform_loop(IdealLoopTree* lpt) { |
73 void SuperWord::transform_loop(IdealLoopTree* lpt) { |
73 assert(UseSuperWord, "should be"); |
74 assert(UseSuperWord, "should be"); |
638 if (Matcher::max_vector_size(bt1) < 2) { |
638 if (Matcher::max_vector_size(bt1) < 2) { |
639 return false; // No vectors for this type |
639 return false; // No vectors for this type |
640 } |
640 } |
641 |
641 |
642 if (isomorphic(s1, s2)) { |
642 if (isomorphic(s1, s2)) { |
643 if (independent(s1, s2)) { |
643 if (independent(s1, s2) || reduction(s1, s2)) { |
644 if (!exists_at(s1, 0) && !exists_at(s2, 1)) { |
644 if (!exists_at(s1, 0) && !exists_at(s2, 1)) { |
645 if (!s1->is_Mem() || are_adjacent_refs(s1, s2)) { |
645 if (!s1->is_Mem() || are_adjacent_refs(s1, s2)) { |
646 int s1_align = alignment(s1); |
646 int s1_align = alignment(s1); |
647 int s2_align = alignment(s2); |
647 int s2_align = alignment(s2); |
648 if (s1_align == top_align || s1_align == align) { |
648 if (s1_align == top_align || s1_align == align) { |
714 Node* shallow = d1 > d2 ? s2 : s1; |
714 Node* shallow = d1 > d2 ? s2 : s1; |
715 |
715 |
716 visited_clear(); |
716 visited_clear(); |
717 |
717 |
718 return independent_path(shallow, deep); |
718 return independent_path(shallow, deep); |
|
719 } |
|
720 |
|
721 //------------------------------reduction--------------------------- |
|
722 // Is there a data path between s1 and s2 and the nodes reductions? |
|
723 bool SuperWord::reduction(Node* s1, Node* s2) { |
|
724 bool retValue = false; |
|
725 int d1 = depth(s1); |
|
726 int d2 = depth(s2); |
|
727 if (d1 + 1 == d2) { |
|
728 if (s1->is_reduction() && s2->is_reduction()) { |
|
729 // This is an ordered set, so s1 should define s2 |
|
730 for (DUIterator_Fast imax, i = s1->fast_outs(imax); i < imax; i++) { |
|
731 Node* t1 = s1->fast_out(i); |
|
732 if (t1 == s2) { |
|
733 // both nodes are reductions and connected |
|
734 retValue = true; |
|
735 } |
|
736 } |
|
737 } |
|
738 } |
|
739 |
|
740 return retValue; |
719 } |
741 } |
720 |
742 |
721 //------------------------------independent_path------------------------------ |
743 //------------------------------independent_path------------------------------ |
722 // Helper for independent |
744 // Helper for independent |
723 bool SuperWord::independent_path(Node* shallow, Node* deep, uint dp) { |
745 bool SuperWord::independent_path(Node* shallow, Node* deep, uint dp) { |
759 //------------------------------extend_packlist--------------------------- |
781 //------------------------------extend_packlist--------------------------- |
760 // Extend packset by following use->def and def->use links from pack members. |
782 // Extend packset by following use->def and def->use links from pack members. |
761 void SuperWord::extend_packlist() { |
783 void SuperWord::extend_packlist() { |
762 bool changed; |
784 bool changed; |
763 do { |
785 do { |
|
786 packset_sort(_packset.length()); |
764 changed = false; |
787 changed = false; |
765 for (int i = 0; i < _packset.length(); i++) { |
788 for (int i = 0; i < _packset.length(); i++) { |
766 Node_List* p = _packset.at(i); |
789 Node_List* p = _packset.at(i); |
767 changed |= follow_use_defs(p); |
790 changed |= follow_use_defs(p); |
768 changed |= follow_def_uses(p); |
791 changed |= follow_def_uses(p); |
769 } |
792 } |
770 } while (changed); |
793 } while (changed); |
|
794 |
|
795 if (_race_possible) { |
|
796 for (int i = 0; i < _packset.length(); i++) { |
|
797 Node_List* p = _packset.at(i); |
|
798 order_def_uses(p); |
|
799 } |
|
800 } |
771 |
801 |
772 #ifndef PRODUCT |
802 #ifndef PRODUCT |
773 if (TraceSuperWord) { |
803 if (TraceSuperWord) { |
774 tty->print_cr("\nAfter extend_packlist"); |
804 tty->print_cr("\nAfter extend_packlist"); |
775 print_packset(); |
805 print_packset(); |
823 |
853 |
824 if (s1->is_Store()) return false; |
854 if (s1->is_Store()) return false; |
825 |
855 |
826 int align = alignment(s1); |
856 int align = alignment(s1); |
827 int savings = -1; |
857 int savings = -1; |
|
858 int num_s1_uses = 0; |
828 Node* u1 = NULL; |
859 Node* u1 = NULL; |
829 Node* u2 = NULL; |
860 Node* u2 = NULL; |
830 for (DUIterator_Fast imax, i = s1->fast_outs(imax); i < imax; i++) { |
861 for (DUIterator_Fast imax, i = s1->fast_outs(imax); i < imax; i++) { |
831 Node* t1 = s1->fast_out(i); |
862 Node* t1 = s1->fast_out(i); |
|
863 num_s1_uses++; |
832 if (!in_bb(t1)) continue; |
864 if (!in_bb(t1)) continue; |
833 for (DUIterator_Fast jmax, j = s2->fast_outs(jmax); j < jmax; j++) { |
865 for (DUIterator_Fast jmax, j = s2->fast_outs(jmax); j < jmax; j++) { |
834 Node* t2 = s2->fast_out(j); |
866 Node* t2 = s2->fast_out(j); |
835 if (!in_bb(t2)) continue; |
867 if (!in_bb(t2)) continue; |
836 if (!opnd_positions_match(s1, t1, s2, t2)) |
868 if (!opnd_positions_match(s1, t1, s2, t2)) |
854 changed = true; |
889 changed = true; |
855 } |
890 } |
856 return changed; |
891 return changed; |
857 } |
892 } |
858 |
893 |
|
894 //------------------------------order_def_uses--------------------------- |
|
895 // For extended packsets, ordinally arrange uses packset by major component |
|
896 void SuperWord::order_def_uses(Node_List* p) { |
|
897 Node* s1 = p->at(0); |
|
898 |
|
899 if (s1->is_Store()) return; |
|
900 |
|
901 // reductions are always managed beforehand |
|
902 if (s1->is_reduction()) return; |
|
903 |
|
904 for (DUIterator_Fast imax, i = s1->fast_outs(imax); i < imax; i++) { |
|
905 Node* t1 = s1->fast_out(i); |
|
906 |
|
907 // Only allow operand swap on commuting operations |
|
908 if (!t1->is_Add() && !t1->is_Mul()) { |
|
909 break; |
|
910 } |
|
911 |
|
912 // Now find t1's packset |
|
913 Node_List* p2 = NULL; |
|
914 for (int j = 0; j < _packset.length(); j++) { |
|
915 p2 = _packset.at(j); |
|
916 Node* first = p2->at(0); |
|
917 if (t1 == first) { |
|
918 break; |
|
919 } |
|
920 p2 = NULL; |
|
921 } |
|
922 // Arrange all sub components by the major component |
|
923 if (p2 != NULL) { |
|
924 for (uint j = 1; j < p->size(); j++) { |
|
925 Node* d1 = p->at(j); |
|
926 Node* u1 = p2->at(j); |
|
927 opnd_positions_match(s1, t1, d1, u1); |
|
928 } |
|
929 } |
|
930 } |
|
931 } |
|
932 |
859 //---------------------------opnd_positions_match------------------------- |
933 //---------------------------opnd_positions_match------------------------- |
860 // Is the use of d1 in u1 at the same operand position as d2 in u2? |
934 // Is the use of d1 in u1 at the same operand position as d2 in u2? |
861 bool SuperWord::opnd_positions_match(Node* d1, Node* u1, Node* d2, Node* u2) { |
935 bool SuperWord::opnd_positions_match(Node* d1, Node* u1, Node* d2, Node* u2) { |
|
936 // check reductions to see if they are marshalled to represent the reduction |
|
937 // operator in a specified opnd |
|
938 if (u1->is_reduction() && u2->is_reduction()) { |
|
939 // ensure reductions have phis and reduction definitions feeding the 1st operand |
|
940 Node* first = u1->in(2); |
|
941 if (first->is_Phi() || first->is_reduction()) { |
|
942 u1->swap_edges(1, 2); |
|
943 } |
|
944 // ensure reductions have phis and reduction definitions feeding the 1st operand |
|
945 first = u2->in(2); |
|
946 if (first->is_Phi() || first->is_reduction()) { |
|
947 u2->swap_edges(1, 2); |
|
948 } |
|
949 return true; |
|
950 } |
|
951 |
862 uint ct = u1->req(); |
952 uint ct = u1->req(); |
863 if (ct != u2->req()) return false; |
953 if (ct != u2->req()) return false; |
864 uint i1 = 0; |
954 uint i1 = 0; |
865 uint i2 = 0; |
955 uint i2 = 0; |
866 do { |
956 do { |
938 while (changed) { |
1028 while (changed) { |
939 changed = false; |
1029 changed = false; |
940 for (int i = 0; i < _packset.length(); i++) { |
1030 for (int i = 0; i < _packset.length(); i++) { |
941 Node_List* p1 = _packset.at(i); |
1031 Node_List* p1 = _packset.at(i); |
942 if (p1 == NULL) continue; |
1032 if (p1 == NULL) continue; |
943 for (int j = 0; j < _packset.length(); j++) { |
1033 // Because of sorting we can start at i + 1 |
|
1034 for (int j = i + 1; j < _packset.length(); j++) { |
944 Node_List* p2 = _packset.at(j); |
1035 Node_List* p2 = _packset.at(j); |
945 if (p2 == NULL) continue; |
1036 if (p2 == NULL) continue; |
946 if (i == j) continue; |
1037 if (i == j) continue; |
947 if (p1->at(p1->size()-1) == p2->at(0)) { |
1038 if (p1->at(p1->size()-1) == p2->at(0)) { |
948 for (uint k = 1; k < p2->size(); k++) { |
1039 for (uint k = 1; k < p2->size(); k++) { |
1065 } |
1156 } |
1066 |
1157 |
1067 //------------------------------implemented--------------------------- |
1158 //------------------------------implemented--------------------------- |
1068 // Can code be generated for pack p? |
1159 // Can code be generated for pack p? |
1069 bool SuperWord::implemented(Node_List* p) { |
1160 bool SuperWord::implemented(Node_List* p) { |
|
1161 bool retValue = false; |
1070 Node* p0 = p->at(0); |
1162 Node* p0 = p->at(0); |
1071 return VectorNode::implemented(p0->Opcode(), p->size(), velt_basic_type(p0)); |
1163 if (p0 != NULL) { |
|
1164 int opc = p0->Opcode(); |
|
1165 uint size = p->size(); |
|
1166 if (p0->is_reduction()) { |
|
1167 const Type *arith_type = p0->bottom_type(); |
|
1168 retValue = ReductionNode::implemented(opc, size, arith_type->basic_type()); |
|
1169 } else { |
|
1170 retValue = VectorNode::implemented(opc, size, velt_basic_type(p0)); |
|
1171 } |
|
1172 } |
|
1173 return retValue; |
1072 } |
1174 } |
1073 |
1175 |
1074 //------------------------------same_inputs-------------------------- |
1176 //------------------------------same_inputs-------------------------- |
1075 // For pack p, are all idx operands the same? |
1177 // For pack p, are all idx operands the same? |
1076 static bool same_inputs(Node_List* p, int idx) { |
1178 static bool same_inputs(Node_List* p, int idx) { |
1100 // (maybe just the ones from outside the block.) |
1202 // (maybe just the ones from outside the block.) |
1101 for (uint i = start; i < end; i++) { |
1203 for (uint i = start; i < end; i++) { |
1102 if (!is_vector_use(p0, i)) |
1204 if (!is_vector_use(p0, i)) |
1103 return false; |
1205 return false; |
1104 } |
1206 } |
|
1207 // Check if reductions are connected |
|
1208 if (p0->is_reduction()) { |
|
1209 Node* second_in = p0->in(2); |
|
1210 Node_List* second_pk = my_pack(second_in); |
|
1211 if (second_pk == NULL) { |
|
1212 // Remove reduction flag if no parent pack, it is not profitable |
|
1213 p0->remove_flag(Node::Flag_is_reduction); |
|
1214 return false; |
|
1215 } else if (second_pk->size() != p->size()) { |
|
1216 return false; |
|
1217 } |
|
1218 } |
1105 if (VectorNode::is_shift(p0)) { |
1219 if (VectorNode::is_shift(p0)) { |
1106 // For now, return false if shift count is vector or not scalar promotion |
1220 // For now, return false if shift count is vector or not scalar promotion |
1107 // case (different shift counts) because it is not supported yet. |
1221 // case (different shift counts) because it is not supported yet. |
1108 Node* cnt = p0->in(2); |
1222 Node* cnt = p0->in(2); |
1109 Node_List* cnt_pk = my_pack(cnt); |
1223 Node_List* cnt_pk = my_pack(cnt); |
1121 for (DUIterator_Fast jmax, j = def->fast_outs(jmax); j < jmax; j++) { |
1235 for (DUIterator_Fast jmax, j = def->fast_outs(jmax); j < jmax; j++) { |
1122 Node* use = def->fast_out(j); |
1236 Node* use = def->fast_out(j); |
1123 for (uint k = 0; k < use->req(); k++) { |
1237 for (uint k = 0; k < use->req(); k++) { |
1124 Node* n = use->in(k); |
1238 Node* n = use->in(k); |
1125 if (def == n) { |
1239 if (def == n) { |
|
1240 // reductions can be loop carried dependences |
|
1241 if (def->is_reduction() && use->is_Phi()) |
|
1242 continue; |
1126 if (!is_vector_use(use, k)) { |
1243 if (!is_vector_use(use, k)) { |
1127 return false; |
1244 return false; |
1128 } |
1245 } |
1129 } |
1246 } |
1130 } |
1247 } |
1405 const TypePtr* atyp = n->adr_type(); |
1522 const TypePtr* atyp = n->adr_type(); |
1406 vn = StoreVectorNode::make(opc, ctl, mem, adr, atyp, val, vlen); |
1523 vn = StoreVectorNode::make(opc, ctl, mem, adr, atyp, val, vlen); |
1407 vlen_in_bytes = vn->as_StoreVector()->memory_size(); |
1524 vlen_in_bytes = vn->as_StoreVector()->memory_size(); |
1408 } else if (n->req() == 3) { |
1525 } else if (n->req() == 3) { |
1409 // Promote operands to vector |
1526 // Promote operands to vector |
1410 Node* in1 = vector_opd(p, 1); |
1527 Node* in1 = NULL; |
|
1528 bool node_isa_reduction = n->is_reduction(); |
|
1529 if (node_isa_reduction) { |
|
1530 // the input to the first reduction operation is retained |
|
1531 in1 = low_adr->in(1); |
|
1532 } else { |
|
1533 in1 = vector_opd(p, 1); |
|
1534 } |
1411 Node* in2 = vector_opd(p, 2); |
1535 Node* in2 = vector_opd(p, 2); |
1412 if (VectorNode::is_invariant_vector(in1) && (n->is_Add() || n->is_Mul())) { |
1536 if (VectorNode::is_invariant_vector(in1) && (node_isa_reduction == false) && (n->is_Add() || n->is_Mul())) { |
1413 // Move invariant vector input into second position to avoid register spilling. |
1537 // Move invariant vector input into second position to avoid register spilling. |
1414 Node* tmp = in1; |
1538 Node* tmp = in1; |
1415 in1 = in2; |
1539 in1 = in2; |
1416 in2 = tmp; |
1540 in2 = tmp; |
1417 } |
1541 } |
1418 vn = VectorNode::make(opc, in1, in2, vlen, velt_basic_type(n)); |
1542 if (node_isa_reduction) { |
1419 vlen_in_bytes = vn->as_Vector()->length_in_bytes(); |
1543 const Type *arith_type = n->bottom_type(); |
|
1544 vn = ReductionNode::make(opc, NULL, in1, in2, arith_type->basic_type()); |
|
1545 if (in2->is_Load()) { |
|
1546 vlen_in_bytes = in2->as_LoadVector()->memory_size(); |
|
1547 } else { |
|
1548 vlen_in_bytes = in2->as_Vector()->length_in_bytes(); |
|
1549 } |
|
1550 } else { |
|
1551 vn = VectorNode::make(opc, in1, in2, vlen, velt_basic_type(n)); |
|
1552 vlen_in_bytes = vn->as_Vector()->length_in_bytes(); |
|
1553 } |
1420 } else { |
1554 } else { |
1421 ShouldNotReachHere(); |
1555 ShouldNotReachHere(); |
1422 } |
1556 } |
1423 assert(vn != NULL, "sanity"); |
1557 assert(vn != NULL, "sanity"); |
1424 _igvn.register_new_node_with_optimizer(vn); |
1558 _igvn.register_new_node_with_optimizer(vn); |
1554 Node* use = _n_idx_list.node(); |
1688 Node* use = _n_idx_list.node(); |
1555 int idx = _n_idx_list.index(); |
1689 int idx = _n_idx_list.index(); |
1556 _n_idx_list.pop(); |
1690 _n_idx_list.pop(); |
1557 Node* def = use->in(idx); |
1691 Node* def = use->in(idx); |
1558 |
1692 |
|
1693 if (def->is_reduction()) continue; |
|
1694 |
1559 // Insert extract operation |
1695 // Insert extract operation |
1560 _igvn.hash_delete(def); |
1696 _igvn.hash_delete(def); |
1561 int def_pos = alignment(def) / data_size(def); |
1697 int def_pos = alignment(def) / data_size(def); |
1562 |
1698 |
1563 Node* ex = ExtractNode::make(def, def_pos, velt_basic_type(def)); |
1699 Node* ex = ExtractNode::make(def, def_pos, velt_basic_type(def)); |
1574 //------------------------------is_vector_use--------------------------- |
1710 //------------------------------is_vector_use--------------------------- |
1575 // Is use->in(u_idx) a vector use? |
1711 // Is use->in(u_idx) a vector use? |
1576 bool SuperWord::is_vector_use(Node* use, int u_idx) { |
1712 bool SuperWord::is_vector_use(Node* use, int u_idx) { |
1577 Node_List* u_pk = my_pack(use); |
1713 Node_List* u_pk = my_pack(use); |
1578 if (u_pk == NULL) return false; |
1714 if (u_pk == NULL) return false; |
|
1715 if (use->is_reduction()) return true; |
1579 Node* def = use->in(u_idx); |
1716 Node* def = use->in(u_idx); |
1580 Node_List* d_pk = my_pack(def); |
1717 Node_List* d_pk = my_pack(def); |
1581 if (d_pk == NULL) { |
1718 if (d_pk == NULL) { |
1582 // check for scalar promotion |
1719 // check for scalar promotion |
1583 Node* n = u_pk->at(0)->in(u_idx); |
1720 Node* n = u_pk->at(0)->in(u_idx); |
1611 // Find non-control nodes with no inputs from within block, |
1748 // Find non-control nodes with no inputs from within block, |
1612 // create a temporary map from node _idx to bb_idx for use |
1749 // create a temporary map from node _idx to bb_idx for use |
1613 // by the visited and post_visited sets, |
1750 // by the visited and post_visited sets, |
1614 // and count number of nodes in block. |
1751 // and count number of nodes in block. |
1615 int bb_ct = 0; |
1752 int bb_ct = 0; |
1616 for (uint i = 0; i < lpt()->_body.size(); i++ ) { |
1753 for (uint i = 0; i < lpt()->_body.size(); i++) { |
1617 Node *n = lpt()->_body.at(i); |
1754 Node *n = lpt()->_body.at(i); |
1618 set_bb_idx(n, i); // Create a temporary map |
1755 set_bb_idx(n, i); // Create a temporary map |
1619 if (in_bb(n)) { |
1756 if (in_bb(n)) { |
1620 if (n->is_LoadStore() || n->is_MergeMem() || |
1757 if (n->is_LoadStore() || n->is_MergeMem() || |
1621 (n->is_Proj() && !n->as_Proj()->is_CFG())) { |
1758 (n->is_Proj() && !n->as_Proj()->is_CFG())) { |
1672 _stk.push(entry); |
1809 _stk.push(entry); |
1673 |
1810 |
1674 // Do a depth first walk over out edges |
1811 // Do a depth first walk over out edges |
1675 int rpo_idx = bb_ct - 1; |
1812 int rpo_idx = bb_ct - 1; |
1676 int size; |
1813 int size; |
|
1814 int reduction_uses = 0; |
1677 while ((size = _stk.length()) > 0) { |
1815 while ((size = _stk.length()) > 0) { |
1678 Node* n = _stk.top(); // Leave node on stack |
1816 Node* n = _stk.top(); // Leave node on stack |
1679 if (!visited_test_set(n)) { |
1817 if (!visited_test_set(n)) { |
1680 // forward arc in graph |
1818 // forward arc in graph |
1681 } else if (!post_visited_test(n)) { |
1819 } else if (!post_visited_test(n)) { |
1683 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { |
1821 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { |
1684 Node *use = n->fast_out(i); |
1822 Node *use = n->fast_out(i); |
1685 if (in_bb(use) && !visited_test(use) && |
1823 if (in_bb(use) && !visited_test(use) && |
1686 // Don't go around backedge |
1824 // Don't go around backedge |
1687 (!use->is_Phi() || n == entry)) { |
1825 (!use->is_Phi() || n == entry)) { |
|
1826 if (use->is_reduction()) { |
|
1827 // First see if we can map the reduction on the given system we are on, then |
|
1828 // make a data entry operation for each reduction we see. |
|
1829 BasicType bt = use->bottom_type()->basic_type(); |
|
1830 if (ReductionNode::implemented(use->Opcode(), Matcher::min_vector_size(bt), bt)) { |
|
1831 reduction_uses++; |
|
1832 } |
|
1833 } |
1688 _stk.push(use); |
1834 _stk.push(use); |
1689 } |
1835 } |
1690 } |
1836 } |
1691 if (_stk.length() == size) { |
1837 if (_stk.length() == size) { |
1692 // There were no additional uses, post visit node now |
1838 // There were no additional uses, post visit node now |
1706 for (int j = 0; j < _block.length(); j++) { |
1852 for (int j = 0; j < _block.length(); j++) { |
1707 Node* n = _block.at(j); |
1853 Node* n = _block.at(j); |
1708 set_bb_idx(n, j); |
1854 set_bb_idx(n, j); |
1709 } |
1855 } |
1710 |
1856 |
1711 initialize_bb(); // Ensure extra info is allocated. |
1857 // Ensure extra info is allocated. |
|
1858 initialize_bb(); |
1712 |
1859 |
1713 #ifndef PRODUCT |
1860 #ifndef PRODUCT |
1714 if (TraceSuperWord) { |
1861 if (TraceSuperWord) { |
1715 print_bb(); |
1862 print_bb(); |
1716 tty->print_cr("\ndata entry nodes: %s", _data_entry.length() > 0 ? "" : "NONE"); |
1863 tty->print_cr("\ndata entry nodes: %s", _data_entry.length() > 0 ? "" : "NONE"); |
1724 tty->print(" "); _mem_slice_tail.at(m)->dump(); |
1871 tty->print(" "); _mem_slice_tail.at(m)->dump(); |
1725 } |
1872 } |
1726 } |
1873 } |
1727 #endif |
1874 #endif |
1728 assert(rpo_idx == -1 && bb_ct == _block.length(), "all block members found"); |
1875 assert(rpo_idx == -1 && bb_ct == _block.length(), "all block members found"); |
1729 return (_mem_slice_head.length() > 0) || (_data_entry.length() > 0); |
1876 return (_mem_slice_head.length() > 0) || (reduction_uses > 0) || (_data_entry.length() > 0); |
1730 } |
1877 } |
1731 |
1878 |
1732 //------------------------------initialize_bb--------------------------- |
1879 //------------------------------initialize_bb--------------------------- |
1733 // Initialize per node info |
1880 // Initialize per node info |
1734 void SuperWord::initialize_bb() { |
1881 void SuperWord::initialize_bb() { |
1955 for (uint i = 0; i < p->size(); i++) { |
2102 for (uint i = 0; i < p->size(); i++) { |
1956 Node* s = p->at(i); |
2103 Node* s = p->at(i); |
1957 set_my_pack(s, NULL); |
2104 set_my_pack(s, NULL); |
1958 } |
2105 } |
1959 _packset.remove_at(pos); |
2106 _packset.remove_at(pos); |
|
2107 } |
|
2108 |
|
2109 void SuperWord::packset_sort(int n) { |
|
2110 // simple bubble sort so that we capitalize with O(n) when its already sorted |
|
2111 while (n != 0) { |
|
2112 bool swapped = false; |
|
2113 for (int i = 1; i < n; i++) { |
|
2114 Node_List* q_low = _packset.at(i-1); |
|
2115 Node_List* q_i = _packset.at(i); |
|
2116 |
|
2117 // only swap when we find something to swap |
|
2118 if (alignment(q_low->at(0)) > alignment(q_i->at(0))) { |
|
2119 Node_List* t = q_i; |
|
2120 *(_packset.adr_at(i)) = q_low; |
|
2121 *(_packset.adr_at(i-1)) = q_i; |
|
2122 swapped = true; |
|
2123 } |
|
2124 } |
|
2125 if (swapped == false) break; |
|
2126 n--; |
|
2127 } |
1960 } |
2128 } |
1961 |
2129 |
1962 //------------------------------executed_first--------------------------- |
2130 //------------------------------executed_first--------------------------- |
1963 // Return the node executed first in pack p. Uses the RPO block list |
2131 // Return the node executed first in pack p. Uses the RPO block list |
1964 // to determine order. |
2132 // to determine order. |