| 1396 | } |
| 1397 | |
| 1398 | Errors TransformVerify::verify() const { |
| 1399 | if (!t.src.getFnAttrs().refinedBy(t.tgt.getFnAttrs())) |
| 1400 | return { "Function attributes not refined", true }; |
| 1401 | |
| 1402 | { |
| 1403 | auto src_inputs = t.src.getInputs(); |
| 1404 | auto tgt_inputs = t.tgt.getInputs(); |
| 1405 | auto litr = src_inputs.begin(), lend = src_inputs.end(); |
| 1406 | auto ritr = tgt_inputs.begin(), rend = tgt_inputs.end(); |
| 1407 | |
| 1408 | while (litr != lend && ritr != rend) { |
| 1409 | auto *lv = dynamic_cast<const Input*>(&*litr); |
| 1410 | auto *rv = dynamic_cast<const Input*>(&*ritr); |
| 1411 | if (lv->getType().toString() != rv->getType().toString()) |
| 1412 | return { "Signature mismatch between src and tgt", false }; |
| 1413 | |
| 1414 | if (!lv->getAttributes().refinedBy(rv->getAttributes())) |
| 1415 | return { "Parameter attributes not refined", true }; |
| 1416 | |
| 1417 | ++litr; |
| 1418 | ++ritr; |
| 1419 | } |
| 1420 | |
| 1421 | if (litr != lend || ritr != rend) |
| 1422 | return { "Signature mismatch between src and tgt", false }; |
| 1423 | } |
| 1424 | |
| 1425 | // Check sizes of global variables |
| 1426 | auto globals_tgt = t.tgt.getGlobalVars(); |
| 1427 | auto globals_src = t.src.getGlobalVars(); |
| 1428 | for (auto GVS : globals_src) { |
| 1429 | auto I = find_if(globals_tgt.begin(), globals_tgt.end(), |
| 1430 | [GVS](auto *GV) -> bool { return GVS->getName() == GV->getName(); }); |
| 1431 | if (I == globals_tgt.end()) |
| 1432 | continue; |
| 1433 | |
| 1434 | auto GVT = *I; |
| 1435 | if (GVS->size() != GVT->size()) { |
| 1436 | stringstream ss; |
| 1437 | ss << "Unsupported interprocedural transformation: global variable " |
| 1438 | << GVS->getName() << " has different size in source and target (" |
| 1439 | << GVS->size() << " vs " << GVT->size() |
| 1440 | << " bytes)"; |
| 1441 | return { ss.str(), false }; |
| 1442 | } else if (GVS->isConst() && !GVT->isConst()) { |
| 1443 | stringstream ss; |
| 1444 | ss << "Transformation is incorrect because global variable " |
| 1445 | << GVS->getName() << " is const in source but not in target"; |
| 1446 | return { ss.str(), true }; |
| 1447 | } else if (!GVS->isConst() && GVT->isConst()) { |
| 1448 | stringstream ss; |
| 1449 | ss << "Unsupported interprocedural transformation: global variable " |
| 1450 | << GVS->getName() << " is const in target but not in source"; |
| 1451 | return { ss.str(), false }; |
| 1452 | } |
| 1453 | } |
| 1454 | for (auto GVT : globals_tgt) { |
| 1455 | auto I = find_if(globals_src.begin(), globals_src.end(), |