#include "WebAssemblyGenInstrInfo.inc"
WebAssemblyInstrInfo::WebAssemblyInstrInfo(const WebAssemblySubtarget &STI)
- : RI(STI.getTargetTriple()) {}
+ : WebAssemblyGenInstrInfo(WebAssembly::ADJCALLSTACKDOWN,
+ WebAssembly::ADJCALLSTACKUP),
+ RI(STI.getTargetTriple()) {}
void WebAssemblyInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
DebugLoc DL, unsigned DestReg,
unsigned SrcReg, bool KillSrc) const {
- const TargetRegisterClass *RC =
- MBB.getParent()->getRegInfo().getRegClass(SrcReg);
+ // This method is called by post-RA expansion, which expects only pregs to
+ // exist. However we need to handle both here.
+ auto &MRI = MBB.getParent()->getRegInfo();
+ const TargetRegisterClass *RC = TargetRegisterInfo::isVirtualRegister(DestReg) ?
+ MRI.getRegClass(DestReg) :
+ MRI.getTargetRegisterInfo()->getMinimalPhysRegClass(SrcReg);
unsigned CopyLocalOpcode;
if (RC == &WebAssembly::I32RegClass)
MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
- bool AllowModify) const {
+ bool /*AllowModify*/) const {
bool HaveCond = false;
- for (MachineInstr &MI : iterator_range<MachineBasicBlock::instr_iterator>(
- MBB.getFirstInstrTerminator(), MBB.instr_end())) {
+ for (MachineInstr &MI : MBB.terminators()) {
switch (MI.getOpcode()) {
default:
// Unhandled instruction; bail out.
case WebAssembly::BR_IF:
if (HaveCond)
return true;
+ // If we're running after CFGStackify, we can't optimize further.
+ if (!MI.getOperand(1).isMBB())
+ return true;
+ Cond.push_back(MachineOperand::CreateImm(true));
+ Cond.push_back(MI.getOperand(0));
+ TBB = MI.getOperand(1).getMBB();
+ HaveCond = true;
+ break;
+ case WebAssembly::BR_UNLESS:
+ if (HaveCond)
+ return true;
+ // If we're running after CFGStackify, we can't optimize further.
+ if (!MI.getOperand(1).isMBB())
+ return true;
+ Cond.push_back(MachineOperand::CreateImm(false));
Cond.push_back(MI.getOperand(0));
TBB = MI.getOperand(1).getMBB();
HaveCond = true;
break;
case WebAssembly::BR:
+ // If we're running after CFGStackify, we can't optimize further.
+ if (!MI.getOperand(0).isMBB())
+ return true;
if (!HaveCond)
TBB = MI.getOperand(0).getMBB();
else
return Count;
}
-unsigned WebAssemblyInstrInfo::InsertBranch(
- MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
- ArrayRef<MachineOperand> Cond, DebugLoc DL) const {
- assert(Cond.size() <= 1);
-
+unsigned WebAssemblyInstrInfo::InsertBranch(MachineBasicBlock &MBB,
+ MachineBasicBlock *TBB,
+ MachineBasicBlock *FBB,
+ ArrayRef<MachineOperand> Cond,
+ DebugLoc DL) const {
if (Cond.empty()) {
if (!TBB)
return 0;
return 1;
}
- BuildMI(&MBB, DL, get(WebAssembly::BR_IF))
- .addOperand(Cond[0])
- .addMBB(TBB);
+ assert(Cond.size() == 2 && "Expected a flag and a successor block");
+
+ if (Cond[0].getImm()) {
+ BuildMI(&MBB, DL, get(WebAssembly::BR_IF))
+ .addOperand(Cond[1])
+ .addMBB(TBB);
+ } else {
+ BuildMI(&MBB, DL, get(WebAssembly::BR_UNLESS))
+ .addOperand(Cond[1])
+ .addMBB(TBB);
+ }
if (!FBB)
return 1;
bool WebAssemblyInstrInfo::ReverseBranchCondition(
SmallVectorImpl<MachineOperand> &Cond) const {
- assert(Cond.size() == 1);
-
- // TODO: Add branch reversal here... And re-enable MachineBlockPlacementID
- // when we do.
-
- return true;
+ assert(Cond.size() == 2 && "Expected a flag and a successor block");
+ Cond.front() = MachineOperand::CreateImm(!Cond.front().getImm());
+ return false;
}