1e5dd7070Spatrick //===--- CGStmt.cpp - Emit LLVM Code from Statements ----------------------===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9e5dd7070Spatrick // This contains code to emit Stmt nodes as LLVM code.
10e5dd7070Spatrick //
11e5dd7070Spatrick //===----------------------------------------------------------------------===//
12e5dd7070Spatrick
13e5dd7070Spatrick #include "CGDebugInfo.h"
14ec727ea7Spatrick #include "CGOpenMPRuntime.h"
15e5dd7070Spatrick #include "CodeGenFunction.h"
16e5dd7070Spatrick #include "CodeGenModule.h"
17e5dd7070Spatrick #include "TargetInfo.h"
18e5dd7070Spatrick #include "clang/AST/Attr.h"
19a9ac8606Spatrick #include "clang/AST/Expr.h"
20a9ac8606Spatrick #include "clang/AST/Stmt.h"
21e5dd7070Spatrick #include "clang/AST/StmtVisitor.h"
22e5dd7070Spatrick #include "clang/Basic/Builtins.h"
23a9ac8606Spatrick #include "clang/Basic/DiagnosticSema.h"
24e5dd7070Spatrick #include "clang/Basic/PrettyStackTrace.h"
25ec727ea7Spatrick #include "clang/Basic/SourceManager.h"
26e5dd7070Spatrick #include "clang/Basic/TargetInfo.h"
27a9ac8606Spatrick #include "llvm/ADT/SmallSet.h"
28e5dd7070Spatrick #include "llvm/ADT/StringExtras.h"
29*12c85518Srobert #include "llvm/IR/Assumptions.h"
30e5dd7070Spatrick #include "llvm/IR/DataLayout.h"
31e5dd7070Spatrick #include "llvm/IR/InlineAsm.h"
32e5dd7070Spatrick #include "llvm/IR/Intrinsics.h"
33e5dd7070Spatrick #include "llvm/IR/MDBuilder.h"
34ec727ea7Spatrick #include "llvm/Support/SaveAndRestore.h"
35*12c85518Srobert #include <optional>
36e5dd7070Spatrick
37e5dd7070Spatrick using namespace clang;
38e5dd7070Spatrick using namespace CodeGen;
39e5dd7070Spatrick
40e5dd7070Spatrick //===----------------------------------------------------------------------===//
41e5dd7070Spatrick // Statement Emission
42e5dd7070Spatrick //===----------------------------------------------------------------------===//
43e5dd7070Spatrick
EmitStopPoint(const Stmt * S)44e5dd7070Spatrick void CodeGenFunction::EmitStopPoint(const Stmt *S) {
45e5dd7070Spatrick if (CGDebugInfo *DI = getDebugInfo()) {
46e5dd7070Spatrick SourceLocation Loc;
47e5dd7070Spatrick Loc = S->getBeginLoc();
48e5dd7070Spatrick DI->EmitLocation(Builder, Loc);
49e5dd7070Spatrick
50e5dd7070Spatrick LastStopPoint = Loc;
51e5dd7070Spatrick }
52e5dd7070Spatrick }
53e5dd7070Spatrick
EmitStmt(const Stmt * S,ArrayRef<const Attr * > Attrs)54e5dd7070Spatrick void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef<const Attr *> Attrs) {
55e5dd7070Spatrick assert(S && "Null statement?");
56e5dd7070Spatrick PGO.setCurrentStmt(S);
57e5dd7070Spatrick
58e5dd7070Spatrick // These statements have their own debug info handling.
59a9ac8606Spatrick if (EmitSimpleStmt(S, Attrs))
60e5dd7070Spatrick return;
61e5dd7070Spatrick
62e5dd7070Spatrick // Check if we are generating unreachable code.
63e5dd7070Spatrick if (!HaveInsertPoint()) {
64e5dd7070Spatrick // If so, and the statement doesn't contain a label, then we do not need to
65e5dd7070Spatrick // generate actual code. This is safe because (1) the current point is
66e5dd7070Spatrick // unreachable, so we don't need to execute the code, and (2) we've already
67e5dd7070Spatrick // handled the statements which update internal data structures (like the
68e5dd7070Spatrick // local variable map) which could be used by subsequent statements.
69e5dd7070Spatrick if (!ContainsLabel(S)) {
70e5dd7070Spatrick // Verify that any decl statements were handled as simple, they may be in
71e5dd7070Spatrick // scope of subsequent reachable statements.
72e5dd7070Spatrick assert(!isa<DeclStmt>(*S) && "Unexpected DeclStmt!");
73e5dd7070Spatrick return;
74e5dd7070Spatrick }
75e5dd7070Spatrick
76e5dd7070Spatrick // Otherwise, make a new block to hold the code.
77e5dd7070Spatrick EnsureInsertPoint();
78e5dd7070Spatrick }
79e5dd7070Spatrick
80e5dd7070Spatrick // Generate a stoppoint if we are emitting debug info.
81e5dd7070Spatrick EmitStopPoint(S);
82e5dd7070Spatrick
83e5dd7070Spatrick // Ignore all OpenMP directives except for simd if OpenMP with Simd is
84e5dd7070Spatrick // enabled.
85e5dd7070Spatrick if (getLangOpts().OpenMP && getLangOpts().OpenMPSimd) {
86e5dd7070Spatrick if (const auto *D = dyn_cast<OMPExecutableDirective>(S)) {
87e5dd7070Spatrick EmitSimpleOMPExecutableDirective(*D);
88e5dd7070Spatrick return;
89e5dd7070Spatrick }
90e5dd7070Spatrick }
91e5dd7070Spatrick
92e5dd7070Spatrick switch (S->getStmtClass()) {
93e5dd7070Spatrick case Stmt::NoStmtClass:
94e5dd7070Spatrick case Stmt::CXXCatchStmtClass:
95e5dd7070Spatrick case Stmt::SEHExceptStmtClass:
96e5dd7070Spatrick case Stmt::SEHFinallyStmtClass:
97e5dd7070Spatrick case Stmt::MSDependentExistsStmtClass:
98e5dd7070Spatrick llvm_unreachable("invalid statement class to emit generically");
99e5dd7070Spatrick case Stmt::NullStmtClass:
100e5dd7070Spatrick case Stmt::CompoundStmtClass:
101e5dd7070Spatrick case Stmt::DeclStmtClass:
102e5dd7070Spatrick case Stmt::LabelStmtClass:
103e5dd7070Spatrick case Stmt::AttributedStmtClass:
104e5dd7070Spatrick case Stmt::GotoStmtClass:
105e5dd7070Spatrick case Stmt::BreakStmtClass:
106e5dd7070Spatrick case Stmt::ContinueStmtClass:
107e5dd7070Spatrick case Stmt::DefaultStmtClass:
108e5dd7070Spatrick case Stmt::CaseStmtClass:
109e5dd7070Spatrick case Stmt::SEHLeaveStmtClass:
110e5dd7070Spatrick llvm_unreachable("should have emitted these statements as simple");
111e5dd7070Spatrick
112e5dd7070Spatrick #define STMT(Type, Base)
113e5dd7070Spatrick #define ABSTRACT_STMT(Op)
114e5dd7070Spatrick #define EXPR(Type, Base) \
115e5dd7070Spatrick case Stmt::Type##Class:
116e5dd7070Spatrick #include "clang/AST/StmtNodes.inc"
117e5dd7070Spatrick {
118e5dd7070Spatrick // Remember the block we came in on.
119e5dd7070Spatrick llvm::BasicBlock *incoming = Builder.GetInsertBlock();
120e5dd7070Spatrick assert(incoming && "expression emission must have an insertion point");
121e5dd7070Spatrick
122e5dd7070Spatrick EmitIgnoredExpr(cast<Expr>(S));
123e5dd7070Spatrick
124e5dd7070Spatrick llvm::BasicBlock *outgoing = Builder.GetInsertBlock();
125e5dd7070Spatrick assert(outgoing && "expression emission cleared block!");
126e5dd7070Spatrick
127e5dd7070Spatrick // The expression emitters assume (reasonably!) that the insertion
128e5dd7070Spatrick // point is always set. To maintain that, the call-emission code
129e5dd7070Spatrick // for noreturn functions has to enter a new block with no
130e5dd7070Spatrick // predecessors. We want to kill that block and mark the current
131e5dd7070Spatrick // insertion point unreachable in the common case of a call like
132e5dd7070Spatrick // "exit();". Since expression emission doesn't otherwise create
133e5dd7070Spatrick // blocks with no predecessors, we can just test for that.
134e5dd7070Spatrick // However, we must be careful not to do this to our incoming
135e5dd7070Spatrick // block, because *statement* emission does sometimes create
136e5dd7070Spatrick // reachable blocks which will have no predecessors until later in
137e5dd7070Spatrick // the function. This occurs with, e.g., labels that are not
138e5dd7070Spatrick // reachable by fallthrough.
139e5dd7070Spatrick if (incoming != outgoing && outgoing->use_empty()) {
140e5dd7070Spatrick outgoing->eraseFromParent();
141e5dd7070Spatrick Builder.ClearInsertionPoint();
142e5dd7070Spatrick }
143e5dd7070Spatrick break;
144e5dd7070Spatrick }
145e5dd7070Spatrick
146e5dd7070Spatrick case Stmt::IndirectGotoStmtClass:
147e5dd7070Spatrick EmitIndirectGotoStmt(cast<IndirectGotoStmt>(*S)); break;
148e5dd7070Spatrick
149e5dd7070Spatrick case Stmt::IfStmtClass: EmitIfStmt(cast<IfStmt>(*S)); break;
150e5dd7070Spatrick case Stmt::WhileStmtClass: EmitWhileStmt(cast<WhileStmt>(*S), Attrs); break;
151e5dd7070Spatrick case Stmt::DoStmtClass: EmitDoStmt(cast<DoStmt>(*S), Attrs); break;
152e5dd7070Spatrick case Stmt::ForStmtClass: EmitForStmt(cast<ForStmt>(*S), Attrs); break;
153e5dd7070Spatrick
154e5dd7070Spatrick case Stmt::ReturnStmtClass: EmitReturnStmt(cast<ReturnStmt>(*S)); break;
155e5dd7070Spatrick
156e5dd7070Spatrick case Stmt::SwitchStmtClass: EmitSwitchStmt(cast<SwitchStmt>(*S)); break;
157e5dd7070Spatrick case Stmt::GCCAsmStmtClass: // Intentional fall-through.
158e5dd7070Spatrick case Stmt::MSAsmStmtClass: EmitAsmStmt(cast<AsmStmt>(*S)); break;
159e5dd7070Spatrick case Stmt::CoroutineBodyStmtClass:
160e5dd7070Spatrick EmitCoroutineBody(cast<CoroutineBodyStmt>(*S));
161e5dd7070Spatrick break;
162e5dd7070Spatrick case Stmt::CoreturnStmtClass:
163e5dd7070Spatrick EmitCoreturnStmt(cast<CoreturnStmt>(*S));
164e5dd7070Spatrick break;
165e5dd7070Spatrick case Stmt::CapturedStmtClass: {
166e5dd7070Spatrick const CapturedStmt *CS = cast<CapturedStmt>(S);
167e5dd7070Spatrick EmitCapturedStmt(*CS, CS->getCapturedRegionKind());
168e5dd7070Spatrick }
169e5dd7070Spatrick break;
170e5dd7070Spatrick case Stmt::ObjCAtTryStmtClass:
171e5dd7070Spatrick EmitObjCAtTryStmt(cast<ObjCAtTryStmt>(*S));
172e5dd7070Spatrick break;
173e5dd7070Spatrick case Stmt::ObjCAtCatchStmtClass:
174e5dd7070Spatrick llvm_unreachable(
175e5dd7070Spatrick "@catch statements should be handled by EmitObjCAtTryStmt");
176e5dd7070Spatrick case Stmt::ObjCAtFinallyStmtClass:
177e5dd7070Spatrick llvm_unreachable(
178e5dd7070Spatrick "@finally statements should be handled by EmitObjCAtTryStmt");
179e5dd7070Spatrick case Stmt::ObjCAtThrowStmtClass:
180e5dd7070Spatrick EmitObjCAtThrowStmt(cast<ObjCAtThrowStmt>(*S));
181e5dd7070Spatrick break;
182e5dd7070Spatrick case Stmt::ObjCAtSynchronizedStmtClass:
183e5dd7070Spatrick EmitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(*S));
184e5dd7070Spatrick break;
185e5dd7070Spatrick case Stmt::ObjCForCollectionStmtClass:
186e5dd7070Spatrick EmitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(*S));
187e5dd7070Spatrick break;
188e5dd7070Spatrick case Stmt::ObjCAutoreleasePoolStmtClass:
189e5dd7070Spatrick EmitObjCAutoreleasePoolStmt(cast<ObjCAutoreleasePoolStmt>(*S));
190e5dd7070Spatrick break;
191e5dd7070Spatrick
192e5dd7070Spatrick case Stmt::CXXTryStmtClass:
193e5dd7070Spatrick EmitCXXTryStmt(cast<CXXTryStmt>(*S));
194e5dd7070Spatrick break;
195e5dd7070Spatrick case Stmt::CXXForRangeStmtClass:
196e5dd7070Spatrick EmitCXXForRangeStmt(cast<CXXForRangeStmt>(*S), Attrs);
197e5dd7070Spatrick break;
198e5dd7070Spatrick case Stmt::SEHTryStmtClass:
199e5dd7070Spatrick EmitSEHTryStmt(cast<SEHTryStmt>(*S));
200e5dd7070Spatrick break;
201*12c85518Srobert case Stmt::OMPMetaDirectiveClass:
202*12c85518Srobert EmitOMPMetaDirective(cast<OMPMetaDirective>(*S));
203*12c85518Srobert break;
204a9ac8606Spatrick case Stmt::OMPCanonicalLoopClass:
205a9ac8606Spatrick EmitOMPCanonicalLoop(cast<OMPCanonicalLoop>(S));
206a9ac8606Spatrick break;
207e5dd7070Spatrick case Stmt::OMPParallelDirectiveClass:
208e5dd7070Spatrick EmitOMPParallelDirective(cast<OMPParallelDirective>(*S));
209e5dd7070Spatrick break;
210e5dd7070Spatrick case Stmt::OMPSimdDirectiveClass:
211e5dd7070Spatrick EmitOMPSimdDirective(cast<OMPSimdDirective>(*S));
212e5dd7070Spatrick break;
213a9ac8606Spatrick case Stmt::OMPTileDirectiveClass:
214a9ac8606Spatrick EmitOMPTileDirective(cast<OMPTileDirective>(*S));
215a9ac8606Spatrick break;
216a9ac8606Spatrick case Stmt::OMPUnrollDirectiveClass:
217a9ac8606Spatrick EmitOMPUnrollDirective(cast<OMPUnrollDirective>(*S));
218a9ac8606Spatrick break;
219e5dd7070Spatrick case Stmt::OMPForDirectiveClass:
220e5dd7070Spatrick EmitOMPForDirective(cast<OMPForDirective>(*S));
221e5dd7070Spatrick break;
222e5dd7070Spatrick case Stmt::OMPForSimdDirectiveClass:
223e5dd7070Spatrick EmitOMPForSimdDirective(cast<OMPForSimdDirective>(*S));
224e5dd7070Spatrick break;
225e5dd7070Spatrick case Stmt::OMPSectionsDirectiveClass:
226e5dd7070Spatrick EmitOMPSectionsDirective(cast<OMPSectionsDirective>(*S));
227e5dd7070Spatrick break;
228e5dd7070Spatrick case Stmt::OMPSectionDirectiveClass:
229e5dd7070Spatrick EmitOMPSectionDirective(cast<OMPSectionDirective>(*S));
230e5dd7070Spatrick break;
231e5dd7070Spatrick case Stmt::OMPSingleDirectiveClass:
232e5dd7070Spatrick EmitOMPSingleDirective(cast<OMPSingleDirective>(*S));
233e5dd7070Spatrick break;
234e5dd7070Spatrick case Stmt::OMPMasterDirectiveClass:
235e5dd7070Spatrick EmitOMPMasterDirective(cast<OMPMasterDirective>(*S));
236e5dd7070Spatrick break;
237e5dd7070Spatrick case Stmt::OMPCriticalDirectiveClass:
238e5dd7070Spatrick EmitOMPCriticalDirective(cast<OMPCriticalDirective>(*S));
239e5dd7070Spatrick break;
240e5dd7070Spatrick case Stmt::OMPParallelForDirectiveClass:
241e5dd7070Spatrick EmitOMPParallelForDirective(cast<OMPParallelForDirective>(*S));
242e5dd7070Spatrick break;
243e5dd7070Spatrick case Stmt::OMPParallelForSimdDirectiveClass:
244e5dd7070Spatrick EmitOMPParallelForSimdDirective(cast<OMPParallelForSimdDirective>(*S));
245e5dd7070Spatrick break;
246e5dd7070Spatrick case Stmt::OMPParallelMasterDirectiveClass:
247e5dd7070Spatrick EmitOMPParallelMasterDirective(cast<OMPParallelMasterDirective>(*S));
248e5dd7070Spatrick break;
249e5dd7070Spatrick case Stmt::OMPParallelSectionsDirectiveClass:
250e5dd7070Spatrick EmitOMPParallelSectionsDirective(cast<OMPParallelSectionsDirective>(*S));
251e5dd7070Spatrick break;
252e5dd7070Spatrick case Stmt::OMPTaskDirectiveClass:
253e5dd7070Spatrick EmitOMPTaskDirective(cast<OMPTaskDirective>(*S));
254e5dd7070Spatrick break;
255e5dd7070Spatrick case Stmt::OMPTaskyieldDirectiveClass:
256e5dd7070Spatrick EmitOMPTaskyieldDirective(cast<OMPTaskyieldDirective>(*S));
257e5dd7070Spatrick break;
258*12c85518Srobert case Stmt::OMPErrorDirectiveClass:
259*12c85518Srobert EmitOMPErrorDirective(cast<OMPErrorDirective>(*S));
260*12c85518Srobert break;
261e5dd7070Spatrick case Stmt::OMPBarrierDirectiveClass:
262e5dd7070Spatrick EmitOMPBarrierDirective(cast<OMPBarrierDirective>(*S));
263e5dd7070Spatrick break;
264e5dd7070Spatrick case Stmt::OMPTaskwaitDirectiveClass:
265e5dd7070Spatrick EmitOMPTaskwaitDirective(cast<OMPTaskwaitDirective>(*S));
266e5dd7070Spatrick break;
267e5dd7070Spatrick case Stmt::OMPTaskgroupDirectiveClass:
268e5dd7070Spatrick EmitOMPTaskgroupDirective(cast<OMPTaskgroupDirective>(*S));
269e5dd7070Spatrick break;
270e5dd7070Spatrick case Stmt::OMPFlushDirectiveClass:
271e5dd7070Spatrick EmitOMPFlushDirective(cast<OMPFlushDirective>(*S));
272e5dd7070Spatrick break;
273ec727ea7Spatrick case Stmt::OMPDepobjDirectiveClass:
274ec727ea7Spatrick EmitOMPDepobjDirective(cast<OMPDepobjDirective>(*S));
275ec727ea7Spatrick break;
276ec727ea7Spatrick case Stmt::OMPScanDirectiveClass:
277ec727ea7Spatrick EmitOMPScanDirective(cast<OMPScanDirective>(*S));
278ec727ea7Spatrick break;
279e5dd7070Spatrick case Stmt::OMPOrderedDirectiveClass:
280e5dd7070Spatrick EmitOMPOrderedDirective(cast<OMPOrderedDirective>(*S));
281e5dd7070Spatrick break;
282e5dd7070Spatrick case Stmt::OMPAtomicDirectiveClass:
283e5dd7070Spatrick EmitOMPAtomicDirective(cast<OMPAtomicDirective>(*S));
284e5dd7070Spatrick break;
285e5dd7070Spatrick case Stmt::OMPTargetDirectiveClass:
286e5dd7070Spatrick EmitOMPTargetDirective(cast<OMPTargetDirective>(*S));
287e5dd7070Spatrick break;
288e5dd7070Spatrick case Stmt::OMPTeamsDirectiveClass:
289e5dd7070Spatrick EmitOMPTeamsDirective(cast<OMPTeamsDirective>(*S));
290e5dd7070Spatrick break;
291e5dd7070Spatrick case Stmt::OMPCancellationPointDirectiveClass:
292e5dd7070Spatrick EmitOMPCancellationPointDirective(cast<OMPCancellationPointDirective>(*S));
293e5dd7070Spatrick break;
294e5dd7070Spatrick case Stmt::OMPCancelDirectiveClass:
295e5dd7070Spatrick EmitOMPCancelDirective(cast<OMPCancelDirective>(*S));
296e5dd7070Spatrick break;
297e5dd7070Spatrick case Stmt::OMPTargetDataDirectiveClass:
298e5dd7070Spatrick EmitOMPTargetDataDirective(cast<OMPTargetDataDirective>(*S));
299e5dd7070Spatrick break;
300e5dd7070Spatrick case Stmt::OMPTargetEnterDataDirectiveClass:
301e5dd7070Spatrick EmitOMPTargetEnterDataDirective(cast<OMPTargetEnterDataDirective>(*S));
302e5dd7070Spatrick break;
303e5dd7070Spatrick case Stmt::OMPTargetExitDataDirectiveClass:
304e5dd7070Spatrick EmitOMPTargetExitDataDirective(cast<OMPTargetExitDataDirective>(*S));
305e5dd7070Spatrick break;
306e5dd7070Spatrick case Stmt::OMPTargetParallelDirectiveClass:
307e5dd7070Spatrick EmitOMPTargetParallelDirective(cast<OMPTargetParallelDirective>(*S));
308e5dd7070Spatrick break;
309e5dd7070Spatrick case Stmt::OMPTargetParallelForDirectiveClass:
310e5dd7070Spatrick EmitOMPTargetParallelForDirective(cast<OMPTargetParallelForDirective>(*S));
311e5dd7070Spatrick break;
312e5dd7070Spatrick case Stmt::OMPTaskLoopDirectiveClass:
313e5dd7070Spatrick EmitOMPTaskLoopDirective(cast<OMPTaskLoopDirective>(*S));
314e5dd7070Spatrick break;
315e5dd7070Spatrick case Stmt::OMPTaskLoopSimdDirectiveClass:
316e5dd7070Spatrick EmitOMPTaskLoopSimdDirective(cast<OMPTaskLoopSimdDirective>(*S));
317e5dd7070Spatrick break;
318e5dd7070Spatrick case Stmt::OMPMasterTaskLoopDirectiveClass:
319e5dd7070Spatrick EmitOMPMasterTaskLoopDirective(cast<OMPMasterTaskLoopDirective>(*S));
320e5dd7070Spatrick break;
321*12c85518Srobert case Stmt::OMPMaskedTaskLoopDirectiveClass:
322*12c85518Srobert llvm_unreachable("masked taskloop directive not supported yet.");
323*12c85518Srobert break;
324e5dd7070Spatrick case Stmt::OMPMasterTaskLoopSimdDirectiveClass:
325e5dd7070Spatrick EmitOMPMasterTaskLoopSimdDirective(
326e5dd7070Spatrick cast<OMPMasterTaskLoopSimdDirective>(*S));
327e5dd7070Spatrick break;
328*12c85518Srobert case Stmt::OMPMaskedTaskLoopSimdDirectiveClass:
329*12c85518Srobert llvm_unreachable("masked taskloop simd directive not supported yet.");
330*12c85518Srobert break;
331e5dd7070Spatrick case Stmt::OMPParallelMasterTaskLoopDirectiveClass:
332e5dd7070Spatrick EmitOMPParallelMasterTaskLoopDirective(
333e5dd7070Spatrick cast<OMPParallelMasterTaskLoopDirective>(*S));
334e5dd7070Spatrick break;
335*12c85518Srobert case Stmt::OMPParallelMaskedTaskLoopDirectiveClass:
336*12c85518Srobert llvm_unreachable("parallel masked taskloop directive not supported yet.");
337*12c85518Srobert break;
338e5dd7070Spatrick case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
339e5dd7070Spatrick EmitOMPParallelMasterTaskLoopSimdDirective(
340e5dd7070Spatrick cast<OMPParallelMasterTaskLoopSimdDirective>(*S));
341e5dd7070Spatrick break;
342*12c85518Srobert case Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass:
343*12c85518Srobert llvm_unreachable(
344*12c85518Srobert "parallel masked taskloop simd directive not supported yet.");
345*12c85518Srobert break;
346e5dd7070Spatrick case Stmt::OMPDistributeDirectiveClass:
347e5dd7070Spatrick EmitOMPDistributeDirective(cast<OMPDistributeDirective>(*S));
348e5dd7070Spatrick break;
349e5dd7070Spatrick case Stmt::OMPTargetUpdateDirectiveClass:
350e5dd7070Spatrick EmitOMPTargetUpdateDirective(cast<OMPTargetUpdateDirective>(*S));
351e5dd7070Spatrick break;
352e5dd7070Spatrick case Stmt::OMPDistributeParallelForDirectiveClass:
353e5dd7070Spatrick EmitOMPDistributeParallelForDirective(
354e5dd7070Spatrick cast<OMPDistributeParallelForDirective>(*S));
355e5dd7070Spatrick break;
356e5dd7070Spatrick case Stmt::OMPDistributeParallelForSimdDirectiveClass:
357e5dd7070Spatrick EmitOMPDistributeParallelForSimdDirective(
358e5dd7070Spatrick cast<OMPDistributeParallelForSimdDirective>(*S));
359e5dd7070Spatrick break;
360e5dd7070Spatrick case Stmt::OMPDistributeSimdDirectiveClass:
361e5dd7070Spatrick EmitOMPDistributeSimdDirective(cast<OMPDistributeSimdDirective>(*S));
362e5dd7070Spatrick break;
363e5dd7070Spatrick case Stmt::OMPTargetParallelForSimdDirectiveClass:
364e5dd7070Spatrick EmitOMPTargetParallelForSimdDirective(
365e5dd7070Spatrick cast<OMPTargetParallelForSimdDirective>(*S));
366e5dd7070Spatrick break;
367e5dd7070Spatrick case Stmt::OMPTargetSimdDirectiveClass:
368e5dd7070Spatrick EmitOMPTargetSimdDirective(cast<OMPTargetSimdDirective>(*S));
369e5dd7070Spatrick break;
370e5dd7070Spatrick case Stmt::OMPTeamsDistributeDirectiveClass:
371e5dd7070Spatrick EmitOMPTeamsDistributeDirective(cast<OMPTeamsDistributeDirective>(*S));
372e5dd7070Spatrick break;
373e5dd7070Spatrick case Stmt::OMPTeamsDistributeSimdDirectiveClass:
374e5dd7070Spatrick EmitOMPTeamsDistributeSimdDirective(
375e5dd7070Spatrick cast<OMPTeamsDistributeSimdDirective>(*S));
376e5dd7070Spatrick break;
377e5dd7070Spatrick case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
378e5dd7070Spatrick EmitOMPTeamsDistributeParallelForSimdDirective(
379e5dd7070Spatrick cast<OMPTeamsDistributeParallelForSimdDirective>(*S));
380e5dd7070Spatrick break;
381e5dd7070Spatrick case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
382e5dd7070Spatrick EmitOMPTeamsDistributeParallelForDirective(
383e5dd7070Spatrick cast<OMPTeamsDistributeParallelForDirective>(*S));
384e5dd7070Spatrick break;
385e5dd7070Spatrick case Stmt::OMPTargetTeamsDirectiveClass:
386e5dd7070Spatrick EmitOMPTargetTeamsDirective(cast<OMPTargetTeamsDirective>(*S));
387e5dd7070Spatrick break;
388e5dd7070Spatrick case Stmt::OMPTargetTeamsDistributeDirectiveClass:
389e5dd7070Spatrick EmitOMPTargetTeamsDistributeDirective(
390e5dd7070Spatrick cast<OMPTargetTeamsDistributeDirective>(*S));
391e5dd7070Spatrick break;
392e5dd7070Spatrick case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
393e5dd7070Spatrick EmitOMPTargetTeamsDistributeParallelForDirective(
394e5dd7070Spatrick cast<OMPTargetTeamsDistributeParallelForDirective>(*S));
395e5dd7070Spatrick break;
396e5dd7070Spatrick case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
397e5dd7070Spatrick EmitOMPTargetTeamsDistributeParallelForSimdDirective(
398e5dd7070Spatrick cast<OMPTargetTeamsDistributeParallelForSimdDirective>(*S));
399e5dd7070Spatrick break;
400e5dd7070Spatrick case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
401e5dd7070Spatrick EmitOMPTargetTeamsDistributeSimdDirective(
402e5dd7070Spatrick cast<OMPTargetTeamsDistributeSimdDirective>(*S));
403e5dd7070Spatrick break;
404a9ac8606Spatrick case Stmt::OMPInteropDirectiveClass:
405*12c85518Srobert EmitOMPInteropDirective(cast<OMPInteropDirective>(*S));
406a9ac8606Spatrick break;
407a9ac8606Spatrick case Stmt::OMPDispatchDirectiveClass:
408a9ac8606Spatrick llvm_unreachable("Dispatch directive not supported yet.");
409a9ac8606Spatrick break;
410a9ac8606Spatrick case Stmt::OMPMaskedDirectiveClass:
411a9ac8606Spatrick EmitOMPMaskedDirective(cast<OMPMaskedDirective>(*S));
412a9ac8606Spatrick break;
413*12c85518Srobert case Stmt::OMPGenericLoopDirectiveClass:
414*12c85518Srobert EmitOMPGenericLoopDirective(cast<OMPGenericLoopDirective>(*S));
415*12c85518Srobert break;
416*12c85518Srobert case Stmt::OMPTeamsGenericLoopDirectiveClass:
417*12c85518Srobert llvm_unreachable("teams loop directive not supported yet.");
418*12c85518Srobert break;
419*12c85518Srobert case Stmt::OMPTargetTeamsGenericLoopDirectiveClass:
420*12c85518Srobert llvm_unreachable("target teams loop directive not supported yet.");
421*12c85518Srobert break;
422*12c85518Srobert case Stmt::OMPParallelGenericLoopDirectiveClass:
423*12c85518Srobert llvm_unreachable("parallel loop directive not supported yet.");
424*12c85518Srobert break;
425*12c85518Srobert case Stmt::OMPTargetParallelGenericLoopDirectiveClass:
426*12c85518Srobert llvm_unreachable("target parallel loop directive not supported yet.");
427*12c85518Srobert break;
428*12c85518Srobert case Stmt::OMPParallelMaskedDirectiveClass:
429*12c85518Srobert llvm_unreachable("parallel masked directive not supported yet.");
430*12c85518Srobert break;
431e5dd7070Spatrick }
432e5dd7070Spatrick }
433e5dd7070Spatrick
EmitSimpleStmt(const Stmt * S,ArrayRef<const Attr * > Attrs)434a9ac8606Spatrick bool CodeGenFunction::EmitSimpleStmt(const Stmt *S,
435a9ac8606Spatrick ArrayRef<const Attr *> Attrs) {
436e5dd7070Spatrick switch (S->getStmtClass()) {
437a9ac8606Spatrick default:
438a9ac8606Spatrick return false;
439a9ac8606Spatrick case Stmt::NullStmtClass:
440a9ac8606Spatrick break;
441a9ac8606Spatrick case Stmt::CompoundStmtClass:
442a9ac8606Spatrick EmitCompoundStmt(cast<CompoundStmt>(*S));
443a9ac8606Spatrick break;
444a9ac8606Spatrick case Stmt::DeclStmtClass:
445a9ac8606Spatrick EmitDeclStmt(cast<DeclStmt>(*S));
446a9ac8606Spatrick break;
447a9ac8606Spatrick case Stmt::LabelStmtClass:
448a9ac8606Spatrick EmitLabelStmt(cast<LabelStmt>(*S));
449a9ac8606Spatrick break;
450e5dd7070Spatrick case Stmt::AttributedStmtClass:
451a9ac8606Spatrick EmitAttributedStmt(cast<AttributedStmt>(*S));
452a9ac8606Spatrick break;
453a9ac8606Spatrick case Stmt::GotoStmtClass:
454a9ac8606Spatrick EmitGotoStmt(cast<GotoStmt>(*S));
455a9ac8606Spatrick break;
456a9ac8606Spatrick case Stmt::BreakStmtClass:
457a9ac8606Spatrick EmitBreakStmt(cast<BreakStmt>(*S));
458a9ac8606Spatrick break;
459a9ac8606Spatrick case Stmt::ContinueStmtClass:
460a9ac8606Spatrick EmitContinueStmt(cast<ContinueStmt>(*S));
461a9ac8606Spatrick break;
462a9ac8606Spatrick case Stmt::DefaultStmtClass:
463a9ac8606Spatrick EmitDefaultStmt(cast<DefaultStmt>(*S), Attrs);
464a9ac8606Spatrick break;
465a9ac8606Spatrick case Stmt::CaseStmtClass:
466a9ac8606Spatrick EmitCaseStmt(cast<CaseStmt>(*S), Attrs);
467a9ac8606Spatrick break;
468a9ac8606Spatrick case Stmt::SEHLeaveStmtClass:
469a9ac8606Spatrick EmitSEHLeaveStmt(cast<SEHLeaveStmt>(*S));
470a9ac8606Spatrick break;
471e5dd7070Spatrick }
472e5dd7070Spatrick return true;
473e5dd7070Spatrick }
474e5dd7070Spatrick
475e5dd7070Spatrick /// EmitCompoundStmt - Emit a compound statement {..} node. If GetLast is true,
476e5dd7070Spatrick /// this captures the expression result of the last sub-statement and returns it
477e5dd7070Spatrick /// (for use by the statement expression extension).
EmitCompoundStmt(const CompoundStmt & S,bool GetLast,AggValueSlot AggSlot)478e5dd7070Spatrick Address CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast,
479e5dd7070Spatrick AggValueSlot AggSlot) {
480e5dd7070Spatrick PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),S.getLBracLoc(),
481e5dd7070Spatrick "LLVM IR generation of compound statement ('{}')");
482e5dd7070Spatrick
483e5dd7070Spatrick // Keep track of the current cleanup stack depth, including debug scopes.
484e5dd7070Spatrick LexicalScope Scope(*this, S.getSourceRange());
485e5dd7070Spatrick
486e5dd7070Spatrick return EmitCompoundStmtWithoutScope(S, GetLast, AggSlot);
487e5dd7070Spatrick }
488e5dd7070Spatrick
489e5dd7070Spatrick Address
EmitCompoundStmtWithoutScope(const CompoundStmt & S,bool GetLast,AggValueSlot AggSlot)490e5dd7070Spatrick CodeGenFunction::EmitCompoundStmtWithoutScope(const CompoundStmt &S,
491e5dd7070Spatrick bool GetLast,
492e5dd7070Spatrick AggValueSlot AggSlot) {
493e5dd7070Spatrick
494e5dd7070Spatrick const Stmt *ExprResult = S.getStmtExprResult();
495e5dd7070Spatrick assert((!GetLast || (GetLast && ExprResult)) &&
496e5dd7070Spatrick "If GetLast is true then the CompoundStmt must have a StmtExprResult");
497e5dd7070Spatrick
498e5dd7070Spatrick Address RetAlloca = Address::invalid();
499e5dd7070Spatrick
500e5dd7070Spatrick for (auto *CurStmt : S.body()) {
501e5dd7070Spatrick if (GetLast && ExprResult == CurStmt) {
502e5dd7070Spatrick // We have to special case labels here. They are statements, but when put
503e5dd7070Spatrick // at the end of a statement expression, they yield the value of their
504e5dd7070Spatrick // subexpression. Handle this by walking through all labels we encounter,
505e5dd7070Spatrick // emitting them before we evaluate the subexpr.
506e5dd7070Spatrick // Similar issues arise for attributed statements.
507e5dd7070Spatrick while (!isa<Expr>(ExprResult)) {
508e5dd7070Spatrick if (const auto *LS = dyn_cast<LabelStmt>(ExprResult)) {
509e5dd7070Spatrick EmitLabel(LS->getDecl());
510e5dd7070Spatrick ExprResult = LS->getSubStmt();
511e5dd7070Spatrick } else if (const auto *AS = dyn_cast<AttributedStmt>(ExprResult)) {
512e5dd7070Spatrick // FIXME: Update this if we ever have attributes that affect the
513e5dd7070Spatrick // semantics of an expression.
514e5dd7070Spatrick ExprResult = AS->getSubStmt();
515e5dd7070Spatrick } else {
516e5dd7070Spatrick llvm_unreachable("unknown value statement");
517e5dd7070Spatrick }
518e5dd7070Spatrick }
519e5dd7070Spatrick
520e5dd7070Spatrick EnsureInsertPoint();
521e5dd7070Spatrick
522e5dd7070Spatrick const Expr *E = cast<Expr>(ExprResult);
523e5dd7070Spatrick QualType ExprTy = E->getType();
524e5dd7070Spatrick if (hasAggregateEvaluationKind(ExprTy)) {
525e5dd7070Spatrick EmitAggExpr(E, AggSlot);
526e5dd7070Spatrick } else {
527e5dd7070Spatrick // We can't return an RValue here because there might be cleanups at
528e5dd7070Spatrick // the end of the StmtExpr. Because of that, we have to emit the result
529e5dd7070Spatrick // here into a temporary alloca.
530e5dd7070Spatrick RetAlloca = CreateMemTemp(ExprTy);
531e5dd7070Spatrick EmitAnyExprToMem(E, RetAlloca, Qualifiers(),
532e5dd7070Spatrick /*IsInit*/ false);
533e5dd7070Spatrick }
534e5dd7070Spatrick } else {
535e5dd7070Spatrick EmitStmt(CurStmt);
536e5dd7070Spatrick }
537e5dd7070Spatrick }
538e5dd7070Spatrick
539e5dd7070Spatrick return RetAlloca;
540e5dd7070Spatrick }
541e5dd7070Spatrick
SimplifyForwardingBlocks(llvm::BasicBlock * BB)542e5dd7070Spatrick void CodeGenFunction::SimplifyForwardingBlocks(llvm::BasicBlock *BB) {
543e5dd7070Spatrick llvm::BranchInst *BI = dyn_cast<llvm::BranchInst>(BB->getTerminator());
544e5dd7070Spatrick
545e5dd7070Spatrick // If there is a cleanup stack, then we it isn't worth trying to
546e5dd7070Spatrick // simplify this block (we would need to remove it from the scope map
547e5dd7070Spatrick // and cleanup entry).
548e5dd7070Spatrick if (!EHStack.empty())
549e5dd7070Spatrick return;
550e5dd7070Spatrick
551e5dd7070Spatrick // Can only simplify direct branches.
552e5dd7070Spatrick if (!BI || !BI->isUnconditional())
553e5dd7070Spatrick return;
554e5dd7070Spatrick
555e5dd7070Spatrick // Can only simplify empty blocks.
556e5dd7070Spatrick if (BI->getIterator() != BB->begin())
557e5dd7070Spatrick return;
558e5dd7070Spatrick
559e5dd7070Spatrick BB->replaceAllUsesWith(BI->getSuccessor(0));
560e5dd7070Spatrick BI->eraseFromParent();
561e5dd7070Spatrick BB->eraseFromParent();
562e5dd7070Spatrick }
563e5dd7070Spatrick
EmitBlock(llvm::BasicBlock * BB,bool IsFinished)564e5dd7070Spatrick void CodeGenFunction::EmitBlock(llvm::BasicBlock *BB, bool IsFinished) {
565e5dd7070Spatrick llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
566e5dd7070Spatrick
567e5dd7070Spatrick // Fall out of the current block (if necessary).
568e5dd7070Spatrick EmitBranch(BB);
569e5dd7070Spatrick
570e5dd7070Spatrick if (IsFinished && BB->use_empty()) {
571e5dd7070Spatrick delete BB;
572e5dd7070Spatrick return;
573e5dd7070Spatrick }
574e5dd7070Spatrick
575e5dd7070Spatrick // Place the block after the current block, if possible, or else at
576e5dd7070Spatrick // the end of the function.
577e5dd7070Spatrick if (CurBB && CurBB->getParent())
578*12c85518Srobert CurFn->insert(std::next(CurBB->getIterator()), BB);
579e5dd7070Spatrick else
580*12c85518Srobert CurFn->insert(CurFn->end(), BB);
581e5dd7070Spatrick Builder.SetInsertPoint(BB);
582e5dd7070Spatrick }
583e5dd7070Spatrick
EmitBranch(llvm::BasicBlock * Target)584e5dd7070Spatrick void CodeGenFunction::EmitBranch(llvm::BasicBlock *Target) {
585e5dd7070Spatrick // Emit a branch from the current block to the target one if this
586e5dd7070Spatrick // was a real block. If this was just a fall-through block after a
587e5dd7070Spatrick // terminator, don't emit it.
588e5dd7070Spatrick llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
589e5dd7070Spatrick
590e5dd7070Spatrick if (!CurBB || CurBB->getTerminator()) {
591e5dd7070Spatrick // If there is no insert point or the previous block is already
592e5dd7070Spatrick // terminated, don't touch it.
593e5dd7070Spatrick } else {
594e5dd7070Spatrick // Otherwise, create a fall-through branch.
595e5dd7070Spatrick Builder.CreateBr(Target);
596e5dd7070Spatrick }
597e5dd7070Spatrick
598e5dd7070Spatrick Builder.ClearInsertionPoint();
599e5dd7070Spatrick }
600e5dd7070Spatrick
EmitBlockAfterUses(llvm::BasicBlock * block)601e5dd7070Spatrick void CodeGenFunction::EmitBlockAfterUses(llvm::BasicBlock *block) {
602e5dd7070Spatrick bool inserted = false;
603e5dd7070Spatrick for (llvm::User *u : block->users()) {
604e5dd7070Spatrick if (llvm::Instruction *insn = dyn_cast<llvm::Instruction>(u)) {
605*12c85518Srobert CurFn->insert(std::next(insn->getParent()->getIterator()), block);
606e5dd7070Spatrick inserted = true;
607e5dd7070Spatrick break;
608e5dd7070Spatrick }
609e5dd7070Spatrick }
610e5dd7070Spatrick
611e5dd7070Spatrick if (!inserted)
612*12c85518Srobert CurFn->insert(CurFn->end(), block);
613e5dd7070Spatrick
614e5dd7070Spatrick Builder.SetInsertPoint(block);
615e5dd7070Spatrick }
616e5dd7070Spatrick
617e5dd7070Spatrick CodeGenFunction::JumpDest
getJumpDestForLabel(const LabelDecl * D)618e5dd7070Spatrick CodeGenFunction::getJumpDestForLabel(const LabelDecl *D) {
619e5dd7070Spatrick JumpDest &Dest = LabelMap[D];
620e5dd7070Spatrick if (Dest.isValid()) return Dest;
621e5dd7070Spatrick
622e5dd7070Spatrick // Create, but don't insert, the new block.
623e5dd7070Spatrick Dest = JumpDest(createBasicBlock(D->getName()),
624e5dd7070Spatrick EHScopeStack::stable_iterator::invalid(),
625e5dd7070Spatrick NextCleanupDestIndex++);
626e5dd7070Spatrick return Dest;
627e5dd7070Spatrick }
628e5dd7070Spatrick
EmitLabel(const LabelDecl * D)629e5dd7070Spatrick void CodeGenFunction::EmitLabel(const LabelDecl *D) {
630e5dd7070Spatrick // Add this label to the current lexical scope if we're within any
631e5dd7070Spatrick // normal cleanups. Jumps "in" to this label --- when permitted by
632e5dd7070Spatrick // the language --- may need to be routed around such cleanups.
633e5dd7070Spatrick if (EHStack.hasNormalCleanups() && CurLexicalScope)
634e5dd7070Spatrick CurLexicalScope->addLabel(D);
635e5dd7070Spatrick
636e5dd7070Spatrick JumpDest &Dest = LabelMap[D];
637e5dd7070Spatrick
638e5dd7070Spatrick // If we didn't need a forward reference to this label, just go
639e5dd7070Spatrick // ahead and create a destination at the current scope.
640e5dd7070Spatrick if (!Dest.isValid()) {
641e5dd7070Spatrick Dest = getJumpDestInCurrentScope(D->getName());
642e5dd7070Spatrick
643e5dd7070Spatrick // Otherwise, we need to give this label a target depth and remove
644e5dd7070Spatrick // it from the branch-fixups list.
645e5dd7070Spatrick } else {
646e5dd7070Spatrick assert(!Dest.getScopeDepth().isValid() && "already emitted label!");
647e5dd7070Spatrick Dest.setScopeDepth(EHStack.stable_begin());
648e5dd7070Spatrick ResolveBranchFixups(Dest.getBlock());
649e5dd7070Spatrick }
650e5dd7070Spatrick
651e5dd7070Spatrick EmitBlock(Dest.getBlock());
652e5dd7070Spatrick
653e5dd7070Spatrick // Emit debug info for labels.
654e5dd7070Spatrick if (CGDebugInfo *DI = getDebugInfo()) {
655e5dd7070Spatrick if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
656e5dd7070Spatrick DI->setLocation(D->getLocation());
657e5dd7070Spatrick DI->EmitLabel(D, Builder);
658e5dd7070Spatrick }
659e5dd7070Spatrick }
660e5dd7070Spatrick
661e5dd7070Spatrick incrementProfileCounter(D->getStmt());
662e5dd7070Spatrick }
663e5dd7070Spatrick
664e5dd7070Spatrick /// Change the cleanup scope of the labels in this lexical scope to
665e5dd7070Spatrick /// match the scope of the enclosing context.
rescopeLabels()666e5dd7070Spatrick void CodeGenFunction::LexicalScope::rescopeLabels() {
667e5dd7070Spatrick assert(!Labels.empty());
668e5dd7070Spatrick EHScopeStack::stable_iterator innermostScope
669e5dd7070Spatrick = CGF.EHStack.getInnermostNormalCleanup();
670e5dd7070Spatrick
671e5dd7070Spatrick // Change the scope depth of all the labels.
672e5dd7070Spatrick for (SmallVectorImpl<const LabelDecl*>::const_iterator
673e5dd7070Spatrick i = Labels.begin(), e = Labels.end(); i != e; ++i) {
674e5dd7070Spatrick assert(CGF.LabelMap.count(*i));
675e5dd7070Spatrick JumpDest &dest = CGF.LabelMap.find(*i)->second;
676e5dd7070Spatrick assert(dest.getScopeDepth().isValid());
677e5dd7070Spatrick assert(innermostScope.encloses(dest.getScopeDepth()));
678e5dd7070Spatrick dest.setScopeDepth(innermostScope);
679e5dd7070Spatrick }
680e5dd7070Spatrick
681e5dd7070Spatrick // Reparent the labels if the new scope also has cleanups.
682e5dd7070Spatrick if (innermostScope != EHScopeStack::stable_end() && ParentScope) {
683e5dd7070Spatrick ParentScope->Labels.append(Labels.begin(), Labels.end());
684e5dd7070Spatrick }
685e5dd7070Spatrick }
686e5dd7070Spatrick
687e5dd7070Spatrick
EmitLabelStmt(const LabelStmt & S)688e5dd7070Spatrick void CodeGenFunction::EmitLabelStmt(const LabelStmt &S) {
689e5dd7070Spatrick EmitLabel(S.getDecl());
690a9ac8606Spatrick
691a9ac8606Spatrick // IsEHa - emit eha.scope.begin if it's a side entry of a scope
692a9ac8606Spatrick if (getLangOpts().EHAsynch && S.isSideEntry())
693a9ac8606Spatrick EmitSehCppScopeBegin();
694a9ac8606Spatrick
695e5dd7070Spatrick EmitStmt(S.getSubStmt());
696e5dd7070Spatrick }
697e5dd7070Spatrick
EmitAttributedStmt(const AttributedStmt & S)698e5dd7070Spatrick void CodeGenFunction::EmitAttributedStmt(const AttributedStmt &S) {
699ec727ea7Spatrick bool nomerge = false;
700*12c85518Srobert bool noinline = false;
701*12c85518Srobert bool alwaysinline = false;
702a9ac8606Spatrick const CallExpr *musttail = nullptr;
703a9ac8606Spatrick
704a9ac8606Spatrick for (const auto *A : S.getAttrs()) {
705*12c85518Srobert switch (A->getKind()) {
706*12c85518Srobert default:
707*12c85518Srobert break;
708*12c85518Srobert case attr::NoMerge:
709ec727ea7Spatrick nomerge = true;
710*12c85518Srobert break;
711*12c85518Srobert case attr::NoInline:
712*12c85518Srobert noinline = true;
713*12c85518Srobert break;
714*12c85518Srobert case attr::AlwaysInline:
715*12c85518Srobert alwaysinline = true;
716*12c85518Srobert break;
717*12c85518Srobert case attr::MustTail:
718a9ac8606Spatrick const Stmt *Sub = S.getSubStmt();
719a9ac8606Spatrick const ReturnStmt *R = cast<ReturnStmt>(Sub);
720a9ac8606Spatrick musttail = cast<CallExpr>(R->getRetValue()->IgnoreParens());
721*12c85518Srobert break;
722a9ac8606Spatrick }
723ec727ea7Spatrick }
724*12c85518Srobert SaveAndRestore save_nomerge(InNoMergeAttributedStmt, nomerge);
725*12c85518Srobert SaveAndRestore save_noinline(InNoInlineAttributedStmt, noinline);
726*12c85518Srobert SaveAndRestore save_alwaysinline(InAlwaysInlineAttributedStmt, alwaysinline);
727*12c85518Srobert SaveAndRestore save_musttail(MustTailCall, musttail);
728e5dd7070Spatrick EmitStmt(S.getSubStmt(), S.getAttrs());
729e5dd7070Spatrick }
730e5dd7070Spatrick
EmitGotoStmt(const GotoStmt & S)731e5dd7070Spatrick void CodeGenFunction::EmitGotoStmt(const GotoStmt &S) {
732e5dd7070Spatrick // If this code is reachable then emit a stop point (if generating
733e5dd7070Spatrick // debug info). We have to do this ourselves because we are on the
734e5dd7070Spatrick // "simple" statement path.
735e5dd7070Spatrick if (HaveInsertPoint())
736e5dd7070Spatrick EmitStopPoint(&S);
737e5dd7070Spatrick
738e5dd7070Spatrick EmitBranchThroughCleanup(getJumpDestForLabel(S.getLabel()));
739e5dd7070Spatrick }
740e5dd7070Spatrick
741e5dd7070Spatrick
EmitIndirectGotoStmt(const IndirectGotoStmt & S)742e5dd7070Spatrick void CodeGenFunction::EmitIndirectGotoStmt(const IndirectGotoStmt &S) {
743e5dd7070Spatrick if (const LabelDecl *Target = S.getConstantTarget()) {
744e5dd7070Spatrick EmitBranchThroughCleanup(getJumpDestForLabel(Target));
745e5dd7070Spatrick return;
746e5dd7070Spatrick }
747e5dd7070Spatrick
748e5dd7070Spatrick // Ensure that we have an i8* for our PHI node.
749e5dd7070Spatrick llvm::Value *V = Builder.CreateBitCast(EmitScalarExpr(S.getTarget()),
750e5dd7070Spatrick Int8PtrTy, "addr");
751e5dd7070Spatrick llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
752e5dd7070Spatrick
753e5dd7070Spatrick // Get the basic block for the indirect goto.
754e5dd7070Spatrick llvm::BasicBlock *IndGotoBB = GetIndirectGotoBlock();
755e5dd7070Spatrick
756e5dd7070Spatrick // The first instruction in the block has to be the PHI for the switch dest,
757e5dd7070Spatrick // add an entry for this branch.
758e5dd7070Spatrick cast<llvm::PHINode>(IndGotoBB->begin())->addIncoming(V, CurBB);
759e5dd7070Spatrick
760e5dd7070Spatrick EmitBranch(IndGotoBB);
761e5dd7070Spatrick }
762e5dd7070Spatrick
EmitIfStmt(const IfStmt & S)763e5dd7070Spatrick void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
764*12c85518Srobert // The else branch of a consteval if statement is always the only branch that
765*12c85518Srobert // can be runtime evaluated.
766*12c85518Srobert if (S.isConsteval()) {
767*12c85518Srobert const Stmt *Executed = S.isNegatedConsteval() ? S.getThen() : S.getElse();
768*12c85518Srobert if (Executed) {
769*12c85518Srobert RunCleanupsScope ExecutedScope(*this);
770*12c85518Srobert EmitStmt(Executed);
771*12c85518Srobert }
772*12c85518Srobert return;
773*12c85518Srobert }
774*12c85518Srobert
775e5dd7070Spatrick // C99 6.8.4.1: The first substatement is executed if the expression compares
776e5dd7070Spatrick // unequal to 0. The condition must be a scalar type.
777e5dd7070Spatrick LexicalScope ConditionScope(*this, S.getCond()->getSourceRange());
778e5dd7070Spatrick
779e5dd7070Spatrick if (S.getInit())
780e5dd7070Spatrick EmitStmt(S.getInit());
781e5dd7070Spatrick
782e5dd7070Spatrick if (S.getConditionVariable())
783e5dd7070Spatrick EmitDecl(*S.getConditionVariable());
784e5dd7070Spatrick
785e5dd7070Spatrick // If the condition constant folds and can be elided, try to avoid emitting
786e5dd7070Spatrick // the condition and the dead arm of the if/else.
787e5dd7070Spatrick bool CondConstant;
788e5dd7070Spatrick if (ConstantFoldsToSimpleInteger(S.getCond(), CondConstant,
789e5dd7070Spatrick S.isConstexpr())) {
790e5dd7070Spatrick // Figure out which block (then or else) is executed.
791e5dd7070Spatrick const Stmt *Executed = S.getThen();
792e5dd7070Spatrick const Stmt *Skipped = S.getElse();
793e5dd7070Spatrick if (!CondConstant) // Condition false?
794e5dd7070Spatrick std::swap(Executed, Skipped);
795e5dd7070Spatrick
796e5dd7070Spatrick // If the skipped block has no labels in it, just emit the executed block.
797e5dd7070Spatrick // This avoids emitting dead code and simplifies the CFG substantially.
798e5dd7070Spatrick if (S.isConstexpr() || !ContainsLabel(Skipped)) {
799e5dd7070Spatrick if (CondConstant)
800e5dd7070Spatrick incrementProfileCounter(&S);
801e5dd7070Spatrick if (Executed) {
802e5dd7070Spatrick RunCleanupsScope ExecutedScope(*this);
803e5dd7070Spatrick EmitStmt(Executed);
804e5dd7070Spatrick }
805e5dd7070Spatrick return;
806e5dd7070Spatrick }
807e5dd7070Spatrick }
808e5dd7070Spatrick
809e5dd7070Spatrick // Otherwise, the condition did not fold, or we couldn't elide it. Just emit
810e5dd7070Spatrick // the conditional branch.
811e5dd7070Spatrick llvm::BasicBlock *ThenBlock = createBasicBlock("if.then");
812e5dd7070Spatrick llvm::BasicBlock *ContBlock = createBasicBlock("if.end");
813e5dd7070Spatrick llvm::BasicBlock *ElseBlock = ContBlock;
814e5dd7070Spatrick if (S.getElse())
815e5dd7070Spatrick ElseBlock = createBasicBlock("if.else");
816e5dd7070Spatrick
817a9ac8606Spatrick // Prefer the PGO based weights over the likelihood attribute.
818a9ac8606Spatrick // When the build isn't optimized the metadata isn't used, so don't generate
819a9ac8606Spatrick // it.
820*12c85518Srobert // Also, differentiate between disabled PGO and a never executed branch with
821*12c85518Srobert // PGO. Assuming PGO is in use:
822*12c85518Srobert // - we want to ignore the [[likely]] attribute if the branch is never
823*12c85518Srobert // executed,
824*12c85518Srobert // - assuming the profile is poor, preserving the attribute may still be
825*12c85518Srobert // beneficial.
826*12c85518Srobert // As an approximation, preserve the attribute only if both the branch and the
827*12c85518Srobert // parent context were not executed.
828a9ac8606Spatrick Stmt::Likelihood LH = Stmt::LH_None;
829*12c85518Srobert uint64_t ThenCount = getProfileCount(S.getThen());
830*12c85518Srobert if (!ThenCount && !getCurrentProfileCount() &&
831*12c85518Srobert CGM.getCodeGenOpts().OptimizationLevel)
832a9ac8606Spatrick LH = Stmt::getLikelihood(S.getThen(), S.getElse());
833*12c85518Srobert EmitBranchOnBoolExpr(S.getCond(), ThenBlock, ElseBlock, ThenCount, LH);
834e5dd7070Spatrick
835e5dd7070Spatrick // Emit the 'then' code.
836e5dd7070Spatrick EmitBlock(ThenBlock);
837e5dd7070Spatrick incrementProfileCounter(&S);
838e5dd7070Spatrick {
839e5dd7070Spatrick RunCleanupsScope ThenScope(*this);
840e5dd7070Spatrick EmitStmt(S.getThen());
841e5dd7070Spatrick }
842e5dd7070Spatrick EmitBranch(ContBlock);
843e5dd7070Spatrick
844e5dd7070Spatrick // Emit the 'else' code if present.
845e5dd7070Spatrick if (const Stmt *Else = S.getElse()) {
846e5dd7070Spatrick {
847e5dd7070Spatrick // There is no need to emit line number for an unconditional branch.
848e5dd7070Spatrick auto NL = ApplyDebugLocation::CreateEmpty(*this);
849e5dd7070Spatrick EmitBlock(ElseBlock);
850e5dd7070Spatrick }
851e5dd7070Spatrick {
852e5dd7070Spatrick RunCleanupsScope ElseScope(*this);
853e5dd7070Spatrick EmitStmt(Else);
854e5dd7070Spatrick }
855e5dd7070Spatrick {
856e5dd7070Spatrick // There is no need to emit line number for an unconditional branch.
857e5dd7070Spatrick auto NL = ApplyDebugLocation::CreateEmpty(*this);
858e5dd7070Spatrick EmitBranch(ContBlock);
859e5dd7070Spatrick }
860e5dd7070Spatrick }
861e5dd7070Spatrick
862e5dd7070Spatrick // Emit the continuation block for code after the if.
863e5dd7070Spatrick EmitBlock(ContBlock, true);
864e5dd7070Spatrick }
865e5dd7070Spatrick
EmitWhileStmt(const WhileStmt & S,ArrayRef<const Attr * > WhileAttrs)866e5dd7070Spatrick void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
867e5dd7070Spatrick ArrayRef<const Attr *> WhileAttrs) {
868e5dd7070Spatrick // Emit the header for the loop, which will also become
869e5dd7070Spatrick // the continue target.
870e5dd7070Spatrick JumpDest LoopHeader = getJumpDestInCurrentScope("while.cond");
871e5dd7070Spatrick EmitBlock(LoopHeader.getBlock());
872e5dd7070Spatrick
873e5dd7070Spatrick // Create an exit block for when the condition fails, which will
874e5dd7070Spatrick // also become the break target.
875e5dd7070Spatrick JumpDest LoopExit = getJumpDestInCurrentScope("while.end");
876e5dd7070Spatrick
877e5dd7070Spatrick // Store the blocks to use for break and continue.
878e5dd7070Spatrick BreakContinueStack.push_back(BreakContinue(LoopExit, LoopHeader));
879e5dd7070Spatrick
880e5dd7070Spatrick // C++ [stmt.while]p2:
881e5dd7070Spatrick // When the condition of a while statement is a declaration, the
882e5dd7070Spatrick // scope of the variable that is declared extends from its point
883e5dd7070Spatrick // of declaration (3.3.2) to the end of the while statement.
884e5dd7070Spatrick // [...]
885e5dd7070Spatrick // The object created in a condition is destroyed and created
886e5dd7070Spatrick // with each iteration of the loop.
887e5dd7070Spatrick RunCleanupsScope ConditionScope(*this);
888e5dd7070Spatrick
889e5dd7070Spatrick if (S.getConditionVariable())
890e5dd7070Spatrick EmitDecl(*S.getConditionVariable());
891e5dd7070Spatrick
892e5dd7070Spatrick // Evaluate the conditional in the while header. C99 6.8.5.1: The
893e5dd7070Spatrick // evaluation of the controlling expression takes place before each
894e5dd7070Spatrick // execution of the loop body.
895e5dd7070Spatrick llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
896e5dd7070Spatrick
897e5dd7070Spatrick // while(1) is common, avoid extra exit blocks. Be sure
898e5dd7070Spatrick // to correctly handle break/continue though.
899a9ac8606Spatrick llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal);
900a9ac8606Spatrick bool CondIsConstInt = C != nullptr;
901a9ac8606Spatrick bool EmitBoolCondBranch = !CondIsConstInt || !C->isOne();
902a9ac8606Spatrick const SourceRange &R = S.getSourceRange();
903a9ac8606Spatrick LoopStack.push(LoopHeader.getBlock(), CGM.getContext(), CGM.getCodeGenOpts(),
904a9ac8606Spatrick WhileAttrs, SourceLocToDebugLoc(R.getBegin()),
905a9ac8606Spatrick SourceLocToDebugLoc(R.getEnd()),
906a9ac8606Spatrick checkIfLoopMustProgress(CondIsConstInt));
907e5dd7070Spatrick
908e5dd7070Spatrick // As long as the condition is true, go to the loop body.
909e5dd7070Spatrick llvm::BasicBlock *LoopBody = createBasicBlock("while.body");
910e5dd7070Spatrick if (EmitBoolCondBranch) {
911e5dd7070Spatrick llvm::BasicBlock *ExitBlock = LoopExit.getBlock();
912e5dd7070Spatrick if (ConditionScope.requiresCleanups())
913e5dd7070Spatrick ExitBlock = createBasicBlock("while.exit");
914a9ac8606Spatrick llvm::MDNode *Weights =
915a9ac8606Spatrick createProfileWeightsForLoop(S.getCond(), getProfileCount(S.getBody()));
916a9ac8606Spatrick if (!Weights && CGM.getCodeGenOpts().OptimizationLevel)
917a9ac8606Spatrick BoolCondVal = emitCondLikelihoodViaExpectIntrinsic(
918a9ac8606Spatrick BoolCondVal, Stmt::getLikelihood(S.getBody()));
919a9ac8606Spatrick Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock, Weights);
920e5dd7070Spatrick
921e5dd7070Spatrick if (ExitBlock != LoopExit.getBlock()) {
922e5dd7070Spatrick EmitBlock(ExitBlock);
923e5dd7070Spatrick EmitBranchThroughCleanup(LoopExit);
924e5dd7070Spatrick }
925a9ac8606Spatrick } else if (const Attr *A = Stmt::getLikelihoodAttr(S.getBody())) {
926a9ac8606Spatrick CGM.getDiags().Report(A->getLocation(),
927a9ac8606Spatrick diag::warn_attribute_has_no_effect_on_infinite_loop)
928a9ac8606Spatrick << A << A->getRange();
929a9ac8606Spatrick CGM.getDiags().Report(
930a9ac8606Spatrick S.getWhileLoc(),
931a9ac8606Spatrick diag::note_attribute_has_no_effect_on_infinite_loop_here)
932a9ac8606Spatrick << SourceRange(S.getWhileLoc(), S.getRParenLoc());
933e5dd7070Spatrick }
934e5dd7070Spatrick
935e5dd7070Spatrick // Emit the loop body. We have to emit this in a cleanup scope
936e5dd7070Spatrick // because it might be a singleton DeclStmt.
937e5dd7070Spatrick {
938e5dd7070Spatrick RunCleanupsScope BodyScope(*this);
939e5dd7070Spatrick EmitBlock(LoopBody);
940e5dd7070Spatrick incrementProfileCounter(&S);
941e5dd7070Spatrick EmitStmt(S.getBody());
942e5dd7070Spatrick }
943e5dd7070Spatrick
944e5dd7070Spatrick BreakContinueStack.pop_back();
945e5dd7070Spatrick
946e5dd7070Spatrick // Immediately force cleanup.
947e5dd7070Spatrick ConditionScope.ForceCleanup();
948e5dd7070Spatrick
949e5dd7070Spatrick EmitStopPoint(&S);
950e5dd7070Spatrick // Branch to the loop header again.
951e5dd7070Spatrick EmitBranch(LoopHeader.getBlock());
952e5dd7070Spatrick
953e5dd7070Spatrick LoopStack.pop();
954e5dd7070Spatrick
955e5dd7070Spatrick // Emit the exit block.
956e5dd7070Spatrick EmitBlock(LoopExit.getBlock(), true);
957e5dd7070Spatrick
958e5dd7070Spatrick // The LoopHeader typically is just a branch if we skipped emitting
959e5dd7070Spatrick // a branch, try to erase it.
960e5dd7070Spatrick if (!EmitBoolCondBranch)
961e5dd7070Spatrick SimplifyForwardingBlocks(LoopHeader.getBlock());
962e5dd7070Spatrick }
963e5dd7070Spatrick
EmitDoStmt(const DoStmt & S,ArrayRef<const Attr * > DoAttrs)964e5dd7070Spatrick void CodeGenFunction::EmitDoStmt(const DoStmt &S,
965e5dd7070Spatrick ArrayRef<const Attr *> DoAttrs) {
966e5dd7070Spatrick JumpDest LoopExit = getJumpDestInCurrentScope("do.end");
967e5dd7070Spatrick JumpDest LoopCond = getJumpDestInCurrentScope("do.cond");
968e5dd7070Spatrick
969e5dd7070Spatrick uint64_t ParentCount = getCurrentProfileCount();
970e5dd7070Spatrick
971e5dd7070Spatrick // Store the blocks to use for break and continue.
972e5dd7070Spatrick BreakContinueStack.push_back(BreakContinue(LoopExit, LoopCond));
973e5dd7070Spatrick
974e5dd7070Spatrick // Emit the body of the loop.
975e5dd7070Spatrick llvm::BasicBlock *LoopBody = createBasicBlock("do.body");
976e5dd7070Spatrick
977e5dd7070Spatrick EmitBlockWithFallThrough(LoopBody, &S);
978e5dd7070Spatrick {
979e5dd7070Spatrick RunCleanupsScope BodyScope(*this);
980e5dd7070Spatrick EmitStmt(S.getBody());
981e5dd7070Spatrick }
982e5dd7070Spatrick
983e5dd7070Spatrick EmitBlock(LoopCond.getBlock());
984e5dd7070Spatrick
985e5dd7070Spatrick // C99 6.8.5.2: "The evaluation of the controlling expression takes place
986e5dd7070Spatrick // after each execution of the loop body."
987e5dd7070Spatrick
988e5dd7070Spatrick // Evaluate the conditional in the while header.
989e5dd7070Spatrick // C99 6.8.5p2/p4: The first substatement is executed if the expression
990e5dd7070Spatrick // compares unequal to 0. The condition must be a scalar type.
991e5dd7070Spatrick llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
992e5dd7070Spatrick
993e5dd7070Spatrick BreakContinueStack.pop_back();
994e5dd7070Spatrick
995e5dd7070Spatrick // "do {} while (0)" is common in macros, avoid extra blocks. Be sure
996e5dd7070Spatrick // to correctly handle break/continue though.
997a9ac8606Spatrick llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal);
998a9ac8606Spatrick bool CondIsConstInt = C;
999a9ac8606Spatrick bool EmitBoolCondBranch = !C || !C->isZero();
1000a9ac8606Spatrick
1001a9ac8606Spatrick const SourceRange &R = S.getSourceRange();
1002a9ac8606Spatrick LoopStack.push(LoopBody, CGM.getContext(), CGM.getCodeGenOpts(), DoAttrs,
1003a9ac8606Spatrick SourceLocToDebugLoc(R.getBegin()),
1004a9ac8606Spatrick SourceLocToDebugLoc(R.getEnd()),
1005a9ac8606Spatrick checkIfLoopMustProgress(CondIsConstInt));
1006e5dd7070Spatrick
1007e5dd7070Spatrick // As long as the condition is true, iterate the loop.
1008e5dd7070Spatrick if (EmitBoolCondBranch) {
1009e5dd7070Spatrick uint64_t BackedgeCount = getProfileCount(S.getBody()) - ParentCount;
1010e5dd7070Spatrick Builder.CreateCondBr(
1011e5dd7070Spatrick BoolCondVal, LoopBody, LoopExit.getBlock(),
1012e5dd7070Spatrick createProfileWeightsForLoop(S.getCond(), BackedgeCount));
1013e5dd7070Spatrick }
1014e5dd7070Spatrick
1015e5dd7070Spatrick LoopStack.pop();
1016e5dd7070Spatrick
1017e5dd7070Spatrick // Emit the exit block.
1018e5dd7070Spatrick EmitBlock(LoopExit.getBlock());
1019e5dd7070Spatrick
1020e5dd7070Spatrick // The DoCond block typically is just a branch if we skipped
1021e5dd7070Spatrick // emitting a branch, try to erase it.
1022e5dd7070Spatrick if (!EmitBoolCondBranch)
1023e5dd7070Spatrick SimplifyForwardingBlocks(LoopCond.getBlock());
1024e5dd7070Spatrick }
1025e5dd7070Spatrick
EmitForStmt(const ForStmt & S,ArrayRef<const Attr * > ForAttrs)1026e5dd7070Spatrick void CodeGenFunction::EmitForStmt(const ForStmt &S,
1027e5dd7070Spatrick ArrayRef<const Attr *> ForAttrs) {
1028e5dd7070Spatrick JumpDest LoopExit = getJumpDestInCurrentScope("for.end");
1029e5dd7070Spatrick
1030e5dd7070Spatrick LexicalScope ForScope(*this, S.getSourceRange());
1031e5dd7070Spatrick
1032e5dd7070Spatrick // Evaluate the first part before the loop.
1033e5dd7070Spatrick if (S.getInit())
1034e5dd7070Spatrick EmitStmt(S.getInit());
1035e5dd7070Spatrick
1036e5dd7070Spatrick // Start the loop with a block that tests the condition.
1037e5dd7070Spatrick // If there's an increment, the continue scope will be overwritten
1038e5dd7070Spatrick // later.
1039a9ac8606Spatrick JumpDest CondDest = getJumpDestInCurrentScope("for.cond");
1040a9ac8606Spatrick llvm::BasicBlock *CondBlock = CondDest.getBlock();
1041e5dd7070Spatrick EmitBlock(CondBlock);
1042e5dd7070Spatrick
1043a9ac8606Spatrick Expr::EvalResult Result;
1044a9ac8606Spatrick bool CondIsConstInt =
1045a9ac8606Spatrick !S.getCond() || S.getCond()->EvaluateAsInt(Result, getContext());
1046a9ac8606Spatrick
1047e5dd7070Spatrick const SourceRange &R = S.getSourceRange();
1048ec727ea7Spatrick LoopStack.push(CondBlock, CGM.getContext(), CGM.getCodeGenOpts(), ForAttrs,
1049e5dd7070Spatrick SourceLocToDebugLoc(R.getBegin()),
1050a9ac8606Spatrick SourceLocToDebugLoc(R.getEnd()),
1051a9ac8606Spatrick checkIfLoopMustProgress(CondIsConstInt));
1052e5dd7070Spatrick
1053e5dd7070Spatrick // Create a cleanup scope for the condition variable cleanups.
1054e5dd7070Spatrick LexicalScope ConditionScope(*this, S.getSourceRange());
1055e5dd7070Spatrick
1056a9ac8606Spatrick // If the for loop doesn't have an increment we can just use the condition as
1057a9ac8606Spatrick // the continue block. Otherwise, if there is no condition variable, we can
1058a9ac8606Spatrick // form the continue block now. If there is a condition variable, we can't
1059a9ac8606Spatrick // form the continue block until after we've emitted the condition, because
1060a9ac8606Spatrick // the condition is in scope in the increment, but Sema's jump diagnostics
1061a9ac8606Spatrick // ensure that there are no continues from the condition variable that jump
1062a9ac8606Spatrick // to the loop increment.
1063a9ac8606Spatrick JumpDest Continue;
1064a9ac8606Spatrick if (!S.getInc())
1065a9ac8606Spatrick Continue = CondDest;
1066a9ac8606Spatrick else if (!S.getConditionVariable())
1067a9ac8606Spatrick Continue = getJumpDestInCurrentScope("for.inc");
1068a9ac8606Spatrick BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
1069a9ac8606Spatrick
1070e5dd7070Spatrick if (S.getCond()) {
1071e5dd7070Spatrick // If the for statement has a condition scope, emit the local variable
1072e5dd7070Spatrick // declaration.
1073e5dd7070Spatrick if (S.getConditionVariable()) {
1074e5dd7070Spatrick EmitDecl(*S.getConditionVariable());
1075a9ac8606Spatrick
1076a9ac8606Spatrick // We have entered the condition variable's scope, so we're now able to
1077a9ac8606Spatrick // jump to the continue block.
1078a9ac8606Spatrick Continue = S.getInc() ? getJumpDestInCurrentScope("for.inc") : CondDest;
1079a9ac8606Spatrick BreakContinueStack.back().ContinueBlock = Continue;
1080e5dd7070Spatrick }
1081e5dd7070Spatrick
1082e5dd7070Spatrick llvm::BasicBlock *ExitBlock = LoopExit.getBlock();
1083e5dd7070Spatrick // If there are any cleanups between here and the loop-exit scope,
1084e5dd7070Spatrick // create a block to stage a loop exit along.
1085e5dd7070Spatrick if (ForScope.requiresCleanups())
1086e5dd7070Spatrick ExitBlock = createBasicBlock("for.cond.cleanup");
1087e5dd7070Spatrick
1088e5dd7070Spatrick // As long as the condition is true, iterate the loop.
1089e5dd7070Spatrick llvm::BasicBlock *ForBody = createBasicBlock("for.body");
1090e5dd7070Spatrick
1091e5dd7070Spatrick // C99 6.8.5p2/p4: The first substatement is executed if the expression
1092e5dd7070Spatrick // compares unequal to 0. The condition must be a scalar type.
1093e5dd7070Spatrick llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
1094a9ac8606Spatrick llvm::MDNode *Weights =
1095a9ac8606Spatrick createProfileWeightsForLoop(S.getCond(), getProfileCount(S.getBody()));
1096a9ac8606Spatrick if (!Weights && CGM.getCodeGenOpts().OptimizationLevel)
1097a9ac8606Spatrick BoolCondVal = emitCondLikelihoodViaExpectIntrinsic(
1098a9ac8606Spatrick BoolCondVal, Stmt::getLikelihood(S.getBody()));
1099a9ac8606Spatrick
1100a9ac8606Spatrick Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock, Weights);
1101e5dd7070Spatrick
1102e5dd7070Spatrick if (ExitBlock != LoopExit.getBlock()) {
1103e5dd7070Spatrick EmitBlock(ExitBlock);
1104e5dd7070Spatrick EmitBranchThroughCleanup(LoopExit);
1105e5dd7070Spatrick }
1106e5dd7070Spatrick
1107e5dd7070Spatrick EmitBlock(ForBody);
1108e5dd7070Spatrick } else {
1109e5dd7070Spatrick // Treat it as a non-zero constant. Don't even create a new block for the
1110e5dd7070Spatrick // body, just fall into it.
1111e5dd7070Spatrick }
1112e5dd7070Spatrick incrementProfileCounter(&S);
1113e5dd7070Spatrick
1114e5dd7070Spatrick {
1115e5dd7070Spatrick // Create a separate cleanup scope for the body, in case it is not
1116e5dd7070Spatrick // a compound statement.
1117e5dd7070Spatrick RunCleanupsScope BodyScope(*this);
1118e5dd7070Spatrick EmitStmt(S.getBody());
1119e5dd7070Spatrick }
1120e5dd7070Spatrick
1121e5dd7070Spatrick // If there is an increment, emit it next.
1122e5dd7070Spatrick if (S.getInc()) {
1123e5dd7070Spatrick EmitBlock(Continue.getBlock());
1124e5dd7070Spatrick EmitStmt(S.getInc());
1125e5dd7070Spatrick }
1126e5dd7070Spatrick
1127e5dd7070Spatrick BreakContinueStack.pop_back();
1128e5dd7070Spatrick
1129e5dd7070Spatrick ConditionScope.ForceCleanup();
1130e5dd7070Spatrick
1131e5dd7070Spatrick EmitStopPoint(&S);
1132e5dd7070Spatrick EmitBranch(CondBlock);
1133e5dd7070Spatrick
1134e5dd7070Spatrick ForScope.ForceCleanup();
1135e5dd7070Spatrick
1136e5dd7070Spatrick LoopStack.pop();
1137e5dd7070Spatrick
1138e5dd7070Spatrick // Emit the fall-through block.
1139e5dd7070Spatrick EmitBlock(LoopExit.getBlock(), true);
1140e5dd7070Spatrick }
1141e5dd7070Spatrick
1142e5dd7070Spatrick void
EmitCXXForRangeStmt(const CXXForRangeStmt & S,ArrayRef<const Attr * > ForAttrs)1143e5dd7070Spatrick CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S,
1144e5dd7070Spatrick ArrayRef<const Attr *> ForAttrs) {
1145e5dd7070Spatrick JumpDest LoopExit = getJumpDestInCurrentScope("for.end");
1146e5dd7070Spatrick
1147e5dd7070Spatrick LexicalScope ForScope(*this, S.getSourceRange());
1148e5dd7070Spatrick
1149e5dd7070Spatrick // Evaluate the first pieces before the loop.
1150e5dd7070Spatrick if (S.getInit())
1151e5dd7070Spatrick EmitStmt(S.getInit());
1152e5dd7070Spatrick EmitStmt(S.getRangeStmt());
1153e5dd7070Spatrick EmitStmt(S.getBeginStmt());
1154e5dd7070Spatrick EmitStmt(S.getEndStmt());
1155e5dd7070Spatrick
1156e5dd7070Spatrick // Start the loop with a block that tests the condition.
1157e5dd7070Spatrick // If there's an increment, the continue scope will be overwritten
1158e5dd7070Spatrick // later.
1159e5dd7070Spatrick llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
1160e5dd7070Spatrick EmitBlock(CondBlock);
1161e5dd7070Spatrick
1162e5dd7070Spatrick const SourceRange &R = S.getSourceRange();
1163ec727ea7Spatrick LoopStack.push(CondBlock, CGM.getContext(), CGM.getCodeGenOpts(), ForAttrs,
1164e5dd7070Spatrick SourceLocToDebugLoc(R.getBegin()),
1165e5dd7070Spatrick SourceLocToDebugLoc(R.getEnd()));
1166e5dd7070Spatrick
1167e5dd7070Spatrick // If there are any cleanups between here and the loop-exit scope,
1168e5dd7070Spatrick // create a block to stage a loop exit along.
1169e5dd7070Spatrick llvm::BasicBlock *ExitBlock = LoopExit.getBlock();
1170e5dd7070Spatrick if (ForScope.requiresCleanups())
1171e5dd7070Spatrick ExitBlock = createBasicBlock("for.cond.cleanup");
1172e5dd7070Spatrick
1173e5dd7070Spatrick // The loop body, consisting of the specified body and the loop variable.
1174e5dd7070Spatrick llvm::BasicBlock *ForBody = createBasicBlock("for.body");
1175e5dd7070Spatrick
1176e5dd7070Spatrick // The body is executed if the expression, contextually converted
1177e5dd7070Spatrick // to bool, is true.
1178e5dd7070Spatrick llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
1179a9ac8606Spatrick llvm::MDNode *Weights =
1180a9ac8606Spatrick createProfileWeightsForLoop(S.getCond(), getProfileCount(S.getBody()));
1181a9ac8606Spatrick if (!Weights && CGM.getCodeGenOpts().OptimizationLevel)
1182a9ac8606Spatrick BoolCondVal = emitCondLikelihoodViaExpectIntrinsic(
1183a9ac8606Spatrick BoolCondVal, Stmt::getLikelihood(S.getBody()));
1184a9ac8606Spatrick Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock, Weights);
1185e5dd7070Spatrick
1186e5dd7070Spatrick if (ExitBlock != LoopExit.getBlock()) {
1187e5dd7070Spatrick EmitBlock(ExitBlock);
1188e5dd7070Spatrick EmitBranchThroughCleanup(LoopExit);
1189e5dd7070Spatrick }
1190e5dd7070Spatrick
1191e5dd7070Spatrick EmitBlock(ForBody);
1192e5dd7070Spatrick incrementProfileCounter(&S);
1193e5dd7070Spatrick
1194e5dd7070Spatrick // Create a block for the increment. In case of a 'continue', we jump there.
1195e5dd7070Spatrick JumpDest Continue = getJumpDestInCurrentScope("for.inc");
1196e5dd7070Spatrick
1197e5dd7070Spatrick // Store the blocks to use for break and continue.
1198e5dd7070Spatrick BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
1199e5dd7070Spatrick
1200e5dd7070Spatrick {
1201e5dd7070Spatrick // Create a separate cleanup scope for the loop variable and body.
1202e5dd7070Spatrick LexicalScope BodyScope(*this, S.getSourceRange());
1203e5dd7070Spatrick EmitStmt(S.getLoopVarStmt());
1204e5dd7070Spatrick EmitStmt(S.getBody());
1205e5dd7070Spatrick }
1206e5dd7070Spatrick
1207e5dd7070Spatrick EmitStopPoint(&S);
1208e5dd7070Spatrick // If there is an increment, emit it next.
1209e5dd7070Spatrick EmitBlock(Continue.getBlock());
1210e5dd7070Spatrick EmitStmt(S.getInc());
1211e5dd7070Spatrick
1212e5dd7070Spatrick BreakContinueStack.pop_back();
1213e5dd7070Spatrick
1214e5dd7070Spatrick EmitBranch(CondBlock);
1215e5dd7070Spatrick
1216e5dd7070Spatrick ForScope.ForceCleanup();
1217e5dd7070Spatrick
1218e5dd7070Spatrick LoopStack.pop();
1219e5dd7070Spatrick
1220e5dd7070Spatrick // Emit the fall-through block.
1221e5dd7070Spatrick EmitBlock(LoopExit.getBlock(), true);
1222e5dd7070Spatrick }
1223e5dd7070Spatrick
EmitReturnOfRValue(RValue RV,QualType Ty)1224e5dd7070Spatrick void CodeGenFunction::EmitReturnOfRValue(RValue RV, QualType Ty) {
1225e5dd7070Spatrick if (RV.isScalar()) {
1226e5dd7070Spatrick Builder.CreateStore(RV.getScalarVal(), ReturnValue);
1227e5dd7070Spatrick } else if (RV.isAggregate()) {
1228e5dd7070Spatrick LValue Dest = MakeAddrLValue(ReturnValue, Ty);
1229e5dd7070Spatrick LValue Src = MakeAddrLValue(RV.getAggregateAddress(), Ty);
1230e5dd7070Spatrick EmitAggregateCopy(Dest, Src, Ty, getOverlapForReturnValue());
1231e5dd7070Spatrick } else {
1232e5dd7070Spatrick EmitStoreOfComplex(RV.getComplexVal(), MakeAddrLValue(ReturnValue, Ty),
1233e5dd7070Spatrick /*init*/ true);
1234e5dd7070Spatrick }
1235e5dd7070Spatrick EmitBranchThroughCleanup(ReturnBlock);
1236e5dd7070Spatrick }
1237e5dd7070Spatrick
1238ec727ea7Spatrick namespace {
1239ec727ea7Spatrick // RAII struct used to save and restore a return statment's result expression.
1240ec727ea7Spatrick struct SaveRetExprRAII {
SaveRetExprRAII__anonda1bbda70111::SaveRetExprRAII1241ec727ea7Spatrick SaveRetExprRAII(const Expr *RetExpr, CodeGenFunction &CGF)
1242ec727ea7Spatrick : OldRetExpr(CGF.RetExpr), CGF(CGF) {
1243ec727ea7Spatrick CGF.RetExpr = RetExpr;
1244ec727ea7Spatrick }
~SaveRetExprRAII__anonda1bbda70111::SaveRetExprRAII1245ec727ea7Spatrick ~SaveRetExprRAII() { CGF.RetExpr = OldRetExpr; }
1246ec727ea7Spatrick const Expr *OldRetExpr;
1247ec727ea7Spatrick CodeGenFunction &CGF;
1248ec727ea7Spatrick };
1249ec727ea7Spatrick } // namespace
1250ec727ea7Spatrick
1251a9ac8606Spatrick /// If we have 'return f(...);', where both caller and callee are SwiftAsync,
1252a9ac8606Spatrick /// codegen it as 'tail call ...; ret void;'.
makeTailCallIfSwiftAsync(const CallExpr * CE,CGBuilderTy & Builder,const CGFunctionInfo * CurFnInfo)1253a9ac8606Spatrick static void makeTailCallIfSwiftAsync(const CallExpr *CE, CGBuilderTy &Builder,
1254a9ac8606Spatrick const CGFunctionInfo *CurFnInfo) {
1255a9ac8606Spatrick auto calleeQualType = CE->getCallee()->getType();
1256a9ac8606Spatrick const FunctionType *calleeType = nullptr;
1257a9ac8606Spatrick if (calleeQualType->isFunctionPointerType() ||
1258a9ac8606Spatrick calleeQualType->isFunctionReferenceType() ||
1259a9ac8606Spatrick calleeQualType->isBlockPointerType() ||
1260a9ac8606Spatrick calleeQualType->isMemberFunctionPointerType()) {
1261a9ac8606Spatrick calleeType = calleeQualType->getPointeeType()->castAs<FunctionType>();
1262a9ac8606Spatrick } else if (auto *ty = dyn_cast<FunctionType>(calleeQualType)) {
1263a9ac8606Spatrick calleeType = ty;
1264a9ac8606Spatrick } else if (auto CMCE = dyn_cast<CXXMemberCallExpr>(CE)) {
1265a9ac8606Spatrick if (auto methodDecl = CMCE->getMethodDecl()) {
1266a9ac8606Spatrick // getMethodDecl() doesn't handle member pointers at the moment.
1267a9ac8606Spatrick calleeType = methodDecl->getType()->castAs<FunctionType>();
1268a9ac8606Spatrick } else {
1269a9ac8606Spatrick return;
1270a9ac8606Spatrick }
1271a9ac8606Spatrick } else {
1272a9ac8606Spatrick return;
1273a9ac8606Spatrick }
1274a9ac8606Spatrick if (calleeType->getCallConv() == CallingConv::CC_SwiftAsync &&
1275a9ac8606Spatrick (CurFnInfo->getASTCallingConvention() == CallingConv::CC_SwiftAsync)) {
1276a9ac8606Spatrick auto CI = cast<llvm::CallInst>(&Builder.GetInsertBlock()->back());
1277a9ac8606Spatrick CI->setTailCallKind(llvm::CallInst::TCK_MustTail);
1278a9ac8606Spatrick Builder.CreateRetVoid();
1279a9ac8606Spatrick Builder.ClearInsertionPoint();
1280a9ac8606Spatrick }
1281a9ac8606Spatrick }
1282a9ac8606Spatrick
1283e5dd7070Spatrick /// EmitReturnStmt - Note that due to GCC extensions, this can have an operand
1284e5dd7070Spatrick /// if the function returns void, or may be missing one if the function returns
1285e5dd7070Spatrick /// non-void. Fun stuff :).
EmitReturnStmt(const ReturnStmt & S)1286e5dd7070Spatrick void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) {
1287e5dd7070Spatrick if (requiresReturnValueCheck()) {
1288e5dd7070Spatrick llvm::Constant *SLoc = EmitCheckSourceLocation(S.getBeginLoc());
1289e5dd7070Spatrick auto *SLocPtr =
1290e5dd7070Spatrick new llvm::GlobalVariable(CGM.getModule(), SLoc->getType(), false,
1291e5dd7070Spatrick llvm::GlobalVariable::PrivateLinkage, SLoc);
1292e5dd7070Spatrick SLocPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1293e5dd7070Spatrick CGM.getSanitizerMetadata()->disableSanitizerForGlobal(SLocPtr);
1294e5dd7070Spatrick assert(ReturnLocation.isValid() && "No valid return location");
1295e5dd7070Spatrick Builder.CreateStore(Builder.CreateBitCast(SLocPtr, Int8PtrTy),
1296e5dd7070Spatrick ReturnLocation);
1297e5dd7070Spatrick }
1298e5dd7070Spatrick
1299e5dd7070Spatrick // Returning from an outlined SEH helper is UB, and we already warn on it.
1300e5dd7070Spatrick if (IsOutlinedSEHHelper) {
1301e5dd7070Spatrick Builder.CreateUnreachable();
1302e5dd7070Spatrick Builder.ClearInsertionPoint();
1303e5dd7070Spatrick }
1304e5dd7070Spatrick
1305e5dd7070Spatrick // Emit the result value, even if unused, to evaluate the side effects.
1306e5dd7070Spatrick const Expr *RV = S.getRetValue();
1307e5dd7070Spatrick
1308ec727ea7Spatrick // Record the result expression of the return statement. The recorded
1309ec727ea7Spatrick // expression is used to determine whether a block capture's lifetime should
1310ec727ea7Spatrick // end at the end of the full expression as opposed to the end of the scope
1311ec727ea7Spatrick // enclosing the block expression.
1312ec727ea7Spatrick //
1313ec727ea7Spatrick // This permits a small, easily-implemented exception to our over-conservative
1314ec727ea7Spatrick // rules about not jumping to statements following block literals with
1315ec727ea7Spatrick // non-trivial cleanups.
1316ec727ea7Spatrick SaveRetExprRAII SaveRetExpr(RV, *this);
1317e5dd7070Spatrick
1318ec727ea7Spatrick RunCleanupsScope cleanupScope(*this);
1319ec727ea7Spatrick if (const auto *EWC = dyn_cast_or_null<ExprWithCleanups>(RV))
1320ec727ea7Spatrick RV = EWC->getSubExpr();
1321e5dd7070Spatrick // FIXME: Clean this up by using an LValue for ReturnTemp,
1322e5dd7070Spatrick // EmitStoreThroughLValue, and EmitAnyExpr.
1323ec727ea7Spatrick // Check if the NRVO candidate was not globalized in OpenMP mode.
1324ec727ea7Spatrick if (getLangOpts().ElideConstructors && S.getNRVOCandidate() &&
1325ec727ea7Spatrick S.getNRVOCandidate()->isNRVOVariable() &&
1326ec727ea7Spatrick (!getLangOpts().OpenMP ||
1327ec727ea7Spatrick !CGM.getOpenMPRuntime()
1328ec727ea7Spatrick .getAddressOfLocalVariable(*this, S.getNRVOCandidate())
1329ec727ea7Spatrick .isValid())) {
1330e5dd7070Spatrick // Apply the named return value optimization for this return statement,
1331e5dd7070Spatrick // which means doing nothing: the appropriate result has already been
1332e5dd7070Spatrick // constructed into the NRVO variable.
1333e5dd7070Spatrick
1334e5dd7070Spatrick // If there is an NRVO flag for this variable, set it to 1 into indicate
1335e5dd7070Spatrick // that the cleanup code should not destroy the variable.
1336e5dd7070Spatrick if (llvm::Value *NRVOFlag = NRVOFlags[S.getNRVOCandidate()])
1337e5dd7070Spatrick Builder.CreateFlagStore(Builder.getTrue(), NRVOFlag);
1338e5dd7070Spatrick } else if (!ReturnValue.isValid() || (RV && RV->getType()->isVoidType())) {
1339e5dd7070Spatrick // Make sure not to return anything, but evaluate the expression
1340e5dd7070Spatrick // for side effects.
1341a9ac8606Spatrick if (RV) {
1342e5dd7070Spatrick EmitAnyExpr(RV);
1343a9ac8606Spatrick if (auto *CE = dyn_cast<CallExpr>(RV))
1344a9ac8606Spatrick makeTailCallIfSwiftAsync(CE, Builder, CurFnInfo);
1345a9ac8606Spatrick }
1346e5dd7070Spatrick } else if (!RV) {
1347e5dd7070Spatrick // Do nothing (return value is left uninitialized)
1348e5dd7070Spatrick } else if (FnRetTy->isReferenceType()) {
1349e5dd7070Spatrick // If this function returns a reference, take the address of the expression
1350e5dd7070Spatrick // rather than the value.
1351e5dd7070Spatrick RValue Result = EmitReferenceBindingToExpr(RV);
1352e5dd7070Spatrick Builder.CreateStore(Result.getScalarVal(), ReturnValue);
1353e5dd7070Spatrick } else {
1354e5dd7070Spatrick switch (getEvaluationKind(RV->getType())) {
1355e5dd7070Spatrick case TEK_Scalar:
1356e5dd7070Spatrick Builder.CreateStore(EmitScalarExpr(RV), ReturnValue);
1357e5dd7070Spatrick break;
1358e5dd7070Spatrick case TEK_Complex:
1359e5dd7070Spatrick EmitComplexExprIntoLValue(RV, MakeAddrLValue(ReturnValue, RV->getType()),
1360e5dd7070Spatrick /*isInit*/ true);
1361e5dd7070Spatrick break;
1362e5dd7070Spatrick case TEK_Aggregate:
1363e5dd7070Spatrick EmitAggExpr(RV, AggValueSlot::forAddr(
1364e5dd7070Spatrick ReturnValue, Qualifiers(),
1365e5dd7070Spatrick AggValueSlot::IsDestructed,
1366e5dd7070Spatrick AggValueSlot::DoesNotNeedGCBarriers,
1367e5dd7070Spatrick AggValueSlot::IsNotAliased,
1368e5dd7070Spatrick getOverlapForReturnValue()));
1369e5dd7070Spatrick break;
1370e5dd7070Spatrick }
1371e5dd7070Spatrick }
1372e5dd7070Spatrick
1373e5dd7070Spatrick ++NumReturnExprs;
1374e5dd7070Spatrick if (!RV || RV->isEvaluatable(getContext()))
1375e5dd7070Spatrick ++NumSimpleReturnExprs;
1376e5dd7070Spatrick
1377e5dd7070Spatrick cleanupScope.ForceCleanup();
1378e5dd7070Spatrick EmitBranchThroughCleanup(ReturnBlock);
1379e5dd7070Spatrick }
1380e5dd7070Spatrick
EmitDeclStmt(const DeclStmt & S)1381e5dd7070Spatrick void CodeGenFunction::EmitDeclStmt(const DeclStmt &S) {
1382e5dd7070Spatrick // As long as debug info is modeled with instructions, we have to ensure we
1383e5dd7070Spatrick // have a place to insert here and write the stop point here.
1384e5dd7070Spatrick if (HaveInsertPoint())
1385e5dd7070Spatrick EmitStopPoint(&S);
1386e5dd7070Spatrick
1387e5dd7070Spatrick for (const auto *I : S.decls())
1388e5dd7070Spatrick EmitDecl(*I);
1389e5dd7070Spatrick }
1390e5dd7070Spatrick
EmitBreakStmt(const BreakStmt & S)1391e5dd7070Spatrick void CodeGenFunction::EmitBreakStmt(const BreakStmt &S) {
1392e5dd7070Spatrick assert(!BreakContinueStack.empty() && "break stmt not in a loop or switch!");
1393e5dd7070Spatrick
1394e5dd7070Spatrick // If this code is reachable then emit a stop point (if generating
1395e5dd7070Spatrick // debug info). We have to do this ourselves because we are on the
1396e5dd7070Spatrick // "simple" statement path.
1397e5dd7070Spatrick if (HaveInsertPoint())
1398e5dd7070Spatrick EmitStopPoint(&S);
1399e5dd7070Spatrick
1400e5dd7070Spatrick EmitBranchThroughCleanup(BreakContinueStack.back().BreakBlock);
1401e5dd7070Spatrick }
1402e5dd7070Spatrick
EmitContinueStmt(const ContinueStmt & S)1403e5dd7070Spatrick void CodeGenFunction::EmitContinueStmt(const ContinueStmt &S) {
1404e5dd7070Spatrick assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
1405e5dd7070Spatrick
1406e5dd7070Spatrick // If this code is reachable then emit a stop point (if generating
1407e5dd7070Spatrick // debug info). We have to do this ourselves because we are on the
1408e5dd7070Spatrick // "simple" statement path.
1409e5dd7070Spatrick if (HaveInsertPoint())
1410e5dd7070Spatrick EmitStopPoint(&S);
1411e5dd7070Spatrick
1412e5dd7070Spatrick EmitBranchThroughCleanup(BreakContinueStack.back().ContinueBlock);
1413e5dd7070Spatrick }
1414e5dd7070Spatrick
1415e5dd7070Spatrick /// EmitCaseStmtRange - If case statement range is not too big then
1416e5dd7070Spatrick /// add multiple cases to switch instruction, one for each value within
1417e5dd7070Spatrick /// the range. If range is too big then emit "if" condition check.
EmitCaseStmtRange(const CaseStmt & S,ArrayRef<const Attr * > Attrs)1418a9ac8606Spatrick void CodeGenFunction::EmitCaseStmtRange(const CaseStmt &S,
1419a9ac8606Spatrick ArrayRef<const Attr *> Attrs) {
1420e5dd7070Spatrick assert(S.getRHS() && "Expected RHS value in CaseStmt");
1421e5dd7070Spatrick
1422e5dd7070Spatrick llvm::APSInt LHS = S.getLHS()->EvaluateKnownConstInt(getContext());
1423e5dd7070Spatrick llvm::APSInt RHS = S.getRHS()->EvaluateKnownConstInt(getContext());
1424e5dd7070Spatrick
1425e5dd7070Spatrick // Emit the code for this case. We do this first to make sure it is
1426e5dd7070Spatrick // properly chained from our predecessor before generating the
1427e5dd7070Spatrick // switch machinery to enter this block.
1428e5dd7070Spatrick llvm::BasicBlock *CaseDest = createBasicBlock("sw.bb");
1429e5dd7070Spatrick EmitBlockWithFallThrough(CaseDest, &S);
1430e5dd7070Spatrick EmitStmt(S.getSubStmt());
1431e5dd7070Spatrick
1432e5dd7070Spatrick // If range is empty, do nothing.
1433e5dd7070Spatrick if (LHS.isSigned() ? RHS.slt(LHS) : RHS.ult(LHS))
1434e5dd7070Spatrick return;
1435e5dd7070Spatrick
1436a9ac8606Spatrick Stmt::Likelihood LH = Stmt::getLikelihood(Attrs);
1437e5dd7070Spatrick llvm::APInt Range = RHS - LHS;
1438e5dd7070Spatrick // FIXME: parameters such as this should not be hardcoded.
1439e5dd7070Spatrick if (Range.ult(llvm::APInt(Range.getBitWidth(), 64))) {
1440e5dd7070Spatrick // Range is small enough to add multiple switch instruction cases.
1441e5dd7070Spatrick uint64_t Total = getProfileCount(&S);
1442e5dd7070Spatrick unsigned NCases = Range.getZExtValue() + 1;
1443e5dd7070Spatrick // We only have one region counter for the entire set of cases here, so we
1444e5dd7070Spatrick // need to divide the weights evenly between the generated cases, ensuring
1445e5dd7070Spatrick // that the total weight is preserved. E.g., a weight of 5 over three cases
1446e5dd7070Spatrick // will be distributed as weights of 2, 2, and 1.
1447e5dd7070Spatrick uint64_t Weight = Total / NCases, Rem = Total % NCases;
1448e5dd7070Spatrick for (unsigned I = 0; I != NCases; ++I) {
1449e5dd7070Spatrick if (SwitchWeights)
1450e5dd7070Spatrick SwitchWeights->push_back(Weight + (Rem ? 1 : 0));
1451a9ac8606Spatrick else if (SwitchLikelihood)
1452a9ac8606Spatrick SwitchLikelihood->push_back(LH);
1453a9ac8606Spatrick
1454e5dd7070Spatrick if (Rem)
1455e5dd7070Spatrick Rem--;
1456e5dd7070Spatrick SwitchInsn->addCase(Builder.getInt(LHS), CaseDest);
1457e5dd7070Spatrick ++LHS;
1458e5dd7070Spatrick }
1459e5dd7070Spatrick return;
1460e5dd7070Spatrick }
1461e5dd7070Spatrick
1462e5dd7070Spatrick // The range is too big. Emit "if" condition into a new block,
1463e5dd7070Spatrick // making sure to save and restore the current insertion point.
1464e5dd7070Spatrick llvm::BasicBlock *RestoreBB = Builder.GetInsertBlock();
1465e5dd7070Spatrick
1466e5dd7070Spatrick // Push this test onto the chain of range checks (which terminates
1467e5dd7070Spatrick // in the default basic block). The switch's default will be changed
1468e5dd7070Spatrick // to the top of this chain after switch emission is complete.
1469e5dd7070Spatrick llvm::BasicBlock *FalseDest = CaseRangeBlock;
1470e5dd7070Spatrick CaseRangeBlock = createBasicBlock("sw.caserange");
1471e5dd7070Spatrick
1472*12c85518Srobert CurFn->insert(CurFn->end(), CaseRangeBlock);
1473e5dd7070Spatrick Builder.SetInsertPoint(CaseRangeBlock);
1474e5dd7070Spatrick
1475e5dd7070Spatrick // Emit range check.
1476e5dd7070Spatrick llvm::Value *Diff =
1477e5dd7070Spatrick Builder.CreateSub(SwitchInsn->getCondition(), Builder.getInt(LHS));
1478e5dd7070Spatrick llvm::Value *Cond =
1479e5dd7070Spatrick Builder.CreateICmpULE(Diff, Builder.getInt(Range), "inbounds");
1480e5dd7070Spatrick
1481e5dd7070Spatrick llvm::MDNode *Weights = nullptr;
1482e5dd7070Spatrick if (SwitchWeights) {
1483e5dd7070Spatrick uint64_t ThisCount = getProfileCount(&S);
1484e5dd7070Spatrick uint64_t DefaultCount = (*SwitchWeights)[0];
1485e5dd7070Spatrick Weights = createProfileWeights(ThisCount, DefaultCount);
1486e5dd7070Spatrick
1487e5dd7070Spatrick // Since we're chaining the switch default through each large case range, we
1488e5dd7070Spatrick // need to update the weight for the default, ie, the first case, to include
1489e5dd7070Spatrick // this case.
1490e5dd7070Spatrick (*SwitchWeights)[0] += ThisCount;
1491a9ac8606Spatrick } else if (SwitchLikelihood)
1492a9ac8606Spatrick Cond = emitCondLikelihoodViaExpectIntrinsic(Cond, LH);
1493a9ac8606Spatrick
1494e5dd7070Spatrick Builder.CreateCondBr(Cond, CaseDest, FalseDest, Weights);
1495e5dd7070Spatrick
1496e5dd7070Spatrick // Restore the appropriate insertion point.
1497e5dd7070Spatrick if (RestoreBB)
1498e5dd7070Spatrick Builder.SetInsertPoint(RestoreBB);
1499e5dd7070Spatrick else
1500e5dd7070Spatrick Builder.ClearInsertionPoint();
1501e5dd7070Spatrick }
1502e5dd7070Spatrick
EmitCaseStmt(const CaseStmt & S,ArrayRef<const Attr * > Attrs)1503a9ac8606Spatrick void CodeGenFunction::EmitCaseStmt(const CaseStmt &S,
1504a9ac8606Spatrick ArrayRef<const Attr *> Attrs) {
1505e5dd7070Spatrick // If there is no enclosing switch instance that we're aware of, then this
1506e5dd7070Spatrick // case statement and its block can be elided. This situation only happens
1507e5dd7070Spatrick // when we've constant-folded the switch, are emitting the constant case,
1508e5dd7070Spatrick // and part of the constant case includes another case statement. For
1509e5dd7070Spatrick // instance: switch (4) { case 4: do { case 5: } while (1); }
1510e5dd7070Spatrick if (!SwitchInsn) {
1511e5dd7070Spatrick EmitStmt(S.getSubStmt());
1512e5dd7070Spatrick return;
1513e5dd7070Spatrick }
1514e5dd7070Spatrick
1515e5dd7070Spatrick // Handle case ranges.
1516e5dd7070Spatrick if (S.getRHS()) {
1517a9ac8606Spatrick EmitCaseStmtRange(S, Attrs);
1518e5dd7070Spatrick return;
1519e5dd7070Spatrick }
1520e5dd7070Spatrick
1521e5dd7070Spatrick llvm::ConstantInt *CaseVal =
1522e5dd7070Spatrick Builder.getInt(S.getLHS()->EvaluateKnownConstInt(getContext()));
1523*12c85518Srobert
1524*12c85518Srobert // Emit debuginfo for the case value if it is an enum value.
1525*12c85518Srobert const ConstantExpr *CE;
1526*12c85518Srobert if (auto ICE = dyn_cast<ImplicitCastExpr>(S.getLHS()))
1527*12c85518Srobert CE = dyn_cast<ConstantExpr>(ICE->getSubExpr());
1528*12c85518Srobert else
1529*12c85518Srobert CE = dyn_cast<ConstantExpr>(S.getLHS());
1530*12c85518Srobert if (CE) {
1531*12c85518Srobert if (auto DE = dyn_cast<DeclRefExpr>(CE->getSubExpr()))
1532*12c85518Srobert if (CGDebugInfo *Dbg = getDebugInfo())
1533*12c85518Srobert if (CGM.getCodeGenOpts().hasReducedDebugInfo())
1534*12c85518Srobert Dbg->EmitGlobalVariable(DE->getDecl(),
1535*12c85518Srobert APValue(llvm::APSInt(CaseVal->getValue())));
1536*12c85518Srobert }
1537*12c85518Srobert
1538a9ac8606Spatrick if (SwitchLikelihood)
1539a9ac8606Spatrick SwitchLikelihood->push_back(Stmt::getLikelihood(Attrs));
1540e5dd7070Spatrick
1541e5dd7070Spatrick // If the body of the case is just a 'break', try to not emit an empty block.
1542e5dd7070Spatrick // If we're profiling or we're not optimizing, leave the block in for better
1543e5dd7070Spatrick // debug and coverage analysis.
1544e5dd7070Spatrick if (!CGM.getCodeGenOpts().hasProfileClangInstr() &&
1545e5dd7070Spatrick CGM.getCodeGenOpts().OptimizationLevel > 0 &&
1546e5dd7070Spatrick isa<BreakStmt>(S.getSubStmt())) {
1547e5dd7070Spatrick JumpDest Block = BreakContinueStack.back().BreakBlock;
1548e5dd7070Spatrick
1549e5dd7070Spatrick // Only do this optimization if there are no cleanups that need emitting.
1550e5dd7070Spatrick if (isObviouslyBranchWithoutCleanups(Block)) {
1551e5dd7070Spatrick if (SwitchWeights)
1552e5dd7070Spatrick SwitchWeights->push_back(getProfileCount(&S));
1553e5dd7070Spatrick SwitchInsn->addCase(CaseVal, Block.getBlock());
1554e5dd7070Spatrick
1555e5dd7070Spatrick // If there was a fallthrough into this case, make sure to redirect it to
1556e5dd7070Spatrick // the end of the switch as well.
1557e5dd7070Spatrick if (Builder.GetInsertBlock()) {
1558e5dd7070Spatrick Builder.CreateBr(Block.getBlock());
1559e5dd7070Spatrick Builder.ClearInsertionPoint();
1560e5dd7070Spatrick }
1561e5dd7070Spatrick return;
1562e5dd7070Spatrick }
1563e5dd7070Spatrick }
1564e5dd7070Spatrick
1565e5dd7070Spatrick llvm::BasicBlock *CaseDest = createBasicBlock("sw.bb");
1566e5dd7070Spatrick EmitBlockWithFallThrough(CaseDest, &S);
1567e5dd7070Spatrick if (SwitchWeights)
1568e5dd7070Spatrick SwitchWeights->push_back(getProfileCount(&S));
1569e5dd7070Spatrick SwitchInsn->addCase(CaseVal, CaseDest);
1570e5dd7070Spatrick
1571e5dd7070Spatrick // Recursively emitting the statement is acceptable, but is not wonderful for
1572e5dd7070Spatrick // code where we have many case statements nested together, i.e.:
1573e5dd7070Spatrick // case 1:
1574e5dd7070Spatrick // case 2:
1575e5dd7070Spatrick // case 3: etc.
1576e5dd7070Spatrick // Handling this recursively will create a new block for each case statement
1577e5dd7070Spatrick // that falls through to the next case which is IR intensive. It also causes
1578e5dd7070Spatrick // deep recursion which can run into stack depth limitations. Handle
1579e5dd7070Spatrick // sequential non-range case statements specially.
1580a9ac8606Spatrick //
1581a9ac8606Spatrick // TODO When the next case has a likelihood attribute the code returns to the
1582a9ac8606Spatrick // recursive algorithm. Maybe improve this case if it becomes common practice
1583a9ac8606Spatrick // to use a lot of attributes.
1584e5dd7070Spatrick const CaseStmt *CurCase = &S;
1585e5dd7070Spatrick const CaseStmt *NextCase = dyn_cast<CaseStmt>(S.getSubStmt());
1586e5dd7070Spatrick
1587e5dd7070Spatrick // Otherwise, iteratively add consecutive cases to this switch stmt.
1588e5dd7070Spatrick while (NextCase && NextCase->getRHS() == nullptr) {
1589e5dd7070Spatrick CurCase = NextCase;
1590e5dd7070Spatrick llvm::ConstantInt *CaseVal =
1591e5dd7070Spatrick Builder.getInt(CurCase->getLHS()->EvaluateKnownConstInt(getContext()));
1592e5dd7070Spatrick
1593e5dd7070Spatrick if (SwitchWeights)
1594e5dd7070Spatrick SwitchWeights->push_back(getProfileCount(NextCase));
1595e5dd7070Spatrick if (CGM.getCodeGenOpts().hasProfileClangInstr()) {
1596e5dd7070Spatrick CaseDest = createBasicBlock("sw.bb");
1597a9ac8606Spatrick EmitBlockWithFallThrough(CaseDest, CurCase);
1598e5dd7070Spatrick }
1599a9ac8606Spatrick // Since this loop is only executed when the CaseStmt has no attributes
1600a9ac8606Spatrick // use a hard-coded value.
1601a9ac8606Spatrick if (SwitchLikelihood)
1602a9ac8606Spatrick SwitchLikelihood->push_back(Stmt::LH_None);
1603e5dd7070Spatrick
1604e5dd7070Spatrick SwitchInsn->addCase(CaseVal, CaseDest);
1605e5dd7070Spatrick NextCase = dyn_cast<CaseStmt>(CurCase->getSubStmt());
1606e5dd7070Spatrick }
1607e5dd7070Spatrick
1608*12c85518Srobert // Generate a stop point for debug info if the case statement is
1609*12c85518Srobert // followed by a default statement. A fallthrough case before a
1610*12c85518Srobert // default case gets its own branch target.
1611*12c85518Srobert if (CurCase->getSubStmt()->getStmtClass() == Stmt::DefaultStmtClass)
1612*12c85518Srobert EmitStopPoint(CurCase);
1613*12c85518Srobert
1614e5dd7070Spatrick // Normal default recursion for non-cases.
1615e5dd7070Spatrick EmitStmt(CurCase->getSubStmt());
1616e5dd7070Spatrick }
1617e5dd7070Spatrick
EmitDefaultStmt(const DefaultStmt & S,ArrayRef<const Attr * > Attrs)1618a9ac8606Spatrick void CodeGenFunction::EmitDefaultStmt(const DefaultStmt &S,
1619a9ac8606Spatrick ArrayRef<const Attr *> Attrs) {
1620e5dd7070Spatrick // If there is no enclosing switch instance that we're aware of, then this
1621e5dd7070Spatrick // default statement can be elided. This situation only happens when we've
1622e5dd7070Spatrick // constant-folded the switch.
1623e5dd7070Spatrick if (!SwitchInsn) {
1624e5dd7070Spatrick EmitStmt(S.getSubStmt());
1625e5dd7070Spatrick return;
1626e5dd7070Spatrick }
1627e5dd7070Spatrick
1628e5dd7070Spatrick llvm::BasicBlock *DefaultBlock = SwitchInsn->getDefaultDest();
1629e5dd7070Spatrick assert(DefaultBlock->empty() &&
1630e5dd7070Spatrick "EmitDefaultStmt: Default block already defined?");
1631e5dd7070Spatrick
1632a9ac8606Spatrick if (SwitchLikelihood)
1633a9ac8606Spatrick SwitchLikelihood->front() = Stmt::getLikelihood(Attrs);
1634a9ac8606Spatrick
1635e5dd7070Spatrick EmitBlockWithFallThrough(DefaultBlock, &S);
1636e5dd7070Spatrick
1637e5dd7070Spatrick EmitStmt(S.getSubStmt());
1638e5dd7070Spatrick }
1639e5dd7070Spatrick
1640e5dd7070Spatrick /// CollectStatementsForCase - Given the body of a 'switch' statement and a
1641e5dd7070Spatrick /// constant value that is being switched on, see if we can dead code eliminate
1642e5dd7070Spatrick /// the body of the switch to a simple series of statements to emit. Basically,
1643e5dd7070Spatrick /// on a switch (5) we want to find these statements:
1644e5dd7070Spatrick /// case 5:
1645e5dd7070Spatrick /// printf(...); <--
1646e5dd7070Spatrick /// ++i; <--
1647e5dd7070Spatrick /// break;
1648e5dd7070Spatrick ///
1649e5dd7070Spatrick /// and add them to the ResultStmts vector. If it is unsafe to do this
1650e5dd7070Spatrick /// transformation (for example, one of the elided statements contains a label
1651e5dd7070Spatrick /// that might be jumped to), return CSFC_Failure. If we handled it and 'S'
1652e5dd7070Spatrick /// should include statements after it (e.g. the printf() line is a substmt of
1653e5dd7070Spatrick /// the case) then return CSFC_FallThrough. If we handled it and found a break
1654e5dd7070Spatrick /// statement, then return CSFC_Success.
1655e5dd7070Spatrick ///
1656e5dd7070Spatrick /// If Case is non-null, then we are looking for the specified case, checking
1657e5dd7070Spatrick /// that nothing we jump over contains labels. If Case is null, then we found
1658e5dd7070Spatrick /// the case and are looking for the break.
1659e5dd7070Spatrick ///
1660e5dd7070Spatrick /// If the recursive walk actually finds our Case, then we set FoundCase to
1661e5dd7070Spatrick /// true.
1662e5dd7070Spatrick ///
1663e5dd7070Spatrick enum CSFC_Result { CSFC_Failure, CSFC_FallThrough, CSFC_Success };
CollectStatementsForCase(const Stmt * S,const SwitchCase * Case,bool & FoundCase,SmallVectorImpl<const Stmt * > & ResultStmts)1664e5dd7070Spatrick static CSFC_Result CollectStatementsForCase(const Stmt *S,
1665e5dd7070Spatrick const SwitchCase *Case,
1666e5dd7070Spatrick bool &FoundCase,
1667e5dd7070Spatrick SmallVectorImpl<const Stmt*> &ResultStmts) {
1668e5dd7070Spatrick // If this is a null statement, just succeed.
1669e5dd7070Spatrick if (!S)
1670e5dd7070Spatrick return Case ? CSFC_Success : CSFC_FallThrough;
1671e5dd7070Spatrick
1672e5dd7070Spatrick // If this is the switchcase (case 4: or default) that we're looking for, then
1673e5dd7070Spatrick // we're in business. Just add the substatement.
1674e5dd7070Spatrick if (const SwitchCase *SC = dyn_cast<SwitchCase>(S)) {
1675e5dd7070Spatrick if (S == Case) {
1676e5dd7070Spatrick FoundCase = true;
1677e5dd7070Spatrick return CollectStatementsForCase(SC->getSubStmt(), nullptr, FoundCase,
1678e5dd7070Spatrick ResultStmts);
1679e5dd7070Spatrick }
1680e5dd7070Spatrick
1681e5dd7070Spatrick // Otherwise, this is some other case or default statement, just ignore it.
1682e5dd7070Spatrick return CollectStatementsForCase(SC->getSubStmt(), Case, FoundCase,
1683e5dd7070Spatrick ResultStmts);
1684e5dd7070Spatrick }
1685e5dd7070Spatrick
1686e5dd7070Spatrick // If we are in the live part of the code and we found our break statement,
1687e5dd7070Spatrick // return a success!
1688e5dd7070Spatrick if (!Case && isa<BreakStmt>(S))
1689e5dd7070Spatrick return CSFC_Success;
1690e5dd7070Spatrick
1691e5dd7070Spatrick // If this is a switch statement, then it might contain the SwitchCase, the
1692e5dd7070Spatrick // break, or neither.
1693e5dd7070Spatrick if (const CompoundStmt *CS = dyn_cast<CompoundStmt>(S)) {
1694e5dd7070Spatrick // Handle this as two cases: we might be looking for the SwitchCase (if so
1695e5dd7070Spatrick // the skipped statements must be skippable) or we might already have it.
1696e5dd7070Spatrick CompoundStmt::const_body_iterator I = CS->body_begin(), E = CS->body_end();
1697e5dd7070Spatrick bool StartedInLiveCode = FoundCase;
1698e5dd7070Spatrick unsigned StartSize = ResultStmts.size();
1699e5dd7070Spatrick
1700e5dd7070Spatrick // If we've not found the case yet, scan through looking for it.
1701e5dd7070Spatrick if (Case) {
1702e5dd7070Spatrick // Keep track of whether we see a skipped declaration. The code could be
1703e5dd7070Spatrick // using the declaration even if it is skipped, so we can't optimize out
1704e5dd7070Spatrick // the decl if the kept statements might refer to it.
1705e5dd7070Spatrick bool HadSkippedDecl = false;
1706e5dd7070Spatrick
1707e5dd7070Spatrick // If we're looking for the case, just see if we can skip each of the
1708e5dd7070Spatrick // substatements.
1709e5dd7070Spatrick for (; Case && I != E; ++I) {
1710e5dd7070Spatrick HadSkippedDecl |= CodeGenFunction::mightAddDeclToScope(*I);
1711e5dd7070Spatrick
1712e5dd7070Spatrick switch (CollectStatementsForCase(*I, Case, FoundCase, ResultStmts)) {
1713e5dd7070Spatrick case CSFC_Failure: return CSFC_Failure;
1714e5dd7070Spatrick case CSFC_Success:
1715e5dd7070Spatrick // A successful result means that either 1) that the statement doesn't
1716e5dd7070Spatrick // have the case and is skippable, or 2) does contain the case value
1717e5dd7070Spatrick // and also contains the break to exit the switch. In the later case,
1718e5dd7070Spatrick // we just verify the rest of the statements are elidable.
1719e5dd7070Spatrick if (FoundCase) {
1720e5dd7070Spatrick // If we found the case and skipped declarations, we can't do the
1721e5dd7070Spatrick // optimization.
1722e5dd7070Spatrick if (HadSkippedDecl)
1723e5dd7070Spatrick return CSFC_Failure;
1724e5dd7070Spatrick
1725e5dd7070Spatrick for (++I; I != E; ++I)
1726e5dd7070Spatrick if (CodeGenFunction::ContainsLabel(*I, true))
1727e5dd7070Spatrick return CSFC_Failure;
1728e5dd7070Spatrick return CSFC_Success;
1729e5dd7070Spatrick }
1730e5dd7070Spatrick break;
1731e5dd7070Spatrick case CSFC_FallThrough:
1732e5dd7070Spatrick // If we have a fallthrough condition, then we must have found the
1733e5dd7070Spatrick // case started to include statements. Consider the rest of the
1734e5dd7070Spatrick // statements in the compound statement as candidates for inclusion.
1735e5dd7070Spatrick assert(FoundCase && "Didn't find case but returned fallthrough?");
1736e5dd7070Spatrick // We recursively found Case, so we're not looking for it anymore.
1737e5dd7070Spatrick Case = nullptr;
1738e5dd7070Spatrick
1739e5dd7070Spatrick // If we found the case and skipped declarations, we can't do the
1740e5dd7070Spatrick // optimization.
1741e5dd7070Spatrick if (HadSkippedDecl)
1742e5dd7070Spatrick return CSFC_Failure;
1743e5dd7070Spatrick break;
1744e5dd7070Spatrick }
1745e5dd7070Spatrick }
1746e5dd7070Spatrick
1747e5dd7070Spatrick if (!FoundCase)
1748e5dd7070Spatrick return CSFC_Success;
1749e5dd7070Spatrick
1750e5dd7070Spatrick assert(!HadSkippedDecl && "fallthrough after skipping decl");
1751e5dd7070Spatrick }
1752e5dd7070Spatrick
1753e5dd7070Spatrick // If we have statements in our range, then we know that the statements are
1754e5dd7070Spatrick // live and need to be added to the set of statements we're tracking.
1755e5dd7070Spatrick bool AnyDecls = false;
1756e5dd7070Spatrick for (; I != E; ++I) {
1757e5dd7070Spatrick AnyDecls |= CodeGenFunction::mightAddDeclToScope(*I);
1758e5dd7070Spatrick
1759e5dd7070Spatrick switch (CollectStatementsForCase(*I, nullptr, FoundCase, ResultStmts)) {
1760e5dd7070Spatrick case CSFC_Failure: return CSFC_Failure;
1761e5dd7070Spatrick case CSFC_FallThrough:
1762e5dd7070Spatrick // A fallthrough result means that the statement was simple and just
1763e5dd7070Spatrick // included in ResultStmt, keep adding them afterwards.
1764e5dd7070Spatrick break;
1765e5dd7070Spatrick case CSFC_Success:
1766e5dd7070Spatrick // A successful result means that we found the break statement and
1767e5dd7070Spatrick // stopped statement inclusion. We just ensure that any leftover stmts
1768e5dd7070Spatrick // are skippable and return success ourselves.
1769e5dd7070Spatrick for (++I; I != E; ++I)
1770e5dd7070Spatrick if (CodeGenFunction::ContainsLabel(*I, true))
1771e5dd7070Spatrick return CSFC_Failure;
1772e5dd7070Spatrick return CSFC_Success;
1773e5dd7070Spatrick }
1774e5dd7070Spatrick }
1775e5dd7070Spatrick
1776e5dd7070Spatrick // If we're about to fall out of a scope without hitting a 'break;', we
1777e5dd7070Spatrick // can't perform the optimization if there were any decls in that scope
1778e5dd7070Spatrick // (we'd lose their end-of-lifetime).
1779e5dd7070Spatrick if (AnyDecls) {
1780e5dd7070Spatrick // If the entire compound statement was live, there's one more thing we
1781e5dd7070Spatrick // can try before giving up: emit the whole thing as a single statement.
1782e5dd7070Spatrick // We can do that unless the statement contains a 'break;'.
1783e5dd7070Spatrick // FIXME: Such a break must be at the end of a construct within this one.
1784e5dd7070Spatrick // We could emit this by just ignoring the BreakStmts entirely.
1785e5dd7070Spatrick if (StartedInLiveCode && !CodeGenFunction::containsBreak(S)) {
1786e5dd7070Spatrick ResultStmts.resize(StartSize);
1787e5dd7070Spatrick ResultStmts.push_back(S);
1788e5dd7070Spatrick } else {
1789e5dd7070Spatrick return CSFC_Failure;
1790e5dd7070Spatrick }
1791e5dd7070Spatrick }
1792e5dd7070Spatrick
1793e5dd7070Spatrick return CSFC_FallThrough;
1794e5dd7070Spatrick }
1795e5dd7070Spatrick
1796e5dd7070Spatrick // Okay, this is some other statement that we don't handle explicitly, like a
1797e5dd7070Spatrick // for statement or increment etc. If we are skipping over this statement,
1798e5dd7070Spatrick // just verify it doesn't have labels, which would make it invalid to elide.
1799e5dd7070Spatrick if (Case) {
1800e5dd7070Spatrick if (CodeGenFunction::ContainsLabel(S, true))
1801e5dd7070Spatrick return CSFC_Failure;
1802e5dd7070Spatrick return CSFC_Success;
1803e5dd7070Spatrick }
1804e5dd7070Spatrick
1805e5dd7070Spatrick // Otherwise, we want to include this statement. Everything is cool with that
1806e5dd7070Spatrick // so long as it doesn't contain a break out of the switch we're in.
1807e5dd7070Spatrick if (CodeGenFunction::containsBreak(S)) return CSFC_Failure;
1808e5dd7070Spatrick
1809e5dd7070Spatrick // Otherwise, everything is great. Include the statement and tell the caller
1810e5dd7070Spatrick // that we fall through and include the next statement as well.
1811e5dd7070Spatrick ResultStmts.push_back(S);
1812e5dd7070Spatrick return CSFC_FallThrough;
1813e5dd7070Spatrick }
1814e5dd7070Spatrick
1815e5dd7070Spatrick /// FindCaseStatementsForValue - Find the case statement being jumped to and
1816e5dd7070Spatrick /// then invoke CollectStatementsForCase to find the list of statements to emit
1817e5dd7070Spatrick /// for a switch on constant. See the comment above CollectStatementsForCase
1818e5dd7070Spatrick /// for more details.
FindCaseStatementsForValue(const SwitchStmt & S,const llvm::APSInt & ConstantCondValue,SmallVectorImpl<const Stmt * > & ResultStmts,ASTContext & C,const SwitchCase * & ResultCase)1819e5dd7070Spatrick static bool FindCaseStatementsForValue(const SwitchStmt &S,
1820e5dd7070Spatrick const llvm::APSInt &ConstantCondValue,
1821e5dd7070Spatrick SmallVectorImpl<const Stmt*> &ResultStmts,
1822e5dd7070Spatrick ASTContext &C,
1823e5dd7070Spatrick const SwitchCase *&ResultCase) {
1824e5dd7070Spatrick // First step, find the switch case that is being branched to. We can do this
1825e5dd7070Spatrick // efficiently by scanning the SwitchCase list.
1826e5dd7070Spatrick const SwitchCase *Case = S.getSwitchCaseList();
1827e5dd7070Spatrick const DefaultStmt *DefaultCase = nullptr;
1828e5dd7070Spatrick
1829e5dd7070Spatrick for (; Case; Case = Case->getNextSwitchCase()) {
1830e5dd7070Spatrick // It's either a default or case. Just remember the default statement in
1831e5dd7070Spatrick // case we're not jumping to any numbered cases.
1832e5dd7070Spatrick if (const DefaultStmt *DS = dyn_cast<DefaultStmt>(Case)) {
1833e5dd7070Spatrick DefaultCase = DS;
1834e5dd7070Spatrick continue;
1835e5dd7070Spatrick }
1836e5dd7070Spatrick
1837e5dd7070Spatrick // Check to see if this case is the one we're looking for.
1838e5dd7070Spatrick const CaseStmt *CS = cast<CaseStmt>(Case);
1839e5dd7070Spatrick // Don't handle case ranges yet.
1840e5dd7070Spatrick if (CS->getRHS()) return false;
1841e5dd7070Spatrick
1842e5dd7070Spatrick // If we found our case, remember it as 'case'.
1843e5dd7070Spatrick if (CS->getLHS()->EvaluateKnownConstInt(C) == ConstantCondValue)
1844e5dd7070Spatrick break;
1845e5dd7070Spatrick }
1846e5dd7070Spatrick
1847e5dd7070Spatrick // If we didn't find a matching case, we use a default if it exists, or we
1848e5dd7070Spatrick // elide the whole switch body!
1849e5dd7070Spatrick if (!Case) {
1850e5dd7070Spatrick // It is safe to elide the body of the switch if it doesn't contain labels
1851e5dd7070Spatrick // etc. If it is safe, return successfully with an empty ResultStmts list.
1852e5dd7070Spatrick if (!DefaultCase)
1853e5dd7070Spatrick return !CodeGenFunction::ContainsLabel(&S);
1854e5dd7070Spatrick Case = DefaultCase;
1855e5dd7070Spatrick }
1856e5dd7070Spatrick
1857e5dd7070Spatrick // Ok, we know which case is being jumped to, try to collect all the
1858e5dd7070Spatrick // statements that follow it. This can fail for a variety of reasons. Also,
1859e5dd7070Spatrick // check to see that the recursive walk actually found our case statement.
1860e5dd7070Spatrick // Insane cases like this can fail to find it in the recursive walk since we
1861e5dd7070Spatrick // don't handle every stmt kind:
1862e5dd7070Spatrick // switch (4) {
1863e5dd7070Spatrick // while (1) {
1864e5dd7070Spatrick // case 4: ...
1865e5dd7070Spatrick bool FoundCase = false;
1866e5dd7070Spatrick ResultCase = Case;
1867e5dd7070Spatrick return CollectStatementsForCase(S.getBody(), Case, FoundCase,
1868e5dd7070Spatrick ResultStmts) != CSFC_Failure &&
1869e5dd7070Spatrick FoundCase;
1870e5dd7070Spatrick }
1871e5dd7070Spatrick
1872*12c85518Srobert static std::optional<SmallVector<uint64_t, 16>>
getLikelihoodWeights(ArrayRef<Stmt::Likelihood> Likelihoods)1873a9ac8606Spatrick getLikelihoodWeights(ArrayRef<Stmt::Likelihood> Likelihoods) {
1874a9ac8606Spatrick // Are there enough branches to weight them?
1875a9ac8606Spatrick if (Likelihoods.size() <= 1)
1876*12c85518Srobert return std::nullopt;
1877a9ac8606Spatrick
1878a9ac8606Spatrick uint64_t NumUnlikely = 0;
1879a9ac8606Spatrick uint64_t NumNone = 0;
1880a9ac8606Spatrick uint64_t NumLikely = 0;
1881a9ac8606Spatrick for (const auto LH : Likelihoods) {
1882a9ac8606Spatrick switch (LH) {
1883a9ac8606Spatrick case Stmt::LH_Unlikely:
1884a9ac8606Spatrick ++NumUnlikely;
1885a9ac8606Spatrick break;
1886a9ac8606Spatrick case Stmt::LH_None:
1887a9ac8606Spatrick ++NumNone;
1888a9ac8606Spatrick break;
1889a9ac8606Spatrick case Stmt::LH_Likely:
1890a9ac8606Spatrick ++NumLikely;
1891a9ac8606Spatrick break;
1892a9ac8606Spatrick }
1893a9ac8606Spatrick }
1894a9ac8606Spatrick
1895a9ac8606Spatrick // Is there a likelihood attribute used?
1896a9ac8606Spatrick if (NumUnlikely == 0 && NumLikely == 0)
1897*12c85518Srobert return std::nullopt;
1898a9ac8606Spatrick
1899a9ac8606Spatrick // When multiple cases share the same code they can be combined during
1900a9ac8606Spatrick // optimization. In that case the weights of the branch will be the sum of
1901a9ac8606Spatrick // the individual weights. Make sure the combined sum of all neutral cases
1902a9ac8606Spatrick // doesn't exceed the value of a single likely attribute.
1903a9ac8606Spatrick // The additions both avoid divisions by 0 and make sure the weights of None
1904a9ac8606Spatrick // don't exceed the weight of Likely.
1905a9ac8606Spatrick const uint64_t Likely = INT32_MAX / (NumLikely + 2);
1906a9ac8606Spatrick const uint64_t None = Likely / (NumNone + 1);
1907a9ac8606Spatrick const uint64_t Unlikely = 0;
1908a9ac8606Spatrick
1909a9ac8606Spatrick SmallVector<uint64_t, 16> Result;
1910a9ac8606Spatrick Result.reserve(Likelihoods.size());
1911a9ac8606Spatrick for (const auto LH : Likelihoods) {
1912a9ac8606Spatrick switch (LH) {
1913a9ac8606Spatrick case Stmt::LH_Unlikely:
1914a9ac8606Spatrick Result.push_back(Unlikely);
1915a9ac8606Spatrick break;
1916a9ac8606Spatrick case Stmt::LH_None:
1917a9ac8606Spatrick Result.push_back(None);
1918a9ac8606Spatrick break;
1919a9ac8606Spatrick case Stmt::LH_Likely:
1920a9ac8606Spatrick Result.push_back(Likely);
1921a9ac8606Spatrick break;
1922a9ac8606Spatrick }
1923a9ac8606Spatrick }
1924a9ac8606Spatrick
1925a9ac8606Spatrick return Result;
1926a9ac8606Spatrick }
1927a9ac8606Spatrick
EmitSwitchStmt(const SwitchStmt & S)1928e5dd7070Spatrick void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) {
1929e5dd7070Spatrick // Handle nested switch statements.
1930e5dd7070Spatrick llvm::SwitchInst *SavedSwitchInsn = SwitchInsn;
1931e5dd7070Spatrick SmallVector<uint64_t, 16> *SavedSwitchWeights = SwitchWeights;
1932a9ac8606Spatrick SmallVector<Stmt::Likelihood, 16> *SavedSwitchLikelihood = SwitchLikelihood;
1933e5dd7070Spatrick llvm::BasicBlock *SavedCRBlock = CaseRangeBlock;
1934e5dd7070Spatrick
1935e5dd7070Spatrick // See if we can constant fold the condition of the switch and therefore only
1936e5dd7070Spatrick // emit the live case statement (if any) of the switch.
1937e5dd7070Spatrick llvm::APSInt ConstantCondValue;
1938e5dd7070Spatrick if (ConstantFoldsToSimpleInteger(S.getCond(), ConstantCondValue)) {
1939e5dd7070Spatrick SmallVector<const Stmt*, 4> CaseStmts;
1940e5dd7070Spatrick const SwitchCase *Case = nullptr;
1941e5dd7070Spatrick if (FindCaseStatementsForValue(S, ConstantCondValue, CaseStmts,
1942e5dd7070Spatrick getContext(), Case)) {
1943e5dd7070Spatrick if (Case)
1944e5dd7070Spatrick incrementProfileCounter(Case);
1945e5dd7070Spatrick RunCleanupsScope ExecutedScope(*this);
1946e5dd7070Spatrick
1947e5dd7070Spatrick if (S.getInit())
1948e5dd7070Spatrick EmitStmt(S.getInit());
1949e5dd7070Spatrick
1950e5dd7070Spatrick // Emit the condition variable if needed inside the entire cleanup scope
1951e5dd7070Spatrick // used by this special case for constant folded switches.
1952e5dd7070Spatrick if (S.getConditionVariable())
1953e5dd7070Spatrick EmitDecl(*S.getConditionVariable());
1954e5dd7070Spatrick
1955e5dd7070Spatrick // At this point, we are no longer "within" a switch instance, so
1956e5dd7070Spatrick // we can temporarily enforce this to ensure that any embedded case
1957e5dd7070Spatrick // statements are not emitted.
1958e5dd7070Spatrick SwitchInsn = nullptr;
1959e5dd7070Spatrick
1960e5dd7070Spatrick // Okay, we can dead code eliminate everything except this case. Emit the
1961e5dd7070Spatrick // specified series of statements and we're good.
1962e5dd7070Spatrick for (unsigned i = 0, e = CaseStmts.size(); i != e; ++i)
1963e5dd7070Spatrick EmitStmt(CaseStmts[i]);
1964e5dd7070Spatrick incrementProfileCounter(&S);
1965e5dd7070Spatrick
1966e5dd7070Spatrick // Now we want to restore the saved switch instance so that nested
1967e5dd7070Spatrick // switches continue to function properly
1968e5dd7070Spatrick SwitchInsn = SavedSwitchInsn;
1969e5dd7070Spatrick
1970e5dd7070Spatrick return;
1971e5dd7070Spatrick }
1972e5dd7070Spatrick }
1973e5dd7070Spatrick
1974e5dd7070Spatrick JumpDest SwitchExit = getJumpDestInCurrentScope("sw.epilog");
1975e5dd7070Spatrick
1976e5dd7070Spatrick RunCleanupsScope ConditionScope(*this);
1977e5dd7070Spatrick
1978e5dd7070Spatrick if (S.getInit())
1979e5dd7070Spatrick EmitStmt(S.getInit());
1980e5dd7070Spatrick
1981e5dd7070Spatrick if (S.getConditionVariable())
1982e5dd7070Spatrick EmitDecl(*S.getConditionVariable());
1983e5dd7070Spatrick llvm::Value *CondV = EmitScalarExpr(S.getCond());
1984e5dd7070Spatrick
1985e5dd7070Spatrick // Create basic block to hold stuff that comes after switch
1986e5dd7070Spatrick // statement. We also need to create a default block now so that
1987e5dd7070Spatrick // explicit case ranges tests can have a place to jump to on
1988e5dd7070Spatrick // failure.
1989e5dd7070Spatrick llvm::BasicBlock *DefaultBlock = createBasicBlock("sw.default");
1990e5dd7070Spatrick SwitchInsn = Builder.CreateSwitch(CondV, DefaultBlock);
1991e5dd7070Spatrick if (PGO.haveRegionCounts()) {
1992e5dd7070Spatrick // Walk the SwitchCase list to find how many there are.
1993e5dd7070Spatrick uint64_t DefaultCount = 0;
1994e5dd7070Spatrick unsigned NumCases = 0;
1995e5dd7070Spatrick for (const SwitchCase *Case = S.getSwitchCaseList();
1996e5dd7070Spatrick Case;
1997e5dd7070Spatrick Case = Case->getNextSwitchCase()) {
1998e5dd7070Spatrick if (isa<DefaultStmt>(Case))
1999e5dd7070Spatrick DefaultCount = getProfileCount(Case);
2000e5dd7070Spatrick NumCases += 1;
2001e5dd7070Spatrick }
2002e5dd7070Spatrick SwitchWeights = new SmallVector<uint64_t, 16>();
2003e5dd7070Spatrick SwitchWeights->reserve(NumCases);
2004e5dd7070Spatrick // The default needs to be first. We store the edge count, so we already
2005e5dd7070Spatrick // know the right weight.
2006e5dd7070Spatrick SwitchWeights->push_back(DefaultCount);
2007a9ac8606Spatrick } else if (CGM.getCodeGenOpts().OptimizationLevel) {
2008a9ac8606Spatrick SwitchLikelihood = new SmallVector<Stmt::Likelihood, 16>();
2009a9ac8606Spatrick // Initialize the default case.
2010a9ac8606Spatrick SwitchLikelihood->push_back(Stmt::LH_None);
2011e5dd7070Spatrick }
2012a9ac8606Spatrick
2013e5dd7070Spatrick CaseRangeBlock = DefaultBlock;
2014e5dd7070Spatrick
2015e5dd7070Spatrick // Clear the insertion point to indicate we are in unreachable code.
2016e5dd7070Spatrick Builder.ClearInsertionPoint();
2017e5dd7070Spatrick
2018e5dd7070Spatrick // All break statements jump to NextBlock. If BreakContinueStack is non-empty
2019e5dd7070Spatrick // then reuse last ContinueBlock.
2020e5dd7070Spatrick JumpDest OuterContinue;
2021e5dd7070Spatrick if (!BreakContinueStack.empty())
2022e5dd7070Spatrick OuterContinue = BreakContinueStack.back().ContinueBlock;
2023e5dd7070Spatrick
2024e5dd7070Spatrick BreakContinueStack.push_back(BreakContinue(SwitchExit, OuterContinue));
2025e5dd7070Spatrick
2026e5dd7070Spatrick // Emit switch body.
2027e5dd7070Spatrick EmitStmt(S.getBody());
2028e5dd7070Spatrick
2029e5dd7070Spatrick BreakContinueStack.pop_back();
2030e5dd7070Spatrick
2031e5dd7070Spatrick // Update the default block in case explicit case range tests have
2032e5dd7070Spatrick // been chained on top.
2033e5dd7070Spatrick SwitchInsn->setDefaultDest(CaseRangeBlock);
2034e5dd7070Spatrick
2035e5dd7070Spatrick // If a default was never emitted:
2036e5dd7070Spatrick if (!DefaultBlock->getParent()) {
2037e5dd7070Spatrick // If we have cleanups, emit the default block so that there's a
2038e5dd7070Spatrick // place to jump through the cleanups from.
2039e5dd7070Spatrick if (ConditionScope.requiresCleanups()) {
2040e5dd7070Spatrick EmitBlock(DefaultBlock);
2041e5dd7070Spatrick
2042e5dd7070Spatrick // Otherwise, just forward the default block to the switch end.
2043e5dd7070Spatrick } else {
2044e5dd7070Spatrick DefaultBlock->replaceAllUsesWith(SwitchExit.getBlock());
2045e5dd7070Spatrick delete DefaultBlock;
2046e5dd7070Spatrick }
2047e5dd7070Spatrick }
2048e5dd7070Spatrick
2049e5dd7070Spatrick ConditionScope.ForceCleanup();
2050e5dd7070Spatrick
2051e5dd7070Spatrick // Emit continuation.
2052e5dd7070Spatrick EmitBlock(SwitchExit.getBlock(), true);
2053e5dd7070Spatrick incrementProfileCounter(&S);
2054e5dd7070Spatrick
2055e5dd7070Spatrick // If the switch has a condition wrapped by __builtin_unpredictable,
2056e5dd7070Spatrick // create metadata that specifies that the switch is unpredictable.
2057e5dd7070Spatrick // Don't bother if not optimizing because that metadata would not be used.
2058e5dd7070Spatrick auto *Call = dyn_cast<CallExpr>(S.getCond());
2059e5dd7070Spatrick if (Call && CGM.getCodeGenOpts().OptimizationLevel != 0) {
2060e5dd7070Spatrick auto *FD = dyn_cast_or_null<FunctionDecl>(Call->getCalleeDecl());
2061e5dd7070Spatrick if (FD && FD->getBuiltinID() == Builtin::BI__builtin_unpredictable) {
2062e5dd7070Spatrick llvm::MDBuilder MDHelper(getLLVMContext());
2063e5dd7070Spatrick SwitchInsn->setMetadata(llvm::LLVMContext::MD_unpredictable,
2064e5dd7070Spatrick MDHelper.createUnpredictable());
2065e5dd7070Spatrick }
2066e5dd7070Spatrick }
2067e5dd7070Spatrick
2068e5dd7070Spatrick if (SwitchWeights) {
2069e5dd7070Spatrick assert(SwitchWeights->size() == 1 + SwitchInsn->getNumCases() &&
2070e5dd7070Spatrick "switch weights do not match switch cases");
2071e5dd7070Spatrick // If there's only one jump destination there's no sense weighting it.
2072e5dd7070Spatrick if (SwitchWeights->size() > 1)
2073e5dd7070Spatrick SwitchInsn->setMetadata(llvm::LLVMContext::MD_prof,
2074e5dd7070Spatrick createProfileWeights(*SwitchWeights));
2075e5dd7070Spatrick delete SwitchWeights;
2076a9ac8606Spatrick } else if (SwitchLikelihood) {
2077a9ac8606Spatrick assert(SwitchLikelihood->size() == 1 + SwitchInsn->getNumCases() &&
2078a9ac8606Spatrick "switch likelihoods do not match switch cases");
2079*12c85518Srobert std::optional<SmallVector<uint64_t, 16>> LHW =
2080a9ac8606Spatrick getLikelihoodWeights(*SwitchLikelihood);
2081a9ac8606Spatrick if (LHW) {
2082a9ac8606Spatrick llvm::MDBuilder MDHelper(CGM.getLLVMContext());
2083a9ac8606Spatrick SwitchInsn->setMetadata(llvm::LLVMContext::MD_prof,
2084a9ac8606Spatrick createProfileWeights(*LHW));
2085a9ac8606Spatrick }
2086a9ac8606Spatrick delete SwitchLikelihood;
2087e5dd7070Spatrick }
2088e5dd7070Spatrick SwitchInsn = SavedSwitchInsn;
2089e5dd7070Spatrick SwitchWeights = SavedSwitchWeights;
2090a9ac8606Spatrick SwitchLikelihood = SavedSwitchLikelihood;
2091e5dd7070Spatrick CaseRangeBlock = SavedCRBlock;
2092e5dd7070Spatrick }
2093e5dd7070Spatrick
2094e5dd7070Spatrick static std::string
SimplifyConstraint(const char * Constraint,const TargetInfo & Target,SmallVectorImpl<TargetInfo::ConstraintInfo> * OutCons=nullptr)2095e5dd7070Spatrick SimplifyConstraint(const char *Constraint, const TargetInfo &Target,
2096e5dd7070Spatrick SmallVectorImpl<TargetInfo::ConstraintInfo> *OutCons=nullptr) {
2097e5dd7070Spatrick std::string Result;
2098e5dd7070Spatrick
2099e5dd7070Spatrick while (*Constraint) {
2100e5dd7070Spatrick switch (*Constraint) {
2101e5dd7070Spatrick default:
2102e5dd7070Spatrick Result += Target.convertConstraint(Constraint);
2103e5dd7070Spatrick break;
2104e5dd7070Spatrick // Ignore these
2105e5dd7070Spatrick case '*':
2106e5dd7070Spatrick case '?':
2107e5dd7070Spatrick case '!':
2108e5dd7070Spatrick case '=': // Will see this and the following in mult-alt constraints.
2109e5dd7070Spatrick case '+':
2110e5dd7070Spatrick break;
2111e5dd7070Spatrick case '#': // Ignore the rest of the constraint alternative.
2112e5dd7070Spatrick while (Constraint[1] && Constraint[1] != ',')
2113e5dd7070Spatrick Constraint++;
2114e5dd7070Spatrick break;
2115e5dd7070Spatrick case '&':
2116e5dd7070Spatrick case '%':
2117e5dd7070Spatrick Result += *Constraint;
2118e5dd7070Spatrick while (Constraint[1] && Constraint[1] == *Constraint)
2119e5dd7070Spatrick Constraint++;
2120e5dd7070Spatrick break;
2121e5dd7070Spatrick case ',':
2122e5dd7070Spatrick Result += "|";
2123e5dd7070Spatrick break;
2124e5dd7070Spatrick case 'g':
2125e5dd7070Spatrick Result += "imr";
2126e5dd7070Spatrick break;
2127e5dd7070Spatrick case '[': {
2128e5dd7070Spatrick assert(OutCons &&
2129e5dd7070Spatrick "Must pass output names to constraints with a symbolic name");
2130e5dd7070Spatrick unsigned Index;
2131e5dd7070Spatrick bool result = Target.resolveSymbolicName(Constraint, *OutCons, Index);
2132e5dd7070Spatrick assert(result && "Could not resolve symbolic name"); (void)result;
2133e5dd7070Spatrick Result += llvm::utostr(Index);
2134e5dd7070Spatrick break;
2135e5dd7070Spatrick }
2136e5dd7070Spatrick }
2137e5dd7070Spatrick
2138e5dd7070Spatrick Constraint++;
2139e5dd7070Spatrick }
2140e5dd7070Spatrick
2141e5dd7070Spatrick return Result;
2142e5dd7070Spatrick }
2143e5dd7070Spatrick
2144e5dd7070Spatrick /// AddVariableConstraints - Look at AsmExpr and if it is a variable declared
2145e5dd7070Spatrick /// as using a particular register add that as a constraint that will be used
2146e5dd7070Spatrick /// in this asm stmt.
2147e5dd7070Spatrick static std::string
AddVariableConstraints(const std::string & Constraint,const Expr & AsmExpr,const TargetInfo & Target,CodeGenModule & CGM,const AsmStmt & Stmt,const bool EarlyClobber,std::string * GCCReg=nullptr)2148e5dd7070Spatrick AddVariableConstraints(const std::string &Constraint, const Expr &AsmExpr,
2149e5dd7070Spatrick const TargetInfo &Target, CodeGenModule &CGM,
2150a9ac8606Spatrick const AsmStmt &Stmt, const bool EarlyClobber,
2151a9ac8606Spatrick std::string *GCCReg = nullptr) {
2152e5dd7070Spatrick const DeclRefExpr *AsmDeclRef = dyn_cast<DeclRefExpr>(&AsmExpr);
2153e5dd7070Spatrick if (!AsmDeclRef)
2154e5dd7070Spatrick return Constraint;
2155e5dd7070Spatrick const ValueDecl &Value = *AsmDeclRef->getDecl();
2156e5dd7070Spatrick const VarDecl *Variable = dyn_cast<VarDecl>(&Value);
2157e5dd7070Spatrick if (!Variable)
2158e5dd7070Spatrick return Constraint;
2159e5dd7070Spatrick if (Variable->getStorageClass() != SC_Register)
2160e5dd7070Spatrick return Constraint;
2161e5dd7070Spatrick AsmLabelAttr *Attr = Variable->getAttr<AsmLabelAttr>();
2162e5dd7070Spatrick if (!Attr)
2163e5dd7070Spatrick return Constraint;
2164e5dd7070Spatrick StringRef Register = Attr->getLabel();
2165e5dd7070Spatrick assert(Target.isValidGCCRegisterName(Register));
2166e5dd7070Spatrick // We're using validateOutputConstraint here because we only care if
2167e5dd7070Spatrick // this is a register constraint.
2168e5dd7070Spatrick TargetInfo::ConstraintInfo Info(Constraint, "");
2169e5dd7070Spatrick if (Target.validateOutputConstraint(Info) &&
2170e5dd7070Spatrick !Info.allowsRegister()) {
2171e5dd7070Spatrick CGM.ErrorUnsupported(&Stmt, "__asm__");
2172e5dd7070Spatrick return Constraint;
2173e5dd7070Spatrick }
2174e5dd7070Spatrick // Canonicalize the register here before returning it.
2175e5dd7070Spatrick Register = Target.getNormalizedGCCRegisterName(Register);
2176a9ac8606Spatrick if (GCCReg != nullptr)
2177a9ac8606Spatrick *GCCReg = Register.str();
2178e5dd7070Spatrick return (EarlyClobber ? "&{" : "{") + Register.str() + "}";
2179e5dd7070Spatrick }
2180e5dd7070Spatrick
EmitAsmInputLValue(const TargetInfo::ConstraintInfo & Info,LValue InputValue,QualType InputType,std::string & ConstraintStr,SourceLocation Loc)2181*12c85518Srobert std::pair<llvm::Value*, llvm::Type *> CodeGenFunction::EmitAsmInputLValue(
2182*12c85518Srobert const TargetInfo::ConstraintInfo &Info, LValue InputValue,
2183*12c85518Srobert QualType InputType, std::string &ConstraintStr, SourceLocation Loc) {
2184e5dd7070Spatrick if (Info.allowsRegister() || !Info.allowsMemory()) {
2185*12c85518Srobert if (CodeGenFunction::hasScalarEvaluationKind(InputType))
2186*12c85518Srobert return {EmitLoadOfLValue(InputValue, Loc).getScalarVal(), nullptr};
2187*12c85518Srobert
2188e5dd7070Spatrick llvm::Type *Ty = ConvertType(InputType);
2189e5dd7070Spatrick uint64_t Size = CGM.getDataLayout().getTypeSizeInBits(Ty);
2190a9ac8606Spatrick if ((Size <= 64 && llvm::isPowerOf2_64(Size)) ||
2191a9ac8606Spatrick getTargetHooks().isScalarizableAsmOperand(*this, Ty)) {
2192e5dd7070Spatrick Ty = llvm::IntegerType::get(getLLVMContext(), Size);
2193e5dd7070Spatrick
2194*12c85518Srobert return {Builder.CreateLoad(Builder.CreateElementBitCast(
2195*12c85518Srobert InputValue.getAddress(*this), Ty)),
2196*12c85518Srobert nullptr};
2197*12c85518Srobert }
2198*12c85518Srobert }
2199*12c85518Srobert
2200*12c85518Srobert Address Addr = InputValue.getAddress(*this);
2201e5dd7070Spatrick ConstraintStr += '*';
2202*12c85518Srobert return {Addr.getPointer(), Addr.getElementType()};
2203e5dd7070Spatrick }
2204e5dd7070Spatrick
2205*12c85518Srobert std::pair<llvm::Value *, llvm::Type *>
EmitAsmInput(const TargetInfo::ConstraintInfo & Info,const Expr * InputExpr,std::string & ConstraintStr)2206*12c85518Srobert CodeGenFunction::EmitAsmInput(const TargetInfo::ConstraintInfo &Info,
2207e5dd7070Spatrick const Expr *InputExpr,
2208e5dd7070Spatrick std::string &ConstraintStr) {
2209e5dd7070Spatrick // If this can't be a register or memory, i.e., has to be a constant
2210e5dd7070Spatrick // (immediate or symbolic), try to emit it as such.
2211e5dd7070Spatrick if (!Info.allowsRegister() && !Info.allowsMemory()) {
2212e5dd7070Spatrick if (Info.requiresImmediateConstant()) {
2213e5dd7070Spatrick Expr::EvalResult EVResult;
2214e5dd7070Spatrick InputExpr->EvaluateAsRValue(EVResult, getContext(), true);
2215e5dd7070Spatrick
2216e5dd7070Spatrick llvm::APSInt IntResult;
2217e5dd7070Spatrick if (EVResult.Val.toIntegralConstant(IntResult, InputExpr->getType(),
2218e5dd7070Spatrick getContext()))
2219*12c85518Srobert return {llvm::ConstantInt::get(getLLVMContext(), IntResult), nullptr};
2220e5dd7070Spatrick }
2221e5dd7070Spatrick
2222e5dd7070Spatrick Expr::EvalResult Result;
2223e5dd7070Spatrick if (InputExpr->EvaluateAsInt(Result, getContext()))
2224*12c85518Srobert return {llvm::ConstantInt::get(getLLVMContext(), Result.Val.getInt()),
2225*12c85518Srobert nullptr};
2226e5dd7070Spatrick }
2227e5dd7070Spatrick
2228e5dd7070Spatrick if (Info.allowsRegister() || !Info.allowsMemory())
2229e5dd7070Spatrick if (CodeGenFunction::hasScalarEvaluationKind(InputExpr->getType()))
2230*12c85518Srobert return {EmitScalarExpr(InputExpr), nullptr};
2231e5dd7070Spatrick if (InputExpr->getStmtClass() == Expr::CXXThisExprClass)
2232*12c85518Srobert return {EmitScalarExpr(InputExpr), nullptr};
2233e5dd7070Spatrick InputExpr = InputExpr->IgnoreParenNoopCasts(getContext());
2234e5dd7070Spatrick LValue Dest = EmitLValue(InputExpr);
2235e5dd7070Spatrick return EmitAsmInputLValue(Info, Dest, InputExpr->getType(), ConstraintStr,
2236e5dd7070Spatrick InputExpr->getExprLoc());
2237e5dd7070Spatrick }
2238e5dd7070Spatrick
2239e5dd7070Spatrick /// getAsmSrcLocInfo - Return the !srcloc metadata node to attach to an inline
2240e5dd7070Spatrick /// asm call instruction. The !srcloc MDNode contains a list of constant
2241e5dd7070Spatrick /// integers which are the source locations of the start of each line in the
2242e5dd7070Spatrick /// asm.
getAsmSrcLocInfo(const StringLiteral * Str,CodeGenFunction & CGF)2243e5dd7070Spatrick static llvm::MDNode *getAsmSrcLocInfo(const StringLiteral *Str,
2244e5dd7070Spatrick CodeGenFunction &CGF) {
2245e5dd7070Spatrick SmallVector<llvm::Metadata *, 8> Locs;
2246e5dd7070Spatrick // Add the location of the first line to the MDNode.
2247e5dd7070Spatrick Locs.push_back(llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2248a9ac8606Spatrick CGF.Int64Ty, Str->getBeginLoc().getRawEncoding())));
2249e5dd7070Spatrick StringRef StrVal = Str->getString();
2250e5dd7070Spatrick if (!StrVal.empty()) {
2251e5dd7070Spatrick const SourceManager &SM = CGF.CGM.getContext().getSourceManager();
2252e5dd7070Spatrick const LangOptions &LangOpts = CGF.CGM.getLangOpts();
2253e5dd7070Spatrick unsigned StartToken = 0;
2254e5dd7070Spatrick unsigned ByteOffset = 0;
2255e5dd7070Spatrick
2256e5dd7070Spatrick // Add the location of the start of each subsequent line of the asm to the
2257e5dd7070Spatrick // MDNode.
2258e5dd7070Spatrick for (unsigned i = 0, e = StrVal.size() - 1; i != e; ++i) {
2259e5dd7070Spatrick if (StrVal[i] != '\n') continue;
2260e5dd7070Spatrick SourceLocation LineLoc = Str->getLocationOfByte(
2261e5dd7070Spatrick i + 1, SM, LangOpts, CGF.getTarget(), &StartToken, &ByteOffset);
2262e5dd7070Spatrick Locs.push_back(llvm::ConstantAsMetadata::get(
2263a9ac8606Spatrick llvm::ConstantInt::get(CGF.Int64Ty, LineLoc.getRawEncoding())));
2264e5dd7070Spatrick }
2265e5dd7070Spatrick }
2266e5dd7070Spatrick
2267e5dd7070Spatrick return llvm::MDNode::get(CGF.getLLVMContext(), Locs);
2268e5dd7070Spatrick }
2269e5dd7070Spatrick
UpdateAsmCallInst(llvm::CallBase & Result,bool HasSideEffect,bool HasUnwindClobber,bool ReadOnly,bool ReadNone,bool NoMerge,const AsmStmt & S,const std::vector<llvm::Type * > & ResultRegTypes,const std::vector<llvm::Type * > & ArgElemTypes,CodeGenFunction & CGF,std::vector<llvm::Value * > & RegResults)2270e5dd7070Spatrick static void UpdateAsmCallInst(llvm::CallBase &Result, bool HasSideEffect,
2271a9ac8606Spatrick bool HasUnwindClobber, bool ReadOnly,
2272a9ac8606Spatrick bool ReadNone, bool NoMerge, const AsmStmt &S,
2273e5dd7070Spatrick const std::vector<llvm::Type *> &ResultRegTypes,
2274*12c85518Srobert const std::vector<llvm::Type *> &ArgElemTypes,
2275e5dd7070Spatrick CodeGenFunction &CGF,
2276e5dd7070Spatrick std::vector<llvm::Value *> &RegResults) {
2277a9ac8606Spatrick if (!HasUnwindClobber)
2278*12c85518Srobert Result.addFnAttr(llvm::Attribute::NoUnwind);
2279a9ac8606Spatrick
2280a9ac8606Spatrick if (NoMerge)
2281*12c85518Srobert Result.addFnAttr(llvm::Attribute::NoMerge);
2282e5dd7070Spatrick // Attach readnone and readonly attributes.
2283e5dd7070Spatrick if (!HasSideEffect) {
2284e5dd7070Spatrick if (ReadNone)
2285*12c85518Srobert Result.setDoesNotAccessMemory();
2286e5dd7070Spatrick else if (ReadOnly)
2287*12c85518Srobert Result.setOnlyReadsMemory();
2288*12c85518Srobert }
2289*12c85518Srobert
2290*12c85518Srobert // Add elementtype attribute for indirect constraints.
2291*12c85518Srobert for (auto Pair : llvm::enumerate(ArgElemTypes)) {
2292*12c85518Srobert if (Pair.value()) {
2293*12c85518Srobert auto Attr = llvm::Attribute::get(
2294*12c85518Srobert CGF.getLLVMContext(), llvm::Attribute::ElementType, Pair.value());
2295*12c85518Srobert Result.addParamAttr(Pair.index(), Attr);
2296*12c85518Srobert }
2297e5dd7070Spatrick }
2298e5dd7070Spatrick
2299e5dd7070Spatrick // Slap the source location of the inline asm into a !srcloc metadata on the
2300e5dd7070Spatrick // call.
2301e5dd7070Spatrick if (const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(&S))
2302e5dd7070Spatrick Result.setMetadata("srcloc",
2303e5dd7070Spatrick getAsmSrcLocInfo(gccAsmStmt->getAsmString(), CGF));
2304e5dd7070Spatrick else {
2305e5dd7070Spatrick // At least put the line number on MS inline asm blobs.
2306a9ac8606Spatrick llvm::Constant *Loc =
2307a9ac8606Spatrick llvm::ConstantInt::get(CGF.Int64Ty, S.getAsmLoc().getRawEncoding());
2308e5dd7070Spatrick Result.setMetadata("srcloc",
2309e5dd7070Spatrick llvm::MDNode::get(CGF.getLLVMContext(),
2310e5dd7070Spatrick llvm::ConstantAsMetadata::get(Loc)));
2311e5dd7070Spatrick }
2312e5dd7070Spatrick
2313e5dd7070Spatrick if (CGF.getLangOpts().assumeFunctionsAreConvergent())
2314e5dd7070Spatrick // Conservatively, mark all inline asm blocks in CUDA or OpenCL as
2315e5dd7070Spatrick // convergent (meaning, they may call an intrinsically convergent op, such
2316e5dd7070Spatrick // as bar.sync, and so can't have certain optimizations applied around
2317e5dd7070Spatrick // them).
2318*12c85518Srobert Result.addFnAttr(llvm::Attribute::Convergent);
2319e5dd7070Spatrick // Extract all of the register value results from the asm.
2320e5dd7070Spatrick if (ResultRegTypes.size() == 1) {
2321e5dd7070Spatrick RegResults.push_back(&Result);
2322e5dd7070Spatrick } else {
2323e5dd7070Spatrick for (unsigned i = 0, e = ResultRegTypes.size(); i != e; ++i) {
2324e5dd7070Spatrick llvm::Value *Tmp = CGF.Builder.CreateExtractValue(&Result, i, "asmresult");
2325e5dd7070Spatrick RegResults.push_back(Tmp);
2326e5dd7070Spatrick }
2327e5dd7070Spatrick }
2328e5dd7070Spatrick }
2329e5dd7070Spatrick
EmitAsmStmt(const AsmStmt & S)2330e5dd7070Spatrick void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
2331*12c85518Srobert // Pop all cleanup blocks at the end of the asm statement.
2332*12c85518Srobert CodeGenFunction::RunCleanupsScope Cleanups(*this);
2333*12c85518Srobert
2334e5dd7070Spatrick // Assemble the final asm string.
2335e5dd7070Spatrick std::string AsmString = S.generateAsmString(getContext());
2336e5dd7070Spatrick
2337e5dd7070Spatrick // Get all the output and input constraints together.
2338e5dd7070Spatrick SmallVector<TargetInfo::ConstraintInfo, 4> OutputConstraintInfos;
2339e5dd7070Spatrick SmallVector<TargetInfo::ConstraintInfo, 4> InputConstraintInfos;
2340e5dd7070Spatrick
2341e5dd7070Spatrick for (unsigned i = 0, e = S.getNumOutputs(); i != e; i++) {
2342e5dd7070Spatrick StringRef Name;
2343e5dd7070Spatrick if (const GCCAsmStmt *GAS = dyn_cast<GCCAsmStmt>(&S))
2344e5dd7070Spatrick Name = GAS->getOutputName(i);
2345e5dd7070Spatrick TargetInfo::ConstraintInfo Info(S.getOutputConstraint(i), Name);
2346e5dd7070Spatrick bool IsValid = getTarget().validateOutputConstraint(Info); (void)IsValid;
2347e5dd7070Spatrick assert(IsValid && "Failed to parse output constraint");
2348e5dd7070Spatrick OutputConstraintInfos.push_back(Info);
2349e5dd7070Spatrick }
2350e5dd7070Spatrick
2351e5dd7070Spatrick for (unsigned i = 0, e = S.getNumInputs(); i != e; i++) {
2352e5dd7070Spatrick StringRef Name;
2353e5dd7070Spatrick if (const GCCAsmStmt *GAS = dyn_cast<GCCAsmStmt>(&S))
2354e5dd7070Spatrick Name = GAS->getInputName(i);
2355e5dd7070Spatrick TargetInfo::ConstraintInfo Info(S.getInputConstraint(i), Name);
2356e5dd7070Spatrick bool IsValid =
2357e5dd7070Spatrick getTarget().validateInputConstraint(OutputConstraintInfos, Info);
2358e5dd7070Spatrick assert(IsValid && "Failed to parse input constraint"); (void)IsValid;
2359e5dd7070Spatrick InputConstraintInfos.push_back(Info);
2360e5dd7070Spatrick }
2361e5dd7070Spatrick
2362e5dd7070Spatrick std::string Constraints;
2363e5dd7070Spatrick
2364e5dd7070Spatrick std::vector<LValue> ResultRegDests;
2365e5dd7070Spatrick std::vector<QualType> ResultRegQualTys;
2366e5dd7070Spatrick std::vector<llvm::Type *> ResultRegTypes;
2367e5dd7070Spatrick std::vector<llvm::Type *> ResultTruncRegTypes;
2368e5dd7070Spatrick std::vector<llvm::Type *> ArgTypes;
2369*12c85518Srobert std::vector<llvm::Type *> ArgElemTypes;
2370e5dd7070Spatrick std::vector<llvm::Value*> Args;
2371e5dd7070Spatrick llvm::BitVector ResultTypeRequiresCast;
2372*12c85518Srobert llvm::BitVector ResultRegIsFlagReg;
2373e5dd7070Spatrick
2374e5dd7070Spatrick // Keep track of inout constraints.
2375e5dd7070Spatrick std::string InOutConstraints;
2376e5dd7070Spatrick std::vector<llvm::Value*> InOutArgs;
2377e5dd7070Spatrick std::vector<llvm::Type*> InOutArgTypes;
2378*12c85518Srobert std::vector<llvm::Type*> InOutArgElemTypes;
2379e5dd7070Spatrick
2380e5dd7070Spatrick // Keep track of out constraints for tied input operand.
2381e5dd7070Spatrick std::vector<std::string> OutputConstraints;
2382e5dd7070Spatrick
2383a9ac8606Spatrick // Keep track of defined physregs.
2384a9ac8606Spatrick llvm::SmallSet<std::string, 8> PhysRegOutputs;
2385a9ac8606Spatrick
2386e5dd7070Spatrick // An inline asm can be marked readonly if it meets the following conditions:
2387e5dd7070Spatrick // - it doesn't have any sideeffects
2388e5dd7070Spatrick // - it doesn't clobber memory
2389e5dd7070Spatrick // - it doesn't return a value by-reference
2390e5dd7070Spatrick // It can be marked readnone if it doesn't have any input memory constraints
2391e5dd7070Spatrick // in addition to meeting the conditions listed above.
2392e5dd7070Spatrick bool ReadOnly = true, ReadNone = true;
2393e5dd7070Spatrick
2394e5dd7070Spatrick for (unsigned i = 0, e = S.getNumOutputs(); i != e; i++) {
2395e5dd7070Spatrick TargetInfo::ConstraintInfo &Info = OutputConstraintInfos[i];
2396e5dd7070Spatrick
2397e5dd7070Spatrick // Simplify the output constraint.
2398e5dd7070Spatrick std::string OutputConstraint(S.getOutputConstraint(i));
2399e5dd7070Spatrick OutputConstraint = SimplifyConstraint(OutputConstraint.c_str() + 1,
2400e5dd7070Spatrick getTarget(), &OutputConstraintInfos);
2401e5dd7070Spatrick
2402e5dd7070Spatrick const Expr *OutExpr = S.getOutputExpr(i);
2403e5dd7070Spatrick OutExpr = OutExpr->IgnoreParenNoopCasts(getContext());
2404e5dd7070Spatrick
2405a9ac8606Spatrick std::string GCCReg;
2406e5dd7070Spatrick OutputConstraint = AddVariableConstraints(OutputConstraint, *OutExpr,
2407e5dd7070Spatrick getTarget(), CGM, S,
2408a9ac8606Spatrick Info.earlyClobber(),
2409a9ac8606Spatrick &GCCReg);
2410a9ac8606Spatrick // Give an error on multiple outputs to same physreg.
2411a9ac8606Spatrick if (!GCCReg.empty() && !PhysRegOutputs.insert(GCCReg).second)
2412a9ac8606Spatrick CGM.Error(S.getAsmLoc(), "multiple outputs to hard register: " + GCCReg);
2413a9ac8606Spatrick
2414e5dd7070Spatrick OutputConstraints.push_back(OutputConstraint);
2415e5dd7070Spatrick LValue Dest = EmitLValue(OutExpr);
2416e5dd7070Spatrick if (!Constraints.empty())
2417e5dd7070Spatrick Constraints += ',';
2418e5dd7070Spatrick
2419e5dd7070Spatrick // If this is a register output, then make the inline asm return it
2420e5dd7070Spatrick // by-value. If this is a memory result, return the value by-reference.
2421a9ac8606Spatrick QualType QTy = OutExpr->getType();
2422a9ac8606Spatrick const bool IsScalarOrAggregate = hasScalarEvaluationKind(QTy) ||
2423a9ac8606Spatrick hasAggregateEvaluationKind(QTy);
2424a9ac8606Spatrick if (!Info.allowsMemory() && IsScalarOrAggregate) {
2425a9ac8606Spatrick
2426e5dd7070Spatrick Constraints += "=" + OutputConstraint;
2427a9ac8606Spatrick ResultRegQualTys.push_back(QTy);
2428e5dd7070Spatrick ResultRegDests.push_back(Dest);
2429a9ac8606Spatrick
2430*12c85518Srobert bool IsFlagReg = llvm::StringRef(OutputConstraint).startswith("{@cc");
2431*12c85518Srobert ResultRegIsFlagReg.push_back(IsFlagReg);
2432*12c85518Srobert
2433a9ac8606Spatrick llvm::Type *Ty = ConvertTypeForMem(QTy);
2434a9ac8606Spatrick const bool RequiresCast = Info.allowsRegister() &&
2435a9ac8606Spatrick (getTargetHooks().isScalarizableAsmOperand(*this, Ty) ||
2436a9ac8606Spatrick Ty->isAggregateType());
2437a9ac8606Spatrick
2438a9ac8606Spatrick ResultTruncRegTypes.push_back(Ty);
2439a9ac8606Spatrick ResultTypeRequiresCast.push_back(RequiresCast);
2440a9ac8606Spatrick
2441a9ac8606Spatrick if (RequiresCast) {
2442a9ac8606Spatrick unsigned Size = getContext().getTypeSize(QTy);
2443a9ac8606Spatrick Ty = llvm::IntegerType::get(getLLVMContext(), Size);
2444e5dd7070Spatrick }
2445a9ac8606Spatrick ResultRegTypes.push_back(Ty);
2446e5dd7070Spatrick // If this output is tied to an input, and if the input is larger, then
2447e5dd7070Spatrick // we need to set the actual result type of the inline asm node to be the
2448e5dd7070Spatrick // same as the input type.
2449e5dd7070Spatrick if (Info.hasMatchingInput()) {
2450e5dd7070Spatrick unsigned InputNo;
2451e5dd7070Spatrick for (InputNo = 0; InputNo != S.getNumInputs(); ++InputNo) {
2452e5dd7070Spatrick TargetInfo::ConstraintInfo &Input = InputConstraintInfos[InputNo];
2453e5dd7070Spatrick if (Input.hasTiedOperand() && Input.getTiedOperand() == i)
2454e5dd7070Spatrick break;
2455e5dd7070Spatrick }
2456e5dd7070Spatrick assert(InputNo != S.getNumInputs() && "Didn't find matching input!");
2457e5dd7070Spatrick
2458e5dd7070Spatrick QualType InputTy = S.getInputExpr(InputNo)->getType();
2459e5dd7070Spatrick QualType OutputType = OutExpr->getType();
2460e5dd7070Spatrick
2461e5dd7070Spatrick uint64_t InputSize = getContext().getTypeSize(InputTy);
2462e5dd7070Spatrick if (getContext().getTypeSize(OutputType) < InputSize) {
2463e5dd7070Spatrick // Form the asm to return the value as a larger integer or fp type.
2464e5dd7070Spatrick ResultRegTypes.back() = ConvertType(InputTy);
2465e5dd7070Spatrick }
2466e5dd7070Spatrick }
2467e5dd7070Spatrick if (llvm::Type* AdjTy =
2468e5dd7070Spatrick getTargetHooks().adjustInlineAsmType(*this, OutputConstraint,
2469e5dd7070Spatrick ResultRegTypes.back()))
2470e5dd7070Spatrick ResultRegTypes.back() = AdjTy;
2471e5dd7070Spatrick else {
2472e5dd7070Spatrick CGM.getDiags().Report(S.getAsmLoc(),
2473e5dd7070Spatrick diag::err_asm_invalid_type_in_input)
2474e5dd7070Spatrick << OutExpr->getType() << OutputConstraint;
2475e5dd7070Spatrick }
2476e5dd7070Spatrick
2477e5dd7070Spatrick // Update largest vector width for any vector types.
2478e5dd7070Spatrick if (auto *VT = dyn_cast<llvm::VectorType>(ResultRegTypes.back()))
2479ec727ea7Spatrick LargestVectorWidth =
2480ec727ea7Spatrick std::max((uint64_t)LargestVectorWidth,
2481*12c85518Srobert VT->getPrimitiveSizeInBits().getKnownMinValue());
2482e5dd7070Spatrick } else {
2483*12c85518Srobert Address DestAddr = Dest.getAddress(*this);
2484a9ac8606Spatrick // Matrix types in memory are represented by arrays, but accessed through
2485a9ac8606Spatrick // vector pointers, with the alignment specified on the access operation.
2486a9ac8606Spatrick // For inline assembly, update pointer arguments to use vector pointers.
2487a9ac8606Spatrick // Otherwise there will be a mis-match if the matrix is also an
2488a9ac8606Spatrick // input-argument which is represented as vector.
2489*12c85518Srobert if (isa<MatrixType>(OutExpr->getType().getCanonicalType()))
2490*12c85518Srobert DestAddr = Builder.CreateElementBitCast(
2491*12c85518Srobert DestAddr, ConvertType(OutExpr->getType()));
2492*12c85518Srobert
2493*12c85518Srobert ArgTypes.push_back(DestAddr.getType());
2494*12c85518Srobert ArgElemTypes.push_back(DestAddr.getElementType());
2495*12c85518Srobert Args.push_back(DestAddr.getPointer());
2496e5dd7070Spatrick Constraints += "=*";
2497e5dd7070Spatrick Constraints += OutputConstraint;
2498e5dd7070Spatrick ReadOnly = ReadNone = false;
2499e5dd7070Spatrick }
2500e5dd7070Spatrick
2501e5dd7070Spatrick if (Info.isReadWrite()) {
2502e5dd7070Spatrick InOutConstraints += ',';
2503e5dd7070Spatrick
2504e5dd7070Spatrick const Expr *InputExpr = S.getOutputExpr(i);
2505*12c85518Srobert llvm::Value *Arg;
2506*12c85518Srobert llvm::Type *ArgElemType;
2507*12c85518Srobert std::tie(Arg, ArgElemType) = EmitAsmInputLValue(
2508*12c85518Srobert Info, Dest, InputExpr->getType(), InOutConstraints,
2509e5dd7070Spatrick InputExpr->getExprLoc());
2510e5dd7070Spatrick
2511e5dd7070Spatrick if (llvm::Type* AdjTy =
2512e5dd7070Spatrick getTargetHooks().adjustInlineAsmType(*this, OutputConstraint,
2513e5dd7070Spatrick Arg->getType()))
2514e5dd7070Spatrick Arg = Builder.CreateBitCast(Arg, AdjTy);
2515e5dd7070Spatrick
2516e5dd7070Spatrick // Update largest vector width for any vector types.
2517e5dd7070Spatrick if (auto *VT = dyn_cast<llvm::VectorType>(Arg->getType()))
2518ec727ea7Spatrick LargestVectorWidth =
2519ec727ea7Spatrick std::max((uint64_t)LargestVectorWidth,
2520*12c85518Srobert VT->getPrimitiveSizeInBits().getKnownMinValue());
2521a9ac8606Spatrick // Only tie earlyclobber physregs.
2522a9ac8606Spatrick if (Info.allowsRegister() && (GCCReg.empty() || Info.earlyClobber()))
2523e5dd7070Spatrick InOutConstraints += llvm::utostr(i);
2524e5dd7070Spatrick else
2525e5dd7070Spatrick InOutConstraints += OutputConstraint;
2526e5dd7070Spatrick
2527e5dd7070Spatrick InOutArgTypes.push_back(Arg->getType());
2528*12c85518Srobert InOutArgElemTypes.push_back(ArgElemType);
2529e5dd7070Spatrick InOutArgs.push_back(Arg);
2530e5dd7070Spatrick }
2531e5dd7070Spatrick }
2532e5dd7070Spatrick
2533e5dd7070Spatrick // If this is a Microsoft-style asm blob, store the return registers (EAX:EDX)
2534e5dd7070Spatrick // to the return value slot. Only do this when returning in registers.
2535e5dd7070Spatrick if (isa<MSAsmStmt>(&S)) {
2536e5dd7070Spatrick const ABIArgInfo &RetAI = CurFnInfo->getReturnInfo();
2537e5dd7070Spatrick if (RetAI.isDirect() || RetAI.isExtend()) {
2538e5dd7070Spatrick // Make a fake lvalue for the return value slot.
2539*12c85518Srobert LValue ReturnSlot = MakeAddrLValueWithoutTBAA(ReturnValue, FnRetTy);
2540e5dd7070Spatrick CGM.getTargetCodeGenInfo().addReturnRegisterOutputs(
2541e5dd7070Spatrick *this, ReturnSlot, Constraints, ResultRegTypes, ResultTruncRegTypes,
2542e5dd7070Spatrick ResultRegDests, AsmString, S.getNumOutputs());
2543e5dd7070Spatrick SawAsmBlock = true;
2544e5dd7070Spatrick }
2545e5dd7070Spatrick }
2546e5dd7070Spatrick
2547e5dd7070Spatrick for (unsigned i = 0, e = S.getNumInputs(); i != e; i++) {
2548e5dd7070Spatrick const Expr *InputExpr = S.getInputExpr(i);
2549e5dd7070Spatrick
2550e5dd7070Spatrick TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i];
2551e5dd7070Spatrick
2552e5dd7070Spatrick if (Info.allowsMemory())
2553e5dd7070Spatrick ReadNone = false;
2554e5dd7070Spatrick
2555e5dd7070Spatrick if (!Constraints.empty())
2556e5dd7070Spatrick Constraints += ',';
2557e5dd7070Spatrick
2558e5dd7070Spatrick // Simplify the input constraint.
2559e5dd7070Spatrick std::string InputConstraint(S.getInputConstraint(i));
2560e5dd7070Spatrick InputConstraint = SimplifyConstraint(InputConstraint.c_str(), getTarget(),
2561e5dd7070Spatrick &OutputConstraintInfos);
2562e5dd7070Spatrick
2563e5dd7070Spatrick InputConstraint = AddVariableConstraints(
2564e5dd7070Spatrick InputConstraint, *InputExpr->IgnoreParenNoopCasts(getContext()),
2565e5dd7070Spatrick getTarget(), CGM, S, false /* No EarlyClobber */);
2566e5dd7070Spatrick
2567e5dd7070Spatrick std::string ReplaceConstraint (InputConstraint);
2568*12c85518Srobert llvm::Value *Arg;
2569*12c85518Srobert llvm::Type *ArgElemType;
2570*12c85518Srobert std::tie(Arg, ArgElemType) = EmitAsmInput(Info, InputExpr, Constraints);
2571e5dd7070Spatrick
2572e5dd7070Spatrick // If this input argument is tied to a larger output result, extend the
2573e5dd7070Spatrick // input to be the same size as the output. The LLVM backend wants to see
2574e5dd7070Spatrick // the input and output of a matching constraint be the same size. Note
2575e5dd7070Spatrick // that GCC does not define what the top bits are here. We use zext because
2576e5dd7070Spatrick // that is usually cheaper, but LLVM IR should really get an anyext someday.
2577e5dd7070Spatrick if (Info.hasTiedOperand()) {
2578e5dd7070Spatrick unsigned Output = Info.getTiedOperand();
2579e5dd7070Spatrick QualType OutputType = S.getOutputExpr(Output)->getType();
2580e5dd7070Spatrick QualType InputTy = InputExpr->getType();
2581e5dd7070Spatrick
2582e5dd7070Spatrick if (getContext().getTypeSize(OutputType) >
2583e5dd7070Spatrick getContext().getTypeSize(InputTy)) {
2584e5dd7070Spatrick // Use ptrtoint as appropriate so that we can do our extension.
2585e5dd7070Spatrick if (isa<llvm::PointerType>(Arg->getType()))
2586e5dd7070Spatrick Arg = Builder.CreatePtrToInt(Arg, IntPtrTy);
2587e5dd7070Spatrick llvm::Type *OutputTy = ConvertType(OutputType);
2588e5dd7070Spatrick if (isa<llvm::IntegerType>(OutputTy))
2589e5dd7070Spatrick Arg = Builder.CreateZExt(Arg, OutputTy);
2590e5dd7070Spatrick else if (isa<llvm::PointerType>(OutputTy))
2591e5dd7070Spatrick Arg = Builder.CreateZExt(Arg, IntPtrTy);
2592*12c85518Srobert else if (OutputTy->isFloatingPointTy())
2593e5dd7070Spatrick Arg = Builder.CreateFPExt(Arg, OutputTy);
2594e5dd7070Spatrick }
2595e5dd7070Spatrick // Deal with the tied operands' constraint code in adjustInlineAsmType.
2596e5dd7070Spatrick ReplaceConstraint = OutputConstraints[Output];
2597e5dd7070Spatrick }
2598e5dd7070Spatrick if (llvm::Type* AdjTy =
2599e5dd7070Spatrick getTargetHooks().adjustInlineAsmType(*this, ReplaceConstraint,
2600e5dd7070Spatrick Arg->getType()))
2601e5dd7070Spatrick Arg = Builder.CreateBitCast(Arg, AdjTy);
2602e5dd7070Spatrick else
2603e5dd7070Spatrick CGM.getDiags().Report(S.getAsmLoc(), diag::err_asm_invalid_type_in_input)
2604e5dd7070Spatrick << InputExpr->getType() << InputConstraint;
2605e5dd7070Spatrick
2606e5dd7070Spatrick // Update largest vector width for any vector types.
2607e5dd7070Spatrick if (auto *VT = dyn_cast<llvm::VectorType>(Arg->getType()))
2608ec727ea7Spatrick LargestVectorWidth =
2609ec727ea7Spatrick std::max((uint64_t)LargestVectorWidth,
2610*12c85518Srobert VT->getPrimitiveSizeInBits().getKnownMinValue());
2611e5dd7070Spatrick
2612e5dd7070Spatrick ArgTypes.push_back(Arg->getType());
2613*12c85518Srobert ArgElemTypes.push_back(ArgElemType);
2614e5dd7070Spatrick Args.push_back(Arg);
2615e5dd7070Spatrick Constraints += InputConstraint;
2616e5dd7070Spatrick }
2617e5dd7070Spatrick
2618*12c85518Srobert // Append the "input" part of inout constraints.
2619*12c85518Srobert for (unsigned i = 0, e = InOutArgs.size(); i != e; i++) {
2620*12c85518Srobert ArgTypes.push_back(InOutArgTypes[i]);
2621*12c85518Srobert ArgElemTypes.push_back(InOutArgElemTypes[i]);
2622*12c85518Srobert Args.push_back(InOutArgs[i]);
2623*12c85518Srobert }
2624*12c85518Srobert Constraints += InOutConstraints;
2625*12c85518Srobert
2626e5dd7070Spatrick // Labels
2627e5dd7070Spatrick SmallVector<llvm::BasicBlock *, 16> Transfer;
2628e5dd7070Spatrick llvm::BasicBlock *Fallthrough = nullptr;
2629e5dd7070Spatrick bool IsGCCAsmGoto = false;
2630e5dd7070Spatrick if (const auto *GS = dyn_cast<GCCAsmStmt>(&S)) {
2631e5dd7070Spatrick IsGCCAsmGoto = GS->isAsmGoto();
2632e5dd7070Spatrick if (IsGCCAsmGoto) {
2633ec727ea7Spatrick for (const auto *E : GS->labels()) {
2634e5dd7070Spatrick JumpDest Dest = getJumpDestForLabel(E->getLabel());
2635e5dd7070Spatrick Transfer.push_back(Dest.getBlock());
2636e5dd7070Spatrick if (!Constraints.empty())
2637e5dd7070Spatrick Constraints += ',';
2638*12c85518Srobert Constraints += "!i";
2639e5dd7070Spatrick }
2640ec727ea7Spatrick Fallthrough = createBasicBlock("asm.fallthrough");
2641e5dd7070Spatrick }
2642e5dd7070Spatrick }
2643e5dd7070Spatrick
2644a9ac8606Spatrick bool HasUnwindClobber = false;
2645a9ac8606Spatrick
2646e5dd7070Spatrick // Clobbers
2647e5dd7070Spatrick for (unsigned i = 0, e = S.getNumClobbers(); i != e; i++) {
2648e5dd7070Spatrick StringRef Clobber = S.getClobber(i);
2649e5dd7070Spatrick
2650e5dd7070Spatrick if (Clobber == "memory")
2651e5dd7070Spatrick ReadOnly = ReadNone = false;
2652a9ac8606Spatrick else if (Clobber == "unwind") {
2653a9ac8606Spatrick HasUnwindClobber = true;
2654a9ac8606Spatrick continue;
2655a9ac8606Spatrick } else if (Clobber != "cc") {
2656e5dd7070Spatrick Clobber = getTarget().getNormalizedGCCRegisterName(Clobber);
2657ec727ea7Spatrick if (CGM.getCodeGenOpts().StackClashProtector &&
2658ec727ea7Spatrick getTarget().isSPRegName(Clobber)) {
2659ec727ea7Spatrick CGM.getDiags().Report(S.getAsmLoc(),
2660ec727ea7Spatrick diag::warn_stack_clash_protection_inline_asm);
2661ec727ea7Spatrick }
2662ec727ea7Spatrick }
2663e5dd7070Spatrick
2664a9ac8606Spatrick if (isa<MSAsmStmt>(&S)) {
2665a9ac8606Spatrick if (Clobber == "eax" || Clobber == "edx") {
2666a9ac8606Spatrick if (Constraints.find("=&A") != std::string::npos)
2667a9ac8606Spatrick continue;
2668a9ac8606Spatrick std::string::size_type position1 =
2669a9ac8606Spatrick Constraints.find("={" + Clobber.str() + "}");
2670a9ac8606Spatrick if (position1 != std::string::npos) {
2671a9ac8606Spatrick Constraints.insert(position1 + 1, "&");
2672a9ac8606Spatrick continue;
2673a9ac8606Spatrick }
2674a9ac8606Spatrick std::string::size_type position2 = Constraints.find("=A");
2675a9ac8606Spatrick if (position2 != std::string::npos) {
2676a9ac8606Spatrick Constraints.insert(position2 + 1, "&");
2677a9ac8606Spatrick continue;
2678a9ac8606Spatrick }
2679a9ac8606Spatrick }
2680a9ac8606Spatrick }
2681e5dd7070Spatrick if (!Constraints.empty())
2682e5dd7070Spatrick Constraints += ',';
2683e5dd7070Spatrick
2684e5dd7070Spatrick Constraints += "~{";
2685e5dd7070Spatrick Constraints += Clobber;
2686e5dd7070Spatrick Constraints += '}';
2687e5dd7070Spatrick }
2688e5dd7070Spatrick
2689a9ac8606Spatrick assert(!(HasUnwindClobber && IsGCCAsmGoto) &&
2690a9ac8606Spatrick "unwind clobber can't be used with asm goto");
2691a9ac8606Spatrick
2692e5dd7070Spatrick // Add machine specific clobbers
2693e5dd7070Spatrick std::string MachineClobbers = getTarget().getClobbers();
2694e5dd7070Spatrick if (!MachineClobbers.empty()) {
2695e5dd7070Spatrick if (!Constraints.empty())
2696e5dd7070Spatrick Constraints += ',';
2697e5dd7070Spatrick Constraints += MachineClobbers;
2698e5dd7070Spatrick }
2699e5dd7070Spatrick
2700e5dd7070Spatrick llvm::Type *ResultType;
2701e5dd7070Spatrick if (ResultRegTypes.empty())
2702e5dd7070Spatrick ResultType = VoidTy;
2703e5dd7070Spatrick else if (ResultRegTypes.size() == 1)
2704e5dd7070Spatrick ResultType = ResultRegTypes[0];
2705e5dd7070Spatrick else
2706e5dd7070Spatrick ResultType = llvm::StructType::get(getLLVMContext(), ResultRegTypes);
2707e5dd7070Spatrick
2708e5dd7070Spatrick llvm::FunctionType *FTy =
2709e5dd7070Spatrick llvm::FunctionType::get(ResultType, ArgTypes, false);
2710e5dd7070Spatrick
2711e5dd7070Spatrick bool HasSideEffect = S.isVolatile() || S.getNumOutputs() == 0;
2712*12c85518Srobert
2713*12c85518Srobert llvm::InlineAsm::AsmDialect GnuAsmDialect =
2714*12c85518Srobert CGM.getCodeGenOpts().getInlineAsmDialect() == CodeGenOptions::IAD_ATT
2715*12c85518Srobert ? llvm::InlineAsm::AD_ATT
2716*12c85518Srobert : llvm::InlineAsm::AD_Intel;
2717e5dd7070Spatrick llvm::InlineAsm::AsmDialect AsmDialect = isa<MSAsmStmt>(&S) ?
2718*12c85518Srobert llvm::InlineAsm::AD_Intel : GnuAsmDialect;
2719*12c85518Srobert
2720a9ac8606Spatrick llvm::InlineAsm *IA = llvm::InlineAsm::get(
2721a9ac8606Spatrick FTy, AsmString, Constraints, HasSideEffect,
2722a9ac8606Spatrick /* IsAlignStack */ false, AsmDialect, HasUnwindClobber);
2723e5dd7070Spatrick std::vector<llvm::Value*> RegResults;
2724e5dd7070Spatrick if (IsGCCAsmGoto) {
2725e5dd7070Spatrick llvm::CallBrInst *Result =
2726e5dd7070Spatrick Builder.CreateCallBr(IA, Fallthrough, Transfer, Args);
2727ec727ea7Spatrick EmitBlock(Fallthrough);
2728a9ac8606Spatrick UpdateAsmCallInst(cast<llvm::CallBase>(*Result), HasSideEffect, false,
2729a9ac8606Spatrick ReadOnly, ReadNone, InNoMergeAttributedStmt, S,
2730*12c85518Srobert ResultRegTypes, ArgElemTypes, *this, RegResults);
2731a9ac8606Spatrick } else if (HasUnwindClobber) {
2732a9ac8606Spatrick llvm::CallBase *Result = EmitCallOrInvoke(IA, Args, "");
2733a9ac8606Spatrick UpdateAsmCallInst(*Result, HasSideEffect, true, ReadOnly, ReadNone,
2734*12c85518Srobert InNoMergeAttributedStmt, S, ResultRegTypes, ArgElemTypes,
2735*12c85518Srobert *this, RegResults);
2736e5dd7070Spatrick } else {
2737e5dd7070Spatrick llvm::CallInst *Result =
2738e5dd7070Spatrick Builder.CreateCall(IA, Args, getBundlesForFunclet(IA));
2739a9ac8606Spatrick UpdateAsmCallInst(cast<llvm::CallBase>(*Result), HasSideEffect, false,
2740a9ac8606Spatrick ReadOnly, ReadNone, InNoMergeAttributedStmt, S,
2741*12c85518Srobert ResultRegTypes, ArgElemTypes, *this, RegResults);
2742e5dd7070Spatrick }
2743e5dd7070Spatrick
2744e5dd7070Spatrick assert(RegResults.size() == ResultRegTypes.size());
2745e5dd7070Spatrick assert(RegResults.size() == ResultTruncRegTypes.size());
2746e5dd7070Spatrick assert(RegResults.size() == ResultRegDests.size());
2747e5dd7070Spatrick // ResultRegDests can be also populated by addReturnRegisterOutputs() above,
2748e5dd7070Spatrick // in which case its size may grow.
2749e5dd7070Spatrick assert(ResultTypeRequiresCast.size() <= ResultRegDests.size());
2750*12c85518Srobert assert(ResultRegIsFlagReg.size() <= ResultRegDests.size());
2751e5dd7070Spatrick for (unsigned i = 0, e = RegResults.size(); i != e; ++i) {
2752e5dd7070Spatrick llvm::Value *Tmp = RegResults[i];
2753a9ac8606Spatrick llvm::Type *TruncTy = ResultTruncRegTypes[i];
2754e5dd7070Spatrick
2755*12c85518Srobert if ((i < ResultRegIsFlagReg.size()) && ResultRegIsFlagReg[i]) {
2756*12c85518Srobert // Target must guarantee the Value `Tmp` here is lowered to a boolean
2757*12c85518Srobert // value.
2758*12c85518Srobert llvm::Constant *Two = llvm::ConstantInt::get(Tmp->getType(), 2);
2759*12c85518Srobert llvm::Value *IsBooleanValue =
2760*12c85518Srobert Builder.CreateCmp(llvm::CmpInst::ICMP_ULT, Tmp, Two);
2761*12c85518Srobert llvm::Function *FnAssume = CGM.getIntrinsic(llvm::Intrinsic::assume);
2762*12c85518Srobert Builder.CreateCall(FnAssume, IsBooleanValue);
2763*12c85518Srobert }
2764*12c85518Srobert
2765e5dd7070Spatrick // If the result type of the LLVM IR asm doesn't match the result type of
2766e5dd7070Spatrick // the expression, do the conversion.
2767e5dd7070Spatrick if (ResultRegTypes[i] != ResultTruncRegTypes[i]) {
2768e5dd7070Spatrick
2769e5dd7070Spatrick // Truncate the integer result to the right size, note that TruncTy can be
2770e5dd7070Spatrick // a pointer.
2771e5dd7070Spatrick if (TruncTy->isFloatingPointTy())
2772e5dd7070Spatrick Tmp = Builder.CreateFPTrunc(Tmp, TruncTy);
2773e5dd7070Spatrick else if (TruncTy->isPointerTy() && Tmp->getType()->isIntegerTy()) {
2774e5dd7070Spatrick uint64_t ResSize = CGM.getDataLayout().getTypeSizeInBits(TruncTy);
2775e5dd7070Spatrick Tmp = Builder.CreateTrunc(Tmp,
2776e5dd7070Spatrick llvm::IntegerType::get(getLLVMContext(), (unsigned)ResSize));
2777e5dd7070Spatrick Tmp = Builder.CreateIntToPtr(Tmp, TruncTy);
2778e5dd7070Spatrick } else if (Tmp->getType()->isPointerTy() && TruncTy->isIntegerTy()) {
2779e5dd7070Spatrick uint64_t TmpSize =CGM.getDataLayout().getTypeSizeInBits(Tmp->getType());
2780e5dd7070Spatrick Tmp = Builder.CreatePtrToInt(Tmp,
2781e5dd7070Spatrick llvm::IntegerType::get(getLLVMContext(), (unsigned)TmpSize));
2782e5dd7070Spatrick Tmp = Builder.CreateTrunc(Tmp, TruncTy);
2783e5dd7070Spatrick } else if (TruncTy->isIntegerTy()) {
2784e5dd7070Spatrick Tmp = Builder.CreateZExtOrTrunc(Tmp, TruncTy);
2785e5dd7070Spatrick } else if (TruncTy->isVectorTy()) {
2786e5dd7070Spatrick Tmp = Builder.CreateBitCast(Tmp, TruncTy);
2787e5dd7070Spatrick }
2788e5dd7070Spatrick }
2789e5dd7070Spatrick
2790e5dd7070Spatrick LValue Dest = ResultRegDests[i];
2791e5dd7070Spatrick // ResultTypeRequiresCast elements correspond to the first
2792e5dd7070Spatrick // ResultTypeRequiresCast.size() elements of RegResults.
2793e5dd7070Spatrick if ((i < ResultTypeRequiresCast.size()) && ResultTypeRequiresCast[i]) {
2794e5dd7070Spatrick unsigned Size = getContext().getTypeSize(ResultRegQualTys[i]);
2795*12c85518Srobert Address A = Builder.CreateElementBitCast(Dest.getAddress(*this),
2796*12c85518Srobert ResultRegTypes[i]);
2797a9ac8606Spatrick if (getTargetHooks().isScalarizableAsmOperand(*this, TruncTy)) {
2798a9ac8606Spatrick Builder.CreateStore(Tmp, A);
2799a9ac8606Spatrick continue;
2800a9ac8606Spatrick }
2801a9ac8606Spatrick
2802e5dd7070Spatrick QualType Ty = getContext().getIntTypeForBitwidth(Size, /*Signed*/ false);
2803e5dd7070Spatrick if (Ty.isNull()) {
2804e5dd7070Spatrick const Expr *OutExpr = S.getOutputExpr(i);
2805*12c85518Srobert CGM.getDiags().Report(OutExpr->getExprLoc(),
2806*12c85518Srobert diag::err_store_value_to_reg);
2807e5dd7070Spatrick return;
2808e5dd7070Spatrick }
2809e5dd7070Spatrick Dest = MakeAddrLValue(A, Ty);
2810e5dd7070Spatrick }
2811e5dd7070Spatrick EmitStoreThroughLValue(RValue::get(Tmp), Dest);
2812e5dd7070Spatrick }
2813e5dd7070Spatrick }
2814e5dd7070Spatrick
InitCapturedStruct(const CapturedStmt & S)2815e5dd7070Spatrick LValue CodeGenFunction::InitCapturedStruct(const CapturedStmt &S) {
2816e5dd7070Spatrick const RecordDecl *RD = S.getCapturedRecordDecl();
2817e5dd7070Spatrick QualType RecordTy = getContext().getRecordType(RD);
2818e5dd7070Spatrick
2819e5dd7070Spatrick // Initialize the captured struct.
2820e5dd7070Spatrick LValue SlotLV =
2821e5dd7070Spatrick MakeAddrLValue(CreateMemTemp(RecordTy, "agg.captured"), RecordTy);
2822e5dd7070Spatrick
2823e5dd7070Spatrick RecordDecl::field_iterator CurField = RD->field_begin();
2824e5dd7070Spatrick for (CapturedStmt::const_capture_init_iterator I = S.capture_init_begin(),
2825e5dd7070Spatrick E = S.capture_init_end();
2826e5dd7070Spatrick I != E; ++I, ++CurField) {
2827e5dd7070Spatrick LValue LV = EmitLValueForFieldInitialization(SlotLV, *CurField);
2828e5dd7070Spatrick if (CurField->hasCapturedVLAType()) {
2829a9ac8606Spatrick EmitLambdaVLACapture(CurField->getCapturedVLAType(), LV);
2830e5dd7070Spatrick } else {
2831e5dd7070Spatrick EmitInitializerForField(*CurField, LV, *I);
2832e5dd7070Spatrick }
2833e5dd7070Spatrick }
2834e5dd7070Spatrick
2835e5dd7070Spatrick return SlotLV;
2836e5dd7070Spatrick }
2837e5dd7070Spatrick
2838e5dd7070Spatrick /// Generate an outlined function for the body of a CapturedStmt, store any
2839e5dd7070Spatrick /// captured variables into the captured struct, and call the outlined function.
2840e5dd7070Spatrick llvm::Function *
EmitCapturedStmt(const CapturedStmt & S,CapturedRegionKind K)2841e5dd7070Spatrick CodeGenFunction::EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K) {
2842e5dd7070Spatrick LValue CapStruct = InitCapturedStruct(S);
2843e5dd7070Spatrick
2844e5dd7070Spatrick // Emit the CapturedDecl
2845e5dd7070Spatrick CodeGenFunction CGF(CGM, true);
2846e5dd7070Spatrick CGCapturedStmtRAII CapInfoRAII(CGF, new CGCapturedStmtInfo(S, K));
2847e5dd7070Spatrick llvm::Function *F = CGF.GenerateCapturedStmtFunction(S);
2848e5dd7070Spatrick delete CGF.CapturedStmtInfo;
2849e5dd7070Spatrick
2850e5dd7070Spatrick // Emit call to the helper function.
2851e5dd7070Spatrick EmitCallOrInvoke(F, CapStruct.getPointer(*this));
2852e5dd7070Spatrick
2853e5dd7070Spatrick return F;
2854e5dd7070Spatrick }
2855e5dd7070Spatrick
GenerateCapturedStmtArgument(const CapturedStmt & S)2856e5dd7070Spatrick Address CodeGenFunction::GenerateCapturedStmtArgument(const CapturedStmt &S) {
2857e5dd7070Spatrick LValue CapStruct = InitCapturedStruct(S);
2858e5dd7070Spatrick return CapStruct.getAddress(*this);
2859e5dd7070Spatrick }
2860e5dd7070Spatrick
2861e5dd7070Spatrick /// Creates the outlined function for a CapturedStmt.
2862e5dd7070Spatrick llvm::Function *
GenerateCapturedStmtFunction(const CapturedStmt & S)2863e5dd7070Spatrick CodeGenFunction::GenerateCapturedStmtFunction(const CapturedStmt &S) {
2864e5dd7070Spatrick assert(CapturedStmtInfo &&
2865e5dd7070Spatrick "CapturedStmtInfo should be set when generating the captured function");
2866e5dd7070Spatrick const CapturedDecl *CD = S.getCapturedDecl();
2867e5dd7070Spatrick const RecordDecl *RD = S.getCapturedRecordDecl();
2868e5dd7070Spatrick SourceLocation Loc = S.getBeginLoc();
2869e5dd7070Spatrick assert(CD->hasBody() && "missing CapturedDecl body");
2870e5dd7070Spatrick
2871e5dd7070Spatrick // Build the argument list.
2872e5dd7070Spatrick ASTContext &Ctx = CGM.getContext();
2873e5dd7070Spatrick FunctionArgList Args;
2874e5dd7070Spatrick Args.append(CD->param_begin(), CD->param_end());
2875e5dd7070Spatrick
2876e5dd7070Spatrick // Create the function declaration.
2877e5dd7070Spatrick const CGFunctionInfo &FuncInfo =
2878e5dd7070Spatrick CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Args);
2879e5dd7070Spatrick llvm::FunctionType *FuncLLVMTy = CGM.getTypes().GetFunctionType(FuncInfo);
2880e5dd7070Spatrick
2881e5dd7070Spatrick llvm::Function *F =
2882e5dd7070Spatrick llvm::Function::Create(FuncLLVMTy, llvm::GlobalValue::InternalLinkage,
2883e5dd7070Spatrick CapturedStmtInfo->getHelperName(), &CGM.getModule());
2884e5dd7070Spatrick CGM.SetInternalFunctionAttributes(CD, F, FuncInfo);
2885e5dd7070Spatrick if (CD->isNothrow())
2886e5dd7070Spatrick F->addFnAttr(llvm::Attribute::NoUnwind);
2887e5dd7070Spatrick
2888e5dd7070Spatrick // Generate the function.
2889e5dd7070Spatrick StartFunction(CD, Ctx.VoidTy, F, FuncInfo, Args, CD->getLocation(),
2890e5dd7070Spatrick CD->getBody()->getBeginLoc());
2891e5dd7070Spatrick // Set the context parameter in CapturedStmtInfo.
2892e5dd7070Spatrick Address DeclPtr = GetAddrOfLocalVar(CD->getContextParam());
2893e5dd7070Spatrick CapturedStmtInfo->setContextValue(Builder.CreateLoad(DeclPtr));
2894e5dd7070Spatrick
2895e5dd7070Spatrick // Initialize variable-length arrays.
2896e5dd7070Spatrick LValue Base = MakeNaturalAlignAddrLValue(CapturedStmtInfo->getContextValue(),
2897e5dd7070Spatrick Ctx.getTagDeclType(RD));
2898e5dd7070Spatrick for (auto *FD : RD->fields()) {
2899e5dd7070Spatrick if (FD->hasCapturedVLAType()) {
2900e5dd7070Spatrick auto *ExprArg =
2901e5dd7070Spatrick EmitLoadOfLValue(EmitLValueForField(Base, FD), S.getBeginLoc())
2902e5dd7070Spatrick .getScalarVal();
2903e5dd7070Spatrick auto VAT = FD->getCapturedVLAType();
2904e5dd7070Spatrick VLASizeMap[VAT->getSizeExpr()] = ExprArg;
2905e5dd7070Spatrick }
2906e5dd7070Spatrick }
2907e5dd7070Spatrick
2908e5dd7070Spatrick // If 'this' is captured, load it into CXXThisValue.
2909e5dd7070Spatrick if (CapturedStmtInfo->isCXXThisExprCaptured()) {
2910e5dd7070Spatrick FieldDecl *FD = CapturedStmtInfo->getThisFieldDecl();
2911e5dd7070Spatrick LValue ThisLValue = EmitLValueForField(Base, FD);
2912e5dd7070Spatrick CXXThisValue = EmitLoadOfLValue(ThisLValue, Loc).getScalarVal();
2913e5dd7070Spatrick }
2914e5dd7070Spatrick
2915e5dd7070Spatrick PGO.assignRegionCounters(GlobalDecl(CD), F);
2916e5dd7070Spatrick CapturedStmtInfo->EmitBody(*this, CD->getBody());
2917e5dd7070Spatrick FinishFunction(CD->getBodyRBrace());
2918e5dd7070Spatrick
2919e5dd7070Spatrick return F;
2920e5dd7070Spatrick }
2921