clang 24.0.0git
LowerModule.cpp
Go to the documentation of this file.
1//===--- LowerModule.cpp - Lower CIR Module to a Target -------------------===//
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 partially mimics clang/lib/CodeGen/CodeGenModule.cpp. The queries
10// are adapted to operate on the CIR dialect, however.
11//
12//===----------------------------------------------------------------------===//
13
14#include "LowerModule.h"
15#include "CIRCXXABI.h"
16#include "mlir/IR/BuiltinAttributes.h"
21#include "llvm/Support/ErrorHandling.h"
22#include "llvm/Support/FileSystem.h"
23
24namespace cir {
25
26static std::unique_ptr<CIRCXXABI> createCXXABI(LowerModule &lm) {
27 switch (lm.getCXXABIKind()) {
28 case clang::TargetCXXABI::AppleARM64:
29 case clang::TargetCXXABI::Fuchsia:
30 case clang::TargetCXXABI::GenericAArch64:
31 case clang::TargetCXXABI::GenericARM:
32 case clang::TargetCXXABI::iOS:
33 case clang::TargetCXXABI::WatchOS:
34 case clang::TargetCXXABI::GenericMIPS:
35 case clang::TargetCXXABI::GenericItanium:
36 case clang::TargetCXXABI::WebAssembly:
37 case clang::TargetCXXABI::XL:
38 return createItaniumCXXABI(lm);
39 case clang::TargetCXXABI::Microsoft:
40 return createMicrosoftCXXABI(lm);
41 }
42
43 llvm_unreachable("invalid C++ ABI kind");
44}
45
46static std::unique_ptr<TargetLoweringInfo>
48 const llvm::Triple &triple = lm.getTarget().getTriple();
49
50 switch (triple.getArch()) {
51 case llvm::Triple::amdgpu:
53 case llvm::Triple::nvptx:
54 case llvm::Triple::nvptx64:
56 case llvm::Triple::spir:
57 case llvm::Triple::spir64:
59 case llvm::Triple::spirv:
60 case llvm::Triple::spirv32:
61 case llvm::Triple::spirv64:
63 default:
65 return std::make_unique<TargetLoweringInfo>();
66 }
67}
68
70 clang::CodeGenOptions codeGenOpts,
71 mlir::ModuleOp &module,
72 std::unique_ptr<clang::TargetInfo> target)
73 : module(module), langOpts(std::move(langOpts)), target(std::move(target)),
74 abi(createCXXABI(*this)) {}
75
77 if (!targetLoweringInfo)
78 targetLoweringInfo = createTargetLoweringInfo(*this);
79 return *targetLoweringInfo;
80}
81
82// TODO: not to create it every time
83std::unique_ptr<LowerModule> createLowerModule(mlir::ModuleOp module) {
84 // If the triple is not present, e.g. CIR modules parsed from text, we
85 // cannot init LowerModule properly.
87 if (!module->hasAttr(cir::CIRDialect::getTripleAttrName()))
88 return nullptr;
89
90 // Fetch target information.
91 llvm::Triple triple(mlir::cast<mlir::StringAttr>(
92 module->getAttr(cir::CIRDialect::getTripleAttrName()))
93 .getValue());
94 clang::TargetOptions targetOptions;
95 targetOptions.Triple = triple.str();
96 auto targetInfo = clang::targets::AllocateTarget(triple, targetOptions);
97
98 // Populate the lowering-relevant LangOptions from the module's
99 // #cir.lowering_options attribute so a reloaded .cir lowers the same
100 // way it was compiled, without a live clang::LangOptions. When the attribute
101 // is absent (e.g. hand-written CIR) the defaults are kept;
102 clang::LangOptions langOpts;
103 if (auto loweringLangOpts =
104 mlir::dyn_cast_if_present<cir::LoweringOptionsAttr>(
105 module->getAttr(cir::CIRDialect::getLoweringOptionsAttrName()))) {
106 langOpts.Exceptions = loweringLangOpts.getExceptions();
107 langOpts.ThreadsafeStatics = loweringLangOpts.getThreadsafeStatics();
108 langOpts.CUDA = loweringLangOpts.getCuda();
109 langOpts.CUDAIsDevice = loweringLangOpts.getCudaIsDevice();
110 langOpts.HIP = loweringLangOpts.getHip();
111 langOpts.GPURelocatableDeviceCode = loweringLangOpts.getGpuRdc();
112 langOpts.OpenMP = loweringLangOpts.getOpenmp();
113 langOpts.OpenMPIsTargetDevice = loweringLangOpts.getOpenmpIsTargetDevice();
114 langOpts.setClangABICompat(static_cast<clang::LangOptions::ClangABI>(
115 loweringLangOpts.getClangAbiCompat()));
116 langOpts.LongDoubleSize = loweringLangOpts.getLongDoubleSize();
117 }
118 // Some langopts are still not lowered.
120
121 if (auto cxxABI = module->getAttrOfType<mlir::StringAttr>(
122 cir::CIRDialect::getCXXABIAttrName()))
123 langOpts.CXXABI = clang::TargetCXXABI::getKind(cxxABI.getValue());
124
125 // FIXME(cir): This just uses the default code generation options. We need to
126 // account for custom options.
128 clang::CodeGenOptions codeGenOpts;
129
130 if (auto optInfo = mlir::cast_if_present<cir::OptInfoAttr>(
131 module->getAttr(cir::CIRDialect::getOptInfoAttrName()))) {
132 codeGenOpts.OptimizationLevel = optInfo.getLevel();
133 codeGenOpts.OptimizeSize = optInfo.getSize();
134 }
135
139 targetInfo->adjust(diags, langOpts, /*Aux=*/nullptr);
140
141 return std::make_unique<LowerModule>(std::move(langOpts),
142 std::move(codeGenOpts), module,
143 std::move(targetInfo));
144}
145
146} // namespace cir
Defines the clang::LangOptions interface.
Defines the clang::TargetOptions class.
LowerModule(clang::LangOptions langOpts, clang::CodeGenOptions codeGenOpts, mlir::ModuleOp &module, std::unique_ptr< clang::TargetInfo > target)
clang::TargetCXXABI::Kind getCXXABIKind() const
Definition LowerModule.h:48
const TargetLoweringInfo & getTargetLoweringInfo()
const clang::TargetInfo & getTarget() const
Definition LowerModule.h:57
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
static llvm::IntrusiveRefCntPtr< DiagnosticIDs > create()
Options for controlling the compiler diagnostics engine.
Concrete class used by the front-end to report problems and issues.
Definition Diagnostic.h:241
A diagnostic client that ignores all diagnostics.
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...
std::optional< TargetCXXABI::Kind > CXXABI
C++ ABI to compile with, if specified by the frontend through -fc++-abi=.
Kind getKind() const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Options for controlling the target.
std::string Triple
The name of the target triple to compile for.
Defines the clang::TargetInfo interface.
static std::unique_ptr< TargetLoweringInfo > createTargetLoweringInfo(LowerModule &lm)
std::unique_ptr< TargetLoweringInfo > createCommonSPIRTargetLoweringInfo()
Definition SPIRV.cpp:53
std::unique_ptr< TargetLoweringInfo > createSPIRVTargetLoweringInfo()
Definition SPIRV.cpp:57
std::unique_ptr< CIRCXXABI > createItaniumCXXABI(LowerModule &lm)
Creates an Itanium-family ABI.
static std::unique_ptr< CIRCXXABI > createCXXABI(LowerModule &lm)
std::unique_ptr< TargetLoweringInfo > createNVPTXTargetLoweringInfo()
Definition NVPTX.cpp:44
std::unique_ptr< CIRCXXABI > createMicrosoftCXXABI(LowerModule &lm)
Creates a Microsoft-family ABI.
std::unique_ptr< LowerModule > createLowerModule(mlir::ModuleOp module)
std::unique_ptr< TargetLoweringInfo > createAMDGPUTargetLoweringInfo()
Definition AMDGPU.cpp:50
std::unique_ptr< clang::TargetInfo > AllocateTarget(const llvm::Triple &Triple, const clang::TargetOptions &Opts)
Definition Targets.cpp:111
static bool lowerModuleLangOpts()
static bool lowerModuleCodeGenOpts()
static bool makeTripleAlwaysPresent()
static bool targetLoweringInfo()