clang 24.0.0git
CIRPasses.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements machinery for any CIR <-> CIR passes used by clang.
10//
11//===----------------------------------------------------------------------===//
12
13#include "mlir/IR/BuiltinOps.h"
14#include "mlir/Pass/PassManager.h"
19#include "llvm/Support/TimeProfiler.h"
20#include "llvm/TargetParser/Triple.h"
21
22namespace cir {
23
24/// Map a target triple to the ABI target that drives CallConvLowering.
25/// Returns None for targets whose calling convention is not yet implemented.
26static CallConvTarget getCallConvTarget(const llvm::Triple &triple) {
27 if (triple.getArch() == llvm::Triple::x86_64)
30}
31
32/// The AVX level the classifier uses to size a native vector, read from the
33/// target ABI name.
34static llvm::abi::X86AVXABILevel getX86AVXABILevel(llvm::StringRef abi) {
35 if (abi == "avx512")
36 return llvm::abi::X86AVXABILevel::AVX512;
37 if (abi == "avx")
38 return llvm::abi::X86AVXABILevel::AVX;
39 return llvm::abi::X86AVXABILevel::None;
40}
41
42/// Whether `__attribute__((target(...)))` on a function may raise its AVX ABI
43/// level above the command line's. A target that opts out, and any ABI older
44/// than the rule, stay at the module level.
45static bool allowsX86TargetAttrAvx(const clang::ASTContext &astContext) {
46 return !astContext.getTargetInfo().getTriple().isPS() &&
47 astContext.getLangOpts().getClangABICompat() >
48 clang::LangOptions::ClangABI::Ver23;
49}
50
51/// The x86_64 ABI-compatibility flags, derived from the target and the
52/// requested compatibility version. Every flag defaults to true in the ABI
53/// library, which is not what any target computes: Clang11Compat is false for a
54/// modern Linux target, so leaving it at the default classifies a union larger
55/// than an eightbyte as though every member spanned its size.
56static llvm::abi::ABICompatInfo
58 const llvm::Triple &triple = astContext.getTargetInfo().getTriple();
59 const clang::LangOptions &langOpts = astContext.getLangOpts();
60 clang::LangOptions::ClangABI compat = langOpts.getClangABICompat();
61 llvm::abi::ABICompatInfo abiCompat;
62 abiCompat.HonorsRevision98 = !triple.isOSDarwin();
63 abiCompat.ClassifyIntegerMMXAsSSE =
64 compat > clang::LangOptions::ClangABI::Ver3_8 && !triple.isOSDarwin() &&
65 !triple.isPS() && !triple.isOSFreeBSD();
66 abiCompat.PassInt128VectorsInMem =
67 compat > clang::LangOptions::ClangABI::Ver9 &&
68 (triple.isOSLinux() || triple.isOSNetBSD());
69 abiCompat.ReturnCXXRecordGreaterThan128InMem =
70 compat > clang::LangOptions::ClangABI::Ver20 && !triple.isPS();
71 abiCompat.Clang11Compat =
72 compat <= clang::LangOptions::ClangABI::Ver11 || triple.isPS();
73 return abiCompat;
74}
75
76mlir::LogicalResult
77runCIRToCIRPasses(mlir::ModuleOp theModule, mlir::MLIRContext &mlirContext,
78 clang::ASTContext &astContext, bool enableVerifier,
79 bool enableIdiomRecognizer, bool enableCIRSimplify,
80 bool enableLibOpt, llvm::StringRef libOptOptions,
81 bool enableCallConvLowering) {
82
83 llvm::TimeTraceScope scope("CIR To CIR Passes");
84
85 mlir::PassManager pm(&mlirContext);
87
88 if (enableCIRSimplify)
89 pm.addPass(mlir::createCIRSimplifyPass());
90
91 if (enableIdiomRecognizer)
93
94 if (enableLibOpt) {
95 auto libOptPass = mlir::createLibOptPass();
96 auto errorHandler = [](const llvm::Twine &) -> mlir::LogicalResult {
97 return mlir::LogicalResult::failure();
98 };
99
100 if (libOptPass->initializeOptions(libOptOptions, errorHandler).failed())
101 return mlir::failure();
102
103 pm.addPass(std::move(libOptPass));
104 }
105
106 pm.addPass(mlir::createTargetLoweringPass());
107 pm.addPass(mlir::createCXXABILoweringPass());
108
109 // LoweringPrepare synthesizes calls to runtime helpers such as __divsc3, and
110 // outlines dynamic global initializers into functions. It must run before
111 // CallConvLowering so the classifier sees them, otherwise their signatures
112 // go unclassified and caller and callee disagree on the ABI.
113 pm.addPass(mlir::createLoweringPreparePass(&astContext));
114
115 if (enableCallConvLowering) {
116 // CallConvLowering rewrites signatures and call sites using the classifier,
117 // so it must run after CXXABILowering has lowered C++ ABI types to plain
118 // records the classifier can handle. Only the x86_64 System V classifier
119 // is implemented; other targets are left unchanged.
120 const clang::TargetInfo &targetInfo = astContext.getTargetInfo();
121 CallConvTarget target = getCallConvTarget(targetInfo.getTriple());
122 if (target != CallConvTarget::None)
124 target, getX86AVXABILevel(targetInfo.getABI()),
125 allowsX86TargetAttrAvx(astContext), getX86ABICompatInfo(astContext)));
126 }
127
128 pm.enableVerifier(enableVerifier);
129 (void)mlir::applyPassManagerCLOptions(pm);
130 return pm.run(theModule);
131}
132
133} // namespace cir
134
135namespace mlir {
136
137void populateCIRPreLoweringPasses(OpPassManager &pm) {
138 pm.addPass(createHoistAllocasPass());
139 pm.addPass(createCIRFlattenCFGPass());
140 pm.addPass(createCIREHABILoweringPass());
141 pm.addPass(createGotoSolverPass());
142}
143
144} // namespace mlir
Defines the clang::ASTContext interface.
Defines the clang::LangOptions interface.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:223
const LangOptions & getLangOpts() const
Definition ASTContext.h:980
const TargetInfo & getTargetInfo() const
Definition ASTContext.h:942
ClangABI
Clang versions with different platform ABI conformance.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Exposes information about the current target.
Definition TargetInfo.h:227
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
virtual StringRef getABI() const
Get the ABI currently in use.
Defines the clang::TargetInfo interface.
static CallConvTarget getCallConvTarget(const llvm::Triple &triple)
Map a target triple to the ABI target that drives CallConvLowering.
Definition CIRPasses.cpp:26
static llvm::abi::ABICompatInfo getX86ABICompatInfo(const clang::ASTContext &astContext)
The x86_64 ABI-compatibility flags, derived from the target and the requested compatibility version.
Definition CIRPasses.cpp:57
mlir::LogicalResult runCIRToCIRPasses(mlir::ModuleOp theModule, mlir::MLIRContext &mlirCtx, clang::ASTContext &astCtx, bool enableVerifier, bool enableIdiomRecognizer, bool enableCIRSimplify, bool enableLibOpt, llvm::StringRef libOptOptions, bool enableCallConvLowering)
Definition CIRPasses.cpp:77
static llvm::abi::X86AVXABILevel getX86AVXABILevel(llvm::StringRef abi)
The AVX level the classifier uses to size a native vector, read from the target ABI name.
Definition CIRPasses.cpp:34
static bool allowsX86TargetAttrAvx(const clang::ASTContext &astContext)
Whether __attribute__((target(...))) on a function may raise its AVX ABI level above the command line...
Definition CIRPasses.cpp:45
CallConvTarget
The ABI target whose calling-convention rules drive CallConvLowering.
Definition Passes.h:23
std::unique_ptr< Pass > createCallConvLoweringPass()
std::unique_ptr< Pass > createCIREHABILoweringPass()
std::unique_ptr< Pass > createCIRCanonicalizePass()
std::unique_ptr< Pass > createCIRFlattenCFGPass()
std::unique_ptr< Pass > createLibOptPass()
Definition LibOpt.cpp:75
std::unique_ptr< Pass > createIdiomRecognizerPass()
void populateCIRPreLoweringPasses(mlir::OpPassManager &pm)
std::unique_ptr< Pass > createTargetLoweringPass()
std::unique_ptr< Pass > createGotoSolverPass()
std::unique_ptr< Pass > createLoweringPreparePass()
std::unique_ptr< Pass > createCIRSimplifyPass()
std::unique_ptr< Pass > createCXXABILoweringPass()
std::unique_ptr< Pass > createHoistAllocasPass()