Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Mips/Mips16ISelDAGToDAG.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- Mips16ISelDAGToDAG.cpp - A Dag to Dag Inst Selector for Mips16 ----===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// Subclass of MipsDAGToDAGISel specialized for mips16.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "Mips16ISelDAGToDAG.h"
14
#include "MCTargetDesc/MipsBaseInfo.h"
15
#include "Mips.h"
16
#include "MipsMachineFunction.h"
17
#include "MipsRegisterInfo.h"
18
#include "llvm/CodeGen/MachineConstantPool.h"
19
#include "llvm/CodeGen/MachineFrameInfo.h"
20
#include "llvm/CodeGen/MachineFunction.h"
21
#include "llvm/CodeGen/MachineInstrBuilder.h"
22
#include "llvm/CodeGen/MachineRegisterInfo.h"
23
#include "llvm/CodeGen/SelectionDAGNodes.h"
24
#include "llvm/IR/CFG.h"
25
#include "llvm/IR/GlobalValue.h"
26
#include "llvm/IR/Instructions.h"
27
#include "llvm/IR/Intrinsics.h"
28
#include "llvm/IR/Type.h"
29
#include "llvm/Support/Debug.h"
30
#include "llvm/Support/ErrorHandling.h"
31
#include "llvm/Support/raw_ostream.h"
32
#include "llvm/Target/TargetMachine.h"
33
using namespace llvm;
34
35
#define DEBUG_TYPE "mips-isel"
36
37
12.8k
bool Mips16DAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {
38
12.8k
  Subtarget = &static_cast<const MipsSubtarget &>(MF.getSubtarget());
39
12.8k
  if (!Subtarget->inMips16Mode())
40
12.5k
    return false;
41
380
  return MipsDAGToDAGISel::runOnMachineFunction(MF);
42
380
}
43
/// Select multiply instructions.
44
std::pair<SDNode *, SDNode *>
45
Mips16DAGToDAGISel::selectMULT(SDNode *N, unsigned Opc, const SDLoc &DL, EVT Ty,
46
8
                               bool HasLo, bool HasHi) {
47
8
  SDNode *Lo = nullptr, *Hi = nullptr;
48
8
  SDNode *Mul = CurDAG->getMachineNode(Opc, DL, MVT::Glue, N->getOperand(0),
49
8
                                       N->getOperand(1));
50
8
  SDValue InFlag = SDValue(Mul, 0);
51
8
52
8
  if (HasLo) {
53
8
    unsigned Opcode = Mips::Mflo16;
54
8
    Lo = CurDAG->getMachineNode(Opcode, DL, Ty, MVT::Glue, InFlag);
55
8
    InFlag = SDValue(Lo, 1);
56
8
  }
57
8
  if (HasHi) {
58
8
    unsigned Opcode = Mips::Mfhi16;
59
8
    Hi = CurDAG->getMachineNode(Opcode, DL, Ty, InFlag);
60
8
  }
61
8
  return std::make_pair(Lo, Hi);
62
8
}
63
64
380
void Mips16DAGToDAGISel::initGlobalBaseReg(MachineFunction &MF) {
65
380
  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
66
380
67
380
  if (!MipsFI->globalBaseRegSet())
68
182
    return;
69
198
70
198
  MachineBasicBlock &MBB = MF.front();
71
198
  MachineBasicBlock::iterator I = MBB.begin();
72
198
  MachineRegisterInfo &RegInfo = MF.getRegInfo();
73
198
  const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
74
198
  DebugLoc DL;
75
198
  unsigned V0, V1, V2, GlobalBaseReg = MipsFI->getGlobalBaseReg();
76
198
  const TargetRegisterClass *RC = &Mips::CPU16RegsRegClass;
77
198
78
198
  V0 = RegInfo.createVirtualRegister(RC);
79
198
  V1 = RegInfo.createVirtualRegister(RC);
80
198
  V2 = RegInfo.createVirtualRegister(RC);
81
198
82
198
83
198
  BuildMI(MBB, I, DL, TII.get(Mips::LiRxImmX16), V0)
84
198
      .addExternalSymbol("_gp_disp", MipsII::MO_ABS_HI);
85
198
  BuildMI(MBB, I, DL, TII.get(Mips::AddiuRxPcImmX16), V1)
86
198
      .addExternalSymbol("_gp_disp", MipsII::MO_ABS_LO);
87
198
88
198
  BuildMI(MBB, I, DL, TII.get(Mips::SllX16), V2).addReg(V0).addImm(16);
89
198
  BuildMI(MBB, I, DL, TII.get(Mips::AdduRxRyRz16), GlobalBaseReg)
90
198
      .addReg(V1)
91
198
      .addReg(V2);
92
198
}
93
94
380
void Mips16DAGToDAGISel::processFunctionAfterISel(MachineFunction &MF) {
95
380
  initGlobalBaseReg(MF);
96
380
}
97
98
bool Mips16DAGToDAGISel::selectAddr(bool SPAllowed, SDValue Addr, SDValue &Base,
99
3.67k
                                    SDValue &Offset) {
100
3.67k
  SDLoc DL(Addr);
101
3.67k
  EVT ValTy = Addr.getValueType();
102
3.67k
103
3.67k
  // if Address is FI, get the TargetFrameIndex.
104
3.67k
  if (SPAllowed) {
105
3.63k
    if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
106
104
      Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
107
104
      Offset = CurDAG->getTargetConstant(0, DL, ValTy);
108
104
      return true;
109
104
    }
110
3.56k
  }
111
3.56k
  // on PIC code Load GA
