clang 23.0.0git
CIRDataLayout.h
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8// Provides an LLVM-like API wrapper to DLTI and MLIR layout queries. This
9// makes it easier to port some of LLVM codegen layout logic to CIR.
10//===----------------------------------------------------------------------===//
11
12#ifndef CLANG_CIR_DIALECT_IR_CIRDATALAYOUT_H
13#define CLANG_CIR_DIALECT_IR_CIRDATALAYOUT_H
14
15#include "mlir/Dialect/DLTI/DLTI.h"
16#include "mlir/IR/BuiltinOps.h"
18
19namespace cir {
20
21// TODO(cir): This might be replaced by a CIRDataLayout interface which can
22// provide the same functionalities.
24 // This is starting with the minimum functionality needed for code that is
25 // being upstreamed. Additional methods and members will be added as needed.
26 bool bigEndian = false;
27
28 unsigned programAddrSpace = 0;
29
30public:
31 mlir::DataLayout layout;
32
33 /// Constructs a DataLayout the module's data layout attribute.
34 CIRDataLayout(mlir::ModuleOp modOp);
35
36 /// Parse a data layout string (with fallback to default values).
37 void reset(mlir::DataLayoutSpecInterface spec);
38
39 bool isBigEndian() const { return bigEndian; }
40
41 unsigned getProgramAddressSpace() const { return programAddrSpace; }
42
43 /// Internal helper method that returns requested alignment for type.
44 llvm::Align getAlignment(mlir::Type ty, bool useABIAlign) const;
45
46 llvm::Align getABITypeAlign(mlir::Type ty) const {
47 return getAlignment(ty, true);
48 }
49
50 /// Returns the maximum number of bytes that may be overwritten by
51 /// storing the specified type.
52 ///
53 /// If Ty is a scalable vector type, the scalable property will be set and
54 /// the runtime size will be a positive integer multiple of the base size.
55 ///
56 /// For example, returns 5 for i36 and 10 for x86_fp80.
57 llvm::TypeSize getTypeStoreSize(mlir::Type ty) const {
58 llvm::TypeSize baseSize = getTypeSizeInBits(ty);
59 return {llvm::divideCeil(baseSize.getKnownMinValue(), 8),
60 baseSize.isScalable()};
61 }
62
63 /// Returns the maximum number of bits that may be overwritten by
64 /// storing the specified type; always a multiple of 8.
65 ///
66 /// If Ty is a scalable vector type, the scalable property will be set and
67 /// the runtime size will be a positive integer multiple of the base size.
68 ///
69 /// For example, returns 40 for i36 and 80 for x86_fp80.
70 llvm::TypeSize getTypeStoreSizeInBits(mlir::Type ty) const {
71 llvm::TypeSize baseSize = getTypeSizeInBits(ty);
72 uint64_t alignedSizeInBits =
73 llvm::alignToPowerOf2(baseSize.getKnownMinValue(), 8);
74 return {alignedSizeInBits, baseSize.isScalable()};
75 }
76
77 /// Returns the offset in bytes between successive objects of the
78 /// specified type, including alignment padding.
79 ///
80 /// If Ty is a scalable vector type, the scalable property will be set and
81 /// the runtime size will be a positive integer multiple of the base size.
82 ///
83 /// This is the amount that alloca reserves for this type. For example,
84 /// returns 12 or 16 for x86_fp80, depending on alignment.
85 llvm::TypeSize getTypeAllocSize(mlir::Type ty) const {
86 // Round up to the next alignment boundary.
87 return llvm::alignTo(getTypeStoreSize(ty), getABITypeAlign(ty).value());
88 }
89
90 /// Returns the offset in bits between successive objects of the
91 /// specified type, including alignment padding; always a multiple of 8.
92 ///
93 /// If Ty is a scalable vector type, the scalable property will be set and
94 /// the runtime size will be a positive integer multiple of the base size.
95 ///
96 /// This is the amount that alloca reserves for this type. For example,
97 /// returns 96 or 128 for x86_fp80, depending on alignment.
98 llvm::TypeSize getTypeAllocSizeInBits(mlir::Type ty) const {
99 return 8 * getTypeAllocSize(ty);
100 }
101
102 llvm::TypeSize getTypeSizeInBits(mlir::Type ty) const;
103
104 llvm::TypeSize getPointerTypeSizeInBits(mlir::Type ty) const {
105 assert(mlir::isa<cir::PointerType>(ty) &&
106 "This should only be called with a pointer type");
107 return layout.getTypeSizeInBits(ty);
108 }
109
110 mlir::Type getIntPtrType(mlir::Type ty) const {
111 assert(mlir::isa<cir::PointerType>(ty) && "Expected pointer type");
112 return cir::IntType::get(ty.getContext(), getPointerTypeSizeInBits(ty),
113 false);
114 }
115
116 /// Returns true if no extra padding bits are needed when storing the
117 /// specified type.
118 ///
119 /// For example, returns false for i19 that has a 24-bit store size.
120 bool typeSizeEqualsStoreSize(mlir::Type ty) const {
122 }
123};
124
125} // namespace cir
126
127#endif // CLANG_CIR_DIALECT_IR_CIRDATALAYOUT_H
mlir::DataLayout layout
void reset(mlir::DataLayoutSpecInterface spec)
Parse a data layout string (with fallback to default values).
CIRDataLayout(mlir::ModuleOp modOp)
Constructs a DataLayout the module's data layout attribute.
llvm::TypeSize getPointerTypeSizeInBits(mlir::Type ty) const
llvm::TypeSize getTypeAllocSize(mlir::Type ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
llvm::TypeSize getTypeStoreSizeInBits(mlir::Type ty) const
Returns the maximum number of bits that may be overwritten by storing the specified type; always a mu...
unsigned getProgramAddressSpace() const
bool isBigEndian() const
llvm::Align getABITypeAlign(mlir::Type ty) const
mlir::Type getIntPtrType(mlir::Type ty) const
llvm::Align getAlignment(mlir::Type ty, bool useABIAlign) const
Internal helper method that returns requested alignment for type.
llvm::TypeSize getTypeAllocSizeInBits(mlir::Type ty) const
Returns the offset in bits between successive objects of the specified type, including alignment padd...
bool typeSizeEqualsStoreSize(mlir::Type ty) const
Returns true if no extra padding bits are needed when storing the specified type.
llvm::TypeSize getTypeSizeInBits(mlir::Type ty) const
llvm::TypeSize getTypeStoreSize(mlir::Type ty) const
Returns the maximum number of bytes that may be overwritten by storing the specified type.