diff --git a/tools/transform.cpp b/tools/transform.cpp index 562bde3ca..fbb9c89bc 100644 --- a/tools/transform.cpp +++ b/tools/transform.cpp @@ -1864,6 +1864,66 @@ void Transform::preprocess() { aligns.clear(); } + // try to align programs to infer alignment in tgt from src + if (config::tgt_is_asm) { + unordered_set seen; + queue> worklist; + worklist.emplace(&src.getFirstBB(), &tgt.getFirstBB()); + + do { + auto [src_bb, tgt_bb] = worklist.front(); + worklist.pop(); + if (!seen.emplace(src_bb).second) + continue; + + auto tgt_instrs = tgt_bb->instrs(); + auto II = tgt_instrs.begin(), EE = tgt_instrs.end(); + for (auto &i : src_bb->instrs()) { + if (!dynamic_cast(&i) && + !dynamic_cast(&i)) + continue; + + while (II != EE && !dynamic_cast(&*II) && + !dynamic_cast(&*II)) { + ++II; + } + if (!(II != EE)) + break; + + if (auto *src_i = dynamic_cast(&i)) { + auto *tgt_i = const_cast(dynamic_cast(&*II)); + if (!tgt_i) + break; + if (src_i->bits() == tgt_i->bits() && + tgt_i->getAlign() < src_i->getAlign()) + tgt_i->setAlign(src_i->getAlign()); + } + else if (auto *src_i = dynamic_cast(&i)) { + auto *tgt_i = const_cast(dynamic_cast(&*II)); + if (!tgt_i) + break; + if (src_i->getValue().bits() == tgt_i->getValue().bits() && + tgt_i->getAlign() < src_i->getAlign()) + tgt_i->setAlign(src_i->getAlign()); + } else { + UNREACHABLE(); + } + ++II; + } + + { + auto tgt_targets = src_bb->targets(); + auto II = tgt_targets.begin(), EE = tgt_targets.end(); + for (auto &s : src_bb->targets()) { + if (!(II != EE)) + break; + worklist.emplace(&s, &*II); + ++II; + } + } + } while (!worklist.empty()); + } + // bits_program_pointer is used by unroll. Initialize it in advance initBitsProgramPointer(*this);