Skip to content

Commit 11cd2a4

Browse files
committed
[CIR][Lowering][NFC] Move helper functions to LoweringHelpers.cpp
This commit moves array initial value lowering relative helper functions from DirectToLLVM/LowerToLLVM.cpp to LoweringHelpers.cpp. So ThroughMLIR/LowerCIRToMLIR.cpp can reuse the helper functions to enable array with initial value lowering in later patch. This is a refactoring without functional changes.
1 parent 7fc592a commit 11cd2a4

File tree

5 files changed

+222
-128
lines changed

5 files changed

+222
-128
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//====- LoweringHelpers.h - Lowering helper functions ---------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file declares helper functions for lowering from CIR to LLVM or MLIR.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
#ifndef LLVM_CLANG_CIR_LOWERINGHELPERS_H
13+
#define LLVM_CLANG_CIR_LOWERINGHELPERS_H
14+
#include "mlir/Dialect/Arith/IR/Arith.h"
15+
#include "mlir/IR/BuiltinAttributes.h"
16+
#include "mlir/IR/BuiltinTypes.h"
17+
#include "mlir/Transforms/DialectConversion.h"
18+
#include "clang/CIR/Dialect/IR/CIRDialect.h"
19+
20+
mlir::DenseElementsAttr
21+
convertStringAttrToDenseElementsAttr(mlir::cir::ConstArrayAttr attr,
22+
mlir::Type type);
23+
24+
template <typename StorageTy> StorageTy getZeroInitFromType(mlir::Type Ty);
25+
template <> mlir::APInt getZeroInitFromType(mlir::Type Ty);
26+
template <> mlir::APFloat getZeroInitFromType(mlir::Type Ty);
27+
28+
mlir::Type getNestedTypeAndElemQuantity(mlir::Type Ty, unsigned &elemQuantity);
29+
30+
template <typename AttrTy, typename StorageTy>
31+
void convertToDenseElementsAttrImpl(mlir::cir::ConstArrayAttr attr,
32+
llvm::SmallVectorImpl<StorageTy> &values);
33+
34+
template <typename AttrTy, typename StorageTy>
35+
mlir::DenseElementsAttr
36+
convertToDenseElementsAttr(mlir::cir::ConstArrayAttr attr,
37+
const llvm::SmallVectorImpl<int64_t> &dims,
38+
mlir::Type type);
39+
40+
std::optional<mlir::Attribute>
41+
lowerConstArrayAttr(mlir::cir::ConstArrayAttr constArr,
42+
const mlir::TypeConverter *converter);
43+
#endif

clang/lib/CIR/Lowering/CMakeLists.txt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,42 @@
1+
set(LLVM_LINK_COMPONENTS
2+
Core
3+
Support
4+
)
5+
6+
get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
7+
8+
add_clang_library(clangCIRLoweringHelpers
9+
LoweringHelpers.cpp
10+
11+
DEPENDS
12+
MLIRCIROpsIncGen
13+
MLIRCIREnumsGen
14+
MLIRCIRASTAttrInterfacesIncGen
15+
MLIRCIROpInterfacesIncGen
16+
MLIRCIRLoopOpInterfaceIncGen
17+
MLIRBuiltinLocationAttributesIncGen
18+
MLIRBuiltinTypeInterfacesIncGen
19+
MLIRFunctionInterfacesIncGen
20+
21+
LINK_LIBS
22+
clangAST
23+
clangBasic
24+
clangCodeGen
25+
clangLex
26+
clangFrontend
27+
clangCIR
28+
${dialect_libs}
29+
MLIRCIR
30+
MLIRAnalysis
31+
MLIRBuiltinToLLVMIRTranslation
32+
MLIRLLVMToLLVMIRTranslation
33+
MLIRIR
34+
MLIRParser
35+
MLIRSideEffectInterfaces
36+
MLIRTransforms
37+
MLIRSupport
38+
MLIRMemRefDialect
39+
)
40+
141
add_subdirectory(DirectToLLVM)
242
add_subdirectory(ThroughMLIR)

