Skip to content

Commit

Permalink
[EVM] Add custom implementation of isBlockOnlyReachableByFallthrough.
Browse files Browse the repository at this point in the history
Default implementation assumes that there should not be non-terminator
instructions between terminator ones. As a result it may mistakenly
conclude that a MBB is fall-through, whereas it's not.
  • Loading branch information
PavelKopyl committed Oct 1, 2024
1 parent 71beca8 commit afef89a
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 2 deletions.
39 changes: 38 additions & 1 deletion llvm/lib/Target/EVM/EVMAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ class EVMAsmPrinter : public AsmPrinter {
void emitInstruction(const MachineInstr *MI) override;

void emitFunctionEntryLabel() override;

/// Return true if the basic block has exactly one predecessor and the control
/// transfer mechanism between the predecessor and this block is a
/// fall-through.
bool isBlockOnlyReachableByFallthrough(
const MachineBasicBlock *MBB) const override;
};
} // end of anonymous namespace

Expand Down Expand Up @@ -70,12 +76,43 @@ void EVMAsmPrinter::emitFunctionEntryLabel() {
void EVMAsmPrinter::emitInstruction(const MachineInstr *MI) {
EVMMCInstLower MCInstLowering(OutContext, *this, VRegMapping,
MF->getRegInfo());

MCInst TmpInst;
MCInstLowering.Lower(MI, TmpInst);
EmitToStreamer(*OutStreamer, TmpInst);
}

bool EVMAsmPrinter::isBlockOnlyReachableByFallthrough(
const MachineBasicBlock *MBB) const {
if (!AsmPrinter::isBlockOnlyReachableByFallthrough(MBB))
return false;

// Check terminators in more details. After the stackification we may have the
// following case:

// PUSH_LABEL %bb.11
// JUMPI %bb.11, %27:gpr..
// PUSH_LABEL %bb.9
// JUMP %bb.9
// bb.11:
//
// The default implementation checks only the first terminator, JUMP %bb.9
// and mistakenly concludes MBB is only reachable by fallthrough.
// There should be only one predecessor, otherwise
// AsmPrinter::isBlockOnlyReachableByFallthrough() should have returned false.
assert(MBB->pred_size() == 1);
MachineBasicBlock *Pred = *MBB->pred_begin();
MachineBasicBlock::const_reverse_iterator I = Pred->rbegin(),
E = Pred->rend();
while (I != E) {
if (I->isUnconditionalBranch() || I->isConditionalBranch())
for (const auto &MO : I->explicit_uses())
if (MO.isMBB() && MO.getMBB() == MBB)
return false;
++I;
}
return true;
}

extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeEVMAsmPrinter() {
const RegisterAsmPrinter<EVMAsmPrinter> X(getTheEVMTarget());
}
4 changes: 3 additions & 1 deletion llvm/lib/Target/EVM/MCTargetDesc/EVMAsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,9 @@ bool EVMAsmBackend::evaluateTargetFixup(const MCAssembler &Asm,
Value = Target.getConstant();
if (const MCSymbolRefExpr *A = Target.getSymA()) {
const MCSymbol &Sym = A->getSymbol();
assert(Sym.isDefined());
if (!Sym.isDefined())
report_fatal_error("Undef symbol: " + Sym.getName());

Value += Layout.getSymbolOffset(Sym);
return true;
}
Expand Down

0 comments on commit afef89a

Please sign in to comment.