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 static char ID;
32
33 XtensaDAGToDAGISel(XtensaTargetMachine &TM, CodeGenOptLevel OptLevel)
34 : SelectionDAGISel(ID, TM, OptLevel) {}
35
36 StringRef getPassName() const override {
37 return "Xtensa DAG->DAG Pattern Instruction Selection";
38 }
39
40 void Select(SDNode *Node) override;
41
42 // For load/store instructions generate (base+offset) pair from
43 // memory address. The offset must be a multiple of scale argument.
44 bool selectMemRegAddr(SDValue Addr, SDValue &Base, SDValue &Offset,
45 int Scale) {
46 EVT ValTy = Addr.getValueType();
47
48 // if Address is FI, get the TargetFrameIndex.
49 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
50 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
51 Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), ValTy);
52
53 return true;
54 }
55
56 if (TM.isPositionIndependent()) {
57 DiagnosticInfoUnsupported Diag(CurDAG->getMachineFunction().getFunction(),
58 "PIC relocations are not supported ",
59 Addr.getDebugLoc());
60 CurDAG->getContext()->diagnose(Diag);
61 }
62
63 if ((Addr.getOpcode() == ISD::TargetExternalSymbol ||
64 Addr.getOpcode() == ISD::TargetGlobalAddress))
65 return false;
66
67 // Addresses of the form FI+const
68 bool Valid = false;
69 if (CurDAG->isBaseWithConstantOffset(Addr)) {
70 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1));
71 int64_t OffsetVal = CN->getSExtValue();
72
73 Valid = isValidAddrOffset(Scale, OffsetVal);
74
75 if (Valid) {
76 // If the first operand is a FI, get the TargetFI Node
77 if (FrameIndexSDNode *FIN =
78 dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))
79 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
80 else
81 Base = Addr.getOperand(0);
82
83 Offset =
84 CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), ValTy);
85 return true;
86 }
87 }
88
89 // Last case
90 Base = Addr;
91 Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), Addr.getValueType());
92 return true;
93 }
94
95 bool selectMemRegAddrISH1(SDValue Addr, SDValue &Base, SDValue &Offset) {
96 return selectMemRegAddr(Addr, Base, Offset, 1);
97 }
98
99 bool selectMemRegAddrISH2(SDValue Addr, SDValue &Base, SDValue &Offset) {
100 return selectMemRegAddr(Addr, Base, Offset, 2);
101 }
102
103 bool selectMemRegAddrISH4(SDValue Addr, SDValue &Base, SDValue &Offset) {
104 return selectMemRegAddr(Addr, Base, Offset, 4);
105 }
106
107// Include the pieces autogenerated from the target description.
108#include "XtensaGenDAGISel.inc"
109}; // namespace
110} // end anonymous namespace
111
112char XtensaDAGToDAGISel::ID = 0;
113
115 CodeGenOptLevel OptLevel) {
116 return new XtensaDAGToDAGISel(TM, OptLevel);
117}
118
119void XtensaDAGToDAGISel::Select(SDNode *Node) {
120 SDLoc DL(Node);
121
122 // If we have a custom node, we already have selected!
123 if (Node->isMachineOpcode()) {
124 Node->setNodeId(-1);
125 return;
126 }
127
128 SelectCode(Node);
129}
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:169
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
Definition: ISDOpcodes.h:164
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:456
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