clang/lib/CIR/Lowering/DirectToLLVM/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ add_clang_library(clangCIRLoweringDirectToLLVM
2626
clangLex
2727
clangFrontend
2828
clangCIR
29+
clangCIRLoweringHelpers
2930
${dialect_libs}
3031
MLIRCIR
3132
MLIRAnalysis

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

Lines changed: 1 addition & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "mlir/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.h"
4747
#include "mlir/Target/LLVMIR/Export.h"
4848
#include "mlir/Transforms/DialectConversion.h"
49+
#include "clang/CIR/LoweringHelpers.h"
4950
#include "clang/CIR/Dialect/IR/CIRAttrs.h"
5051
#include "clang/CIR/Dialect/IR/CIRDialect.h"
5152
#include "clang/CIR/Dialect/IR/CIROpsEnums.h"
@@ -962,134 +963,6 @@ class CIRStoreLowering : public mlir::OpConversionPattern<mlir::cir::StoreOp> {
962963
}
963964
};
964965

965-
mlir::DenseElementsAttr
966-
convertStringAttrToDenseElementsAttr(mlir::cir::ConstArrayAttr attr,
967-
mlir::Type type) {
968-
auto values = llvm::SmallVector<mlir::APInt, 8>{};
969-
auto stringAttr = mlir::dyn_cast<mlir::StringAttr>(attr.getElts());
970-
assert(stringAttr && "expected string attribute here");
971-
for (auto element : stringAttr)
972-
values.push_back({8, (uint64_t)element});
973-
return mlir::DenseElementsAttr::get(
974-
mlir::RankedTensorType::get({(int64_t)values.size()}, type),
975-
llvm::ArrayRef(values));
976-
}
977-
978-
template <typename StorageTy> StorageTy getZeroInitFromType(mlir::Type Ty);
979-
980-
template <> mlir::APInt getZeroInitFromType(mlir::Type Ty) {
981-
assert(mlir::isa<mlir::cir::IntType>(Ty) && "expected int type");
982-
auto IntTy = mlir::cast<mlir::cir::IntType>(Ty);
983-
return mlir::APInt::getZero(IntTy.getWidth());
984-
}
985-
986-
template <> mlir::APFloat getZeroInitFromType(mlir::Type Ty) {
987-
assert((mlir::isa<mlir::cir::SingleType, mlir::cir::DoubleType>(Ty)) &&
988-
"only float and double supported");
989-
if (Ty.isF32() || mlir::isa<mlir::cir::SingleType>(Ty))
990-
return mlir::APFloat(0.f);
991-
if (Ty.isF64() || mlir::isa<mlir::cir::DoubleType>(Ty))
992-
return mlir::APFloat(0.0);
993-
llvm_unreachable("NYI");
994-
}
995-
996-
// return the nested type and quantity of elements for cir.array type.
997-
// e.g: for !cir.array<!cir.array<!s32i x 3> x 1>
998-
// it returns !s32i as return value and stores 3 to elemQuantity.
999-
mlir::Type getNestedTypeAndElemQuantity(mlir::Type Ty, unsigned &elemQuantity) {
1000-
assert(mlir::isa<mlir::cir::ArrayType>(Ty) && "expected ArrayType");
1001-
1002-
elemQuantity = 1;
1003-
mlir::Type nestTy = Ty;
1004-
while (auto ArrTy = mlir::dyn_cast<mlir::cir::ArrayType>(nestTy)) {
1005-
nestTy = ArrTy.getEltType();
1006-
elemQuantity *= ArrTy.getSize();
1007-
}
1008-
1009-
return nestTy;
1010-
}
1011-
1012-
template <typename AttrTy, typename StorageTy>
1013-
void convertToDenseElementsAttrImpl(mlir::cir::ConstArrayAttr attr,
1014-
llvm::SmallVectorImpl<StorageTy> &values) {
1015-
auto arrayAttr = mlir::cast<mlir::ArrayAttr>(attr.getElts());
1016-
for (auto eltAttr : arrayAttr) {
1017-
if (auto valueAttr = mlir::dyn_cast<AttrTy>(eltAttr)) {
1018-
values.push_back(valueAttr.getValue());
1019-
} else if (auto subArrayAttr =
1020-
mlir::dyn_cast<mlir::cir::ConstArrayAttr>(eltAttr)) {
1021-
convertToDenseElementsAttrImpl<AttrTy>(subArrayAttr, values);
1022-
} else if (auto zeroAttr = mlir::dyn_cast<mlir::cir::ZeroAttr>(eltAttr)) {
1023-
unsigned numStoredZeros = 0;
1024-
auto nestTy =
1025-
getNestedTypeAndElemQuantity(zeroAttr.getType(), numStoredZeros);
1026-
values.insert(values.end(), numStoredZeros,
1027-
getZeroInitFromType<StorageTy>(nestTy));
1028-
} else {
1029-
llvm_unreachable("unknown element in ConstArrayAttr");
1030-
}
1031-
}
1032-
1033-
// Only fill in trailing zeros at the local cir.array level where the element
1034-
// type isn't another array (for the mult-dim case).
1035-
auto numTrailingZeros = attr.getTrailingZerosNum();
1036-
if (numTrailingZeros) {
1037-
auto localArrayTy = mlir::dyn_cast<mlir::cir::ArrayType>(attr.getType());
1038-
assert(localArrayTy && "expected !cir.array");
1039-
1040-
auto nestTy = localArrayTy.getEltType();
1041-
if (!mlir::isa<mlir::cir::ArrayType>(nestTy))
1042-
values.insert(values.end(), localArrayTy.getSize() - numTrailingZeros,
1043-
getZeroInitFromType<StorageTy>(nestTy));
1044-
}
1045-
}
1046-
1047-
template <typename AttrTy, typename StorageTy>
1048-
mlir::DenseElementsAttr
1049-
convertToDenseElementsAttr(mlir::cir::ConstArrayAttr attr,
1050-
const llvm::SmallVectorImpl<int64_t> &dims,
1051-
mlir::Type type) {
1052-
auto values = llvm::SmallVector<StorageTy, 8>{};
1053-
convertToDenseElementsAttrImpl<AttrTy>(attr, values);
1054-
return mlir::DenseElementsAttr::get(mlir::RankedTensorType::get(dims, type),
1055-
llvm::ArrayRef(values));
1056-
}
1057-
1058-
std::optional<mlir::Attribute>
1059-
lowerConstArrayAttr(mlir::cir::ConstArrayAttr constArr,
1060-
const mlir::TypeConverter *converter) {
1061-
1062-
// Ensure ConstArrayAttr has a type.
1063-
auto typedConstArr = mlir::dyn_cast<mlir::TypedAttr>(constArr);
1064-
assert(typedConstArr && "cir::ConstArrayAttr is not a mlir::TypedAttr");
1065-
1066-
// Ensure ConstArrayAttr type is a ArrayType.
1067-
auto cirArrayType =
1068-
mlir::dyn_cast<mlir::cir::ArrayType>(typedConstArr.getType());
1069-
assert(cirArrayType && "cir::ConstArrayAttr is not a cir::ArrayType");
1070-
1071-
// Is a ConstArrayAttr with an cir::ArrayType: fetch element type.
1072-
mlir::Type type = cirArrayType;
1073-
auto dims = llvm::SmallVector<int64_t, 2>{};
1074-
while (auto arrayType = mlir::dyn_cast<mlir::cir::ArrayType>(type)) {
1075-
dims.push_back(arrayType.getSize());
1076-
type = arrayType.getEltType();
1077-
}
1078-
1079-
// Convert array attr to LLVM compatible dense elements attr.
1080-
if (mlir::isa<mlir::StringAttr>(constArr.getElts()))
1081-
return convertStringAttrToDenseElementsAttr(constArr,
1082-
converter->convertType(type));
1083-
if (mlir::isa<mlir::cir::IntType>(type))
1084-
return convertToDenseElementsAttr<mlir::cir::IntAttr, mlir::APInt>(
1085-
constArr, dims, converter->convertType(type));
1086-
if (mlir::isa<mlir::cir::CIRFPTypeInterface>(type))
1087-
return convertToDenseElementsAttr<mlir::cir::FPAttr, mlir::APFloat>(
1088-
constArr, dims, converter->convertType(type));
1089-
1090-
return std::nullopt;
1091-
}
1092-
1093966
bool hasTrailingZeros(mlir::cir::ConstArrayAttr attr) {
1094967
auto array = mlir::dyn_cast<mlir::ArrayAttr>(attr.getElts());
1095968
return attr.hasTrailingZeros() ||
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
//====- LoweringHelpers.cpp - Lowering helper functions -------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file contains helper functions for lowering from CIR to LLVM or MLIR.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
#include "clang/CIR/LoweringHelpers.h"
13+
14+
mlir::DenseElementsAttr
15+
convertStringAttrToDenseElementsAttr(mlir::cir::ConstArrayAttr attr,
16+
mlir::Type type) {
17+
auto values = llvm::SmallVector<mlir::APInt, 8>{};
18+
auto stringAttr = mlir::dyn_cast<mlir::StringAttr>(attr.getElts());
19+
assert(stringAttr && "expected string attribute here");
20+
for (auto element : stringAttr)
21+
values.push_back({8, (uint64_t)element});
22+
return mlir::DenseElementsAttr::get(
23+
mlir::RankedTensorType::get({(int64_t)values.size()}, type),
24+
llvm::ArrayRef(values));
25+
}
26+
27+
template <> mlir::APInt getZeroInitFromType(mlir::Type Ty) {
28+
assert(mlir::isa<mlir::cir::IntType>(Ty) && "expected int type");
29+
auto IntTy = mlir::cast<mlir::cir::IntType>(Ty);
30+
return mlir::APInt::getZero(IntTy.getWidth());
31+
}
32+
33+
template <> mlir::APFloat getZeroInitFromType(mlir::Type Ty) {
34+
assert((mlir::isa<mlir::cir::SingleType, mlir::cir::DoubleType>(Ty)) &&
35+
"only float and double supported");
36+
if (Ty.isF32() || mlir::isa<mlir::cir::SingleType>(Ty))
37+
return mlir::APFloat(0.f);
38+
if (Ty.isF64() || mlir::isa<mlir::cir::DoubleType>(Ty))
39+
return mlir::APFloat(0.0);
40+
llvm_unreachable("NYI");
41+
}
42+
43+
// return the nested type and quantity of elements for cir.array type.
44+
// e.g: for !cir.array<!cir.array<!s32i x 3> x 1>
45+
// it returns !s32i as return value and stores 3 to elemQuantity.
46+
mlir::Type getNestedTypeAndElemQuantity(mlir::Type Ty, unsigned &elemQuantity) {
47+
assert(mlir::isa<mlir::cir::ArrayType>(Ty) && "expected ArrayType");
48+
49+
elemQuantity = 1;
50+
mlir::Type nestTy = Ty;
51+
while (auto ArrTy = mlir::dyn_cast<mlir::cir::ArrayType>(nestTy)) {
52+
nestTy = ArrTy.getEltType();
53+
elemQuantity *= ArrTy.getSize();
54+
}
55+
56+
return nestTy;
57+
}
58+
59+
template <typename AttrTy, typename StorageTy>
60+
void convertToDenseElementsAttrImpl(mlir::cir::ConstArrayAttr attr,
61+
llvm::SmallVectorImpl<StorageTy> &values) {
62+
auto arrayAttr = mlir::cast<mlir::ArrayAttr>(attr.getElts());
63+
for (auto eltAttr : arrayAttr) {
64+
if (auto valueAttr = mlir::dyn_cast<AttrTy>(eltAttr)) {
65+
values.push_back(valueAttr.getValue());
66+
} else if (auto subArrayAttr =
67+
mlir::dyn_cast<mlir::cir::ConstArrayAttr>(eltAttr)) {
68+
convertToDenseElementsAttrImpl<AttrTy>(subArrayAttr, values);
69+
} else if (auto zeroAttr = mlir::dyn_cast<mlir::cir::ZeroAttr>(eltAttr)) {
70+
unsigned numStoredZeros = 0;
71+
auto nestTy =
72+
getNestedTypeAndElemQuantity(zeroAttr.getType(), numStoredZeros);
73+
values.insert(values.end(), numStoredZeros,
74+
getZeroInitFromType<StorageTy>(nestTy));
75+
} else {
76+
llvm_unreachable("unknown element in ConstArrayAttr");
77+
}
78+
}
79+
80+
// Only fill in trailing zeros at the local cir.array level where the element
81+
// type isn't another array (for the mult-dim case).
82+
auto numTrailingZeros = attr.getTrailingZerosNum();
83+
if (numTrailingZeros) {
84+
auto localArrayTy = mlir::dyn_cast<mlir::cir::ArrayType>(attr.getType());
85+
assert(localArrayTy && "expected !cir.array");
86+
87+
auto nestTy = localArrayTy.getEltType();
88+
if (!mlir::isa<mlir::cir::ArrayType>(nestTy))
89+
values.insert(values.end(), localArrayTy.getSize() - numTrailingZeros,
90+
getZeroInitFromType<StorageTy>(nestTy));
91+
}
92+
}
93+
94+
template <typename AttrTy, typename StorageTy>
95+
mlir::DenseElementsAttr
96+
convertToDenseElementsAttr(mlir::cir::ConstArrayAttr attr,
97+
const llvm::SmallVectorImpl<int64_t> &dims,
98+
mlir::Type type) {
99+
auto values = llvm::SmallVector<StorageTy, 8>{};
100+
convertToDenseElementsAttrImpl<AttrTy>(attr, values);
101+
return mlir::DenseElementsAttr::get(mlir::RankedTensorType::get(dims, type),
102+
llvm::ArrayRef(values));
103+
}
104+
105+
std::optional<mlir::Attribute>
106+
lowerConstArrayAttr(mlir::cir::ConstArrayAttr constArr,
107+
const mlir::TypeConverter *converter) {
108+
109+
// Ensure ConstArrayAttr has a type.
110+
auto typedConstArr = mlir::dyn_cast<mlir::TypedAttr>(constArr);
111+
assert(typedConstArr && "cir::ConstArrayAttr is not a mlir::TypedAttr");
112+
113+
// Ensure ConstArrayAttr type is a ArrayType.
114+
auto cirArrayType =
115+
mlir::dyn_cast<mlir::cir::ArrayType>(typedConstArr.getType());
116+
assert(cirArrayType && "cir::ConstArrayAttr is not a cir::ArrayType");
117+
118+
// Is a ConstArrayAttr with an cir::ArrayType: fetch element type.
119+
mlir::Type type = cirArrayType;
120+
auto dims = llvm::SmallVector<int64_t, 2>{};
121+
while (auto arrayType = mlir::dyn_cast<mlir::cir::ArrayType>(type)) {
122+
dims.push_back(arrayType.getSize());
123+
type = arrayType.getEltType();
124+
}
125+
126+
if (mlir::isa<mlir::StringAttr>(constArr.getElts()))
127+
return convertStringAttrToDenseElementsAttr(constArr,
128+
converter->convertType(type));
129+
if (mlir::isa<mlir::cir::IntType>(type))
130+
return convertToDenseElementsAttr<mlir::cir::IntAttr, mlir::APInt>(
131+
constArr, dims, converter->convertType(type));
132+
if (mlir::isa<mlir::cir::CIRFPTypeInterface>(type))
133+
return convertToDenseElementsAttr<mlir::cir::FPAttr, mlir::APFloat>(
134+
constArr, dims, converter->convertType(type));
135+
136+
return std::nullopt;
137+
}

0 commit comments

Comments
 (0)