given a collective array, create a member out of induction variables in the context */
| 1400 | |
| 1401 | /* given a collective array, create a member out of induction variables in the context */ |
| 1402 | ArrayVariable* |
| 1403 | VariableSelector::itemize_array(CGContext& cg_context, const ArrayVariable* av) |
| 1404 | { |
| 1405 | if (av->get_dimension() > cg_context.iv_bounds.size()) return NULL; |
| 1406 | vector<const Expression*> indices; |
| 1407 | |
| 1408 | for (size_t i=0; i<av->get_dimension(); i++) { |
| 1409 | // choose which induction variables to be used as indices, prefer the ones within array bound |
| 1410 | vector<const Variable*> ok_ivs; |
| 1411 | unsigned int dimen_len = av->get_sizes()[i]; |
| 1412 | map<const Variable*, unsigned int>::iterator iter; |
| 1413 | for(iter = cg_context.iv_bounds.begin(); iter != cg_context.iv_bounds.end(); ++iter) { |
| 1414 | if (iter->second != INVALID_BOUND && iter->second < dimen_len) { |
| 1415 | const Variable* iv = iter->first; |
| 1416 | if (!CGOptions::signed_char_index() && iv->type->is_signed_char()) |
| 1417 | continue; |
| 1418 | if (CGOptions::ccomp() && iv->is_packed_aggregate_field_var()) |
| 1419 | continue; |
| 1420 | if (iv->type->is_float()) |
| 1421 | continue; |
| 1422 | // unfortunately different std::map implementations give us diff. order, we |
| 1423 | // have to sort them to generate consistant outputs across diff. platforms |
| 1424 | bool insert_middle = false; |
| 1425 | for (size_t j=0; j<ok_ivs.size(); j++) { |
| 1426 | if (ok_ivs[j]->name.compare(iv->name) > 0) { |
| 1427 | ok_ivs.insert(ok_ivs.begin() + j, iv); |
| 1428 | insert_middle = true; |
| 1429 | break; |
| 1430 | } |
| 1431 | } |
| 1432 | if (insert_middle) |
| 1433 | continue; |
| 1434 | ok_ivs.push_back(iv); |
| 1435 | } |
| 1436 | } |
| 1437 | |
| 1438 | const Variable* v = choose_ok_var(ok_ivs); |
| 1439 | // this could happen if the context contained 2 or more array to be used, but the longer one(s) has |
| 1440 | // been removed, and leaving the shorter one that is too short for the induction variable's range |
| 1441 | if (v == NULL) return NULL; |
| 1442 | |
| 1443 | const Expression* ev = new ExpressionVariable(*v);; |
| 1444 | // add random offset to the chosen induction variable |
| 1445 | unsigned int offset = 0; |
| 1446 | if (dimen_len - cg_context.iv_bounds[v] > 1) { |
| 1447 | offset = rnd_upto(dimen_len - cg_context.iv_bounds[v]); |
| 1448 | } |
| 1449 | if (offset) { |
| 1450 | const FunctionInvocation* fi = new FunctionInvocationBinary(eAdd, ev, new Constant(get_int_type(), StringUtils::int2str(offset)), 0); |
| 1451 | ev = new ExpressionFuncall(*fi); |
| 1452 | } |
| 1453 | indices.push_back(ev); |
| 1454 | } |
| 1455 | return av->itemize(indices, cg_context.get_current_block()); |
| 1456 | } |
| 1457 | |
| 1458 | const Variable* |
| 1459 | VariableSelector::select_must_use_var(Effect::Access access, CGContext &cg_context, const Type* type, const CVQualifiers* qfer) |
nothing calls this directly
no test coverage detected