1 #ifndef CPPAD_CG_RANGE_INCLUDED
2 #define CPPAD_CG_RANGE_INCLUDED
27 inline void combineNonOverlapingIterationRanges(std::vector<size_t>& iterRegions,
28 const std::vector<size_t>& newIterRegions) {
29 if (iterRegions.empty()) {
30 iterRegions = newIterRegions;
32 }
else if (newIterRegions.empty()) {
39 std::vector<size_t>::iterator itPos = iterRegions.begin();
40 std::vector<size_t>::const_iterator itNew;
41 for (itNew = newIterRegions.begin(); itNew != newIterRegions.end(); ++itNew) {
43 itPos = std::lower_bound(itPos, iterRegions.end(), pos);
44 if (itPos == iterRegions.end()) {
45 iterRegions.insert(iterRegions.end(), itNew, newIterRegions.end());
47 }
else if (*itPos == pos) {
49 itPos = iterRegions.erase(itPos);
51 itPos = iterRegions.insert(itPos, pos);
54 CPPADCG_ASSERT_UNKNOWN(iterRegions.size() % 2 == 0);
63 inline void combineOverlapingIterationRanges(std::vector<size_t>& iterRegions,
64 const std::vector<size_t>& newIterRegions) {
65 if (iterRegions.empty()) {
66 iterRegions = newIterRegions;
68 }
else if (newIterRegions.empty()) {
72 std::vector<std::pair<size_t, size_t> > sorted;
73 for (
size_t i = 0; i < iterRegions.size(); i += 2) {
74 sorted.insert(sorted.end(), std::make_pair(iterRegions[i], iterRegions[i + 1]));
77 std::vector<std::pair<size_t, size_t> >::iterator begin = sorted.begin();
78 for (
size_t i = 0; i < newIterRegions.size(); i += 2) {
79 std::pair<size_t, size_t> p(newIterRegions[i], newIterRegions[i + 1]);
80 begin = std::lower_bound(begin, sorted.end(), p);
81 begin = sorted.insert(begin, p);
85 std::vector<std::pair<size_t, size_t> > result;
86 result.reserve(sorted.size());
87 result.push_back(sorted[0]);
88 for (
size_t i = 1; i < sorted.size(); i++) {
89 const std::pair<size_t, size_t>& curr = sorted[i];
90 std::pair<size_t, size_t>& top = result.back();
92 if (top.second == (std::numeric_limits<size_t>::max)())
97 if (top.second + 1 < curr.first) {
98 result.push_back(curr);
99 }
else if (top.second < curr.second) {
102 top.second = curr.second;
106 iterRegions.resize(result.size() * 2);
107 for (
size_t i = 0; i < result.size(); i++) {
108 iterRegions[2 * i] = result[i].first;
109 iterRegions[2 * i + 1] = result[i].second;
122 inline std::vector<size_t> invertIterationRanges(
const std::vector<size_t>& iterRegions) {
123 std::vector<size_t> inverted;
124 if (iterRegions.empty()) {
126 inverted[1] = (std::numeric_limits<size_t>::max)();
130 CPPADCG_ASSERT_UNKNOWN(iterRegions.size() % 2 == 0);
131 inverted.reserve(iterRegions.size() + 4);
133 if (iterRegions[0] != 0) {
134 inverted.push_back(0);
135 inverted.push_back(iterRegions[0] - 1);
138 for (
size_t i = 2; i < iterRegions.size(); i += 2) {
139 CPPADCG_ASSERT_UNKNOWN(iterRegions[i - 1] < iterRegions[i]);
140 inverted.push_back(iterRegions[i - 1] + 1);
141 inverted.push_back(iterRegions[i] - 1);
144 if (iterRegions.back() != (std::numeric_limits<size_t>::max)()) {
145 inverted.push_back(iterRegions.back() + 1);
146 inverted.push_back((std::numeric_limits<size_t>::max)());
161 inline std::vector<size_t> ifBranchIterationRanges(
const OperationNode<Base>* bScope,
162 IndexOperationNode<Base>*& iterationIndexOp) {
163 CGOpCode bOp = bScope->getOperationType();
165 if (bOp == CGOpCode::StartIf || bOp == CGOpCode::ElseIf) {
166 OperationNode<Base>* cond = bScope->getArguments()[bOp == CGOpCode::StartIf ? 0 : 1].getOperation();
167 CPPADCG_ASSERT_UNKNOWN(cond->getOperationType() == CGOpCode::IndexCondExpr);
168 CPPADCG_ASSERT_UNKNOWN(cond->getArguments().size() == 1);
169 CPPADCG_ASSERT_UNKNOWN(cond->getArguments()[0].getOperation() !=
nullptr);
170 CPPADCG_ASSERT_UNKNOWN(cond->getArguments()[0].getOperation()->getOperationType() == CGOpCode::Index);
171 iterationIndexOp =
static_cast<IndexOperationNode<Base>*
> (cond->getArguments()[0].getOperation());
172 return cond->getInfo();
176 CPPADCG_ASSERT_UNKNOWN(bOp == CGOpCode::Else);
178 std::vector<size_t> nonIterationRegions;
179 OperationNode<Base>* ifBranch = bScope->getArguments()[0].getOperation();
181 CGOpCode bbOp = ifBranch->getOperationType();
182 OperationNode<Base>* cond = ifBranch->getArguments()[bbOp == CGOpCode::StartIf ? 0 : 1].getOperation();
183 CPPADCG_ASSERT_UNKNOWN(cond->getOperationType() == CGOpCode::IndexCondExpr);
184 CPPADCG_ASSERT_UNKNOWN(cond->getArguments().size() == 1);
185 CPPADCG_ASSERT_UNKNOWN(cond->getArguments()[0].getOperation() !=
nullptr);
186 CPPADCG_ASSERT_UNKNOWN(cond->getArguments()[0].getOperation()->getOperationType() == CGOpCode::Index);
187 IndexOperationNode<Base>* indexOp =
static_cast<IndexOperationNode<Base>*
> (cond->getArguments()[0].getOperation());
188 CPPADCG_ASSERT_UNKNOWN(iterationIndexOp ==
nullptr || iterationIndexOp == indexOp);
189 iterationIndexOp = indexOp;
191 combineOverlapingIterationRanges(nonIterationRegions, cond->getInfo());
193 ifBranch = ifBranch->getArguments()[0].getOperation();
194 }
while (ifBranch->getOperationType() == CGOpCode::ElseIf);
196 CPPADCG_ASSERT_UNKNOWN(iterationIndexOp !=
nullptr);
199 return invertIterationRanges(nonIterationRegions);