102 lines
3.9 KiB
C++
102 lines
3.9 KiB
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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
// Provides an LLVM-like API wrapper to DLTI and MLIR layout queries. This
|
|
// makes it easier to port some of LLVM codegen layout logic to CIR.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef CLANG_CIR_DIALECT_IR_CIRDATALAYOUT_H
|
|
#define CLANG_CIR_DIALECT_IR_CIRDATALAYOUT_H
|
|
|
|
#include "mlir/Dialect/DLTI/DLTI.h"
|
|
#include "mlir/IR/BuiltinOps.h"
|
|
#include "clang/CIR/Dialect/IR/CIRTypes.h"
|
|
|
|
namespace cir {
|
|
|
|
// TODO(cir): This might be replaced by a CIRDataLayout interface which can
|
|
// provide the same functionalities.
|
|
class CIRDataLayout {
|
|
// This is starting with the minimum functionality needed for code that is
|
|
// being upstreamed. Additional methods and members will be added as needed.
|
|
bool bigEndian = false;
|
|
|
|
public:
|
|
mlir::DataLayout layout;
|
|
|
|
/// Constructs a DataLayout the module's data layout attribute.
|
|
CIRDataLayout(mlir::ModuleOp modOp);
|
|
|
|
/// Parse a data layout string (with fallback to default values).
|
|
void reset(mlir::DataLayoutSpecInterface spec);
|
|
|
|
bool isBigEndian() const { return bigEndian; }
|
|
|
|
/// Internal helper method that returns requested alignment for type.
|
|
llvm::Align getAlignment(mlir::Type ty, bool useABIAlign) const;
|
|
|
|
llvm::Align getABITypeAlign(mlir::Type ty) const {
|
|
return getAlignment(ty, true);
|
|
}
|
|
|
|
/// Returns the maximum number of bytes that may be overwritten by
|
|
/// storing the specified type.
|
|
///
|
|
/// If Ty is a scalable vector type, the scalable property will be set and
|
|
/// the runtime size will be a positive integer multiple of the base size.
|
|
///
|
|
/// For example, returns 5 for i36 and 10 for x86_fp80.
|
|
llvm::TypeSize getTypeStoreSize(mlir::Type ty) const {
|
|
llvm::TypeSize baseSize = getTypeSizeInBits(ty);
|
|
return {llvm::divideCeil(baseSize.getKnownMinValue(), 8),
|
|
baseSize.isScalable()};
|
|
}
|
|
|
|
/// Returns the offset in bytes between successive objects of the
|
|
/// specified type, including alignment padding.
|
|
///
|
|
/// If Ty is a scalable vector type, the scalable property will be set and
|
|
/// the runtime size will be a positive integer multiple of the base size.
|
|
///
|
|
/// This is the amount that alloca reserves for this type. For example,
|
|
/// returns 12 or 16 for x86_fp80, depending on alignment.
|
|
llvm::TypeSize getTypeAllocSize(mlir::Type ty) const {
|
|
// Round up to the next alignment boundary.
|
|
return llvm::alignTo(getTypeStoreSize(ty), getABITypeAlign(ty).value());
|
|
}
|
|
|
|
/// Returns the offset in bits between successive objects of the
|
|
/// specified type, including alignment padding; always a multiple of 8.
|
|
///
|
|
/// If Ty is a scalable vector type, the scalable property will be set and
|
|
/// the runtime size will be a positive integer multiple of the base size.
|
|
///
|
|
/// This is the amount that alloca reserves for this type. For example,
|
|
/// returns 96 or 128 for x86_fp80, depending on alignment.
|
|
llvm::TypeSize getTypeAllocSizeInBits(mlir::Type ty) const {
|
|
return 8 * getTypeAllocSize(ty);
|
|
}
|
|
|
|
llvm::TypeSize getTypeSizeInBits(mlir::Type ty) const;
|
|
|
|
llvm::TypeSize getPointerTypeSizeInBits(mlir::Type ty) const {
|
|
assert(mlir::isa<cir::PointerType>(ty) &&
|
|
"This should only be called with a pointer type");
|
|
return layout.getTypeSizeInBits(ty);
|
|
}
|
|
|
|
mlir::Type getIntPtrType(mlir::Type ty) const {
|
|
assert(mlir::isa<cir::PointerType>(ty) && "Expected pointer type");
|
|
return cir::IntType::get(ty.getContext(), getPointerTypeSizeInBits(ty),
|
|
false);
|
|
}
|
|
};
|
|
|
|
} // namespace cir
|
|
|
|
#endif // CLANG_CIR_DIALECT_IR_CIRDATALAYOUT_H
|