1 //==- llvm/CodeGen/SelectionDAGTargetInfo.h - SelectionDAG Info --*- 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 declares the SelectionDAGTargetInfo class, which targets can
11 // subclass to parameterize the SelectionDAG lowering and instruction
12 // selection process.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #ifndef LLVM_CODEGEN_SELECTIONDAGTARGETINFO_H
17 #define LLVM_CODEGEN_SELECTIONDAGTARGETINFO_H
18 
19 #include "llvm/CodeGen/MachineMemOperand.h"
20 #include "llvm/CodeGen/SelectionDAGNodes.h"
21 #include "llvm/Support/CodeGen.h"
22 #include <utility>
23 
24 namespace llvm {
25 
26 class SelectionDAG;
27 
28 //===----------------------------------------------------------------------===//
29 /// Targets can subclass this to parameterize the
30 /// SelectionDAG lowering and instruction selection process.
31 ///
32 class SelectionDAGTargetInfo {
33 public:
34   explicit SelectionDAGTargetInfo() = default;
35   SelectionDAGTargetInfo(const SelectionDAGTargetInfo &) = delete;
36   SelectionDAGTargetInfo &operator=(const SelectionDAGTargetInfo &) = delete;
37   virtual ~SelectionDAGTargetInfo();
38 
39   /// Emit target-specific code that performs a memcpy.
40   /// This can be used by targets to provide code sequences for cases
41   /// that don't fit the target's parameters for simple loads/stores and can be
42   /// more efficient than using a library call. This function can return a null
43   /// SDValue if the target declines to use custom code and a different
44   /// lowering strategy should be used.
45   ///
46   /// If AlwaysInline is true, the size is constant and the target should not
47   /// emit any calls and is strongly encouraged to attempt to emit inline code
48   /// even if it is beyond the usual threshold because this intrinsic is being
49   /// expanded in a place where calls are not feasible (e.g. within the prologue
50   /// for another call). If the target chooses to decline an AlwaysInline
51   /// request here, legalize will resort to using simple loads and stores.
EmitTargetCodeForMemcpy(SelectionDAG & DAG,const SDLoc & dl,SDValue Chain,SDValue Op1,SDValue Op2,SDValue Op3,unsigned Align,bool isVolatile,bool AlwaysInline,MachinePointerInfo DstPtrInfo,MachinePointerInfo SrcPtrInfo)52   virtual SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, const SDLoc &dl,
53                                           SDValue Chain, SDValue Op1,
54                                           SDValue Op2, SDValue Op3,
55                                           unsigned Align, bool isVolatile,
56                                           bool AlwaysInline,
57                                           MachinePointerInfo DstPtrInfo,
58                                           MachinePointerInfo SrcPtrInfo) const {
59     return SDValue();
60   }
61 
62   /// Emit target-specific code that performs a memmove.
63   /// This can be used by targets to provide code sequences for cases
64   /// that don't fit the target's parameters for simple loads/stores and can be
65   /// more efficient than using a library call. This function can return a null
66   /// SDValue if the target declines to use custom code and a different
67   /// lowering strategy should be used.
EmitTargetCodeForMemmove(SelectionDAG & DAG,const SDLoc & dl,SDValue Chain,SDValue Op1,SDValue Op2,SDValue Op3,unsigned Align,bool isVolatile,MachinePointerInfo DstPtrInfo,MachinePointerInfo SrcPtrInfo)68   virtual SDValue EmitTargetCodeForMemmove(
69       SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Op1,
70       SDValue Op2, SDValue Op3, unsigned Align, bool isVolatile,
71       MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const {
72     return SDValue();
73   }
74 
75   /// Emit target-specific code that performs a memset.
76   /// This can be used by targets to provide code sequences for cases
77   /// that don't fit the target's parameters for simple stores and can be more
78   /// efficient than using a library call. This function can return a null
79   /// SDValue if the target declines to use custom code and a different
80   /// lowering strategy should be used.
EmitTargetCodeForMemset(SelectionDAG & DAG,const SDLoc & dl,SDValue Chain,SDValue Op1,SDValue Op2,SDValue Op3,unsigned Align,bool isVolatile,MachinePointerInfo DstPtrInfo)81   virtual SDValue EmitTargetCodeForMemset(SelectionDAG &DAG, const SDLoc &dl,
82                                           SDValue Chain, SDValue Op1,
83                                           SDValue Op2, SDValue Op3,
84                                           unsigned Align, bool isVolatile,
85                                           MachinePointerInfo DstPtrInfo) const {
86     return SDValue();
87   }
88 
89   /// Emit target-specific code that performs a memcmp, in cases where that is
90   /// faster than a libcall. The first returned SDValue is the result of the
91   /// memcmp and the second is the chain. Both SDValues can be null if a normal
92   /// libcall should be used.
93   virtual std::pair<SDValue, SDValue>
EmitTargetCodeForMemcmp(SelectionDAG & DAG,const SDLoc & dl,SDValue Chain,SDValue Op1,SDValue Op2,SDValue Op3,MachinePointerInfo Op1PtrInfo,MachinePointerInfo Op2PtrInfo)94   EmitTargetCodeForMemcmp(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain,
95                           SDValue Op1, SDValue Op2, SDValue Op3,
96                           MachinePointerInfo Op1PtrInfo,
97                           MachinePointerInfo Op2PtrInfo) const {
98     return std::make_pair(SDValue(), SDValue());
99   }
100 
101   /// Emit target-specific code that performs a memchr, in cases where that is
102   /// faster than a libcall. The first returned SDValue is the result of the
103   /// memchr and the second is the chain. Both SDValues can be null if a normal
104   /// libcall should be used.
105   virtual std::pair<SDValue, SDValue>
EmitTargetCodeForMemchr(SelectionDAG & DAG,const SDLoc & dl,SDValue Chain,SDValue Src,SDValue Char,SDValue Length,MachinePointerInfo SrcPtrInfo)106   EmitTargetCodeForMemchr(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain,
107                           SDValue Src, SDValue Char, SDValue Length,
108                           MachinePointerInfo SrcPtrInfo) const {
109     return std::make_pair(SDValue(), SDValue());
110   }
111 
112   /// Emit target-specific code that performs a strcpy or stpcpy, in cases
113   /// where that is faster than a libcall.
114   /// The first returned SDValue is the result of the copy (the start
115   /// of the destination string for strcpy, a pointer to the null terminator
116   /// for stpcpy) and the second is the chain.  Both SDValues can be null
117   /// if a normal libcall should be used.
118   virtual std::pair<SDValue, SDValue>
EmitTargetCodeForStrcpy(SelectionDAG & DAG,const SDLoc & DL,SDValue Chain,SDValue Dest,SDValue Src,MachinePointerInfo DestPtrInfo,MachinePointerInfo SrcPtrInfo,bool isStpcpy)119   EmitTargetCodeForStrcpy(SelectionDAG &DAG, const SDLoc &DL, SDValue Chain,
120                           SDValue Dest, SDValue Src,
121                           MachinePointerInfo DestPtrInfo,
122                           MachinePointerInfo SrcPtrInfo, bool isStpcpy) const {
123     return std::make_pair(SDValue(), SDValue());
124   }
125 
126   /// Emit target-specific code that performs a strcmp, in cases where that is
127   /// faster than a libcall.
128   /// The first returned SDValue is the result of the strcmp and the second is
129   /// the chain. Both SDValues can be null if a normal libcall should be used.
130   virtual std::pair<SDValue, SDValue>
EmitTargetCodeForStrcmp(SelectionDAG & DAG,const SDLoc & dl,SDValue Chain,SDValue Op1,SDValue Op2,MachinePointerInfo Op1PtrInfo,MachinePointerInfo Op2PtrInfo)131   EmitTargetCodeForStrcmp(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain,
132                           SDValue Op1, SDValue Op2,
133                           MachinePointerInfo Op1PtrInfo,
134                           MachinePointerInfo Op2PtrInfo) const {
135     return std::make_pair(SDValue(), SDValue());
136   }
137 
138   virtual std::pair<SDValue, SDValue>
EmitTargetCodeForStrlen(SelectionDAG & DAG,const SDLoc & DL,SDValue Chain,SDValue Src,MachinePointerInfo SrcPtrInfo)139   EmitTargetCodeForStrlen(SelectionDAG &DAG, const SDLoc &DL, SDValue Chain,
140                           SDValue Src, MachinePointerInfo SrcPtrInfo) const {
141     return std::make_pair(SDValue(), SDValue());
142   }
143 
144   virtual std::pair<SDValue, SDValue>
EmitTargetCodeForStrnlen(SelectionDAG & DAG,const SDLoc & DL,SDValue Chain,SDValue Src,SDValue MaxLength,MachinePointerInfo SrcPtrInfo)145   EmitTargetCodeForStrnlen(SelectionDAG &DAG, const SDLoc &DL, SDValue Chain,
146                            SDValue Src, SDValue MaxLength,
147                            MachinePointerInfo SrcPtrInfo) const {
148     return std::make_pair(SDValue(), SDValue());
149   }
150 
151   // Return true when the decision to generate FMA's (or FMS, FMLA etc) rather
152   // than FMUL and ADD is delegated to the machine combiner.
generateFMAsInMachineCombiner(CodeGenOpt::Level OptLevel)153   virtual bool generateFMAsInMachineCombiner(CodeGenOpt::Level OptLevel) const {
154     return false;
155   }
156 };
157 
158 } // end namespace llvm
159 
160 #endif // LLVM_CODEGEN_SELECTIONDAGTARGETINFO_H
161