Files
clang-p2996/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp
Dan Gohman 4ba4816b97 [WebAssembly] Enable register coloring and register stackifying.
This also takes the push/pop syntax another step forward, introducing stack
slot numbers to make it easier to see how expressions are connected. For
example, the value pushed in $push7 is popped in $pop7.

And, this begins an experiment with making get_local and set_local implicit
when an operation directly uses or defines a register. This greatly reduces
clutter. If this experiment succeeds, it may make sense to do this for
const instructions as well.

And, this introduces more special code for ARGUMENTS; hopefully this code
will soon be obviated by proper support for live-in virtual registers.

llvm-svn: 253465
2015-11-18 16:12:01 +00:00

141 lines
4.1 KiB
C++

//===-- WebAssemblyInstrInfo.cpp - WebAssembly Instruction Information ----===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This file contains the WebAssembly implementation of the
/// TargetInstrInfo class.
///
//===----------------------------------------------------------------------===//
#include "WebAssemblyInstrInfo.h"
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "WebAssemblySubtarget.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
using namespace llvm;
#define DEBUG_TYPE "wasm-instr-info"
#define GET_INSTRINFO_CTOR_DTOR
#include "WebAssemblyGenInstrInfo.inc"
WebAssemblyInstrInfo::WebAssemblyInstrInfo(const WebAssemblySubtarget &STI)
: 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);
unsigned SetLocalOpcode;
if (RC == &WebAssembly::I32RegClass)
SetLocalOpcode = WebAssembly::SET_LOCAL_I32;
else if (RC == &WebAssembly::I64RegClass)
SetLocalOpcode = WebAssembly::SET_LOCAL_I64;
else if (RC == &WebAssembly::F32RegClass)
SetLocalOpcode = WebAssembly::SET_LOCAL_F32;
else if (RC == &WebAssembly::F64RegClass)
SetLocalOpcode = WebAssembly::SET_LOCAL_F64;
else
llvm_unreachable("Unexpected register class");
BuildMI(MBB, I, DL, get(SetLocalOpcode), DestReg)
.addReg(SrcReg, KillSrc ? RegState::Kill : 0);
}
// Branch analysis.
bool WebAssemblyInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify) const {
bool HaveCond = false;
for (MachineInstr &MI : iterator_range<MachineBasicBlock::instr_iterator>(
MBB.getFirstInstrTerminator(), MBB.instr_end())) {
switch (MI.getOpcode()) {
default:
// Unhandled instruction; bail out.
return true;
case WebAssembly::BR_IF:
if (HaveCond)
return true;
Cond.push_back(MI.getOperand(0));
TBB = MI.getOperand(1).getMBB();
HaveCond = true;
break;
case WebAssembly::BR:
if (!HaveCond)
TBB = MI.getOperand(0).getMBB();
else
FBB = MI.getOperand(0).getMBB();
break;
}
if (MI.isBarrier())
break;
}
return false;
}
unsigned WebAssemblyInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
MachineBasicBlock::instr_iterator I = MBB.instr_end();
unsigned Count = 0;
while (I != MBB.instr_begin()) {
--I;
if (I->isDebugValue())
continue;
if (!I->isTerminator())
break;
// Remove the branch.
I->eraseFromParent();
I = MBB.instr_end();
++Count;
}
return Count;
}
unsigned WebAssemblyInstrInfo::InsertBranch(
MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
ArrayRef<MachineOperand> Cond, DebugLoc DL) const {
assert(Cond.size() <= 1);
if (Cond.empty()) {
if (!TBB)
return 0;
BuildMI(&MBB, DL, get(WebAssembly::BR)).addMBB(TBB);
return 1;
}
BuildMI(&MBB, DL, get(WebAssembly::BR_IF))
.addOperand(Cond[0])
.addMBB(TBB);
if (!FBB)
return 1;
BuildMI(&MBB, DL, get(WebAssembly::BR)).addMBB(FBB);
return 2;
}
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;
}