LLVM 19.0.0git
XtensaISelDAGToDAG.cpp
Go to the documentation of this file.
1//===- XtensaISelDAGToDAG.cpp - A dag to dag inst selector for Xtensa -----===//
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// This file defines an instruction selector for the Xtensa target.
10//
11//===----------------------------------------------------------------------===//
12
13#include "Xtensa.h"
14#include "XtensaTargetMachine.h"
15#include "XtensaUtils.h"
20#include "llvm/Support/Debug.h"
22
23using namespace llvm;
24
25#define DEBUG_TYPE "xtensa-isel"
26
27namespace {
28
29class XtensaDAGToDAGISel : public SelectionDAGISel {
30public:
31 XtensaDAGToDAGISel(XtensaTargetMachine &TM, CodeGenOptLevel OptLevel)
32 : SelectionDAGISel(TM, OptLevel) {}
33
34 void Select(SDNode *Node) override;
35
36 // For load/store instructions generate (base+offset) pair from
37 // memory address. The offset must be a multiple of scale argument.
38 bool selectMemRegAddr(SDValue Addr, SDValue &Base, SDValue &Offset,
39 int Scale) {
40 EVT ValTy = Addr.getValueType();
41
42 // if Address is FI, get the TargetFrameIndex.
43 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
44 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
45 Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), ValTy);
46
47 return true;
48 }
49
50 if (TM.isPositionIndependent()) {
51 DiagnosticInfoUnsupported Diag(CurDAG->getMachineFunction().getFunction(),
52 "PIC relocations are not supported ",
53 Addr.getDebugLoc());
54 CurDAG->getContext()->diagnose(Diag);
55 }
56
57 if ((Addr.getOpcode() == ISD::TargetExternalSymbol ||
58 Addr.getOpcode() == ISD::TargetGlobalAddress))
59 return false;
60
61 // Addresses of the form FI+const
62 bool Valid = false;
63 if (CurDAG->isBaseWithConstantOffset(Addr)) {
64 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1));
65 int64_t OffsetVal = CN->getSExtValue();
66
67 Valid = isValidAddrOffset(Scale, OffsetVal);
68
69 if (Valid) {
70 // If the first operand is a FI, get the TargetFI Node
71 if (FrameIndexSDNode *FIN =
72 dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))
73 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
74 else
75 Base = Addr.getOperand(0);
76
77 Offset =
78 CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), ValTy);
79 return true;
80 }
81 }
82
83 // Last case
84 Base = Addr;
85 Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), Addr.getValueType());
86 return true;
87 }
88
89 bool selectMemRegAddrISH1(SDValue Addr, SDValue &Base, SDValue &Offset) {
90 return selectMemRegAddr(Addr, Base, Offset, 1);
91 }
92
93 bool selectMemRegAddrISH2(SDValue Addr, SDValue &Base, SDValue &Offset) {
94 return selectMemRegAddr(Addr, Base, Offset, 2);
95 }
96
97 bool selectMemRegAddrISH4(SDValue Addr, SDValue &Base, SDValue &Offset) {
98 return selectMemRegAddr(Addr, Base, Offset, 4);
99 }
100
101// Include the pieces autogenerated from the target description.
102#include "XtensaGenDAGISel.inc"
103}; // namespace
104
105class XtensaDAGToDAGISelLegacy : public SelectionDAGISelLegacy {
106public:
107 static char ID;
108
109 XtensaDAGToDAGISelLegacy(XtensaTargetMachine &TM, CodeGenOptLevel OptLevel)
111 ID, std::make_unique<XtensaDAGToDAGISel>(TM, OptLevel)) {}
112
113 StringRef getPassName() const override {
114 return "Xtensa DAG->DAG Pattern Instruction Selection";
115 }
116};
117} // end anonymous namespace
118
119char XtensaDAGToDAGISelLegacy::ID = 0;
120
122 CodeGenOptLevel OptLevel) {
123 return new XtensaDAGToDAGISelLegacy(TM, OptLevel);
124}
125
126void XtensaDAGToDAGISel::Select(SDNode *Node) {
127 SDLoc DL(Node);
128
129 // If we have a custom node, we already have selected!
130 if (Node->isMachineOpcode()) {
131 Node->setNodeId(-1);
132 return;
133 }
134
135 SelectCode(Node);
136}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
amdgpu AMDGPU Register Bank Select
uint64_t Addr
const char LLVMTargetMachineRef TM
uint64_t getZExtValue() const
int64_t getSExtValue() const
Diagnostic information for unsupported feature in backend.
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:311
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Definition: Pass.cpp:81
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
@ TargetExternalSymbol
Definition: ISDOpcodes.h:175
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
Definition: ISDOpcodes.h:170
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
FunctionPass * createXtensaISelDag(XtensaTargetMachine &TM, CodeGenOptLevel OptLevel)
CodeGenOptLevel
Code generation optimization level.
Definition: CodeGen.h:54
bool isValidAddrOffset(int Scale, int64_t OffsetVal)
Definition: XtensaUtils.cpp:17
Extended Value Type.
Definition: ValueTypes.h:34