LLVM  8.0.1
ARCISelDAGToDAG.cpp
Go to the documentation of this file.
1 //===- ARCISelDAGToDAG.cpp - ARC dag to dag inst selector -------*- C++ -*-===//
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 // This file defines an instruction selector for the ARC target.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "ARC.h"
15 #include "ARCTargetMachine.h"
23 #include "llvm/IR/CallingConv.h"
24 #include "llvm/IR/Constants.h"
25 #include "llvm/IR/DerivedTypes.h"
26 #include "llvm/IR/Function.h"
27 #include "llvm/IR/Intrinsics.h"
28 #include "llvm/IR/LLVMContext.h"
29 #include "llvm/Support/Compiler.h"
30 #include "llvm/Support/Debug.h"
33 
34 using namespace llvm;
35 
36 /// ARCDAGToDAGISel - ARC specific code to select ARC machine
37 /// instructions for SelectionDAG operations.
38 namespace {
39 
40 class ARCDAGToDAGISel : public SelectionDAGISel {
41 public:
42  ARCDAGToDAGISel(ARCTargetMachine &TM, CodeGenOpt::Level OptLevel)
43  : SelectionDAGISel(TM, OptLevel) {}
44 
45  void Select(SDNode *N) override;
46 
47  // Complex Pattern Selectors.
48  bool SelectFrameADDR_ri(SDValue Addr, SDValue &Base, SDValue &Offset);
49  bool SelectAddrModeS9(SDValue Addr, SDValue &Base, SDValue &Offset);
50  bool SelectAddrModeImm(SDValue Addr, SDValue &Base, SDValue &Offset);
51  bool SelectAddrModeFar(SDValue Addr, SDValue &Base, SDValue &Offset);
52  bool SelectCMOVPred(SDValue N, SDValue &Pred, SDValue &Reg) {
53  const ConstantSDNode *CN = cast<ConstantSDNode>(N);
54  Pred = CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(N), MVT::i32);
55  Reg = CurDAG->getRegister(ARC::STATUS32, MVT::i32);
56  return true;
57  }
58 
59  StringRef getPassName() const override {
60  return "ARC DAG->DAG Pattern Instruction Selection";
61  }
62 
63 // Include the pieces autogenerated from the target description.
64 #include "ARCGenDAGISel.inc"
65 };
66 
67 } // end anonymous namespace
68 
69 /// This pass converts a legalized DAG into a ARC-specific DAG, ready for
70 /// instruction scheduling.
72  CodeGenOpt::Level OptLevel) {
73  return new ARCDAGToDAGISel(TM, OptLevel);
74 }
75 
76 bool ARCDAGToDAGISel::SelectAddrModeImm(SDValue Addr, SDValue &Base,
77  SDValue &Offset) {
78  if (Addr.getOpcode() == ARCISD::GAWRAPPER) {
79  Base = Addr.getOperand(0);
80  Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
81  return true;
82  }
83  return false;
84 }
85 
86 bool ARCDAGToDAGISel::SelectAddrModeS9(SDValue Addr, SDValue &Base,
87  SDValue &Offset) {
88  if (Addr.getOpcode() == ARCISD::GAWRAPPER) {
89  return false;
90  }
91 
92  if (Addr.getOpcode() != ISD::ADD && Addr.getOpcode() != ISD::SUB &&
93  !CurDAG->isBaseWithConstantOffset(Addr)) {
94  if (Addr.getOpcode() == ISD::FrameIndex) {
95  // Match frame index.
96  int FI = cast<FrameIndexSDNode>(Addr)->getIndex();
97  Base = CurDAG->getTargetFrameIndex(
98  FI, TLI->getPointerTy(CurDAG->getDataLayout()));
99  } else {
100  Base = Addr;
101  }
102  Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
103  return true;
104  }
105 
106  if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
107  int32_t RHSC = RHS->getSExtValue();
108  if (Addr.getOpcode() == ISD::SUB)
109  RHSC = -RHSC;
110 
111  // Do we need more than 9 bits to encode?
112  if (!isInt<9>(RHSC))
113  return false;
114  Base = Addr.getOperand(0);
115  if (Base.getOpcode() == ISD::FrameIndex) {
116  int FI = cast<FrameIndexSDNode>(Base)->getIndex();
117  Base = CurDAG->getTargetFrameIndex(
118  FI, TLI->getPointerTy(CurDAG->getDataLayout()));
119  }
120  Offset = CurDAG->getTargetConstant(RHSC, SDLoc(Addr), MVT::i32);
121  return true;
122  }
123  Base = Addr;
124  Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
125  return true;
126 }
127 
128 bool ARCDAGToDAGISel::SelectAddrModeFar(SDValue Addr, SDValue &Base,
129  SDValue &Offset) {
130  if (SelectAddrModeS9(Addr, Base, Offset))
131  return false;
132  if (Addr.getOpcode() == ARCISD::GAWRAPPER) {
133  return false;
134  }
135  if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
136  int32_t RHSC = RHS->getSExtValue();
137  if (Addr.getOpcode() == ISD::SUB)
138  RHSC = -RHSC;
139  Base = Addr.getOperand(0);
140  Offset = CurDAG->getTargetConstant(RHSC, SDLoc(Addr), MVT::i32);
141  return true;
142  }
143  return false;
144 }
145 
146 // Is this a legal frame index addressing expression.
147 bool ARCDAGToDAGISel::SelectFrameADDR_ri(SDValue Addr, SDValue &Base,
148  SDValue &Offset) {
149  FrameIndexSDNode *FIN = nullptr;
150  if ((FIN = dyn_cast<FrameIndexSDNode>(Addr))) {
151  Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
152  Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
153  return true;
154  }
155  if (Addr.getOpcode() == ISD::ADD) {
156  ConstantSDNode *CN = nullptr;
157  if ((FIN = dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) &&
158  (CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) &&
159  (CN->getSExtValue() % 4 == 0 && CN->getSExtValue() >= 0)) {
160  // Constant positive word offset from frame index
161  Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
162  Offset =
163  CurDAG->getTargetConstant(CN->getSExtValue(), SDLoc(Addr), MVT::i32);
164  return true;
165  }
166  }
167  return false;
168 }
169 
171  switch (N->getOpcode()) {
172  case ISD::Constant: {
173  uint64_t CVal = cast<ConstantSDNode>(N)->getZExtValue();
174  ReplaceNode(N, CurDAG->getMachineNode(
175  isInt<12>(CVal) ? ARC::MOV_rs12 : ARC::MOV_rlimm,
176  SDLoc(N), MVT::i32,
177  CurDAG->getTargetConstant(CVal, SDLoc(N), MVT::i32)));
178  return;
179  }
180  }
181  SelectCode(N);
182 }
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
This class represents lattice values for constants.
Definition: AllocatorList.h:24
unsigned Reg
FunctionPass * createARCISelDag(ARCTargetMachine &TM, CodeGenOpt::Level OptLevel)
This pass converts a legalized DAG into a ARC-specific DAG, ready for instruction scheduling...
int64_t getSExtValue() const
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:201
This file contains the declarations for the subclasses of Constant, which represent the different fla...
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:285
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
#define N
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:323
unsigned getOpcode() const
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
const SDValue & getOperand(unsigned i) const
uint64_t getZExtValue() const
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
This file describes how to lower LLVM code to machine code.