Skip to content

Commit dc9b8fe

Browse files
[CIR ] Add DLTI dialect support to module attributes (#142241)
This PR adds support for the DLTI dialect by attaching it to the module attributes and introduces a utility function to determine if the target is big-endian, which is required for #142041. Some tests were updated because we now use `mlir::translateDataLayout`, which "updates" the `DataLayout` where the alignment for `long` is 8 instead of the previously 4. This updated is consistent with Incubator.
1 parent 3096f87 commit dc9b8fe

File tree

9 files changed

+100
-6
lines changed

9 files changed

+100
-6
lines changed

clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#ifndef CLANG_CIR_DIALECT_IR_CIRDATALAYOUT_H
1313
#define CLANG_CIR_DIALECT_IR_CIRDATALAYOUT_H
1414

15+
#include "mlir/Dialect/DLTI/DLTI.h"
1516
#include "mlir/IR/BuiltinOps.h"
1617

1718
namespace cir {
@@ -21,11 +22,18 @@ namespace cir {
2122
class CIRDataLayout {
2223
// This is starting with the minimum functionality needed for code that is
2324
// being upstreamed. Additional methods and members will be added as needed.
25+
bool bigEndian = false;
26+
2427
public:
2528
mlir::DataLayout layout;
2629

2730
/// Constructs a DataLayout the module's data layout attribute.
28-
CIRDataLayout(mlir::ModuleOp modOp) : layout{modOp} {}
31+
CIRDataLayout(mlir::ModuleOp modOp);
32+
33+
/// Parse a data layout string (with fallback to default values).
34+
void reset(mlir::DataLayoutSpecInterface spec);
35+
36+
bool isBigEndian() const { return bigEndian; }
2937
};
3038

3139
} // namespace cir

clang/lib/CIR/CodeGen/CIRGenerator.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@
1414

1515
#include "mlir/Dialect/OpenACC/OpenACC.h"
1616
#include "mlir/IR/MLIRContext.h"
17+
#include "mlir/Target/LLVMIR/Import.h"
1718

1819
#include "clang/AST/DeclGroup.h"
1920
#include "clang/CIR/CIRGenerator.h"
2021
#include "clang/CIR/Dialect/IR/CIRDialect.h"
2122
#include "clang/CIR/Dialect/OpenACC/RegisterOpenACCExtensions.h"
23+
#include "llvm/IR/DataLayout.h"
2224

2325
using namespace cir;
2426
using namespace clang;
@@ -35,12 +37,20 @@ CIRGenerator::~CIRGenerator() {
3537
assert(deferredInlineMemberFuncDefs.empty() || diags.hasErrorOccurred());
3638
}
3739

40+
static void setMLIRDataLayout(mlir::ModuleOp &mod, const llvm::DataLayout &dl) {
41+
mlir::MLIRContext *mlirContext = mod.getContext();
42+
mlir::DataLayoutSpecInterface dlSpec =
43+
mlir::translateDataLayout(dl, mlirContext);
44+
mod->setAttr(mlir::DLTIDialect::kDataLayoutAttrName, dlSpec);
45+
}
46+
3847
void CIRGenerator::Initialize(ASTContext &astContext) {
3948
using namespace llvm;
4049

4150
this->astContext = &astContext;
4251

4352
mlirContext = std::make_unique<mlir::MLIRContext>();
53+
mlirContext->loadDialect<mlir::DLTIDialect>();
4454
mlirContext->loadDialect<cir::CIRDialect>();
4555
mlirContext->getOrLoadDialect<mlir::acc::OpenACCDialect>();
4656

@@ -51,6 +61,10 @@ void CIRGenerator::Initialize(ASTContext &astContext) {
5161

5262
cgm = std::make_unique<clang::CIRGen::CIRGenModule>(
5363
*mlirContext.get(), astContext, codeGenOpts, diags);
64+
mlir::ModuleOp mod = cgm->getModule();
65+
llvm::DataLayout layout =
66+
llvm::DataLayout(astContext.getTargetInfo().getDataLayoutString());
67+
setMLIRDataLayout(mod, layout);
5468
}
5569

5670
bool CIRGenerator::verifyModule() const { return cgm->verifyModule(); }

clang/lib/CIR/CodeGen/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,5 @@ add_clang_library(clangCIR
4242
CIROpenACCSupport
4343
MLIRCIR
4444
MLIRCIRInterfaces
45+
MLIRTargetLLVMIRImport
4546
)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#include "clang/CIR/Dialect/IR/CIRDataLayout.h"
2+
3+
using namespace cir;
4+
5+
//===----------------------------------------------------------------------===//
6+
// DataLayout Class Implementation
7+
//===----------------------------------------------------------------------===//
8+
9+
CIRDataLayout::CIRDataLayout(mlir::ModuleOp modOp) : layout(modOp) {
10+
reset(modOp.getDataLayoutSpec());
11+
}
12+
13+
void CIRDataLayout::reset(mlir::DataLayoutSpecInterface spec) {
14+
bigEndian = false;
15+
if (spec) {
16+
mlir::StringAttr key = mlir::StringAttr::get(
17+
spec.getContext(), mlir::DLTIDialect::kDataLayoutEndiannessKey);
18+
if (mlir::DataLayoutEntryInterface entry = spec.getSpecForIdentifier(key))
19+
if (auto str = llvm::dyn_cast<mlir::StringAttr>(entry.getValue()))
20+
bigEndian = str == mlir::DLTIDialect::kDataLayoutEndiannessBig;
21+
}
22+
}

clang/lib/CIR/Dialect/IR/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ add_clang_library(MLIRCIR
33
CIRDialect.cpp
44
CIRMemorySlot.cpp
55
CIRTypes.cpp
6+
CIRDataLayout.cpp
67

78
DEPENDS
89
MLIRCIROpsIncGen

clang/test/CIR/CodeGen/dlti.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s --check-prefix=LITTLE
3+
4+
void foo() {}
5+
6+
// LITTLE-DAG: dlti.dl_spec =
7+
// LITTLE-DAG: #dlti.dl_spec<
8+
// LITTLE-DAG: i16 = dense<16> : vector<2xi64>,
9+
// LITTLE-DAG: i32 = dense<32> : vector<2xi64>,
10+
// LITTLE-DAG: i8 = dense<8> : vector<2xi64>,
11+
// LITTLE-DAG: i1 = dense<8> : vector<2xi64>,
12+
// LITTLE-DAG: !llvm.ptr = dense<64> : vector<4xi64>,
13+
// LITTLE-DAG: f80 = dense<128> : vector<2xi64>,
14+
// LITTLE-DAG: i128 = dense<128> : vector<2xi64>,
15+
// LITTLE-DAG: !llvm.ptr<272> = dense<64> : vector<4xi64>,
16+
// LITTLE-DAG: i64 = dense<64> : vector<2xi64>,
17+
// LITTLE-DAG: !llvm.ptr<270> = dense<32> : vector<4xi64>,
18+
// LITTLE-DAG: !llvm.ptr<271> = dense<32> : vector<4xi64>,
19+
// LITTLE-DAG: f128 = dense<128> : vector<2xi64>,
20+
// LITTLE-DAG: f16 = dense<16> : vector<2xi64>,
21+
// LITTLE-DAG: f64 = dense<64> : vector<2xi64>,
22+
// LITTLE-DAG: "dlti.stack_alignment" = 128 : i64
23+
// LITTLE-DAG: "dlti.endianness" = "little"

clang/test/CIR/CodeGen/dlti_be.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// REQUIRES: aarch64-registered-target
2+
// RUN: %clang_cc1 -triple aarch64_be-linux-gnu -emit-cir %s -o %t.cir
3+
// RUN: FileCheck --input-file=%t.cir %s --check-prefix=BIG
4+
5+
void foo() {}
6+
7+
// BIG-DAG: dlti.dl_spec =
8+
// BIG-DAG: #dlti.dl_spec<
9+
// BIG-DAG: i16 = dense<[16, 32]> : vector<2xi64>,
10+
// BIG-DAG: i32 = dense<32> : vector<2xi64>,
11+
// BIG-DAG: i8 = dense<[8, 32]> : vector<2xi64>,
12+
// BIG-DAG: i1 = dense<8> : vector<2xi64>,
13+
// BIG-DAG: !llvm.ptr = dense<64> : vector<4xi64>,
14+
// BIG-DAG: i128 = dense<128> : vector<2xi64>,
15+
// BIG-DAG: !llvm.ptr<272> = dense<64> : vector<4xi64>,
16+
// BIG-DAG: i64 = dense<64> : vector<2xi64>,
17+
// BIG-DAG: !llvm.ptr<270> = dense<32> : vector<4xi64>,
18+
// BIG-DAG: !llvm.ptr<271> = dense<32> : vector<4xi64>,
19+
// BIG-DAG: f128 = dense<128> : vector<2xi64>,
20+
// BIG-DAG: f16 = dense<16> : vector<2xi64>,
21+
// BIG-DAG: f64 = dense<64> : vector<2xi64>,
22+
// BIG-DAG: "dlti.stack_alignment" = 128 : i64
23+
// BIG-DAG: "dlti.endianness" = "big"

clang/test/CIR/Lowering/func-simple.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ int scopes() {
4242
long longfunc() { return 42l; }
4343
// CHECK: define{{.*}} i64 @_Z8longfuncv() {
4444
// CHECK: %[[RV:.*]] = alloca i64, i64 1, align 8
45-
// CHECK: store i64 42, ptr %[[RV]], align 4
46-
// CHECK: %[[R:.*]] = load i64, ptr %[[RV]], align 4
45+
// CHECK: store i64 42, ptr %[[RV]], align 8
46+
// CHECK: %[[R:.*]] = load i64, ptr %[[RV]], align 8
4747
// CHECK: ret i64 %[[R]]
4848
// CHECK: }
4949

@@ -58,8 +58,8 @@ unsigned unsignedfunc() { return 42u; }
5858
unsigned long long ullfunc() { return 42ull; }
5959
// CHECK: define{{.*}} i64 @_Z7ullfuncv() {
6060
// CHECK: %[[RV:.*]] = alloca i64, i64 1, align 8
61-
// CHECK: store i64 42, ptr %[[RV]], align 4
62-
// CHECK: %[[R:.*]] = load i64, ptr %[[RV]], align 4
61+
// CHECK: store i64 42, ptr %[[RV]], align 8
62+
// CHECK: %[[R:.*]] = load i64, ptr %[[RV]], align 8
6363
// CHECK: ret i64 %[[R]]
6464
// CHECK: }
6565

clang/tools/cir-opt/cir-opt.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
//===----------------------------------------------------------------------===//
1414

1515
#include "mlir/Conversion/ReconcileUnrealizedCasts/ReconcileUnrealizedCasts.h"
16+
#include "mlir/Dialect/DLTI/DLTI.h"
1617
#include "mlir/Dialect/Func/IR/FuncOps.h"
1718
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
1819
#include "mlir/Dialect/MemRef/IR/MemRef.h"
@@ -32,7 +33,8 @@ int main(int argc, char **argv) {
3233
// TODO: register needed MLIR passes for CIR?
3334
mlir::DialectRegistry registry;
3435
registry.insert<mlir::BuiltinDialect, cir::CIRDialect,
35-
mlir::memref::MemRefDialect, mlir::LLVM::LLVMDialect>();
36+
mlir::memref::MemRefDialect, mlir::LLVM::LLVMDialect,
37+
mlir::DLTIDialect>();
3638

3739
::mlir::registerPass([]() -> std::unique_ptr<::mlir::Pass> {
3840
return mlir::createCIRCanonicalizePass();

0 commit comments

Comments
 (0)