OpenASIP 2.2
Loading...
Searching...
No Matches
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
55using namespace llvm;
56
57class TCEDAGToDAGISel : public llvm::SelectionDAGISel {
58public:
59 #ifndef LLVM_OLDER_THAN_16
60 static char ID;
61 #endif
62
64 virtual ~TCEDAGToDAGISel();
65
66 bool SelectADDRrr(SDValue N, SDValue &R1, SDValue &R2);
67 bool SelectADDRri(SDValue N, SDValue &Base, SDValue &Offset);
68
69 void Select(llvm::SDNode* op) override;
70
71 virtual StringRef getPassName() const override {
72 return "TCE DAG->DAG Pattern Instruction Selection";
73 }
74
75private:
76
77 static bool isBroadcast(SDNode *n);
78 static bool isConstantBuild(SDNode* n);
79 static bool isConstantFPBuild(SDNode* n);
81 // returns size of cancat
82
83 EVT getIntegerVectorVT(EVT vt);
84
85 MachineSDNode* createPackNode(SDNode*n, const EVT& vt, int laneCount, SDValue* vals);
86
90
91 #include "TCEGenDAGISel.inc"
92};
93
94#ifndef LLVM_OLDER_THAN_16
95char TCEDAGToDAGISel::ID = 0;
96#endif
97
98/**
99 * Constructor.
100 */
102 #ifdef LLVM_OLDER_THAN_16
103 SelectionDAGISel(tm),
104 #else
105 SelectionDAGISel(ID, tm),
106 #endif
107 lowering_(*static_cast<TCETargetLowering*>(tm.getTargetLowering())),
108 subtarget_(*tm.getSubtargetImpl()), tm_(&tm) {
109}
110
111/**
112 * Destructor.
113 */
116
117// in LLVM 3.9 select() returns void
118#define SELECT_NODE_AND_RETURN(args...) \
119 CurDAG->SelectNodeTo(args); \
120 return
121#define RETURN_SELECTED_NODE(node) \
122 (void)(node); \
123 return
124
125
126/**
127 * Handles custom instruction selections.
128 *
129 * @param op Operation to select.
130 */
131void
133 // Custom nodes are already selected
134 if (n->isMachineOpcode()) {
135 n->setNodeId(-1);
136 return;
137 }
138
139 SDLoc dl(n);
140 if (n->getOpcode() >= ISD::BUILTIN_OP_END &&
141 n->getOpcode() < TCEISD::FIRST_NUMBER) {
142 // Already selected.
143 return;
144 } else if (n->getOpcode() == ISD::BR) {
145 SDValue chain = n->getOperand(0);
146
147 MachineBasicBlock* dest =
148 cast<BasicBlockSDNode>(n->getOperand(1))->getBasicBlock();
150 n, TCE::TCEBR, MVT::Other, CurDAG->getBasicBlock(dest), chain);
151 } else if (n->getOpcode() == ISD::FrameIndex) {
152 int fi = cast<FrameIndexSDNode>(n)->getIndex();
153
154 if (n->hasOneUse()) {
157 CurDAG->getTargetFrameIndex(fi, DEFAULT_TYPE));
158 } else {
159 auto fiN = CurDAG->getMachineNode(
161 CurDAG->getTargetFrameIndex(fi, DEFAULT_TYPE));
162 ReplaceNode(n, fiN);
163 return;
164 }
165 } else if (n->getOpcode() == ISD::VSELECT ||
166 (n->getOpcode() == ISD::SELECT &&
167 !n->getOperand(1).getValueType().isVector())) {
168 SDNode* node2 = dyn_cast<SDNode>(n->getOperand(0));
169 if (node2->getOpcode() == ISD::SETCC) {
170 SDValue val1 = n->getOperand(1);
171 SDValue val2 = n->getOperand(2);
172
173 SDValue n2val1 = node2->getOperand(0);
174 SDValue n2val2 = node2->getOperand(1);
175
176 if (val1 == n2val1 && val2 == n2val2 && node2->hasOneUse()) {
177 int opc;
178 ISD::CondCode cc = cast<CondCodeSDNode>(
179 node2->getOperand(2))->get();
180
181 switch (cc) {
182 case ISD::SETLT:
183 case ISD::SETLE:
184 case ISD::SETOLT:
185 case ISD::SETOLE:
186 opc = tm_->getMinOpcode(n);
187 if (opc != -1) {
189 n,opc, n->getSimpleValueType(0), val1, val2);
190 }
191 break;
192 case ISD::SETGT:
193 case ISD::SETGE:
194 case ISD::SETOGT:
195 case ISD::SETOGE: // todo: what is ordered here? nan handling?
196 opc = tm_->getMaxOpcode(n);
197 if (opc != -1) {
199 n, opc, n->getSimpleValueType(0), val1, val2);
200 }
201 break;
202 case ISD::SETULT:
203 case ISD::SETULE:
204 opc = tm_->getMinuOpcode(n);
205 if (opc != -1) {
207 n, opc, n->getSimpleValueType(0), val1, val2);
208 }
209 break;
210 case ISD::SETUGT:
211 case ISD::SETUGE:
212 opc = tm_->getMaxuOpcode(n);
213 if (opc != -1) {
215 n, opc, n->getSimpleValueType(0), val1, val2);
216 }
217 break;
218 default:
219 break;
220 }
221 }
222 }
223 } else if (n->getOpcode() == ISD::SHL ||
224 n->getOpcode() == ISD::SRA ||
225 n->getOpcode() == ISD::SRL) {
226 SDValue shifted = n->getOperand(0);
227 SDValue shifter = n->getOperand(1);
228 EVT shiftedVt = shifted.getValueType();
229 EVT shifterVt = shifter.getValueType();
230
231 } else if (n->getOpcode() == ISD::AND ||
232 n->getOpcode() == ISD::OR ||
233 n->getOpcode() == ISD::XOR) {
234 SDValue lhs = n->getOperand(0);
235 SDValue rhs = n->getOperand(1);
236 EVT lhsVt = lhs.getValueType();
237 EVT rhsVt = rhs.getValueType();
238 }
239
240 SelectCode(n);
241}
242#undef SELECT_NODE_AND_RETURN
243#undef RETURN_SELECTED_NODE
244
245/**
246 * Handles ADDRri operands.
247 */
248bool
250 SDValue addr, SDValue& base, SDValue& offset) {
251
252 if (FrameIndexSDNode* fin = dyn_cast<FrameIndexSDNode>(addr)) {
253 base = CurDAG->getTargetFrameIndex(fin->getIndex(), DEFAULT_TYPE);
254 offset = CurDAG->getTargetConstant(0, SDLoc(), DEFAULT_TYPE);
255 return true;
256 } else if (addr.getOpcode() == ISD::TargetExternalSymbol ||
257 addr.getOpcode() == ISD::TargetGlobalAddress) {
258
259 return false; // direct calls.
260 }
261 base = addr;
262 offset = CurDAG->getTargetConstant(0, SDLoc(), DEFAULT_TYPE);
263 return true;
264}
265
266/**
267 * Handles ADDRrr operands.
268 */
269bool
271 SDValue addr, SDValue& r1, SDValue& r2) {
272
273 if (addr.getOpcode() == ISD::TargetGlobalAddress) {
274 //r1 = addr.getOperand(0);
275 //r2 = CurDAG->getTargetConstant(cn->getValue(), MVT::i32);
276 //return true:
277 return false;
278 } else if (addr.getOpcode() == ISD::TargetExternalSymbol) {
279 return false;
280 } else if (addr.getOpcode() == ISD::FrameIndex) {
281 return false;
282 }
283
284 r1 = addr;
285
286 r2 = CurDAG->getTargetConstant(0, SDLoc(), DEFAULT_TYPE);
287 return true;
288}
289
290/**
291 * Returns an instance of the instruction selector.
292 *
293 * @param tm Target machine description.
294 */
295FunctionPass*
299
300bool
304
305bool
307 int operandCount = n->getNumOperands();
308 for (unsigned i = 1; i <operandCount; i++) {
309 SDValue val2 = n->getOperand(i);
310 SDNode *n2 = val2.getNode();
311 if (n2->getOpcode() != ISD::Constant ) {
312 return false;
313 }
314 }
315 return true;
316}
317
318bool
320 int operandCount = n->getNumOperands();
321 for (unsigned i = 1; i <operandCount; i++) {
322 SDValue val2 = n->getOperand(i);
323 SDNode *n2 = val2.getNode();
324 if (n2->getOpcode() != ISD::ConstantFP) {
325 return false;
326 }
327 }
328 return true;
329}
#define MOVE_IMM
#define DEFAULT_TYPE
#define SELECT_NODE_AND_RETURN(args...)
virtual StringRef getPassName() const override
TCEDAGToDAGISel(llvm::TCETargetMachine &tm)
llvm::TCETargetLowering & lowering_
static bool isConstantFPBuild(SDNode *n)
EVT getIntegerVectorVT(EVT vt)
bool SelectADDRrr(SDValue N, SDValue &R1, SDValue &R2)
static bool isConstantBuild(SDNode *n)
void Select(llvm::SDNode *op) override
const llvm::TCESubtarget & subtarget_
MachineSDNode * createPackNode(SDNode *n, const EVT &vt, int laneCount, SDValue *vals)
llvm::TCETargetMachine * tm_
bool SelectADDRri(SDValue N, SDValue &Base, SDValue &Offset)
virtual ~TCEDAGToDAGISel()
static bool isBroadcast(SDNode *n)
void SelectOptimizedBuildVector(SDNode *n)
static bool isBroadcast(SDNode *n)
int getMaxOpcode(llvm::SDNode *n)
int getMinuOpcode(llvm::SDNode *n)
int getMinOpcode(llvm::SDNode *n)
int getMaxuOpcode(llvm::SDNode *n)
FunctionPass * createTCEISelDag(TCETargetMachine &tm)