ed30b535480e98b670af69c7feacd4d0dce874a1
[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   BuildMI(MBB, I, DL, get(WebAssembly::COPY), DestReg)
38       .addReg(SrcReg, KillSrc ? RegState::Kill : 0);
39 }
40
41 // Branch analysis.
42 bool WebAssemblyInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
43                                          MachineBasicBlock *&TBB,
44                                          MachineBasicBlock *&FBB,
45                                          SmallVectorImpl<MachineOperand> &Cond,
46                                          bool AllowModify) const {
47   bool HaveCond = false;
48   for (MachineInstr &MI : iterator_range<MachineBasicBlock::instr_iterator>(
49            MBB.getFirstInstrTerminator(), MBB.instr_end())) {
50     switch (MI.getOpcode()) {
51     default:
52       // Unhandled instruction; bail out.
53       return true;
54     case WebAssembly::BR_IF:
55       if (HaveCond)
56         return true;
57       Cond.push_back(MI.getOperand(0));
58       TBB = MI.getOperand(1).getMBB();
59       HaveCond = true;
60       break;
61     case WebAssembly::BR:
62       if (!HaveCond)
63         TBB = MI.getOperand(0).getMBB();
64       else
65         FBB = MI.getOperand(0).getMBB();
66       break;
67     }
68     if (MI.isBarrier())
69       break;
70   }
71
72   return false;
73 }
74
75 unsigned WebAssemblyInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
76   MachineBasicBlock::instr_iterator I = MBB.instr_end();
77   unsigned Count = 0;
78
79   while (I != MBB.instr_begin()) {
80     --I;
81     if (I->isDebugValue())
82       continue;
83     if (!I->isTerminator())
84       break;
85     // Remove the branch.
86     I->eraseFromParent();
87     I = MBB.instr_end();
88     ++Count;
89   }
90
91   return Count;
92 }
93
94 unsigned WebAssemblyInstrInfo::InsertBranch(
95     MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
96     ArrayRef<MachineOperand> Cond, DebugLoc DL) const {
97   assert(Cond.size() <= 1);
98
99   if (Cond.empty()) {
100     if (!TBB)
101       return 0;
102
103     BuildMI(&MBB, DL, get(WebAssembly::BR)).addMBB(TBB);
104     return 1;
105   }
106
107   BuildMI(&MBB, DL, get(WebAssembly::BR_IF))
108       .addOperand(Cond[0])
109       .addMBB(TBB);
110   if (!FBB)
111     return 1;
112
113   BuildMI(&MBB, DL, get(WebAssembly::BR)).addMBB(FBB);
114   return 2;
115 }
116
117 bool WebAssemblyInstrInfo::ReverseBranchCondition(
118     SmallVectorImpl<MachineOperand> &Cond) const {
119   assert(Cond.size() == 1);
120
121   // TODO: Add branch reversal here... And re-enable MachineBlockPlacementID
122   // when we do.
123
124   return true;
125 }