Skip to content

Commit

Permalink
Add a program alignment preprocessing step for the ASM mode
Browse files Browse the repository at this point in the history
This copies pointer alignment from source in a semi-naive way
It can lead to false positives, but I expect/hope them to be zero
because the assembly generation part doesn't change the control-flow
significantly.
  • Loading branch information
nunoplopes committed Dec 22, 2024
1 parent c769c3b commit 68a2a89
Showing 1 changed file with 60 additions and 0 deletions.
60 changes: 60 additions & 0 deletions tools/transform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<const BasicBlock*> seen;
queue<pair<const BasicBlock*, const BasicBlock*>> 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<const Load*>(&i) &&
!dynamic_cast<const Store*>(&i))
continue;

while (II != EE && !dynamic_cast<const Load*>(&*II) &&
!dynamic_cast<const Store*>(&*II)) {
++II;
}
if (!(II != EE))
break;

if (auto *src_i = dynamic_cast<const Load*>(&i)) {
auto *tgt_i = const_cast<Load*>(dynamic_cast<const Load*>(&*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<const Store*>(&i)) {
auto *tgt_i = const_cast<Store*>(dynamic_cast<const Store*>(&*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);

Expand Down

0 comments on commit 68a2a89

Please sign in to comment.