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:
58 case llvm::Triple::spirv:
59 case llvm::Triple::spirv32:
60 case llvm::Triple::spirv64:
62 default:
64 return std::make_unique<TargetLoweringInfo>();
65 }
66}
67
69 clang::CodeGenOptions codeGenOpts,
70 mlir::ModuleOp &module,
71 std::unique_ptr<clang::TargetInfo> target)
72 : module(module), langOpts(std::move(langOpts)), target(std::move(target)),
73 abi(createCXXABI(*this)) {}
74
76 if (!targetLoweringInfo)
77 targetLoweringInfo = createTargetLoweringInfo(*this);
78 return *targetLoweringInfo;
79}
80
81// TODO: not to create it every time
82std::unique_ptr<LowerModule> createLowerModule(mlir::ModuleOp module) {
83 // If the triple is not present, e.g. CIR modules parsed from text, we
84 // cannot init LowerModule properly.
86 if (!module->hasAttr(cir::CIRDialect::getTripleAttrName()))
87 return nullptr;
88
89 // Fetch target information.
90 llvm::Triple triple(mlir::cast<mlir::StringAttr>(
91 module->getAttr(cir::CIRDialect::getTripleAttrName()))
92 .getValue());
93 clang::TargetOptions targetOptions;
94 targetOptions.Triple = triple.str();
95 auto targetInfo = clang::targets::AllocateTarget(triple, targetOptions);
96
97 // Populate the lowering-relevant LangOptions from the module's
98 // #cir.lowering_lang_options attribute so a reloaded .cir lowers the same
99 // way it was compiled, without a live clang::LangOptions. When the attribute
100 // is absent (e.g. hand-written CIR) the defaults are kept;
101 clang::LangOptions langOpts;
102 if (auto loweringLangOpts =
103 mlir::dyn_cast_if_present<cir::LoweringLangOptionsAttr>(
104 module->getAttr(
105 cir::CIRDialect::getLoweringLangOptionsAttrName()))) {
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 }
117
118 // FIXME(cir): This just uses the default code generation options. We need to
119 // account for custom options.
121 clang::CodeGenOptions codeGenOpts;
122
123 if (auto optInfo = mlir::cast_if_present<cir::OptInfoAttr>(
124 module->getAttr(cir::CIRDialect::getOptInfoAttrName()))) {
125 codeGenOpts.OptimizationLevel = optInfo.getLevel();
126 codeGenOpts.OptimizeSize = optInfo.getSize();
127 }
128
129 return std::make_unique<LowerModule>(std::move(langOpts),
130 std::move(codeGenOpts), module,
131 std::move(targetInfo));
132}
133
134} // 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:54
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
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...
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 > createSPIRVTargetLoweringInfo()
Definition SPIRV.cpp:41
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:45
std::unique_ptr< clang::TargetInfo > AllocateTarget(const llvm::Triple &Triple, const clang::TargetOptions &Opts)
Definition Targets.cpp:111
static bool lowerModuleCodeGenOpts()
static bool makeTripleAlwaysPresent()
static bool targetLoweringInfo()