MCPcopy Create free account
hub / github.com/csmith-project/csmith / itemize_array

Method itemize_array

src/VariableSelector.cpp:1402–1456  ·  view source on GitHub ↗

given a collective array, create a member out of induction variables in the context */

Source from the content-addressed store, hash-verified

1400
1401/* given a collective array, create a member out of induction variables in the context */
1402ArrayVariable*
1403VariableSelector::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
1458const Variable*
1459VariableSelector::select_must_use_var(Effect::Access access, CGContext &cg_context, const Type* type, const CVQualifiers* qfer)

Callers

nothing calls this directly

Calls 12

rnd_uptoFunction · 0.85
get_int_typeFunction · 0.85
sizeMethod · 0.80
get_sizesMethod · 0.80
beginMethod · 0.80
endMethod · 0.80
is_signed_charMethod · 0.80
is_floatMethod · 0.80
itemizeMethod · 0.80
get_current_blockMethod · 0.80
get_dimensionMethod · 0.45

Tested by

no test coverage detected