112
3.56k
  if (Addr.getOpcode() == MipsISD::Wrapper) {
113
1.37k
    Base = Addr.getOperand(0);
114
1.37k
    Offset = Addr.getOperand(1);
115
1.37k
    return true;
116
1.37k
  }
117
2.19k
  if (!TM.isPositionIndependent()) {
118
1.26k
    if ((Addr.getOpcode() == ISD::TargetExternalSymbol ||
119
1.26k
         Addr.getOpcode() == ISD::TargetGlobalAddress))
120
0
      return false;
121
2.19k
  }
122
2.19k
  // Addresses of the form FI+const or FI|const
123
2.19k
  if (CurDAG->isBaseWithConstantOffset(Addr)) {
124
731
    ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1));
125
731
    if (isInt<16>(CN->getSExtValue())) {
126
731
      // If the first operand is a FI, get the TargetFI Node
127
731
      if (SPAllowed) {
128
727
        if (FrameIndexSDNode *FIN =
129
42
                dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) {
130
42
          Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
131
42
          Offset = CurDAG->getTargetConstant(CN->getZExtValue(), DL, ValTy);
132
42
          return true;
133
42
        }
134
689
      }
135
689
136
689
      Base = Addr.getOperand(0);
137
689
      Offset = CurDAG->getTargetConstant(CN->getZExtValue(), DL, ValTy);
138
689
      return true;
139
689
    }
140
731
  }
141
1.46k
  // Operand is a result from an ADD.
142
1.46k
  if (Addr.getOpcode() == ISD::ADD) {
143
714
    // When loading from constant pools, load the lower address part in
144
714
    // the instruction itself. Example, instead of:
145
714
    //  lui $2, %hi($CPI1_0)
146
714
    //  addiu $2, $2, %lo($CPI1_0)
147
714
    //  lwc1 $f0, 0($2)
148
714
    // Generate:
149
714
    //  lui $2, %hi($CPI1_0)
150
714
    //  lwc1 $f0, %lo($CPI1_0)($2)
151
714
    if (Addr.getOperand(1).getOpcode() == MipsISD::Lo ||
152
714
        
Addr.getOperand(1).getOpcode() == MipsISD::GPRel6
) {
153
708
      SDValue Opnd0 = Addr.getOperand(1).getOperand(0);
154
708
      if (isa<ConstantPoolSDNode>(Opnd0) || isa<GlobalAddressSDNode>(Opnd0) ||
155
708
          
isa<JumpTableSDNode>(Opnd0)1
) {
156
708
        Base = Addr.getOperand(0);
157
708
        Offset = Opnd0;
158
708
        return true;
159
708
      }
160
756
    }
161
714
  }
162
756
  Base = Addr;
163
756
  Offset = CurDAG->getTargetConstant(0, DL, ValTy);
164
756
  return true;
165
756
}
166
167
bool Mips16DAGToDAGISel::selectAddr16(SDValue Addr, SDValue &Base,
168
38
                                      SDValue &Offset) {
169
38
  return selectAddr(false, Addr, Base, Offset);
170
38
}
171
172
bool Mips16DAGToDAGISel::selectAddr16SP(SDValue Addr, SDValue &Base,
173
3.63k
                                        SDValue &Offset) {
174
3.63k
  return selectAddr(true, Addr, Base, Offset);
175
3.63k
}
176
177
/// Select instructions not customized! Used for
178
/// expanded, promoted and normal instructions
179
19.8k
bool Mips16DAGToDAGISel::trySelect(SDNode *Node) {
180
19.8k
  unsigned Opcode = Node->getOpcode();
181
19.8k
  SDLoc DL(Node);
182
19.8k
183
19.8k
  ///
184
19.8k
  // Instruction Selection not handled by the auto-generated
185
19.8k
  // tablegen selection should be handled here.
186
19.8k
  ///
187
19.8k
  EVT NodeTy = Node->getValueType(0);
188
19.8k
  unsigned MultOpc;
189
19.8k
190
19.8k
  switch (Opcode) {
191
19.8k
  default:
192
19.8k
    break;
193
19.8k
194
19.8k
  /// Mul with two results
195
19.8k
  case ISD::SMUL_LOHI:
196
8
  case ISD::UMUL_LOHI: {
197
8
    MultOpc = (Opcode == ISD::UMUL_LOHI ? 
Mips::MultuRxRy164
:
Mips::MultRxRy164
);
198
8
    std::pair<SDNode *, SDNode *> LoHi =
199
8
        selectMULT(Node, MultOpc, DL, NodeTy, true, true);
200
8
    if (!SDValue(Node, 0).use_empty())
201
8
      ReplaceUses(SDValue(Node, 0), SDValue(LoHi.first, 0));
202
8
203
8
    if (!SDValue(Node, 1).use_empty())
204
8
      ReplaceUses(SDValue(Node, 1), SDValue(LoHi.second, 0));
205
8
206
8
    CurDAG->RemoveDeadNode(Node);
207
8
    return true;
208
8
  }
209
8
210
8
  case ISD::MULHS:
211
0
  case ISD::MULHU: {
212
0
    MultOpc = (Opcode == ISD::MULHU ? Mips::MultuRxRy16 : Mips::MultRxRy16);
213
0
    auto LoHi = selectMULT(Node, MultOpc, DL, NodeTy, false, true);
214
0
    ReplaceNode(Node, LoHi.second);
215
0
    return true;
216
19.8k
  }
217
19.8k
  }
218
19.8k
219
19.8k
  return false;
220
19.8k
}
221
222
FunctionPass *llvm::createMips16ISelDag(MipsTargetMachine &TM,
223
2.03k
                                        CodeGenOpt::Level OptLevel) {
224
2.03k
  return new Mips16DAGToDAGISel(TM, OptLevel);
225
2.03k
}