[WebAssembly] Minor clang-format and selected clang-tidy cleanups. NFC.
[oota-llvm.git] / lib / Target / WebAssembly / WebAssemblyInstrInfo.cpp
1 //===-- WebAssemblyInstrInfo.cpp - WebAssembly Instruction Information ----===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// \brief This file contains the WebAssembly implementation of the
12 /// TargetInstrInfo class.
13 ///
14 //===----------------------------------------------------------------------===//
15
16 #include "WebAssemblyInstrInfo.h"
17 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
18 #include "WebAssemblySubtarget.h"
19 #include "llvm/CodeGen/MachineFrameInfo.h"
20 #include "llvm/CodeGen/MachineInstrBuilder.h"
21 #include "llvm/CodeGen/MachineMemOperand.h"
22 #include "llvm/CodeGen/MachineRegisterInfo.h"
23 using namespace llvm;
24
25 #define DEBUG_TYPE "wasm-instr-info"
26
27 #define GET_INSTRINFO_CTOR_DTOR
28 #include "WebAssemblyGenInstrInfo.inc"
29
30 WebAssemblyInstrInfo::WebAssemblyInstrInfo(const WebAssemblySubtarget &STI)
31     : RI(STI.getTargetTriple()) {}
32
33 void WebAssemblyInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
34                                        MachineBasicBlock::iterator I,
35                                        DebugLoc DL, unsigned DestReg,
36                                        unsigned SrcReg, bool KillSrc) const {
37   const TargetRegisterClass *RC =
38       MBB.getParent()->getRegInfo().getRegClass(SrcReg);
39
40   unsigned CopyLocalOpcode;
41   if (RC == &WebAssembly::I32RegClass)
42     CopyLocalOpcode = WebAssembly::COPY_LOCAL_I32;
43   else if (RC == &WebAssembly::I64RegClass)
44     CopyLocalOpcode = WebAssembly::COPY_LOCAL_I64;
45   else if (RC == &WebAssembly::F32RegClass)
46     CopyLocalOpcode = WebAssembly::COPY_LOCAL_F32;
47   else if (RC == &WebAssembly::F64RegClass)
48     CopyLocalOpcode = WebAssembly::COPY_LOCAL_F64;
49   else
50     llvm_unreachable("Unexpected register class");
51
52   BuildMI(MBB, I, DL, get(CopyLocalOpcode), DestReg)
53       .addReg(SrcReg, KillSrc ? RegState::Kill : 0);
54 }
55
56 // Branch analysis.
57 bool WebAssemblyInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
58                                          MachineBasicBlock *&TBB,
59                                          MachineBasicBlock *&FBB,
60                                          SmallVectorImpl<MachineOperand> &Cond,
61                                          bool /*AllowModify*/) const {
62   bool HaveCond = false;
63   for (MachineInstr &MI : iterator_range<MachineBasicBlock::instr_iterator>(
64            MBB.getFirstInstrTerminator(), MBB.instr_end())) {
65     switch (MI.getOpcode()) {
66     default:
67       // Unhandled instruction; bail out.
68       return true;
69     case WebAssembly::BR_IF:
70       if (HaveCond)
71         return true;
72       Cond.push_back(MI.getOperand(0));
73       TBB = MI.getOperand(1).getMBB();
74       HaveCond = true;
75       break;
76     case WebAssembly::BR:
77       if (!HaveCond)
78         TBB = MI.getOperand(0).getMBB();
79       else
80         FBB = MI.getOperand(0).getMBB();
81       break;
82     }
83     if (MI.isBarrier())
84       break;
85   }
86
87   return false;
88 }
89
90 unsigned WebAssemblyInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
91   MachineBasicBlock::instr_iterator I = MBB.instr_end();
92   unsigned Count = 0;
93
94   while (I != MBB.instr_begin()) {
95     --I;
96     if (I->isDebugValue())
97       continue;
98     if (!I->isTerminator())
99       break;
100     // Remove the branch.
101     I->eraseFromParent();
102     I = MBB.instr_end();
103     ++Count;
104   }
105
106   return Count;
107 }
108
109 unsigned WebAssemblyInstrInfo::InsertBranch(MachineBasicBlock &MBB,
110                                             MachineBasicBlock *TBB,
111                                             MachineBasicBlock *FBB,
112                                             ArrayRef<MachineOperand> Cond,
113                                             DebugLoc DL) const {
114   assert(Cond.size() <= 1);
115
116   if (Cond.empty()) {
117     if (!TBB)
118       return 0;
119
120     BuildMI(&MBB, DL, get(WebAssembly::BR)).addMBB(TBB);
121     return 1;
122   }
123
124   BuildMI(&MBB, DL, get(WebAssembly::BR_IF)).addOperand(Cond[0]).addMBB(TBB);
125   if (!FBB)
126     return 1;
127
128   BuildMI(&MBB, DL, get(WebAssembly::BR)).addMBB(FBB);
129   return 2;
130 }
131
132 bool WebAssemblyInstrInfo::ReverseBranchCondition(
133     SmallVectorImpl<MachineOperand> &Cond) const {
134   assert(Cond.size() == 1);
135
136   // TODO: Add branch reversal here... And re-enable MachineBlockPlacementID
137   // when we do.
138
139   return true;
140 }