From c7a074b98bbc9eb174dda3d3d3f16b3b02068472 Mon Sep 17 00:00:00 2001 From: David Rivera Date: Sat, 21 Jun 2025 13:13:57 -0400 Subject: [PATCH 1/2] [CIR] Add Intrinsic handling skeleton --- .../clang/CIR/Dialect/IR/CIRIntrinsics.h | 200 ++++++++++++++++++ clang/lib/CIR/CodeGen/CIRGenModule.cpp | 6 + clang/lib/CIR/CodeGen/CIRGenModule.h | 3 +- clang/lib/CIR/Dialect/IR/CIRIntrinsics.cpp | 179 ++++++++++++++++ clang/lib/CIR/Dialect/IR/CMakeLists.txt | 1 + 5 files changed, 388 insertions(+), 1 deletion(-) create mode 100644 clang/include/clang/CIR/Dialect/IR/CIRIntrinsics.h create mode 100644 clang/lib/CIR/Dialect/IR/CIRIntrinsics.cpp diff --git a/clang/include/clang/CIR/Dialect/IR/CIRIntrinsics.h b/clang/include/clang/CIR/Dialect/IR/CIRIntrinsics.h new file mode 100644 index 000000000000..c6d69f094110 --- /dev/null +++ b/clang/include/clang/CIR/Dialect/IR/CIRIntrinsics.h @@ -0,0 +1,200 @@ +//===- CIRIntrinsics.h - CIR Intrinsic Function Handling ----------*- C++ +//-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines a set of enums which allow processing of intrinsic +// functions. Values of these enum types are returned by +// Function::getIntrinsicID. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_CIR_DIALECT_INTRINSICS_H +#define LLVM_CLANG_CIR_DIALECT_INTRINSICS_H + +#include "mlir/IR/BuiltinAttributes.h" +#include "mlir/IR/SymbolTable.h" +#include "clang/CIR/Dialect/IR/CIRDialect.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/Support/TypeSize.h" +#include +#include +// #include "mlir/IR/Types.h" +#include "mlir/Interfaces/DataLayoutInterfaces.h" +#include "clang/CIR/Dialect/IR/CIROpsEnums.h" +#include "clang/CIR/Interfaces/ASTAttrInterfaces.h" +#include "clang/CIR/Interfaces/CIRFPTypeInterface.h" + +namespace mlir { +class Type; +class ModuleOp; +class MLIRContext; +} // namespace mlir + +namespace llvm { +class StringRef; + +namespace Intrinsic { +struct IITDescriptor; // No need to duplicate the definition here +} // namespace Intrinsic + +} // namespace llvm +namespace cir { +class LLVMIntrinsicCallOp; +class FuncOp; +// FIXME: Unsure if we need a proper function type + +namespace Intrinsic { + +// Abstraction for the arguments of the noalias intrinsics +static const int NoAliasScopeDeclScopeArg = 0; + +// Intrinsic ID type. This is an opaque typedef to facilitate splitting up +// the enum into target-specific enums. +typedef unsigned ID; + +enum IndependentIntrinsics : unsigned { + not_intrinsic = 0, // Must be zero + +// Get the intrinsic enums generated from Intrinsics.td +#define GET_INTRINSIC_ENUM_VALUES +#include "llvm/IR/IntrinsicEnums.inc" +#undef GET_INTRINSIC_ENUM_VALUES +}; + +/// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx". +/// Note, this version is for intrinsics with no overloads. Use the other +/// version of getName if overloads are required. +llvm::StringRef getName(ID id); + +/// Return the LLVM name for an intrinsic, without encoded types for +/// overloading, such as "llvm.ssa.copy". +llvm::StringRef getBaseName(ID id); + +/// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx" or +/// "llvm.ssa.copy.p0s_s.1". Note, this version of getName supports overloads. +/// This is less efficient than the StringRef version of this function. If no +/// overloads are required, it is safe to use this version, but better to use +/// the StringRef version. If one of the types is based on an unnamed type, a +/// function type will be computed. Providing FT will avoid this computation. +std::string getName(ID Id, llvm::ArrayRef Tys, mlir::ModuleOp M, + mlir::Type FT = nullptr); + +/// Return the LLVM name for an intrinsic. This is a special version only to +/// be used by LLVMIntrinsicCopyOverloadedName. It only supports overloads +/// based on named types. +std::string getNameNoUnnamedTypes(ID Id, llvm::ArrayRef Tys); + +/// Return the function type for an intrinsic. +mlir::Type *getType(mlir::MLIRContext& Context, ID id, + llvm::ArrayRef Tys = {}); + +/// Returns true if the intrinsic can be overloaded. +bool isOverloaded(ID id); + +ID lookupIntrinsicID(llvm::StringRef Name); + +// FIXME: Uses table from LLVM, but we don't have it yet. +/// Return the attributes for an intrinsic. +// AttributeList getAttributes(mlir::MLIRContext &C, ID id); +// this is also defined as: +// /// This defines the "Intrinsic::getAttributes(ID id)" method. +// #define GET_INTRINSIC_ATTRIBUTES +// #include "llvm/IR/IntrinsicImpl.inc" +// #undef GET_INTRINSIC_ATTRIBUTES + +/// Look up the Function declaration of the intrinsic \p id in the Module +/// \p M. If it does not exist, add a declaration and return it. Otherwise, +/// return the existing declaration. +/// +/// The \p Tys parameter is for intrinsics with overloaded types (e.g., those +/// using iAny, fAny, vAny, or pAny). For a declaration of an overloaded +/// intrinsic, Tys must provide exactly one type for each overloaded type in +/// the intrinsic. +LLVMIntrinsicCallOp getOrInsertDeclaration(mlir::ModuleOp M, ID id, + llvm::ArrayRef Tys = {}); + +/// Look up the Function declaration of the intrinsic \p id in the Module +/// \p M and return it if it exists. Otherwise, return nullptr. This version +/// supports non-overloaded intrinsics. +LLVMIntrinsicCallOp getDeclarationIfExists(const mlir::ModuleOp *M, ID id); + +/// This version supports overloaded intrinsics. +LLVMIntrinsicCallOp getDeclarationIfExists(mlir::ModuleOp M, ID id, + llvm::ArrayRef Tys, + mlir::Type FT = nullptr); + +/// Map a Clang builtin name to an intrinsic ID. +ID getIntrinsicForClangBuiltin(llvm::StringRef TargetPrefix, + llvm::StringRef BuiltinName); + +/// Map a MS builtin name to an intrinsic ID. +ID getIntrinsicForMSBuiltin(llvm::StringRef TargetPrefix, + llvm::StringRef BuiltinName); + +// FIXME: Uses table from LLVM, but we don't have it yet. +// /// Returns true if the intrinsic ID is for one of the "Constrained +// /// Floating-Point Intrinsics". +// bool isConstrainedFPIntrinsic(ID QID); + +// /// Returns true if the intrinsic ID is for one of the "Constrained +// /// Floating-Point Intrinsics" that take rounding mode metadata. +// bool hasConstrainedFPRoundingModeOperand(ID QID); + +/// Return the IIT table descriptor for the specified intrinsic into an array +/// of IITDescriptors. +void getIntrinsicInfoTableEntries( + ID id, llvm::SmallVectorImpl &T); + +enum MatchIntrinsicTypesResult { + MatchIntrinsicTypes_Match = 0, + MatchIntrinsicTypes_NoMatchRet = 1, + MatchIntrinsicTypes_NoMatchArg = 2, +}; + +/// Match the specified function type with the type constraints specified by +/// the .td file. If the given type is an overloaded type it is pushed to the +/// ArgTys vector. +/// +/// Returns false if the given type matches with the constraints, true +/// otherwise. +MatchIntrinsicTypesResult +matchIntrinsicSignature(FuncOp FTy, + llvm::ArrayRef &Infos, + llvm::SmallVectorImpl &ArgTys); + +/// Verify if the intrinsic has variable arguments. This method is intended to +/// be called after all the fixed arguments have been matched first. +/// +/// This method returns true on error. +bool matchIntrinsicVarArg( + bool isVarArg, llvm::ArrayRef &Infos); + +/// Gets the type arguments of an intrinsic call by matching type contraints +/// specified by the .td file. The overloaded types are pushed into the +/// AgTys vector. +/// +/// Returns false if the given ID and function type combination is not a +/// valid intrinsic call. +bool getIntrinsicSignature(Intrinsic::ID, mlir::Type FT, + llvm::SmallVectorImpl &ArgTys); + +/// Same as previous, but accepts a Function instead of ID and FunctionType. +bool getIntrinsicSignature(FuncOp F, llvm::SmallVectorImpl &ArgTys); + +// Checks if the intrinsic name matches with its signature and if not +// returns the declaration with the same signature and remangled name. +// An existing GlobalValue with the wanted name but with a wrong prototype +// or of the wrong kind will be renamed by adding ".renamed" to the name. +std::optional remangleIntrinsicFunction(FuncOp F); + +} // namespace Intrinsic +} // namespace cir + +#endif // LLVM_CLANG_CIR_DIALECT_INTRINSICS_H \ No newline at end of file diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index 09d2609cd7b3..d48400a1c1d1 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -33,6 +33,7 @@ #include "mlir/IR/Verifier.h" #include "clang/AST/Expr.h" #include "clang/Basic/Cuda.h" +#include "clang/CIR/Dialect/IR/CIRIntrinsics.h" #include "clang/CIR/Dialect/IR/CIRTypes.h" #include "clang/CIR/MissingFeatures.h" @@ -2477,6 +2478,11 @@ void CIRGenModule::emitAliasForGlobal(StringRef mangledName, setCommonAttributes(aliasGD, alias); } +cir::LLVMIntrinsicCallOp +CIRGenModule::getIntrinsic(unsigned IID, ArrayRef Tys) { + return cir::Intrinsic::getOrInsertDeclaration(getModule(), (cir::Intrinsic::ID)IID, Tys); +} + mlir::Type CIRGenModule::convertType(QualType type) { return genTypes.convertType(type); } diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h b/clang/lib/CIR/CodeGen/CIRGenModule.h index e96220ea395a..83da871d8e43 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.h +++ b/clang/lib/CIR/CodeGen/CIRGenModule.h @@ -655,7 +655,8 @@ class CIRGenModule : public CIRGenTypeCache { void emitAliasForGlobal(llvm::StringRef mangledName, mlir::Operation *op, GlobalDecl aliasGD, cir::FuncOp aliasee, cir::GlobalLinkageKind linkage); - +cir::LLVMIntrinsicCallOp getIntrinsic(unsigned IID, + ArrayRef Tys); mlir::Type convertType(clang::QualType type); /// Set the visibility for the given global. diff --git a/clang/lib/CIR/Dialect/IR/CIRIntrinsics.cpp b/clang/lib/CIR/Dialect/IR/CIRIntrinsics.cpp new file mode 100644 index 000000000000..cc7d0dc1ee45 --- /dev/null +++ b/clang/lib/CIR/Dialect/IR/CIRIntrinsics.cpp @@ -0,0 +1,179 @@ +//===-- CIRIntrinsics.cpp - Intrinsic Function Handling ------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements functions required for supporting intrinsic functions. +// +//===----------------------------------------------------------------------===// + +#include "clang/CIR/Dialect/IR/CIRIntrinsics.h" +#include "clang/CIR/Dialect/IR/CIRDialect.h" +#include "llvm/Support/ErrorHandling.h" +#include + +using namespace cir; + +/// Table of string intrinsic names indexed by enum value. +#define GET_INTRINSIC_NAME_TABLE +#include "llvm/IR/IntrinsicImpl.inc" +#undef GET_INTRINSIC_NAME_TABLE + +llvm::StringRef Intrinsic::getBaseName(ID id) { + assert(id < num_intrinsics && "Invalid intrinsic ID!"); + return IntrinsicNameTable[IntrinsicNameOffsetTable[id]]; +} + +llvm::StringRef Intrinsic::getName(ID id) { + assert(id < num_intrinsics && "Invalid intrinsic ID!"); + assert(!Intrinsic::isOverloaded(id) && + "This version of getName does not support overloading"); + return getBaseName(id); +} + +/// Returns a stable mangling for the type specified for use in the name +/// mangling scheme used by 'any' types in intrinsic signatures. The mangling +/// of named types is simply their name. Manglings for unnamed types consist +/// of a prefix ('p' for pointers, 'a' for arrays, 'f_' for functions) +/// combined with the mangling of their component types. A vararg function +/// type will have a suffix of 'vararg'. Since function types can contain +/// other function types, we close a function type mangling with suffix 'f' +/// which can't be confused with it's prefix. This ensures we don't have +/// collisions between two unrelated function types. Otherwise, you might +/// parse ffXX as f(fXX) or f(fX)X. (X is a placeholder for any other type.) +/// The HasUnnamedType boolean is set if an unnamed type was encountered, +/// indicating that extra care must be taken to ensure a unique name. +static std::string getMangledTypeStr(mlir::Type Ty, bool &HasUnnamedType) { + llvm_unreachable("NYI"); + std::string Result; +// if (PointerType *PTyp = dyn_cast(Ty)) { +// Result += "p" + utostr(PTyp->getAddressSpace()); +// } else if (ArrayType *ATyp = dyn_cast(Ty)) { +// Result += "a" + utostr(ATyp->getNumElements()) + +// getMangledTypeStr(ATyp->getElementType(), HasUnnamedType); +// } else if (StructType *STyp = dyn_cast(Ty)) { +// if (!STyp->isLiteral()) { +// Result += "s_"; +// if (STyp->hasName()) +// Result += STyp->getName(); +// else +// HasUnnamedType = true; +// } else { +// Result += "sl_"; +// for (auto *Elem : STyp->elements()) +// Result += getMangledTypeStr(Elem, HasUnnamedType); +// } +// // Ensure nested structs are distinguishable. +// Result += "s"; +// } else if (FunctionType *FT = dyn_cast(Ty)) { +// Result += "f_" + getMangledTypeStr(FT->getReturnType(), HasUnnamedType); +// for (size_t i = 0; i < FT->getNumParams(); i++) +// Result += getMangledTypeStr(FT->getParamType(i), HasUnnamedType); +// if (FT->isVarArg()) +// Result += "vararg"; +// // Ensure nested function types are distinguishable. +// Result += "f"; +// } else if (VectorType *VTy = dyn_cast(Ty)) { +// ElementCount EC = VTy->getElementCount(); +// if (EC.isScalable()) +// Result += "nx"; +// Result += "v" + utostr(EC.getKnownMinValue()) + +// getMangledTypeStr(VTy->getElementType(), HasUnnamedType); +// } else if (TargetExtType *TETy = dyn_cast(Ty)) { +// Result += "t"; +// Result += TETy->getName(); +// for (Type *ParamTy : TETy->type_params()) +// Result += "_" + getMangledTypeStr(ParamTy, HasUnnamedType); +// for (unsigned IntParam : TETy->int_params()) +// Result += "_" + utostr(IntParam); +// // Ensure nested target extension types are distinguishable. +// Result += "t"; +// } else if (Ty) { +// switch (Ty->getTypeID()) { +// default: +// llvm_unreachable("Unhandled type"); +// case Type::VoidTyID: +// Result += "isVoid"; +// break; +// case Type::MetadataTyID: +// Result += "Metadata"; +// break; +// case Type::HalfTyID: +// Result += "f16"; +// break; +// case Type::BFloatTyID: +// Result += "bf16"; +// break; +// case Type::FloatTyID: +// Result += "f32"; +// break; +// case Type::DoubleTyID: +// Result += "f64"; +// break; +// case Type::X86_FP80TyID: +// Result += "f80"; +// break; +// case Type::FP128TyID: +// Result += "f128"; +// break; +// case Type::PPC_FP128TyID: +// Result += "ppcf128"; +// break; +// case Type::X86_AMXTyID: +// Result += "x86amx"; +// break; +// case Type::IntegerTyID: +// Result += "i" + utostr(cast(Ty)->getBitWidth()); +// break; +// } +// } + return Result; +} + +//TODO: This takes care of overloading, let's focus on the non-overloaded +static std::string getIntrinsicNameImpl(Intrinsic::ID Id, llvm::ArrayRef Tys, + mlir::ModuleOp M, mlir::Type FT, + bool EarlyModuleCheck) { + + llvm_unreachable("NYI: getIntrinsicNameImpl for CIR"); + std::string Result; + +// assert(Id < Intrinsic::num_intrinsics && "Invalid intrinsic ID!"); +// assert((Tys.empty() || Intrinsic::isOverloaded(Id)) && +// "This version of getName is for overloaded intrinsics only"); +// (void)EarlyModuleCheck; +// assert((!EarlyModuleCheck || M || +// !any_of(Tys, [](Type *T) { return isa(T); })) && +// "Intrinsic overloading on pointer types need to provide a Module"); +// bool HasUnnamedType = false; +// std::string Result(Intrinsic::getBaseName(Id)); +// for (Type *Ty : Tys) +// Result += "." + getMangledTypeStr(Ty, HasUnnamedType); +// if (HasUnnamedType) { +// assert(M && "unnamed types need a module"); +// if (!FT) +// FT = Intrinsic::getType(M->getContext(), Id, Tys); +// else +// assert((FT == Intrinsic::getType(M->getContext(), Id, Tys)) && +// "Provided FunctionType must match arguments"); +// return M->getUniqueIntrinsicName(Result, Id, FT); +// } + return Result; +} + +LLVMIntrinsicCallOp Intrinsic::getOrInsertDeclaration(mlir::ModuleOp M, ID id, + llvm::ArrayRef Tys) { + // There can never be multiple globals with the same name of different types, + // because intrinsics must be a specific type. + auto *FT = Intrinsic::getType(*M.getContext(), id, Tys); + + //From our module we should get a global function with the name of the intrinsic. (if not overloaded) + // return cast( + // M->getOrInsertFunction( + // Tys.empty() ? getName(id) : getName(id, Tys, M, FT), FT) + // .getCallee()); + return {}; +} diff --git a/clang/lib/CIR/Dialect/IR/CMakeLists.txt b/clang/lib/CIR/Dialect/IR/CMakeLists.txt index b75301d468d4..90e1c35d8e96 100644 --- a/clang/lib/CIR/Dialect/IR/CMakeLists.txt +++ b/clang/lib/CIR/Dialect/IR/CMakeLists.txt @@ -6,6 +6,7 @@ add_clang_library(MLIRCIR CIRMemorySlot.cpp CIRTypes.cpp FPEnv.cpp + CIRIntrinsics.cpp DEPENDS MLIRBuiltinLocationAttributesIncGen From 71f3dc1602d5b77251f1d3a5afbb57845a30999d Mon Sep 17 00:00:00 2001 From: David Rivera Date: Sun, 22 Jun 2025 21:41:52 -0400 Subject: [PATCH 2/2] Refactor intrinsic handling: rename namespace to `CIRIntrinsic` and introduce `IntrinsicDescriptor` struct for better intrinsic management --- .../clang/CIR/Dialect/IR/CIRIntrinsics.h | 48 +- clang/lib/CIR/CodeGen/CIRGenBuilder.h | 12 + clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp | 54 +- clang/lib/CIR/CodeGen/CIRGenModule.cpp | 5 +- clang/lib/CIR/CodeGen/CIRGenModule.h | 5 +- clang/lib/CIR/Dialect/IR/CIRIntrinsics.cpp | 656 ++++++++++++++---- clang/lib/CodeGen/CodeGenModule.cpp | 493 ++++++------- 7 files changed, 859 insertions(+), 414 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRIntrinsics.h b/clang/include/clang/CIR/Dialect/IR/CIRIntrinsics.h index c6d69f094110..aeeff92355bf 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRIntrinsics.h +++ b/clang/include/clang/CIR/Dialect/IR/CIRIntrinsics.h @@ -50,7 +50,7 @@ class LLVMIntrinsicCallOp; class FuncOp; // FIXME: Unsure if we need a proper function type -namespace Intrinsic { +namespace CIRIntrinsic { // Abstraction for the arguments of the noalias intrinsics static const int NoAliasScopeDeclScopeArg = 0; @@ -68,6 +68,26 @@ enum IndependentIntrinsics : unsigned { #undef GET_INTRINSIC_ENUM_VALUES }; +// Simple descriptor struct that holds essential intrinsic information +// In order to build CIRIntrinsicCallOp +struct IntrinsicDescriptor { + mlir::StringAttr name; // Mangled name attribute + mlir::Type resultType; // Return type for the intrinsic + ID id; // Original intrinsic ID (optional) + + // Basic constructor + IntrinsicDescriptor(mlir::StringAttr name, mlir::Type resultType, + ID id = not_intrinsic) + : name(name), resultType(resultType), id(id) {} + + // Default constructor for empty/invalid descriptors + IntrinsicDescriptor() + : name(nullptr), resultType(nullptr), id(not_intrinsic) {} + + // Check if descriptor is valid + bool isValid() const { return name && resultType; } +}; + /// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx". /// Note, this version is for intrinsics with no overloads. Use the other /// version of getName if overloads are required. @@ -92,11 +112,15 @@ std::string getName(ID Id, llvm::ArrayRef Tys, mlir::ModuleOp M, std::string getNameNoUnnamedTypes(ID Id, llvm::ArrayRef Tys); /// Return the function type for an intrinsic. -mlir::Type *getType(mlir::MLIRContext& Context, ID id, - llvm::ArrayRef Tys = {}); +// mlir::Type getType(mlir::MLIRContext &Context, ID id, +// llvm::ArrayRef Tys = {}); + +// Get both return type and parameter types in one call +mlir::Type getType(mlir::MLIRContext &Context, ID id, + llvm::ArrayRef Tys); /// Returns true if the intrinsic can be overloaded. -bool isOverloaded(ID id); +bool isOverloaded(ID id); // NYI ID lookupIntrinsicID(llvm::StringRef Name); @@ -117,18 +141,18 @@ ID lookupIntrinsicID(llvm::StringRef Name); /// using iAny, fAny, vAny, or pAny). For a declaration of an overloaded /// intrinsic, Tys must provide exactly one type for each overloaded type in /// the intrinsic. -LLVMIntrinsicCallOp getOrInsertDeclaration(mlir::ModuleOp M, ID id, - llvm::ArrayRef Tys = {}); +IntrinsicDescriptor getOrInsertDeclaration(mlir::ModuleOp M, ID id, + llvm::ArrayRef Tys = {}); /// Look up the Function declaration of the intrinsic \p id in the Module /// \p M and return it if it exists. Otherwise, return nullptr. This version /// supports non-overloaded intrinsics. -LLVMIntrinsicCallOp getDeclarationIfExists(const mlir::ModuleOp *M, ID id); +IntrinsicDescriptor getDeclarationIfExists(const mlir::ModuleOp *M, ID id); /// This version supports overloaded intrinsics. -LLVMIntrinsicCallOp getDeclarationIfExists(mlir::ModuleOp M, ID id, - llvm::ArrayRef Tys, - mlir::Type FT = nullptr); +IntrinsicDescriptor getDeclarationIfExists(mlir::ModuleOp M, ID id, + llvm::ArrayRef Tys, + mlir::Type FT = nullptr); /// Map a Clang builtin name to an intrinsic ID. ID getIntrinsicForClangBuiltin(llvm::StringRef TargetPrefix, @@ -182,7 +206,7 @@ bool matchIntrinsicVarArg( /// /// Returns false if the given ID and function type combination is not a /// valid intrinsic call. -bool getIntrinsicSignature(Intrinsic::ID, mlir::Type FT, +bool getIntrinsicSignature(ID, mlir::Type FT, llvm::SmallVectorImpl &ArgTys); /// Same as previous, but accepts a Function instead of ID and FunctionType. @@ -194,7 +218,7 @@ bool getIntrinsicSignature(FuncOp F, llvm::SmallVectorImpl &ArgTys); // or of the wrong kind will be renamed by adding ".renamed" to the name. std::optional remangleIntrinsicFunction(FuncOp F); -} // namespace Intrinsic +} // namespace CIRIntrinsic } // namespace cir #endif // LLVM_CLANG_CIR_DIALECT_INTRINSICS_H \ No newline at end of file diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h index 046030805ee5..945fd7baeb06 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h +++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h @@ -12,6 +12,7 @@ #include "Address.h" #include "CIRGenRecordLayout.h" #include "CIRGenTypeCache.h" +#include "clang/CIR/Dialect/IR/CIRIntrinsics.h" #include "clang/CIR/MissingFeatures.h" #include "clang/AST/Decl.h" @@ -749,6 +750,17 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy { return create(loc, retTy, sym, mlir::Value{}, offset); } + mlir::Value + createIntrinsicCall(mlir::Location loc, + cir::CIRIntrinsic::IntrinsicDescriptor descriptor, + llvm::ArrayRef args = {}) { + assert(descriptor.isValid() && "invalid intrinsic descriptor"); + + return create(loc, descriptor.name, + descriptor.resultType, args) + .getResult(); + } + // FIXME(cir): CIRGenBuilder class should have an attribute with a reference // to the module so that we don't have search for it or pass it around. // FIXME(cir): Track a list of globals, or at least the last one inserted, so diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp index 42f61fed74fb..5137a7f8fe98 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp @@ -25,6 +25,8 @@ #include "clang/Basic/TargetBuiltins.h" #include "clang/CIR/Dialect/IR/CIRDialect.h" #include "clang/CIR/Dialect/IR/CIRTypes.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/IntrinsicsX86.h" #include "llvm/Support/ErrorHandling.h" using namespace clang; @@ -98,51 +100,33 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned BuiltinID, llvm_unreachable("_mm_prefetch NYI"); } case X86::BI_mm_clflush: { - mlir::Type voidTy = cir::VoidType::get(&getMLIRContext()); - return builder - .create( - getLoc(E->getExprLoc()), builder.getStringAttr("x86.sse2.clflush"), - voidTy, Ops[0]) - .getResult(); + return builder.createIntrinsicCall( + getLoc(E->getExprLoc()), + CGM.getIntrinsic(llvm::Intrinsic::x86_sse2_clflush), Ops[0]); } case X86::BI_mm_lfence: { - mlir::Type voidTy = cir::VoidType::get(&getMLIRContext()); - return builder - .create( - getLoc(E->getExprLoc()), builder.getStringAttr("x86.sse2.lfence"), - voidTy) - .getResult(); + return builder.createIntrinsicCall( + getLoc(E->getExprLoc()), + CGM.getIntrinsic(llvm::Intrinsic::x86_sse2_lfence)); } case X86::BI_mm_pause: { - mlir::Type voidTy = cir::VoidType::get(&getMLIRContext()); - return builder - .create( - getLoc(E->getExprLoc()), builder.getStringAttr("x86.sse2.pause"), - voidTy) - .getResult(); + return builder.createIntrinsicCall( + getLoc(E->getExprLoc()), + CGM.getIntrinsic(llvm::Intrinsic::x86_sse2_pause)); } case X86::BI_mm_mfence: { - mlir::Type voidTy = cir::VoidType::get(&getMLIRContext()); - return builder - .create( - getLoc(E->getExprLoc()), builder.getStringAttr("x86.sse2.mfence"), - voidTy) - .getResult(); + return builder.createIntrinsicCall( + getLoc(E->getExprLoc()), + CGM.getIntrinsic(llvm::Intrinsic::x86_sse2_mfence)); } case X86::BI_mm_sfence: { - mlir::Type voidTy = cir::VoidType::get(&getMLIRContext()); - return builder - .create( - getLoc(E->getExprLoc()), builder.getStringAttr("x86.sse.sfence"), - voidTy) - .getResult(); + return builder.createIntrinsicCall( + getLoc(E->getExprLoc()), + CGM.getIntrinsic(llvm::Intrinsic::x86_sse_sfence)); } case X86::BI__rdtsc: { - mlir::Type intTy = cir::IntType::get(&getMLIRContext(), 64, false); - return builder - .create( - getLoc(E->getExprLoc()), builder.getStringAttr("x86.rdtsc"), intTy) - .getResult(); + return builder.createIntrinsicCall( + getLoc(E->getExprLoc()), CGM.getIntrinsic(llvm::Intrinsic::x86_rdtsc)); } case X86::BI__builtin_ia32_rdtscp: { llvm_unreachable("__rdtscp NYI"); diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index d48400a1c1d1..d3484cac314d 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -2478,9 +2478,10 @@ void CIRGenModule::emitAliasForGlobal(StringRef mangledName, setCommonAttributes(aliasGD, alias); } -cir::LLVMIntrinsicCallOp +cir::CIRIntrinsic::IntrinsicDescriptor CIRGenModule::getIntrinsic(unsigned IID, ArrayRef Tys) { - return cir::Intrinsic::getOrInsertDeclaration(getModule(), (cir::Intrinsic::ID)IID, Tys); + return cir::CIRIntrinsic::getOrInsertDeclaration( + getModule(), (cir::CIRIntrinsic::ID)IID, Tys); } mlir::Type CIRGenModule::convertType(QualType type) { diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h b/clang/lib/CIR/CodeGen/CIRGenModule.h index 83da871d8e43..d7727adadbf7 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.h +++ b/clang/lib/CIR/CodeGen/CIRGenModule.h @@ -32,6 +32,7 @@ #include "clang/CIR/Dialect/IR/CIRAttrs.h" #include "clang/CIR/Dialect/IR/CIRDataLayout.h" #include "clang/CIR/Dialect/IR/CIRDialect.h" +#include "clang/CIR/Dialect/IR/CIRIntrinsics.h" #include "clang/CIR/Dialect/IR/CIROpsEnums.h" #include "clang/CIR/Dialect/IR/CIRTypes.h" #include "clang/CIR/Interfaces/CIROpInterfaces.h" @@ -655,8 +656,8 @@ class CIRGenModule : public CIRGenTypeCache { void emitAliasForGlobal(llvm::StringRef mangledName, mlir::Operation *op, GlobalDecl aliasGD, cir::FuncOp aliasee, cir::GlobalLinkageKind linkage); -cir::LLVMIntrinsicCallOp getIntrinsic(unsigned IID, - ArrayRef Tys); + cir::CIRIntrinsic::IntrinsicDescriptor + getIntrinsic(unsigned IID, ArrayRef Tys = {}); mlir::Type convertType(clang::QualType type); /// Set the visibility for the given global. diff --git a/clang/lib/CIR/Dialect/IR/CIRIntrinsics.cpp b/clang/lib/CIR/Dialect/IR/CIRIntrinsics.cpp index cc7d0dc1ee45..c2d03b019147 100644 --- a/clang/lib/CIR/Dialect/IR/CIRIntrinsics.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRIntrinsics.cpp @@ -1,4 +1,5 @@ -//===-- CIRIntrinsics.cpp - Intrinsic Function Handling ------------*- C++ -*-===// +//===-- CIRIntrinsics.cpp - Intrinsic Function Handling ------------*- C++ +//-*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -11,7 +12,13 @@ //===----------------------------------------------------------------------===// #include "clang/CIR/Dialect/IR/CIRIntrinsics.h" +#include "mlir/IR/BuiltinAttributes.h" +#include "mlir/IR/MLIRContext.h" #include "clang/CIR/Dialect/IR/CIRDialect.h" +#include "clang/CIR/Dialect/IR/CIRTypes.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/IntrinsicsX86.h" #include "llvm/Support/ErrorHandling.h" #include @@ -22,18 +29,30 @@ using namespace cir; #include "llvm/IR/IntrinsicImpl.inc" #undef GET_INTRINSIC_NAME_TABLE -llvm::StringRef Intrinsic::getBaseName(ID id) { +llvm::StringRef CIRIntrinsic::getBaseName(ID id) { assert(id < num_intrinsics && "Invalid intrinsic ID!"); - return IntrinsicNameTable[IntrinsicNameOffsetTable[id]]; + + llvm::StringRef fullName = IntrinsicNameTable[IntrinsicNameOffsetTable[id]]; + // The format returned is llvm., so we need to skip the "llvm." to + // represent + // our intrinsic call ops. + return fullName.substr(5); } -llvm::StringRef Intrinsic::getName(ID id) { +llvm::StringRef CIRIntrinsic::getName(ID id) { assert(id < num_intrinsics && "Invalid intrinsic ID!"); - assert(!Intrinsic::isOverloaded(id) && + assert(!CIRIntrinsic::isOverloaded(id) && "This version of getName does not support overloading"); return getBaseName(id); } +std::string CIRIntrinsic::getName(ID Id, llvm::ArrayRef Tys, + mlir::ModuleOp M, mlir::Type FT) { + llvm_unreachable("GetIntrinsic Overloading NYI"); + // assert(M && "We need to have a Module"); + // return getIntrinsicNameImpl(Id, Tys, M, FT, true); +} + /// Returns a stable mangling for the type specified for use in the name /// mangling scheme used by 'any' types in intrinsic signatures. The mangling /// of named types is simply their name. Manglings for unnamed types consist @@ -47,133 +66,526 @@ llvm::StringRef Intrinsic::getName(ID id) { /// The HasUnnamedType boolean is set if an unnamed type was encountered, /// indicating that extra care must be taken to ensure a unique name. static std::string getMangledTypeStr(mlir::Type Ty, bool &HasUnnamedType) { - llvm_unreachable("NYI"); - std::string Result; -// if (PointerType *PTyp = dyn_cast(Ty)) { -// Result += "p" + utostr(PTyp->getAddressSpace()); -// } else if (ArrayType *ATyp = dyn_cast(Ty)) { -// Result += "a" + utostr(ATyp->getNumElements()) + -// getMangledTypeStr(ATyp->getElementType(), HasUnnamedType); -// } else if (StructType *STyp = dyn_cast(Ty)) { -// if (!STyp->isLiteral()) { -// Result += "s_"; -// if (STyp->hasName()) -// Result += STyp->getName(); -// else -// HasUnnamedType = true; -// } else { -// Result += "sl_"; -// for (auto *Elem : STyp->elements()) -// Result += getMangledTypeStr(Elem, HasUnnamedType); -// } -// // Ensure nested structs are distinguishable. -// Result += "s"; -// } else if (FunctionType *FT = dyn_cast(Ty)) { -// Result += "f_" + getMangledTypeStr(FT->getReturnType(), HasUnnamedType); -// for (size_t i = 0; i < FT->getNumParams(); i++) -// Result += getMangledTypeStr(FT->getParamType(i), HasUnnamedType); -// if (FT->isVarArg()) -// Result += "vararg"; -// // Ensure nested function types are distinguishable. -// Result += "f"; -// } else if (VectorType *VTy = dyn_cast(Ty)) { -// ElementCount EC = VTy->getElementCount(); -// if (EC.isScalable()) -// Result += "nx"; -// Result += "v" + utostr(EC.getKnownMinValue()) + -// getMangledTypeStr(VTy->getElementType(), HasUnnamedType); -// } else if (TargetExtType *TETy = dyn_cast(Ty)) { -// Result += "t"; -// Result += TETy->getName(); -// for (Type *ParamTy : TETy->type_params()) -// Result += "_" + getMangledTypeStr(ParamTy, HasUnnamedType); -// for (unsigned IntParam : TETy->int_params()) -// Result += "_" + utostr(IntParam); -// // Ensure nested target extension types are distinguishable. -// Result += "t"; -// } else if (Ty) { -// switch (Ty->getTypeID()) { -// default: -// llvm_unreachable("Unhandled type"); -// case Type::VoidTyID: -// Result += "isVoid"; -// break; -// case Type::MetadataTyID: -// Result += "Metadata"; -// break; -// case Type::HalfTyID: -// Result += "f16"; -// break; -// case Type::BFloatTyID: -// Result += "bf16"; -// break; -// case Type::FloatTyID: -// Result += "f32"; -// break; -// case Type::DoubleTyID: -// Result += "f64"; -// break; -// case Type::X86_FP80TyID: -// Result += "f80"; -// break; -// case Type::FP128TyID: -// Result += "f128"; -// break; -// case Type::PPC_FP128TyID: -// Result += "ppcf128"; -// break; -// case Type::X86_AMXTyID: -// Result += "x86amx"; -// break; -// case Type::IntegerTyID: -// Result += "i" + utostr(cast(Ty)->getBitWidth()); -// break; -// } -// } - return Result; + llvm_unreachable("Intrinsic Mangling NYI"); + return {}; } -//TODO: This takes care of overloading, let's focus on the non-overloaded -static std::string getIntrinsicNameImpl(Intrinsic::ID Id, llvm::ArrayRef Tys, +static std::string getIntrinsicNameImpl(cir::CIRIntrinsic::ID Id, + llvm::ArrayRef Tys, mlir::ModuleOp M, mlir::Type FT, bool EarlyModuleCheck) { llvm_unreachable("NYI: getIntrinsicNameImpl for CIR"); - std::string Result; - -// assert(Id < Intrinsic::num_intrinsics && "Invalid intrinsic ID!"); -// assert((Tys.empty() || Intrinsic::isOverloaded(Id)) && -// "This version of getName is for overloaded intrinsics only"); -// (void)EarlyModuleCheck; -// assert((!EarlyModuleCheck || M || -// !any_of(Tys, [](Type *T) { return isa(T); })) && -// "Intrinsic overloading on pointer types need to provide a Module"); -// bool HasUnnamedType = false; -// std::string Result(Intrinsic::getBaseName(Id)); -// for (Type *Ty : Tys) -// Result += "." + getMangledTypeStr(Ty, HasUnnamedType); -// if (HasUnnamedType) { -// assert(M && "unnamed types need a module"); -// if (!FT) -// FT = Intrinsic::getType(M->getContext(), Id, Tys); -// else -// assert((FT == Intrinsic::getType(M->getContext(), Id, Tys)) && -// "Provided FunctionType must match arguments"); -// return M->getUniqueIntrinsicName(Result, Id, FT); -// } - return Result; + return {}; } -LLVMIntrinsicCallOp Intrinsic::getOrInsertDeclaration(mlir::ModuleOp M, ID id, - llvm::ArrayRef Tys) { +CIRIntrinsic::IntrinsicDescriptor +CIRIntrinsic::getOrInsertDeclaration(mlir::ModuleOp M, ID id, + llvm::ArrayRef Tys) { + LLVMIntrinsicCallOp res; + // There can never be multiple globals with the same name of different types, // because intrinsics must be a specific type. - auto *FT = Intrinsic::getType(*M.getContext(), id, Tys); + mlir::Type ResultTy = CIRIntrinsic::getType(*M->getContext(), id, Tys); + + // 2. Generate the mangled name for the intrinsic + llvm::StringRef Name = + Tys.empty() + ? getName(id) + : getName(id, Tys, M); // FIXME: Need to strip the llvm. prefix + + mlir::StringAttr nameAttr = mlir::StringAttr::get(M->getContext(), Name); + + return CIRIntrinsic::IntrinsicDescriptor(nameAttr, ResultTy, id); +} + +//(cir)TODO: Most IIT Descriptor helpers should be common to Codegen to avoid +// duplication. +/// IIT_Info - These are enumerators that describe the entries returned by the +/// getIntrinsicInfoTableEntries function. +/// +/// Defined in Intrinsics.td. +enum IIT_Info { +#define GET_INTRINSIC_IITINFO +#include "llvm/IR/IntrinsicImpl.inc" +#undef GET_INTRINSIC_IITINFO +}; + +static void DecodeIITType( + unsigned &NextElt, llvm::ArrayRef Infos, IIT_Info LastInfo, + llvm::SmallVectorImpl &OutputTable) { + using namespace llvm::Intrinsic; + + bool IsScalableVector = (LastInfo == IIT_SCALABLE_VEC); + + IIT_Info Info = IIT_Info(Infos[NextElt++]); + unsigned StructElts = 2; + + switch (Info) { + case IIT_Done: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::Void, 0)); + return; + case IIT_VARARG: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::VarArg, 0)); + return; + case IIT_MMX: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::MMX, 0)); + return; + case IIT_AMX: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::AMX, 0)); + return; + case IIT_TOKEN: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::Token, 0)); + return; + case IIT_METADATA: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::Metadata, 0)); + return; + case IIT_F16: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::Half, 0)); + return; + case IIT_BF16: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::BFloat, 0)); + return; + case IIT_F32: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::Float, 0)); + return; + case IIT_F64: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::Double, 0)); + return; + case IIT_F128: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::Quad, 0)); + return; + case IIT_PPCF128: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::PPCQuad, 0)); + return; + case IIT_I1: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 1)); + return; + case IIT_I2: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 2)); + return; + case IIT_I4: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 4)); + return; + case IIT_AARCH64_SVCOUNT: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::AArch64Svcount, 0)); + return; + case IIT_I8: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 8)); + return; + case IIT_I16: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 16)); + return; + case IIT_I32: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 32)); + return; + case IIT_I64: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 64)); + return; + case IIT_I128: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 128)); + return; + case IIT_V1: + OutputTable.push_back(IITDescriptor::getVector(1, IsScalableVector)); + DecodeIITType(NextElt, Infos, Info, OutputTable); + return; + case IIT_V2: + OutputTable.push_back(IITDescriptor::getVector(2, IsScalableVector)); + DecodeIITType(NextElt, Infos, Info, OutputTable); + return; + case IIT_V3: + OutputTable.push_back(IITDescriptor::getVector(3, IsScalableVector)); + DecodeIITType(NextElt, Infos, Info, OutputTable); + return; + case IIT_V4: + OutputTable.push_back(IITDescriptor::getVector(4, IsScalableVector)); + DecodeIITType(NextElt, Infos, Info, OutputTable); + return; + case IIT_V6: + OutputTable.push_back(IITDescriptor::getVector(6, IsScalableVector)); + DecodeIITType(NextElt, Infos, Info, OutputTable); + return; + case IIT_V8: + OutputTable.push_back(IITDescriptor::getVector(8, IsScalableVector)); + DecodeIITType(NextElt, Infos, Info, OutputTable); + return; + case IIT_V10: + OutputTable.push_back(IITDescriptor::getVector(10, IsScalableVector)); + DecodeIITType(NextElt, Infos, Info, OutputTable); + return; + case IIT_V16: + OutputTable.push_back(IITDescriptor::getVector(16, IsScalableVector)); + DecodeIITType(NextElt, Infos, Info, OutputTable); + return; + case IIT_V32: + OutputTable.push_back(IITDescriptor::getVector(32, IsScalableVector)); + DecodeIITType(NextElt, Infos, Info, OutputTable); + return; + case IIT_V64: + OutputTable.push_back(IITDescriptor::getVector(64, IsScalableVector)); + DecodeIITType(NextElt, Infos, Info, OutputTable); + return; + case IIT_V128: + OutputTable.push_back(IITDescriptor::getVector(128, IsScalableVector)); + DecodeIITType(NextElt, Infos, Info, OutputTable); + return; + case IIT_V256: + OutputTable.push_back(IITDescriptor::getVector(256, IsScalableVector)); + DecodeIITType(NextElt, Infos, Info, OutputTable); + return; + case IIT_V512: + OutputTable.push_back(IITDescriptor::getVector(512, IsScalableVector)); + DecodeIITType(NextElt, Infos, Info, OutputTable); + return; + case IIT_V1024: + OutputTable.push_back(IITDescriptor::getVector(1024, IsScalableVector)); + DecodeIITType(NextElt, Infos, Info, OutputTable); + return; + case IIT_EXTERNREF: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, 10)); + return; + case IIT_FUNCREF: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, 20)); + return; + case IIT_PTR: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, 0)); + return; + case IIT_ANYPTR: // [ANYPTR addrspace] + OutputTable.push_back( + IITDescriptor::get(IITDescriptor::Pointer, Infos[NextElt++])); + return; + case IIT_ARG: { + unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); + OutputTable.push_back(IITDescriptor::get(IITDescriptor::Argument, ArgInfo)); + return; + } + case IIT_EXTEND_ARG: { + unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); + OutputTable.push_back( + IITDescriptor::get(IITDescriptor::ExtendArgument, ArgInfo)); + return; + } + case IIT_TRUNC_ARG: { + unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); + OutputTable.push_back( + IITDescriptor::get(IITDescriptor::TruncArgument, ArgInfo)); + return; + } + case IIT_HALF_VEC_ARG: { + unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); + OutputTable.push_back( + IITDescriptor::get(IITDescriptor::HalfVecArgument, ArgInfo)); + return; + } + case IIT_ONE_THIRD_VEC_ARG: { + unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); + OutputTable.push_back( + IITDescriptor::get(IITDescriptor::OneThirdVecArgument, ArgInfo)); + return; + } + case IIT_ONE_FIFTH_VEC_ARG: { + unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); + OutputTable.push_back( + IITDescriptor::get(IITDescriptor::OneFifthVecArgument, ArgInfo)); + return; + } + case IIT_ONE_SEVENTH_VEC_ARG: { + unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); + OutputTable.push_back( + IITDescriptor::get(IITDescriptor::OneSeventhVecArgument, ArgInfo)); + return; + } + case IIT_SAME_VEC_WIDTH_ARG: { + unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); + OutputTable.push_back( + IITDescriptor::get(IITDescriptor::SameVecWidthArgument, ArgInfo)); + return; + } + case IIT_VEC_OF_ANYPTRS_TO_ELT: { + unsigned short ArgNo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); + unsigned short RefNo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); + OutputTable.push_back( + IITDescriptor::get(IITDescriptor::VecOfAnyPtrsToElt, ArgNo, RefNo)); + return; + } + case IIT_EMPTYSTRUCT: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::Struct, 0)); + return; + case IIT_STRUCT9: + ++StructElts; + [[fallthrough]]; + case IIT_STRUCT8: + ++StructElts; + [[fallthrough]]; + case IIT_STRUCT7: + ++StructElts; + [[fallthrough]]; + case IIT_STRUCT6: + ++StructElts; + [[fallthrough]]; + case IIT_STRUCT5: + ++StructElts; + [[fallthrough]]; + case IIT_STRUCT4: + ++StructElts; + [[fallthrough]]; + case IIT_STRUCT3: + ++StructElts; + [[fallthrough]]; + case IIT_STRUCT2: { + OutputTable.push_back( + IITDescriptor::get(IITDescriptor::Struct, StructElts)); + + for (unsigned i = 0; i != StructElts; ++i) + DecodeIITType(NextElt, Infos, Info, OutputTable); + return; + } + case IIT_SUBDIVIDE2_ARG: { + unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); + OutputTable.push_back( + IITDescriptor::get(IITDescriptor::Subdivide2Argument, ArgInfo)); + return; + } + case IIT_SUBDIVIDE4_ARG: { + unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); + OutputTable.push_back( + IITDescriptor::get(IITDescriptor::Subdivide4Argument, ArgInfo)); + return; + } + case IIT_VEC_ELEMENT: { + unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); + OutputTable.push_back( + IITDescriptor::get(IITDescriptor::VecElementArgument, ArgInfo)); + return; + } + case IIT_SCALABLE_VEC: { + DecodeIITType(NextElt, Infos, Info, OutputTable); + return; + } + case IIT_VEC_OF_BITCASTS_TO_INT: { + unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); + OutputTable.push_back( + IITDescriptor::get(IITDescriptor::VecOfBitcastsToInt, ArgInfo)); + return; + } + } + llvm_unreachable("unhandled"); +} + +#define GET_INTRINSIC_GENERATOR_GLOBAL +#include "llvm/IR/IntrinsicImpl.inc" +#undef GET_INTRINSIC_GENERATOR_GLOBAL + +void CIRIntrinsic::getIntrinsicInfoTableEntries( + ID id, llvm::SmallVectorImpl &T) { + static_assert(sizeof(IIT_Table[0]) == 2, + "Expect 16-bit entries in IIT_Table"); + // Check to see if the intrinsic's type was expressible by the table. + uint16_t TableVal = IIT_Table[id - 1]; + + // Decode the TableVal into an array of IITValues. + llvm::SmallVector IITValues; + llvm::ArrayRef IITEntries; + unsigned NextElt = 0; + if (TableVal >> 15) { + // This is an offset into the IIT_LongEncodingTable. + IITEntries = IIT_LongEncodingTable; - //From our module we should get a global function with the name of the intrinsic. (if not overloaded) - // return cast( - // M->getOrInsertFunction( - // Tys.empty() ? getName(id) : getName(id, Tys, M, FT), FT) - // .getCallee()); + // Strip sentinel bit. + NextElt = TableVal & 0x7fff; + } else { + // If the entry was encoded into a single word in the table itself, decode + // it from an array of nibbles to an array of bytes. + do { + IITValues.push_back(TableVal & 0xF); + TableVal >>= 4; + } while (TableVal); + + IITEntries = IITValues; + NextElt = 0; + } + + // Okay, decode the table into the output vector of IITDescriptors. + DecodeIITType(NextElt, IITEntries, IIT_Done, T); + while (NextElt != IITEntries.size() && IITEntries[NextElt] != 0) + DecodeIITType(NextElt, IITEntries, IIT_Done, T); +} + +// Cir requires us to specify signedness for integer types. This function +// determines if the intrinsic is signed or unsigned based on the intrinsic ID. +// This is needed as the IITDescriptor +// does not contain metadata about signedness. +static bool isSigned(unsigned IID) { + using namespace llvm::Intrinsic; + + switch (IID) { + default: + return true; + case llvm::Intrinsic::x86_rdtsc: + case llvm::Intrinsic::x86_rdtscp: + case llvm::Intrinsic::ctlz: + // Add more cases as needed + return false; + } +} + +static mlir::Type +DecodeFixedType(llvm::ArrayRef &Infos, + llvm::ArrayRef Tys, mlir::MLIRContext &Context, + unsigned IID) { + using namespace llvm::Intrinsic; + + IITDescriptor D = Infos.front(); + Infos = Infos.slice(1); + bool IsSignedInt = isSigned(IID); + + switch (D.Kind) { + case IITDescriptor::Void: + return cir::VoidType::get(&Context); + case IITDescriptor::VarArg: + return cir::VoidType::get(&Context); + case IITDescriptor::MMX: + return cir::VectorType::get(&Context, cir::IntType::get(&Context, 64, true), + 1); + case IITDescriptor::AMX: + llvm_unreachable("AMX intrinsic mapping type NYI"); + case IITDescriptor::Token: + llvm_unreachable("Token intrinsic mapping type NYI"); + case IITDescriptor::Metadata: + llvm_unreachable("Metadata intrinsic mapping type NYI"); + case IITDescriptor::Half: + return cir::FP16Type::get(&Context); + case IITDescriptor::BFloat: + return cir::FP128Type::get(&Context); + case IITDescriptor::Float: + return cir::SingleType::get(&Context); + case IITDescriptor::Double: + return cir::DoubleType::get(&Context); + case IITDescriptor::Quad: + return cir::FP128Type::get(&Context); + case IITDescriptor::PPCQuad: + llvm_unreachable("PPC Quad type NYI"); + case IITDescriptor::AArch64Svcount: + llvm_unreachable( + "AArch64 SVCount type NYI - this is a target extension type"); + case IITDescriptor::Integer: + // FIXME: Not sure if we should default to signed or unsigned here as + // IITDescriptor does not contain relevant metadata. + return cir::IntType::get(&Context, D.Integer_Width, IsSignedInt); + + case IITDescriptor::Vector: + return cir::VectorType::get(&Context, + DecodeFixedType(Infos, Tys, Context, IID), + D.Vector_Width.getKnownMinValue()); + case IITDescriptor::Pointer: { + mlir::Type i8Type = + cir::IntType::get(&Context, 8, true); // or whatever represents i8 + mlir::IntegerAttr addrSpaceAttr = mlir::IntegerAttr::get( + mlir::IntegerType::get(&Context, 32), D.Pointer_AddressSpace); + return cir::PointerType::get(i8Type, addrSpaceAttr); + } + case IITDescriptor::Struct: { + llvm::SmallVector memberTypes; + + // Collect all the member types from the descriptor + for (unsigned i = 0, e = D.Struct_NumElements; i != e; ++i) + memberTypes.push_back(DecodeFixedType(Infos, Tys, Context, IID)); + + // Create and return the RecordType + return cir::RecordType::get( + &Context, memberTypes, + mlir::StringAttr(), // Name of the record, empty for anonymous + false, + true, // Most structs are padded for alignment + cir::RecordType::Struct // Record kind (struct/class/union) + ); + } + // case IITDescriptor::Argument: + // return Tys[D.getArgumentNumber()]; + // case IITDescriptor::ExtendArgument: { + // Type *Ty = Tys[D.getArgumentNumber()]; + // if (VectorType *VTy = dyn_cast(Ty)) + // return VectorType::getExtendedElementVectorType(VTy); + + // return IntegerType::get(Context, 2 * + // cast(Ty)->getBitWidth()); + // } + // case IITDescriptor::TruncArgument: { + // Type *Ty = Tys[D.getArgumentNumber()]; + // if (VectorType *VTy = dyn_cast(Ty)) + // return VectorType::getTruncatedElementVectorType(VTy); + + // IntegerType *ITy = cast(Ty); + // assert(ITy->getBitWidth() % 2 == 0); + // return IntegerType::get(Context, ITy->getBitWidth() / 2); + // } + // case IITDescriptor::Subdivide2Argument: + // case IITDescriptor::Subdivide4Argument: { + // Type *Ty = Tys[D.getArgumentNumber()]; + // VectorType *VTy = dyn_cast(Ty); + // assert(VTy && "Expected an argument of Vector Type"); + // int SubDivs = D.Kind == IITDescriptor::Subdivide2Argument ? 1 : 2; + // return VectorType::getSubdividedVectorType(VTy, SubDivs); + // } + // case IITDescriptor::HalfVecArgument: + // return VectorType::getHalfElementsVectorType( + // cast(Tys[D.getArgumentNumber()])); + // case IITDescriptor::OneThirdVecArgument: + // case IITDescriptor::OneFifthVecArgument: + // case IITDescriptor::OneSeventhVecArgument: + // return VectorType::getOneNthElementsVectorType( + // cast(Tys[D.getArgumentNumber()]), + // 3 + (D.Kind - IITDescriptor::OneThirdVecArgument) * 2); + // case IITDescriptor::SameVecWidthArgument: { + // Type *EltTy = DecodeFixedType(Infos, Tys, Context); + // Type *Ty = Tys[D.getArgumentNumber()]; + // if (auto *VTy = dyn_cast(Ty)) + // return VectorType::get(EltTy, VTy->getElementCount()); + // return EltTy; + // } + // case IITDescriptor::VecElementArgument: { + // Type *Ty = Tys[D.getArgumentNumber()]; + // if (VectorType *VTy = dyn_cast(Ty)) + // return VTy->getElementType(); + // llvm_unreachable("Expected an argument of Vector Type"); + // } + // case IITDescriptor::VecOfBitcastsToInt: { + // Type *Ty = Tys[D.getArgumentNumber()]; + // VectorType *VTy = dyn_cast(Ty); + // assert(VTy && "Expected an argument of Vector Type"); + // return VectorType::getInteger(VTy); + // } + // case IITDescriptor::VecOfAnyPtrsToElt: + // // Return the overloaded type (which determines the pointers address + // space) return Tys[D.getOverloadArgNumber()]; + // } + llvm_unreachable("unhandled"); + } return {}; } + +bool CIRIntrinsic::isOverloaded(ID id) { + return false; // NYI +} + +// TODO: Lil placeholder for now, we will need to re-implement this later +mlir::Type CIRIntrinsic::getType(mlir::MLIRContext &Context, ID id, + llvm::ArrayRef Tys) { + llvm::SmallVector Table; + CIRIntrinsic::getIntrinsicInfoTableEntries(id, Table); + + // Process the table once to get both return and parameter types + llvm::ArrayRef TableRef = Table; + + // First descriptor is the return type + mlir::Type ResultTy = DecodeFixedType(TableRef, Tys, Context, id); + + // NOTE: In theory we could deal with the arg types here, + // But I don't see the point given that we don't care about strict typing for + // Intrinsic Ops... + + // if (!ArgTys.empty() && ArgTys.back()->isVoidTy()) { + // ArgTys.pop_back(); + // return FunctionType::get(ResultTy, ArgTys, true); + return ResultTy; +} diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index f88d6202ad38..93f21596697e 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -362,14 +362,15 @@ CodeGenModule::CodeGenModule(ASTContext &C, C.toCharUnitsFromBits(C.getTargetInfo().getPointerAlign(LangAS::Default)) .getQuantity(); SizeSizeInBytes = - C.toCharUnitsFromBits(C.getTargetInfo().getMaxPointerWidth()).getQuantity(); + C.toCharUnitsFromBits(C.getTargetInfo().getMaxPointerWidth()) + .getQuantity(); IntAlignInBytes = - C.toCharUnitsFromBits(C.getTargetInfo().getIntAlign()).getQuantity(); + C.toCharUnitsFromBits(C.getTargetInfo().getIntAlign()).getQuantity(); CharTy = - llvm::IntegerType::get(LLVMContext, C.getTargetInfo().getCharWidth()); + llvm::IntegerType::get(LLVMContext, C.getTargetInfo().getCharWidth()); IntTy = llvm::IntegerType::get(LLVMContext, C.getTargetInfo().getIntWidth()); IntPtrTy = llvm::IntegerType::get(LLVMContext, - C.getTargetInfo().getMaxPointerWidth()); + C.getTargetInfo().getMaxPointerWidth()); Int8PtrTy = llvm::PointerType::get(LLVMContext, C.getTargetAddressSpace(LangAS::Default)); const llvm::DataLayout &DL = M.getDataLayout(); @@ -545,7 +546,8 @@ void CodeGenModule::applyReplacements() { } } -void CodeGenModule::addGlobalValReplacement(llvm::GlobalValue *GV, llvm::Constant *C) { +void CodeGenModule::addGlobalValReplacement(llvm::GlobalValue *GV, + llvm::Constant *C) { GlobalValReplacements.push_back(std::make_pair(GV, C)); } @@ -582,8 +584,9 @@ static const llvm::GlobalValue *getAliasedGlobal(const llvm::GlobalValue *GV) { } static bool checkAliasedGlobal( - const ASTContext &Context, DiagnosticsEngine &Diags, SourceLocation Location, - bool IsIFunc, const llvm::GlobalValue *Alias, const llvm::GlobalValue *&GV, + const ASTContext &Context, DiagnosticsEngine &Diags, + SourceLocation Location, bool IsIFunc, const llvm::GlobalValue *Alias, + const llvm::GlobalValue *&GV, const llvm::MapVector &MangledDeclNames, SourceRange AliasRange) { GV = getAliasedGlobal(Alias); @@ -763,7 +766,8 @@ void InstrProfStats::reportDiagnostics(DiagnosticsEngine &Diags, Diags.Report(diag::warn_profile_data_unprofiled) << MainFile; } else { if (Mismatched > 0) - Diags.Report(diag::warn_profile_data_out_of_date) << Visited << Mismatched; + Diags.Report(diag::warn_profile_data_out_of_date) + << Visited << Mismatched; if (Missing > 0) Diags.Report(diag::warn_profile_data_missing) << Visited << Missing; @@ -995,7 +999,8 @@ void CodeGenModule::Release() { // usage of #pragma comment(lib, *) is intended for host libraries on // Windows. Therefore emit llvm.dependent-libraries only for host. if (!ELFDependentLibraries.empty() && !Context.getLangOpts().CUDAIsDevice) { - auto *NMD = getModule().getOrInsertNamedMetadata("llvm.dependent-libraries"); + auto *NMD = + getModule().getOrInsertNamedMetadata("llvm.dependent-libraries"); for (auto *MD : ELFDependentLibraries) NMD->addOperand(MD); } @@ -1039,12 +1044,12 @@ void CodeGenModule::Release() { // FIXME: we could support it by stripping all the information introduced // by StrictVTablePointers. - getModule().addModuleFlag(llvm::Module::Error, "StrictVTablePointers",1); + getModule().addModuleFlag(llvm::Module::Error, "StrictVTablePointers", 1); llvm::Metadata *Ops[2] = { - llvm::MDString::get(VMContext, "StrictVTablePointers"), - llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( - llvm::Type::getInt32Ty(VMContext), 1))}; + llvm::MDString::get(VMContext, "StrictVTablePointers"), + llvm::ConstantAsMetadata::get( + llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1))}; getModule().addModuleFlag(llvm::Module::Require, "StrictVTablePointersRequirement", @@ -1159,15 +1164,13 @@ void CodeGenModule::Release() { if (CodeGenOpts.CFProtectionReturn && Target.checkCFProtectionReturnSupported(getDiags())) { // Indicate that we want to instrument return control flow protection. - getModule().addModuleFlag(llvm::Module::Min, "cf-protection-return", - 1); + getModule().addModuleFlag(llvm::Module::Min, "cf-protection-return", 1); } if (CodeGenOpts.CFProtectionBranch && Target.checkCFProtectionBranchSupported(getDiags())) { // Indicate that we want to instrument branch control flow protection. - getModule().addModuleFlag(llvm::Module::Min, "cf-protection-branch", - 1); + getModule().addModuleFlag(llvm::Module::Min, "cf-protection-branch", 1); auto Scheme = CodeGenOpts.getCFBranchLabelScheme(); if (Target.checkCFBranchLabelSchemeSupported(Scheme, getDiags())) { @@ -1181,10 +1184,12 @@ void CodeGenModule::Release() { } if (CodeGenOpts.FunctionReturnThunks) - getModule().addModuleFlag(llvm::Module::Override, "function_return_thunk_extern", 1); + getModule().addModuleFlag(llvm::Module::Override, + "function_return_thunk_extern", 1); if (CodeGenOpts.IndirectBranchCSPrefix) - getModule().addModuleFlag(llvm::Module::Override, "indirect_branch_cs_prefix", 1); + getModule().addModuleFlag(llvm::Module::Override, + "indirect_branch_cs_prefix", 1); // Add module metadata for return address signing (ignoring // non-leaf/all) and stack tagging. These are actually turned on by function @@ -1321,10 +1326,10 @@ void CodeGenModule::Release() { // OpenCL. auto Version = LangOpts.getOpenCLCompatibleVersion(); llvm::Metadata *SPIRVerElts[] = { - llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( - Int32Ty, Version / 100)), - llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( - Int32Ty, (Version / 100 > 1) ? 0 : 2))}; + llvm::ConstantAsMetadata::get( + llvm::ConstantInt::get(Int32Ty, Version / 100)), + llvm::ConstantAsMetadata::get( + llvm::ConstantInt::get(Int32Ty, (Version / 100 > 1) ? 0 : 2))}; llvm::NamedMDNode *SPIRVerMD = TheModule.getOrInsertNamedMetadata("opencl.spir.version"); llvm::LLVMContext &Ctx = TheModule.getContext(); @@ -1345,14 +1350,15 @@ void CodeGenModule::Release() { if (getCodeGenOpts().CodeModel.size() > 0) { unsigned CM = llvm::StringSwitch(getCodeGenOpts().CodeModel) - .Case("tiny", llvm::CodeModel::Tiny) - .Case("small", llvm::CodeModel::Small) - .Case("kernel", llvm::CodeModel::Kernel) - .Case("medium", llvm::CodeModel::Medium) - .Case("large", llvm::CodeModel::Large) - .Default(~0u); + .Case("tiny", llvm::CodeModel::Tiny) + .Case("small", llvm::CodeModel::Small) + .Case("kernel", llvm::CodeModel::Kernel) + .Case("medium", llvm::CodeModel::Medium) + .Case("large", llvm::CodeModel::Large) + .Default(~0u); if (CM != ~0u) { - llvm::CodeModel::Model codeModel = static_cast(CM); + llvm::CodeModel::Model codeModel = + static_cast(CM); getModule().setCodeModel(codeModel); if ((CM == llvm::CodeModel::Medium || CM == llvm::CodeModel::Large) && @@ -1872,8 +1878,7 @@ static void AppendCPUSpecificCPUDispatchMangling(const CodeGenModule &CGM, // Returns true if GD is a function decl with internal linkage and // needs a unique suffix after the mangled name. -static bool isUniqueInternalLinkageDecl(GlobalDecl GD, - CodeGenModule &CGM) { +static bool isUniqueInternalLinkageDecl(GlobalDecl GD, CodeGenModule &CGM) { const Decl *D = GD.getDecl(); return !CGM.getModuleNameHash().empty() && isa(D) && (CGM.getFunctionLinkage(GD) == llvm::GlobalValue::InternalLinkage); @@ -2007,7 +2012,8 @@ void CodeGenModule::UpdateMultiVersionNames(GlobalDecl GD, auto Result = Manglings.insert(std::make_pair(OtherName, OtherGD)); StringRef OtherNameRef = MangledDeclNames[OtherGD.getCanonicalDecl()] = Result.first->first(); - // If this is the current decl is being created, make sure we update the name. + // If this is the current decl is being created, make sure we update the + // name. if (GD.getCanonicalDecl() == OtherGD.getCanonicalDecl()) CurName = OtherNameRef; if (llvm::GlobalValue *Entry = GetGlobalValue(NonTargetName)) @@ -2086,8 +2092,8 @@ StringRef CodeGenModule::getBlockMangledName(GlobalDecl GD, SmallString<256> Buffer; llvm::raw_svector_ostream Out(Buffer); if (!D) - MangleCtx.mangleGlobalBlock(BD, - dyn_cast_or_null(initializedGlobalDecl.getDecl()), Out); + MangleCtx.mangleGlobalBlock( + BD, dyn_cast_or_null(initializedGlobalDecl.getDecl()), Out); else if (const auto *CD = dyn_cast(D)) MangleCtx.mangleCtorBlock(CD, GD.getCtorType(), BD, Out); else if (const auto *DD = dyn_cast(D)) @@ -2137,7 +2143,8 @@ void CodeGenModule::AddGlobalDtor(llvm::Function *Dtor, int Priority, } void CodeGenModule::EmitCtorList(CtorList &Fns, const char *GlobalName) { - if (Fns.empty()) return; + if (Fns.empty()) + return; const PointerAuthSchema &InitFiniAuthSchema = getCodeGenOpts().PointerAuth.InitFiniPointers; @@ -2204,7 +2211,8 @@ CodeGenModule::getFunctionLinkage(GlobalDecl GD) { llvm::ConstantInt *CodeGenModule::CreateCrossDsoCfiTypeId(llvm::Metadata *MD) { llvm::MDString *MDS = dyn_cast(MD); - if (!MDS) return nullptr; + if (!MDS) + return nullptr; return llvm::ConstantInt::get(Int64Ty, llvm::MD5Hash(MDS->getString())); } @@ -2246,7 +2254,7 @@ void CodeGenModule::SetLLVMFunctionAttributes(GlobalDecl GD, F->setCallingConv(static_cast(CallingConv)); } -static void removeImageAccessQualifier(std::string& TyName) { +static void removeImageAccessQualifier(std::string &TyName) { std::string ReadOnlyQual("__read_only"); std::string::size_type ReadOnlyPos = TyName.find(ReadOnlyQual); if (ReadOnlyPos != std::string::npos) @@ -2432,8 +2440,7 @@ void CodeGenModule::GenKernelArgMetadata(llvm::Function *Fn, } if (getCodeGenOpts().EmitOpenCLArgMetadata || getCodeGenOpts().HIPSaveKernelArgName) - Fn->setMetadata("kernel_arg_name", - llvm::MDNode::get(VMContext, argNames)); + Fn->setMetadata("kernel_arg_name", llvm::MDNode::get(VMContext, argNames)); } /// Determines whether the language options require us to model @@ -2443,10 +2450,12 @@ void CodeGenModule::GenKernelArgMetadata(llvm::Function *Fn, /// enables this. static bool hasUnwindExceptions(const LangOptions &LangOpts) { // If exceptions are completely disabled, obviously this is false. - if (!LangOpts.Exceptions) return false; + if (!LangOpts.Exceptions) + return false; // If C++ exceptions are enabled, this is true. - if (LangOpts.CXXExceptions) return true; + if (LangOpts.CXXExceptions) + return true; // If ObjC exceptions are enabled, this depends on the ABI. if (LangOpts.ObjCExceptions) { @@ -2473,7 +2482,7 @@ SmallVector CodeGenModule::getMostBaseClasses(const CXXRecordDecl *RD) { llvm::SetVector MostBases; - std::function CollectMostBases; + std::function CollectMostBases; CollectMostBases = [&](const CXXRecordDecl *RD) { if (RD->getNumBases() == 0) MostBases.insert(RD); @@ -2755,8 +2764,8 @@ bool CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD, AddedAttr = true; } if (!Features.empty() && SetTargetFeatures) { - llvm::erase_if(Features, [&](const std::string& F) { - return getTarget().isReadOnlyFeature(F.substr(1)); + llvm::erase_if(Features, [&](const std::string &F) { + return getTarget().isReadOnlyFeature(F.substr(1)); }); llvm::sort(Features); Attrs.addAttribute("target-features", llvm::join(Features, ",")); @@ -2953,10 +2962,10 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F, // GCC and does not actually return "this". if (!IsThunk && getCXXABI().HasThisReturn(GD) && !(getTriple().isiOS() && getTriple().isOSVersionLT(6))) { - assert(!F->arg_empty() && - F->arg_begin()->getType() - ->canLosslesslyBitCastTo(F->getReturnType()) && - "unexpected this return"); + assert( + !F->arg_empty() && + F->arg_begin()->getType()->canLosslesslyBitCastTo(F->getReturnType()) && + "unexpected this return"); F->addParamAttr(0, llvm::Attribute::Returned); } @@ -2973,7 +2982,7 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F, if (const auto *CSA = FD->getAttr()) F->setSection(CSA->getName()); else if (const auto *SA = FD->getAttr()) - F->setSection(SA->getName()); + F->setSection(SA->getName()); if (const auto *EA = FD->getAttr()) { if (EA->isError()) @@ -3020,7 +3029,8 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F, getOpenMPRuntime().emitDeclareSimdFunction(FD, F); if (CodeGenOpts.InlineMaxStackSize != UINT_MAX) - F->addFnAttr("inline-max-stacksize", llvm::utostr(CodeGenOpts.InlineMaxStackSize)); + F->addFnAttr("inline-max-stacksize", + llvm::utostr(CodeGenOpts.InlineMaxStackSize)); if (const auto *CB = FD->getAttr()) { // Annotate the callback behavior as metadata: @@ -3068,12 +3078,11 @@ static void emitUsed(CodeGenModule &CGM, StringRef Name, return; // Convert List to what ConstantArray needs. - SmallVector UsedArray; + SmallVector UsedArray; UsedArray.resize(List.size()); for (unsigned i = 0, e = List.size(); i != e; ++i) { - UsedArray[i] = - llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast( - cast(&*List[i]), CGM.Int8PtrTy); + UsedArray[i] = llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast( + cast(&*List[i]), CGM.Int8PtrTy); } if (UsedArray.empty()) @@ -3109,7 +3118,7 @@ void CodeGenModule::AddDetectMismatch(StringRef Name, StringRef Value) { void CodeGenModule::AddDependentLib(StringRef Lib) { auto &C = getLLVMContext(); if (getTarget().getTriple().isOSBinFormatELF()) { - ELFDependentLibraries.push_back( + ELFDependentLibraries.push_back( llvm::MDNode::get(C, llvm::MDString::get(C, Lib))); return; } @@ -3308,8 +3317,8 @@ void CodeGenModule::EmitDeferred() { // to get GlobalValue with exactly the type we need, not something that // might had been created for another decl with the same mangled name but // different type. - llvm::GlobalValue *GV = dyn_cast( - GetAddrOfGlobal(D, ForDefinition)); + llvm::GlobalValue *GV = + dyn_cast(GetAddrOfGlobal(D, ForDefinition)); // In case of different address spaces, we may still get a cast, even with // IsForDefinition equal to true. Query mangled names table to get @@ -3352,8 +3361,9 @@ void CodeGenModule::EmitVTablesOpportunistically() { // is not allowed to create new references to things that need to be emitted // lazily. Note that it also uses fact that we eagerly emitting RTTI. - assert((OpportunisticVTables.empty() || shouldOpportunisticallyEmitVTables()) - && "Only emit opportunistic vtables with optimizations"); + assert( + (OpportunisticVTables.empty() || shouldOpportunisticallyEmitVTables()) && + "Only emit opportunistic vtables with optimizations"); for (const CXXRecordDecl *RD : OpportunisticVTables) { assert(getVTables().isVTableExternal(RD) && @@ -3365,7 +3375,7 @@ void CodeGenModule::EmitVTablesOpportunistically() { } void CodeGenModule::EmitGlobalAnnotations() { - for (const auto& [MangledName, VD] : DeferredAnnotations) { + for (const auto &[MangledName, VD] : DeferredAnnotations) { llvm::GlobalValue *GV = GetGlobalValue(MangledName); if (GV) AddGlobalAnnotations(VD, GV); @@ -3376,8 +3386,9 @@ void CodeGenModule::EmitGlobalAnnotations() { return; // Create a new global variable for the ConstantStruct in the Module. - llvm::Constant *Array = llvm::ConstantArray::get(llvm::ArrayType::get( - Annotations[0]->getType(), Annotations.size()), Annotations); + llvm::Constant *Array = llvm::ConstantArray::get( + llvm::ArrayType::get(Annotations[0]->getType(), Annotations.size()), + Annotations); auto *gv = new llvm::GlobalVariable(getModule(), Array->getType(), false, llvm::GlobalValue::AppendingLinkage, Array, "llvm.global.annotations"); @@ -3412,8 +3423,8 @@ llvm::Constant *CodeGenModule::EmitAnnotationUnit(SourceLocation Loc) { llvm::Constant *CodeGenModule::EmitAnnotationLineNo(SourceLocation L) { SourceManager &SM = getContext().getSourceManager(); PresumedLoc PLoc = SM.getPresumedLoc(L); - unsigned LineNo = PLoc.isValid() ? PLoc.getLine() : - SM.getExpansionLineNumber(L); + unsigned LineNo = + PLoc.isValid() ? PLoc.getLine() : SM.getExpansionLineNumber(L); return llvm::ConstantInt::get(Int32Ty, LineNo); } @@ -3757,7 +3768,7 @@ ConstantAddress CodeGenModule::GetAddrOfTemplateParamObject( ConstantEmitter Emitter(*this); llvm::Constant *Init = Emitter.emitForInitializer( - TPO->getValue(), TPO->getType().getAddressSpace(), TPO->getType()); + TPO->getValue(), TPO->getType().getAddressSpace(), TPO->getType()); if (!Init) { ErrorUnsupported(TPO, "template parameter object"); @@ -3775,7 +3786,7 @@ ConstantAddress CodeGenModule::GetAddrOfTemplateParamObject( GV->setComdat(TheModule.getOrInsertComdat(GV->getName())); Emitter.finalize(GV); - return ConstantAddress(GV, GV->getValueType(), Alignment); + return ConstantAddress(GV, GV->getValueType(), Alignment); } ConstantAddress CodeGenModule::GetWeakRefReference(const ValueDecl *VD) { @@ -4004,109 +4015,108 @@ static bool HasNonDllImportDtor(QualType T) { } namespace { - struct FunctionIsDirectlyRecursive - : public ConstStmtVisitor { - const StringRef Name; - const Builtin::Context &BI; - FunctionIsDirectlyRecursive(StringRef N, const Builtin::Context &C) - : Name(N), BI(C) {} - - bool VisitCallExpr(const CallExpr *E) { - const FunctionDecl *FD = E->getDirectCallee(); - if (!FD) - return false; - AsmLabelAttr *Attr = FD->getAttr(); - if (Attr && Name == Attr->getLabel()) - return true; - unsigned BuiltinID = FD->getBuiltinID(); - if (!BuiltinID || !BI.isLibFunction(BuiltinID)) - return false; - std::string BuiltinNameStr = BI.getName(BuiltinID); - StringRef BuiltinName = BuiltinNameStr; - if (BuiltinName.starts_with("__builtin_") && - Name == BuiltinName.slice(strlen("__builtin_"), StringRef::npos)) { - return true; - } +struct FunctionIsDirectlyRecursive + : public ConstStmtVisitor { + const StringRef Name; + const Builtin::Context &BI; + FunctionIsDirectlyRecursive(StringRef N, const Builtin::Context &C) + : Name(N), BI(C) {} + + bool VisitCallExpr(const CallExpr *E) { + const FunctionDecl *FD = E->getDirectCallee(); + if (!FD) return false; - } - - bool VisitStmt(const Stmt *S) { - for (const Stmt *Child : S->children()) - if (Child && this->Visit(Child)) - return true; + AsmLabelAttr *Attr = FD->getAttr(); + if (Attr && Name == Attr->getLabel()) + return true; + unsigned BuiltinID = FD->getBuiltinID(); + if (!BuiltinID || !BI.isLibFunction(BuiltinID)) return false; + std::string BuiltinNameStr = BI.getName(BuiltinID); + StringRef BuiltinName = BuiltinNameStr; + if (BuiltinName.starts_with("__builtin_") && + Name == BuiltinName.slice(strlen("__builtin_"), StringRef::npos)) { + return true; } - }; - - // Make sure we're not referencing non-imported vars or functions. - struct DLLImportFunctionVisitor - : public RecursiveASTVisitor { - bool SafeToInline = true; + return false; + } - bool shouldVisitImplicitCode() const { return true; } + bool VisitStmt(const Stmt *S) { + for (const Stmt *Child : S->children()) + if (Child && this->Visit(Child)) + return true; + return false; + } +}; - bool VisitVarDecl(VarDecl *VD) { - if (VD->getTLSKind()) { - // A thread-local variable cannot be imported. - SafeToInline = false; - return SafeToInline; - } +// Make sure we're not referencing non-imported vars or functions. +struct DLLImportFunctionVisitor + : public RecursiveASTVisitor { + bool SafeToInline = true; - // A variable definition might imply a destructor call. - if (VD->isThisDeclarationADefinition()) - SafeToInline = !HasNonDllImportDtor(VD->getType()); + bool shouldVisitImplicitCode() const { return true; } + bool VisitVarDecl(VarDecl *VD) { + if (VD->getTLSKind()) { + // A thread-local variable cannot be imported. + SafeToInline = false; return SafeToInline; } - bool VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) { - if (const auto *D = E->getTemporary()->getDestructor()) - SafeToInline = D->hasAttr(); - return SafeToInline; - } + // A variable definition might imply a destructor call. + if (VD->isThisDeclarationADefinition()) + SafeToInline = !HasNonDllImportDtor(VD->getType()); - bool VisitDeclRefExpr(DeclRefExpr *E) { - ValueDecl *VD = E->getDecl(); - if (isa(VD)) - SafeToInline = VD->hasAttr(); - else if (VarDecl *V = dyn_cast(VD)) - SafeToInline = !V->hasGlobalStorage() || V->hasAttr(); - return SafeToInline; - } + return SafeToInline; + } - bool VisitCXXConstructExpr(CXXConstructExpr *E) { - SafeToInline = E->getConstructor()->hasAttr(); - return SafeToInline; - } + bool VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) { + if (const auto *D = E->getTemporary()->getDestructor()) + SafeToInline = D->hasAttr(); + return SafeToInline; + } - bool VisitCXXMemberCallExpr(CXXMemberCallExpr *E) { - CXXMethodDecl *M = E->getMethodDecl(); - if (!M) { - // Call through a pointer to member function. This is safe to inline. - SafeToInline = true; - } else { - SafeToInline = M->hasAttr(); - } - return SafeToInline; - } + bool VisitDeclRefExpr(DeclRefExpr *E) { + ValueDecl *VD = E->getDecl(); + if (isa(VD)) + SafeToInline = VD->hasAttr(); + else if (VarDecl *V = dyn_cast(VD)) + SafeToInline = !V->hasGlobalStorage() || V->hasAttr(); + return SafeToInline; + } - bool VisitCXXDeleteExpr(CXXDeleteExpr *E) { - SafeToInline = E->getOperatorDelete()->hasAttr(); - return SafeToInline; - } + bool VisitCXXConstructExpr(CXXConstructExpr *E) { + SafeToInline = E->getConstructor()->hasAttr(); + return SafeToInline; + } - bool VisitCXXNewExpr(CXXNewExpr *E) { - SafeToInline = E->getOperatorNew()->hasAttr(); - return SafeToInline; + bool VisitCXXMemberCallExpr(CXXMemberCallExpr *E) { + CXXMethodDecl *M = E->getMethodDecl(); + if (!M) { + // Call through a pointer to member function. This is safe to inline. + SafeToInline = true; + } else { + SafeToInline = M->hasAttr(); } - }; -} + return SafeToInline; + } + + bool VisitCXXDeleteExpr(CXXDeleteExpr *E) { + SafeToInline = E->getOperatorDelete()->hasAttr(); + return SafeToInline; + } + + bool VisitCXXNewExpr(CXXNewExpr *E) { + SafeToInline = E->getOperatorNew()->hasAttr(); + return SafeToInline; + } +}; +} // namespace // isTriviallyRecursive - Check if this function calls another // decl that, because of the asm attribute or the other decl being a builtin, // ends up pointing to itself. -bool -CodeGenModule::isTriviallyRecursive(const FunctionDecl *FD) { +bool CodeGenModule::isTriviallyRecursive(const FunctionDecl *FD) { StringRef Name; if (getCXXABI().getMangleContext().shouldMangleDeclName(FD)) { // asm labels are a special kind of mangling we have to support. @@ -4161,7 +4171,7 @@ bool CodeGenModule::shouldEmitFunction(GlobalDecl GD) { if (F->hasAttr() && !F->hasAttr()) { // Check whether it would be safe to inline this dllimport function. DLLImportFunctionVisitor Visitor; - Visitor.TraverseFunctionDecl(const_cast(F)); + Visitor.TraverseFunctionDecl(const_cast(F)); if (!Visitor.SafeToInline) return false; @@ -4439,8 +4449,7 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) { llvm::PointerType::get(getLLVMContext(), getTypes().getTargetAddressSpace(FD->getType())), false); - } - else { + } else { ResolverType = DeclTy; ResolverGD = GD; } @@ -4472,10 +4481,10 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) { if (!ExistingDecl.getDecl()) ExistingDecl = GD.getWithMultiVersionIndex(Index); - Func = GetOrCreateLLVMFunction( - MangledName, DeclTy, ExistingDecl, - /*ForVTable=*/false, /*DontDefer=*/true, - /*IsThunk=*/false, llvm::AttributeList(), ForDefinition); + Func = GetOrCreateLLVMFunction(MangledName, DeclTy, ExistingDecl, + /*ForVTable=*/false, /*DontDefer=*/true, + /*IsThunk=*/false, llvm::AttributeList(), + ForDefinition); } } @@ -4528,8 +4537,8 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) { IFunc = GI; } - std::string AliasName = getMangledNameImpl( - *this, GD, FD, /*OmitMultiVersionMangling=*/true); + std::string AliasName = + getMangledNameImpl(*this, GD, FD, /*OmitMultiVersionMangling=*/true); llvm::Constant *AliasFunc = GetGlobalValue(AliasName); if (!AliasFunc) { auto *GA = llvm::GlobalAlias::create(DeclTy, AS, Linkage, AliasName, @@ -4735,8 +4744,8 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction( } // Make sure the result is of the correct type. - // (If function is requested for a definition, we always need to create a new - // function, not just return a bitcast.) + // (If function is requested for a definition, we always need to create a + // new function, not just return a bitcast.) if (!IsForDefinition) return Entry; } @@ -4894,8 +4903,8 @@ llvm::Constant *CodeGenModule::GetFunctionStart(const ValueDecl *Decl) { return llvm::NoCFIValue::get(F); } -static const FunctionDecl * -GetRuntimeFunctionDecl(ASTContext &C, StringRef Name) { +static const FunctionDecl *GetRuntimeFunctionDecl(ASTContext &C, + StringRef Name) { TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl(); DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl); @@ -4989,10 +4998,9 @@ CodeGenModule::CreateRuntimeFunction(llvm::FunctionType *FTy, StringRef Name, ExtraAttrs.addFnAttribute(VMContext, llvm::Attribute::Convergent); } - llvm::Constant *C = - GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(), /*ForVTable=*/false, - /*DontDefer=*/false, /*IsThunk=*/false, - ExtraAttrs); + llvm::Constant *C = GetOrCreateLLVMFunction( + Name, FTy, GlobalDecl(), /*ForVTable=*/false, + /*DontDefer=*/false, /*IsThunk=*/false, ExtraAttrs); if (auto *F = dyn_cast(C)) { if (F->empty()) { @@ -5263,8 +5271,8 @@ llvm::GlobalVariable *CodeGenModule::CreateOrReplaceCXXRuntimeVariable( } // Create a new variable. - GV = new llvm::GlobalVariable(getModule(), Ty, /*isConstant=*/true, - Linkage, nullptr, Name); + GV = new llvm::GlobalVariable(getModule(), Ty, /*isConstant=*/true, Linkage, + nullptr, Name); if (OldGV) { // Replace occurrences of the old variable if needed. @@ -5292,9 +5300,9 @@ llvm::GlobalVariable *CodeGenModule::CreateOrReplaceCXXRuntimeVariable( /// normal requested type would be. If IsForDefinition is true, it is guaranteed /// that an actual global with type Ty will be returned, not conversion of a /// variable with the same mangled name but some other type. -llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D, - llvm::Type *Ty, - ForDefinition_t IsForDefinition) { +llvm::Constant * +CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D, llvm::Type *Ty, + ForDefinition_t IsForDefinition) { assert(D->hasGlobalStorage() && "Not a global variable"); QualType ASTTy = D->getType(); if (!Ty) @@ -5307,9 +5315,8 @@ llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D, /// CreateRuntimeVariable - Create a new runtime global variable with the /// specified type and name. -llvm::Constant * -CodeGenModule::CreateRuntimeVariable(llvm::Type *Ty, - StringRef Name) { +llvm::Constant *CodeGenModule::CreateRuntimeVariable(llvm::Type *Ty, + StringRef Name) { LangAS AddrSpace = getContext().getLangOpts().OpenCL ? LangAS::opencl_global : LangAS::Default; auto *Ret = GetOrCreateLLVMGlobal(Name, Ty, AddrSpace, nullptr); @@ -5332,8 +5339,8 @@ void CodeGenModule::EmitTentativeDefinition(const VarDecl *D) { // If we have not seen a reference to this variable yet, place it into the // deferred declarations table to be emitted if needed later. if (!MustBeEmitted(D) && !GV) { - DeferredDecls[MangledName] = D; - return; + DeferredDecls[MangledName] = D; + return; } // The tentative definition is the only definition. @@ -5355,12 +5362,9 @@ CharUnits CodeGenModule::GetTargetTypeStoreSize(llvm::Type *Ty) const { LangAS CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D) { if (LangOpts.OpenCL) { LangAS AS = D ? D->getType().getAddressSpace() : LangAS::opencl_global; - assert(AS == LangAS::opencl_global || - AS == LangAS::opencl_global_device || - AS == LangAS::opencl_global_host || - AS == LangAS::opencl_constant || - AS == LangAS::opencl_local || - AS >= LangAS::FirstTargetAddressSpace); + assert(AS == LangAS::opencl_global || AS == LangAS::opencl_global_device || + AS == LangAS::opencl_global_host || AS == LangAS::opencl_constant || + AS == LangAS::opencl_local || AS >= LangAS::FirstTargetAddressSpace); return AS; } @@ -5433,7 +5437,7 @@ castStringLiteralToDefaultAddressSpace(CodeGenModule &CGM, return Cast; } -template +template void CodeGenModule::MaybeHandleStaticInExternC(const SomeDecl *D, llvm::GlobalValue *GV) { if (!getLangOpts().CPlusPlus) @@ -5631,7 +5635,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D, } } - llvm::Type* InitType = Init->getType(); + llvm::Type *InitType = Init->getType(); llvm::Constant *Entry = GetAddrOfGlobalVar(D, InitType, ForDefinition_t(!IsTentative)); @@ -6083,7 +6087,8 @@ static void replaceUsesOfNonProtoConstant(llvm::Constant *old, static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old, llvm::Function *NewFn) { // If we're redefining a global as a function, don't transform it. - if (!isa(Old)) return; + if (!isa(Old)) + return; replaceUsesOfNonProtoConstant(Old, NewFn); } @@ -6232,7 +6237,8 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) { // Emit global alias debug information. if (isa(D)) if (CGDebugInfo *DI = getModuleDebugInfo()) - DI->EmitGlobalAlias(cast(GA->getAliasee()->stripPointerCasts()), GD); + DI->EmitGlobalAlias( + cast(GA->getAliasee()->stripPointerCasts()), GD); } void CodeGenModule::emitIFuncDefinition(GlobalDecl GD) { @@ -6298,7 +6304,7 @@ void CodeGenModule::emitIFuncDefinition(GlobalDecl GD) { } llvm::Function *CodeGenModule::getIntrinsic(unsigned IID, - ArrayRef Tys) { + ArrayRef Tys) { return llvm::Intrinsic::getOrInsertDeclaration(&getModule(), (llvm::Intrinsic::ID)IID, Tys); } @@ -6334,7 +6340,8 @@ GetConstantCFStringEntry(llvm::StringMap &Map, return *Map.insert(std::make_pair( StringRef(reinterpret_cast(ToBuf.data()), (StringLength + 1) * 2), - nullptr)).first; + nullptr)) + .first; } ConstantAddress @@ -6347,8 +6354,8 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { StringLength); if (auto *C = Entry.second) - return ConstantAddress( - C, C->getValueType(), CharUnits::fromQuantity(C->getAlignment())); + return ConstantAddress(C, C->getValueType(), + CharUnits::fromQuantity(C->getAlignment())); const ASTContext &Context = getContext(); const llvm::Triple &Triple = getTriple(); @@ -6366,8 +6373,10 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { Ty = llvm::ArrayType::get(Ty, 0); switch (CFRuntime) { - default: break; - case LangOptions::CoreFoundationABI::Swift: [[fallthrough]]; + default: + break; + case LangOptions::CoreFoundationABI::Swift: + [[fallthrough]]; case LangOptions::CoreFoundationABI::Swift5_0: CFConstantStringClassName = Triple.isOSDarwin() ? "$s15SwiftFoundation19_NSCFConstantStringCN" @@ -6479,9 +6488,8 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { Fields.add(GV); // String length. - llvm::IntegerType *LengthTy = - llvm::IntegerType::get(getModule().getContext(), - Context.getTargetInfo().getLongWidth()); + llvm::IntegerType *LengthTy = llvm::IntegerType::get( + getModule().getContext(), Context.getTargetInfo().getLongWidth()); if (IsSwiftABI) { if (CFRuntime == LangOptions::CoreFoundationABI::Swift4_1 || CFRuntime == LangOptions::CoreFoundationABI::Swift4_2) @@ -6539,14 +6547,11 @@ QualType CodeGenModule::getObjCFastEnumerationStateType() { nullptr, ArraySizeModifier::Normal, 0)}; for (size_t i = 0; i < 4; ++i) { - FieldDecl *Field = FieldDecl::Create(Context, - D, - SourceLocation(), - SourceLocation(), nullptr, - FieldTypes[i], /*TInfo=*/nullptr, - /*BitWidth=*/nullptr, - /*Mutable=*/false, - ICIS_NoInit); + FieldDecl *Field = + FieldDecl::Create(Context, D, SourceLocation(), SourceLocation(), + nullptr, FieldTypes[i], /*TInfo=*/nullptr, + /*BitWidth=*/nullptr, + /*Mutable=*/false, ICIS_NoInit); Field->setAccess(AS_public); D->addDecl(Field); } @@ -6583,7 +6588,7 @@ CodeGenModule::GetConstantArrayFromStringLiteral(const StringLiteral *E) { SmallVector Elements; Elements.reserve(NumElements); - for(unsigned i = 0, e = E->getLength(); i != e; ++i) + for (unsigned i = 0, e = E->getLength(); i != e; ++i) Elements.push_back(E->getCodeUnit(i)); Elements.resize(NumElements); return llvm::ConstantDataArray::get(VMContext, Elements); @@ -6593,7 +6598,7 @@ CodeGenModule::GetConstantArrayFromStringLiteral(const StringLiteral *E) { SmallVector Elements; Elements.reserve(NumElements); - for(unsigned i = 0, e = E->getLength(); i != e; ++i) + for (unsigned i = 0, e = E->getLength(); i != e; ++i) Elements.push_back(E->getCodeUnit(i)); Elements.resize(NumElements); return llvm::ConstantDataArray::get(VMContext, Elements); @@ -6688,8 +6693,9 @@ CodeGenModule::GetAddrOfConstantStringFromObjCEncode(const ObjCEncodeExpr *E) { /// GetAddrOfConstantCString - Returns a pointer to a character array containing /// the literal and a terminating '\0' character. /// The result has pointer to array type. -ConstantAddress CodeGenModule::GetAddrOfConstantCString( - const std::string &Str, const char *GlobalName) { +ConstantAddress +CodeGenModule::GetAddrOfConstantCString(const std::string &Str, + const char *GlobalName) { StringRef StrWithNull(Str.c_str(), Str.size() + 1); CharUnits Alignment = getContext().getAlignOfGlobalVarInChars( getContext().CharTy, /*VD=*/nullptr); @@ -6722,10 +6728,12 @@ ConstantAddress CodeGenModule::GetAddrOfConstantCString( GV->getValueType(), Alignment); } -ConstantAddress CodeGenModule::GetAddrOfGlobalTemporary( - const MaterializeTemporaryExpr *E, const Expr *Init) { +ConstantAddress +CodeGenModule::GetAddrOfGlobalTemporary(const MaterializeTemporaryExpr *E, + const Expr *Init) { assert((E->getStorageDuration() == SD_Static || - E->getStorageDuration() == SD_Thread) && "not a global temporary"); + E->getStorageDuration() == SD_Thread) && + "not a global temporary"); const auto *VD = cast(E->getExtendingDecl()); // If we're not materializing a subobject of the temporary, keep the @@ -6789,8 +6797,8 @@ ConstantAddress CodeGenModule::GetAddrOfGlobalTemporary( if (Value) { // The temporary has a constant initializer, use it. emitter.emplace(*this); - InitialValue = emitter->emitForInitializer(*Value, AddrSpace, - MaterializedType); + InitialValue = + emitter->emitForInitializer(*Value, AddrSpace, MaterializedType); Constant = MaterializedType.isConstantStorage(getContext(), /*ExcludeCtor*/ Value, /*ExcludeDtor*/ false); @@ -6820,7 +6828,8 @@ ConstantAddress CodeGenModule::GetAddrOfGlobalTemporary( auto *GV = new llvm::GlobalVariable( getModule(), Type, Constant, Linkage, InitialValue, Name.c_str(), /*InsertBefore=*/nullptr, llvm::GlobalVariable::NotThreadLocal, TargetAS); - if (emitter) emitter->finalize(GV); + if (emitter) + emitter->finalize(GV); // Don't assign dllimport or dllexport to local linkage globals. if (!llvm::GlobalValue::isLocalLinkage(Linkage)) { setGVProperties(GV, VD); @@ -6855,8 +6864,8 @@ ConstantAddress CodeGenModule::GetAddrOfGlobalTemporary( /// EmitObjCPropertyImplementations - Emit information for synthesized /// properties for an implementation. -void CodeGenModule::EmitObjCPropertyImplementations(const - ObjCImplementationDecl *D) { +void CodeGenModule::EmitObjCPropertyImplementations( + const ObjCImplementationDecl *D) { for (const auto *PID : D->property_impls()) { // Dynamic is just for type-checking. if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) { @@ -6874,15 +6883,15 @@ void CodeGenModule::EmitObjCPropertyImplementations(const auto *Setter = PID->getSetterMethodDecl(); if (!PD->isReadOnly() && (!Setter || Setter->isSynthesizedAccessorStub())) CodeGenFunction(*this).GenerateObjCSetter( - const_cast(D), PID); + const_cast(D), PID); } } } static bool needsDestructMethod(ObjCImplementationDecl *impl) { const ObjCInterfaceDecl *iface = impl->getClassInterface(); - for (const ObjCIvarDecl *ivar = iface->all_declared_ivar_begin(); - ivar; ivar = ivar->getNextIvar()) + for (const ObjCIvarDecl *ivar = iface->all_declared_ivar_begin(); ivar; + ivar = ivar->getNextIvar()) if (ivar->getType().isDestructedType()) return true; @@ -6893,7 +6902,8 @@ static bool AllTrivialInitializers(CodeGenModule &CGM, ObjCImplementationDecl *D) { CodeGenFunction CGF(CGM); for (ObjCImplementationDecl::init_iterator B = D->init_begin(), - E = D->init_end(); B != E; ++B) { + E = D->init_end(); + B != E; ++B) { CXXCtorInitializer *CtorInitExp = *B; Expr *Init = CtorInitExp->getInit(); if (!CGF.isTrivialInitializer(Init)) @@ -6923,8 +6933,7 @@ void CodeGenModule::EmitObjCIvarInitializations(ObjCImplementationDecl *D) { // If the implementation doesn't have any ivar initializers, we don't need // a .cxx_construct. - if (D->getNumIvarInitializers() == 0 || - AllTrivialInitializers(*this, D)) + if (D->getNumIvarInitializers() == 0 || AllTrivialInitializers(*this, D)) return; const IdentifierInfo *II = &getContext().Idents.get(".cxx_construct"); @@ -7057,7 +7066,8 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { TSK_ExplicitInstantiationDefinition && Spec->hasDefinition()) DI->completeTemplateDefinition(*Spec); - } [[fallthrough]]; + } + [[fallthrough]]; case Decl::CXXRecord: { CXXRecordDecl *CRD = cast(D); if (CGDebugInfo *DI = getModuleDebugInfo()) { @@ -7085,9 +7095,9 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { case Decl::Empty: case Decl::Binding: break; - case Decl::Using: // using X; [C++] + case Decl::Using: // using X; [C++] if (CGDebugInfo *DI = getModuleDebugInfo()) - DI->EmitUsingDecl(cast(*D)); + DI->EmitUsingDecl(cast(*D)); break; case Decl::UsingEnum: // using enum X; [C++] if (CGDebugInfo *DI = getModuleDebugInfo()) @@ -7095,7 +7105,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { break; case Decl::NamespaceAlias: if (CGDebugInfo *DI = getModuleDebugInfo()) - DI->EmitNamespaceAlias(cast(*D)); + DI->EmitNamespaceAlias(cast(*D)); break; case Decl::UsingDirective: // using namespace X; [C++] if (CGDebugInfo *DI = getModuleDebugInfo()) @@ -7140,8 +7150,9 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { // Emit global variable debug information. if (CGDebugInfo *DI = getModuleDebugInfo()) if (getCodeGenOpts().hasReducedDebugInfo()) - DI->getOrCreateInterfaceType(getContext().getObjCInterfaceType( - OMD->getClassInterface()), OMD->getLocation()); + DI->getOrCreateInterfaceType( + getContext().getObjCInterfaceType(OMD->getClassInterface()), + OMD->getLocation()); break; } case Decl::ObjCMethod: { @@ -7164,7 +7175,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { AppendLinkerOptions(PCD->getArg()); break; case PCK_Lib: - AddDependentLib(PCD->getArg()); + AddDependentLib(PCD->getArg()); break; case PCK_Compiler: case PCK_ExeStr: @@ -7401,7 +7412,8 @@ void CodeGenModule::EmitMainVoidAlias() { // new-style no-argument main is in used. if (llvm::Function *F = getModule().getFunction("main")) { if (!F->isDeclaration() && F->arg_size() == 0 && !F->isVarArg() && - F->getReturnType()->isIntegerTy(Context.getTargetInfo().getIntWidth())) { + F->getReturnType()->isIntegerTy( + Context.getTargetInfo().getIntWidth())) { auto *GA = llvm::GlobalAlias::create("__main_void", F); GA->setVisibility(llvm::GlobalValue::HiddenVisibility); } @@ -7418,11 +7430,10 @@ static llvm::Constant *GetPointerConstant(llvm::LLVMContext &Context, static void EmitGlobalDeclMetadata(CodeGenModule &CGM, llvm::NamedMDNode *&GlobalMetadata, - GlobalDecl D, - llvm::GlobalValue *Addr) { + GlobalDecl D, llvm::GlobalValue *Addr) { if (!GlobalMetadata) GlobalMetadata = - CGM.getModule().getOrInsertNamedMetadata("clang.global.decl.ptrs"); + CGM.getModule().getOrInsertNamedMetadata("clang.global.decl.ptrs"); // TODO: should we report variant information for ctors/dtors? llvm::Metadata *Ops[] = {llvm::ConstantAsMetadata::get(Addr), @@ -7556,7 +7567,8 @@ void CodeGenModule::EmitDeclMetadata() { /// Emits metadata nodes for all the local variables in the current /// function. void CodeGenFunction::EmitDeclMetadata() { - if (LocalDeclMap.empty()) return; + if (LocalDeclMap.empty()) + return; llvm::LLVMContext &Context = getLLVMContext(); @@ -7582,7 +7594,7 @@ void CodeGenFunction::EmitDeclMetadata() { void CodeGenModule::EmitVersionIdentMetadata() { llvm::NamedMDNode *IdentMetadata = - TheModule.getOrInsertNamedMetadata("llvm.ident"); + TheModule.getOrInsertNamedMetadata("llvm.ident"); std::string Version = getClangFullVersion(); llvm::LLVMContext &Ctx = TheModule.getContext(); @@ -7592,7 +7604,7 @@ void CodeGenModule::EmitVersionIdentMetadata() { void CodeGenModule::EmitCommandLineMetadata() { llvm::NamedMDNode *CommandLineMetadata = - TheModule.getOrInsertNamedMetadata("llvm.commandline"); + TheModule.getOrInsertNamedMetadata("llvm.commandline"); std::string CommandLine = getCodeGenOpts().RecordCommandLine; llvm::LLVMContext &Ctx = TheModule.getContext(); @@ -7703,8 +7715,8 @@ static QualType GeneralizeType(ASTContext &Ctx, QualType Ty) { return Ty; return Ctx.getPointerType( - QualType(Ctx.VoidTy).withCVRQualifiers( - Ty->getPointeeType().getCVRQualifiers())); + QualType(Ctx.VoidTy) + .withCVRQualifiers(Ty->getPointeeType().getCVRQualifiers())); } // Apply type generalization to a FunctionType's return and argument types @@ -7714,9 +7726,8 @@ static QualType GeneralizeFunctionType(ASTContext &Ctx, QualType Ty) { for (auto &Param : FnType->param_types()) GeneralizedParams.push_back(GeneralizeType(Ctx, Param)); - return Ctx.getFunctionType( - GeneralizeType(Ctx, FnType->getReturnType()), - GeneralizedParams, FnType->getExtProtoInfo()); + return Ctx.getFunctionType(GeneralizeType(Ctx, FnType->getReturnType()), + GeneralizedParams, FnType->getExtProtoInfo()); } if (auto *FnType = Ty->getAs())