OpenASIP  2.0
TCEDAGToDAGISel.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2009 Tampere University.
3 
4  This file is part of TTA-Based Codesign Environment (TCE).
5 
6  Permission is hereby granted, free of charge, to any person obtaining a
7  copy of this software and associated documentation files (the "Software"),
8  to deal in the Software without restriction, including without limitation
9  the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  and/or sell copies of the Software, and to permit persons to whom the
11  Software is furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in
14  all copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  DEALINGS IN THE SOFTWARE.
23  */
24 /**
25  * @file TCEDAGToDAGISel.cpp
26  *
27  * TCE DAG to DAG instruction selector implementation.
28  *
29  * @author Veli-Pekka J��skel�inen 2007 (vjaaskel-no.spam-cs.tut.fi)
30  * @author Mikael Lepist� 2009 (mikael.lepisto-no.spam-tut.fi)
31  * @author Heikki Kultala 2012 (heikki.kultala-no.spam-tut.fi)
32  */
33 
34 #include "tce_config.h"
35 #include <llvm/IR/Intrinsics.h>
36 #include <llvm/Support/Debug.h>
37 #include <llvm/Support/Compiler.h>
38 #include <llvm/Support/raw_ostream.h>
39 
40 #include "TCEDAGToDAGISel.hh"
41 #include "TCETargetMachine.hh"
42 #include "TCESubtarget.hh"
43 #include "TCEISelLowering.hh"
44 #include "Conversion.hh"
45 #include "MathTools.hh"
46 
47 #ifdef TARGET64BIT
48 #define DEFAULT_TYPE MVT::i64
49 #define MOVE_IMM TCE::MOVI64sa
50 #else
51 #define DEFAULT_TYPE MVT::i32
52 #define MOVE_IMM TCE::MOVI32ri
53 #endif
54 
55 using namespace llvm;
56 
57 class TCEDAGToDAGISel : public llvm::SelectionDAGISel {
58 public:
60  virtual ~TCEDAGToDAGISel();
61 
62  bool SelectADDRrr(SDValue N, SDValue &R1, SDValue &R2);
63  bool SelectADDRri(SDValue N, SDValue &Base, SDValue &Offset);
64 
65  void Select(llvm::SDNode* op) override;
66 
67  virtual StringRef getPassName() const override {
68  return "TCE DAG->DAG Pattern Instruction Selection";
69  }
70 
71 private:
72 
73  static bool isBroadcast(SDNode *n);
74  static bool isConstantBuild(SDNode* n);
75  static bool isConstantFPBuild(SDNode* n);
76  void SelectOptimizedBuildVector(SDNode* n);
77  // returns size of cancat
78 
79  EVT getIntegerVectorVT(EVT vt);
80 
81  MachineSDNode* createPackNode(SDNode*n, const EVT& vt, int laneCount, SDValue* vals);
82 
86 
87  #include "TCEGenDAGISel.inc"
88 };
89 
90 /**
91  * Constructor.
92  */
94  SelectionDAGISel(tm),
95  lowering_(*static_cast<TCETargetLowering*>(tm.getTargetLowering())),
96  subtarget_(*tm.getSubtargetImpl()), tm_(&tm) {
97 }
98 
99 /**
100  * Destructor.
101  */
103 }
104 
105 // in LLVM 3.9 select() returns void
106 #define SELECT_NODE_AND_RETURN(args...) \
107  CurDAG->SelectNodeTo(args); \
108  return
109 #define RETURN_SELECTED_NODE(node) \
110  (void)(node); \
111  return
112 
113 
114 /**
115  * Handles custom instruction selections.
116  *
117  * @param op Operation to select.
118  */
119 void
121  // Custom nodes are already selected
122  if (n->isMachineOpcode()) {
123  n->setNodeId(-1);
124  return;
125  }
126 
127  SDLoc dl(n);
128  if (n->getOpcode() >= ISD::BUILTIN_OP_END &&
129  n->getOpcode() < TCEISD::FIRST_NUMBER) {
130  // Already selected.
131  return;
132  } else if (n->getOpcode() == ISD::BR) {
133  SDValue chain = n->getOperand(0);
134 
135  MachineBasicBlock* dest =
136  cast<BasicBlockSDNode>(n->getOperand(1))->getBasicBlock();
138  n, TCE::TCEBR, MVT::Other, CurDAG->getBasicBlock(dest), chain);
139  } else if (n->getOpcode() == ISD::FrameIndex) {
140  int fi = cast<FrameIndexSDNode>(n)->getIndex();
141 
142  if (n->hasOneUse()) {
145  CurDAG->getTargetFrameIndex(fi, DEFAULT_TYPE));
146  } else {
147  auto fiN = CurDAG->getMachineNode(
148  MOVE_IMM, dl, DEFAULT_TYPE,
149  CurDAG->getTargetFrameIndex(fi, DEFAULT_TYPE));
150  ReplaceNode(n, fiN);
151  return;
152  }
153  } else if (n->getOpcode() == ISD::VSELECT ||
154  (n->getOpcode() == ISD::SELECT &&
155  !n->getOperand(1).getValueType().isVector())) {
156  SDNode* node2 = dyn_cast<SDNode>(n->getOperand(0));
157  if (node2->getOpcode() == ISD::SETCC) {
158  SDValue val1 = n->getOperand(1);
159  SDValue val2 = n->getOperand(2);
160 
161  SDValue n2val1 = node2->getOperand(0);
162  SDValue n2val2 = node2->getOperand(1);
163 
164  if (val1 == n2val1 && val2 == n2val2 && node2->hasOneUse()) {
165  int opc;
166  ISD::CondCode cc = cast<CondCodeSDNode>(
167  node2->getOperand(2))->get();
168 
169  switch (cc) {
170  case ISD::SETLT:
171  case ISD::SETLE:
172  case ISD::SETOLT:
173  case ISD::SETOLE:
174  opc = tm_->getMinOpcode(n);
175  if (opc != -1) {
177  n,opc, n->getSimpleValueType(0), val1, val2);
178  }
179  break;
180  case ISD::SETGT:
181  case ISD::SETGE:
182  case ISD::SETOGT:
183  case ISD::SETOGE: // todo: what is ordered here? nan handling?
184  opc = tm_->getMaxOpcode(n);
185  if (opc != -1) {
187  n, opc, n->getSimpleValueType(0), val1, val2);
188  }
189  break;
190  case ISD::SETULT:
191  case ISD::SETULE:
192  opc = tm_->getMinuOpcode(n);
193  if (opc != -1) {
195  n, opc, n->getSimpleValueType(0), val1, val2);
196  }
197  break;
198  case ISD::SETUGT:
199  case ISD::SETUGE:
200  opc = tm_->getMaxuOpcode(n);
201  if (opc != -1) {
203  n, opc, n->getSimpleValueType(0), val1, val2);
204  }
205  break;
206  default:
207  break;
208  }
209  }
210  }
211  } else if (n->getOpcode() == ISD::SHL ||
212  n->getOpcode() == ISD::SRA ||
213  n->getOpcode() == ISD::SRL) {
214  SDValue shifted = n->getOperand(0);
215  SDValue shifter = n->getOperand(1);
216  EVT shiftedVt = shifted.getValueType();
217  EVT shifterVt = shifter.getValueType();
218 
219  } else if (n->getOpcode() == ISD::AND ||
220  n->getOpcode() == ISD::OR ||
221  n->getOpcode() == ISD::XOR) {
222  SDValue lhs = n->getOperand(0);
223  SDValue rhs = n->getOperand(1);
224  EVT lhsVt = lhs.getValueType();
225  EVT rhsVt = rhs.getValueType();
226  }
227 
228  SelectCode(n);
229 }
230 #undef SELECT_NODE_AND_RETURN
231 #undef RETURN_SELECTED_NODE
232 
233 /**
234  * Handles ADDRri operands.
235  */
236 bool
238  SDValue addr, SDValue& base, SDValue& offset) {
239 
240  if (FrameIndexSDNode* fin = dyn_cast<FrameIndexSDNode>(addr)) {
241  base = CurDAG->getTargetFrameIndex(fin->getIndex(), DEFAULT_TYPE);
242  offset = CurDAG->getTargetConstant(0, SDLoc(), DEFAULT_TYPE);
243  return true;
244  } else if (addr.getOpcode() == ISD::TargetExternalSymbol ||
245  addr.getOpcode() == ISD::TargetGlobalAddress) {
246 
247  return false; // direct calls.
248  }
249  base = addr;
250  offset = CurDAG->getTargetConstant(0, SDLoc(), DEFAULT_TYPE);
251  return true;
252 }
253 
254 /**
255  * Handles ADDRrr operands.
256  */
257 bool
259  SDValue addr, SDValue& r1, SDValue& r2) {
260 
261  if (addr.getOpcode() == ISD::TargetGlobalAddress) {
262  //r1 = addr.getOperand(0);
263  //r2 = CurDAG->getTargetConstant(cn->getValue(), MVT::i32);
264  //return true:
265  return false;
266  } else if (addr.getOpcode() == ISD::TargetExternalSymbol) {
267  return false;
268  } else if (addr.getOpcode() == ISD::FrameIndex) {
269  return false;
270  }
271 
272  r1 = addr;
273 
274  r2 = CurDAG->getTargetConstant(0, SDLoc(), DEFAULT_TYPE);
275  return true;
276 }
277 
278 /**
279  * Returns an instance of the instruction selector.
280  *
281  * @param tm Target machine description.
282  */
283 FunctionPass*
285  return new TCEDAGToDAGISel(tm);
286 }
287 
288 bool
290  return TCETargetLowering::isBroadcast(n);
291 }
292 
293 bool
295  int operandCount = n->getNumOperands();
296  for (unsigned i = 1; i <operandCount; i++) {
297  SDValue val2 = n->getOperand(i);
298  SDNode *n2 = val2.getNode();
299  if (n2->getOpcode() != ISD::Constant ) {
300  return false;
301  }
302  }
303  return true;
304 }
305 
306 bool
308  int operandCount = n->getNumOperands();
309  for (unsigned i = 1; i <operandCount; i++) {
310  SDValue val2 = n->getOperand(i);
311  SDNode *n2 = val2.getNode();
312  if (n2->getOpcode() != ISD::ConstantFP) {
313  return false;
314  }
315  }
316  return true;
317 }
llvm::TCETargetMachine::getMinuOpcode
int getMinuOpcode(llvm::SDNode *n)
Definition: TCETargetMachine.hh:249
llvm
Definition: InlineAsmParser.hh:49
llvm::TCETargetMachine::getMaxOpcode
int getMaxOpcode(llvm::SDNode *n)
Definition: TCETargetMachine.hh:253
TCEISD::FIRST_NUMBER
@ FIRST_NUMBER
Definition: TCEISelLowering.hh:46
TCEDAGToDAGISel::Select
void Select(llvm::SDNode *op) override
Definition: TCEDAGToDAGISel.cc:120
llvm::TCESubtarget
Definition: TCESubtarget.hh:56
TCEDAGToDAGISel::isConstantFPBuild
static bool isConstantFPBuild(SDNode *n)
Definition: TCEDAGToDAGISel.cc:307
llvm::TCETargetMachine::getMaxuOpcode
int getMaxuOpcode(llvm::SDNode *n)
Definition: TCETargetMachine.hh:257
TCEDAGToDAGISel
Definition: TCEDAGToDAGISel.cc:57
TCEDAGToDAGISel::tm_
llvm::TCETargetMachine * tm_
Definition: TCEDAGToDAGISel.cc:85
TCEDAGToDAGISel::SelectADDRrr
bool SelectADDRrr(SDValue N, SDValue &R1, SDValue &R2)
Definition: TCEDAGToDAGISel.cc:258
TCEDAGToDAGISel::isBroadcast
static bool isBroadcast(SDNode *n)
Definition: TCEDAGToDAGISel.cc:289
Conversion.hh
TCETargetMachine.hh
llvm::createTCEISelDag
FunctionPass * createTCEISelDag(TCETargetMachine &tm)
Definition: TCEDAGToDAGISel.cc:284
TCEDAGToDAGISel::TCEDAGToDAGISel
TCEDAGToDAGISel(llvm::TCETargetMachine &tm)
Definition: TCEDAGToDAGISel.cc:93
TCEDAGToDAGISel.hh
llvm::TCETargetLowering
Definition: TCEISelLowering.hh:83
TCEISelLowering.hh
TCEDAGToDAGISel::~TCEDAGToDAGISel
virtual ~TCEDAGToDAGISel()
Definition: TCEDAGToDAGISel.cc:102
llvm::TCETargetMachine
Definition: TCETargetMachine.hh:106
TCEDAGToDAGISel::subtarget_
const llvm::TCESubtarget & subtarget_
Definition: TCEDAGToDAGISel.cc:84
DEFAULT_TYPE
#define DEFAULT_TYPE
Definition: TCEDAGToDAGISel.cc:51
MathTools.hh
TCEDAGToDAGISel::getPassName
virtual StringRef getPassName() const override
Definition: TCEDAGToDAGISel.cc:67
SELECT_NODE_AND_RETURN
#define SELECT_NODE_AND_RETURN(args...)
Definition: TCEDAGToDAGISel.cc:106
TCEDAGToDAGISel::isConstantBuild
static bool isConstantBuild(SDNode *n)
Definition: TCEDAGToDAGISel.cc:294
llvm::TCETargetMachine::getMinOpcode
int getMinOpcode(llvm::SDNode *n)
Definition: TCETargetMachine.hh:245
TCEDAGToDAGISel::lowering_
llvm::TCETargetLowering & lowering_
Definition: TCEDAGToDAGISel.cc:83
TCESubtarget.hh
TCEDAGToDAGISel::SelectADDRri
bool SelectADDRri(SDValue N, SDValue &Base, SDValue &Offset)
Definition: TCEDAGToDAGISel.cc:237
MOVE_IMM
#define MOVE_IMM
Definition: TCEDAGToDAGISel.cc:52