@@ -15,6 +15,12 @@ using namespace llvm;
15
15
16
16
#define DEBUG_TYPE " aarch64-selectiondag-info"
17
17
18
+ static cl::opt<bool >
19
+ LowerToSMERoutines (" aarch64-lower-to-sme-routines" , cl::Hidden,
20
+ cl::desc (" Enable AArch64 SME memory operations "
21
+ " to lower to librt functions" ),
22
+ cl::init(true ));
23
+
18
24
SDValue AArch64SelectionDAGInfo::EmitMOPS (AArch64ISD::NodeType SDOpcode,
19
25
SelectionDAG &DAG, const SDLoc &DL,
20
26
SDValue Chain, SDValue Dst,
@@ -76,15 +82,79 @@ SDValue AArch64SelectionDAGInfo::EmitMOPS(AArch64ISD::NodeType SDOpcode,
76
82
}
77
83
}
78
84
85
+ SDValue AArch64SelectionDAGInfo::EmitStreamingCompatibleMemLibCall (
86
+ SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Dst, SDValue Src,
87
+ SDValue Size, RTLIB::Libcall LC) const {
88
+ const AArch64Subtarget &STI =
89
+ DAG.getMachineFunction ().getSubtarget <AArch64Subtarget>();
90
+ const AArch64TargetLowering *TLI = STI.getTargetLowering ();
91
+ SDValue Symbol;
92
+ TargetLowering::ArgListEntry DstEntry;
93
+ DstEntry.Ty = PointerType::getUnqual (*DAG.getContext ());
94
+ DstEntry.Node = Dst;
95
+ TargetLowering::ArgListTy Args;
96
+ Args.push_back (DstEntry);
97
+ EVT PointerVT = TLI->getPointerTy (DAG.getDataLayout ());
98
+
99
+ switch (LC) {
100
+ case RTLIB::MEMCPY: {
101
+ TargetLowering::ArgListEntry Entry;
102
+ Entry.Ty = PointerType::getUnqual (*DAG.getContext ());
103
+ Symbol = DAG.getExternalSymbol (" __arm_sc_memcpy" , PointerVT);
104
+ Entry.Node = Src;
105
+ Args.push_back (Entry);
106
+ break ;
107
+ }
108
+ case RTLIB::MEMMOVE: {
109
+ TargetLowering::ArgListEntry Entry;
110
+ Entry.Ty = PointerType::getUnqual (*DAG.getContext ());
111
+ Symbol = DAG.getExternalSymbol (" __arm_sc_memmove" , PointerVT);
112
+ Entry.Node = Src;
113
+ Args.push_back (Entry);
114
+ break ;
115
+ }
116
+ case RTLIB::MEMSET: {
117
+ TargetLowering::ArgListEntry Entry;
118
+ Entry.Ty = Type::getInt32Ty (*DAG.getContext ());
119
+ Symbol = DAG.getExternalSymbol (" __arm_sc_memset" , PointerVT);
120
+ Src = DAG.getZExtOrTrunc (Src, DL, MVT::i32 );
121
+ Entry.Node = Src;
122
+ Args.push_back (Entry);
123
+ break ;
124
+ }
125
+ default :
126
+ return SDValue ();
127
+ }
128
+
129
+ TargetLowering::ArgListEntry SizeEntry;
130
+ SizeEntry.Node = Size;
131
+ SizeEntry.Ty = DAG.getDataLayout ().getIntPtrType (*DAG.getContext ());
132
+ Args.push_back (SizeEntry);
133
+ assert (Symbol->getOpcode () == ISD::ExternalSymbol &&
134
+ " Function name is not set" );
135
+
136
+ TargetLowering::CallLoweringInfo CLI (DAG);
137
+ PointerType *RetTy = PointerType::getUnqual (*DAG.getContext ());
138
+ CLI.setDebugLoc (DL).setChain (Chain).setLibCallee (
139
+ TLI->getLibcallCallingConv (LC), RetTy, Symbol, std::move (Args));
140
+ return TLI->LowerCallTo (CLI).second ;
141
+ }
142
+
79
143
SDValue AArch64SelectionDAGInfo::EmitTargetCodeForMemcpy (
80
144
SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Dst, SDValue Src,
81
145
SDValue Size, Align Alignment, bool isVolatile, bool AlwaysInline,
82
146
MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const {
83
147
const AArch64Subtarget &STI =
84
148
DAG.getMachineFunction ().getSubtarget <AArch64Subtarget>();
149
+
85
150
if (STI.hasMOPS ())
86
151
return EmitMOPS (AArch64ISD::MOPS_MEMCOPY, DAG, DL, Chain, Dst, Src, Size,
87
152
Alignment, isVolatile, DstPtrInfo, SrcPtrInfo);
153
+
154
+ SMEAttrs Attrs (DAG.getMachineFunction ().getFunction ());
155
+ if (LowerToSMERoutines && !Attrs.hasNonStreamingInterfaceAndBody ())
156
+ return EmitStreamingCompatibleMemLibCall (DAG, DL, Chain, Dst, Src, Size,
157
+ RTLIB::MEMCPY);
88
158
return SDValue ();
89
159
}
90
160
@@ -95,10 +165,14 @@ SDValue AArch64SelectionDAGInfo::EmitTargetCodeForMemset(
95
165
const AArch64Subtarget &STI =
96
166
DAG.getMachineFunction ().getSubtarget <AArch64Subtarget>();
97
167
98
- if (STI.hasMOPS ()) {
168
+ if (STI.hasMOPS ())
99
169
return EmitMOPS (AArch64ISD::MOPS_MEMSET, DAG, dl, Chain, Dst, Src, Size,
100
170
Alignment, isVolatile, DstPtrInfo, MachinePointerInfo{});
101
- }
171
+
172
+ SMEAttrs Attrs (DAG.getMachineFunction ().getFunction ());
173
+ if (LowerToSMERoutines && !Attrs.hasNonStreamingInterfaceAndBody ())
174
+ return EmitStreamingCompatibleMemLibCall (DAG, dl, Chain, Dst, Src, Size,
175
+ RTLIB::MEMSET);
102
176
return SDValue ();
103
177
}
104
178
@@ -108,10 +182,15 @@ SDValue AArch64SelectionDAGInfo::EmitTargetCodeForMemmove(
108
182
MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const {
109
183
const AArch64Subtarget &STI =
110
184
DAG.getMachineFunction ().getSubtarget <AArch64Subtarget>();
111
- if (STI.hasMOPS ()) {
185
+
186
+ if (STI.hasMOPS ())
112
187
return EmitMOPS (AArch64ISD::MOPS_MEMMOVE, DAG, dl, Chain, Dst, Src, Size,
113
188
Alignment, isVolatile, DstPtrInfo, SrcPtrInfo);
114
- }
189
+
190
+ SMEAttrs Attrs (DAG.getMachineFunction ().getFunction ());
191
+ if (LowerToSMERoutines && !Attrs.hasNonStreamingInterfaceAndBody ())
192
+ return EmitStreamingCompatibleMemLibCall (DAG, dl, Chain, Dst, Src, Size,
193
+ RTLIB::MEMMOVE);
115
194
return SDValue ();
116
195
}
117
196
0 commit comments