|
| 1 | +From a15e14e27fdbb7e874f51d02e06b4c6c9349f798 Mon Sep 17 00:00:00 2001 |
| 2 | +From: serge-sans-paille <sguelton@mozilla.com> |
| 3 | +Date: Wed, 10 Jul 2024 22:42:19 +0200 |
| 4 | +Subject: [PATCH 3/7] Specialize Flang to target WASM |
| 5 | + |
| 6 | +Many values were explicitly encoded under the assumation that host and target have |
| 7 | +the same architecture. |
| 8 | +--- |
| 9 | + .../Optimizer/Builder/Runtime/RTBuilder.h | 31 ++++++++++--------- |
| 10 | + .../flang/Optimizer/Support/DataLayout.h | 16 ++++++++++ |
| 11 | + flang/lib/Optimizer/CodeGen/CodeGen.cpp | 8 +++-- |
| 12 | + 3 files changed, 38 insertions(+), 17 deletions(-) |
| 13 | + |
| 14 | +diff --git a/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h b/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h |
| 15 | +index 845ba385918d..adc6479f9cbf 100644 |
| 16 | +--- a/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h |
| 17 | ++++ b/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h |
| 18 | +@@ -22,6 +22,7 @@ |
| 19 | + #include "flang/Optimizer/Builder/FIRBuilder.h" |
| 20 | + #include "flang/Optimizer/Dialect/FIRDialect.h" |
| 21 | + #include "flang/Optimizer/Dialect/FIRType.h" |
| 22 | ++#include "flang/Optimizer/Support/DataLayout.h" |
| 23 | + #include "flang/Runtime/reduce.h" |
| 24 | + #include "mlir/IR/BuiltinTypes.h" |
| 25 | + #include "mlir/IR/MLIRContext.h" |
| 26 | +@@ -85,7 +86,7 @@ using FuncTypeBuilderFunc = mlir::FunctionType (*)(mlir::MLIRContext *); |
| 27 | + auto voidTy = fir::LLVMPointerType::get( \ |
| 28 | + context, mlir::IntegerType::get(context, 8)); \ |
| 29 | + auto size_tTy = \ |
| 30 | +- mlir::IntegerType::get(context, 8 * sizeof(std::size_t)); \ |
| 31 | ++ mlir::IntegerType::get(context, 8 * FLANG_TARGET_SIZEOF_SIZE_T); \ |
| 32 | + auto refTy = fir::ReferenceType::get(f(context)); \ |
| 33 | + return mlir::FunctionType::get( \ |
| 34 | + context, {refTy, size_tTy, refTy, refTy, size_tTy, size_tTy}, \ |
| 35 | +@@ -113,13 +114,13 @@ static constexpr TypeBuilderFunc getModel(); |
| 36 | + template <> |
| 37 | + constexpr TypeBuilderFunc getModel<unsigned int>() { |
| 38 | + return [](mlir::MLIRContext *context) -> mlir::Type { |
| 39 | +- return mlir::IntegerType::get(context, 8 * sizeof(unsigned int)); |
| 40 | ++ return mlir::IntegerType::get(context, 8 * FLANG_TARGET_SIZEOF_UINT); |
| 41 | + }; |
| 42 | + } |
| 43 | + template <> |
| 44 | + constexpr TypeBuilderFunc getModel<short int>() { |
| 45 | + return [](mlir::MLIRContext *context) -> mlir::Type { |
| 46 | +- return mlir::IntegerType::get(context, 8 * sizeof(short int)); |
| 47 | ++ return mlir::IntegerType::get(context, 8 * FLANG_TARGET_SIZEOF_SHORT); |
| 48 | + }; |
| 49 | + } |
| 50 | + template <> |
| 51 | +@@ -136,7 +137,7 @@ constexpr TypeBuilderFunc getModel<const short int *>() { |
| 52 | + template <> |
| 53 | + constexpr TypeBuilderFunc getModel<int>() { |
| 54 | + return [](mlir::MLIRContext *context) -> mlir::Type { |
| 55 | +- return mlir::IntegerType::get(context, 8 * sizeof(int)); |
| 56 | ++ return mlir::IntegerType::get(context, 8 * FLANG_TARGET_SIZEOF_INT); |
| 57 | + }; |
| 58 | + } |
| 59 | + template <> |
| 60 | +@@ -182,13 +183,13 @@ constexpr TypeBuilderFunc getModel<const char32_t *>() { |
| 61 | + template <> |
| 62 | + constexpr TypeBuilderFunc getModel<char>() { |
| 63 | + return [](mlir::MLIRContext *context) -> mlir::Type { |
| 64 | +- return mlir::IntegerType::get(context, 8 * sizeof(char)); |
| 65 | ++ return mlir::IntegerType::get(context, 8 * FLANG_TARGET_SIZEOF_CHAR); |
| 66 | + }; |
| 67 | + } |
| 68 | + template <> |
| 69 | + constexpr TypeBuilderFunc getModel<signed char>() { |
| 70 | + return [](mlir::MLIRContext *context) -> mlir::Type { |
| 71 | +- return mlir::IntegerType::get(context, 8 * sizeof(signed char)); |
| 72 | ++ return mlir::IntegerType::get(context, 8 * FLANG_TARGET_SIZEOF_SCHAR); |
| 73 | + }; |
| 74 | + } |
| 75 | + template <> |
| 76 | +@@ -205,7 +206,7 @@ constexpr TypeBuilderFunc getModel<const signed char *>() { |
| 77 | + template <> |
| 78 | + constexpr TypeBuilderFunc getModel<char16_t>() { |
| 79 | + return [](mlir::MLIRContext *context) -> mlir::Type { |
| 80 | +- return mlir::IntegerType::get(context, 8 * sizeof(char16_t)); |
| 81 | ++ return mlir::IntegerType::get(context, 8 * FLANG_TARGET_SIZEOF_CHAR16); |
| 82 | + }; |
| 83 | + } |
| 84 | + template <> |
| 85 | +@@ -218,7 +219,7 @@ constexpr TypeBuilderFunc getModel<char16_t *>() { |
| 86 | + template <> |
| 87 | + constexpr TypeBuilderFunc getModel<char32_t>() { |
| 88 | + return [](mlir::MLIRContext *context) -> mlir::Type { |
| 89 | +- return mlir::IntegerType::get(context, 8 * sizeof(char32_t)); |
| 90 | ++ return mlir::IntegerType::get(context, 8 * FLANG_TARGET_SIZEOF_CHAR32); |
| 91 | + }; |
| 92 | + } |
| 93 | + template <> |
| 94 | +@@ -231,7 +232,7 @@ constexpr TypeBuilderFunc getModel<char32_t *>() { |
| 95 | + template <> |
| 96 | + constexpr TypeBuilderFunc getModel<unsigned char>() { |
| 97 | + return [](mlir::MLIRContext *context) -> mlir::Type { |
| 98 | +- return mlir::IntegerType::get(context, 8 * sizeof(unsigned char)); |
| 99 | ++ return mlir::IntegerType::get(context, 8 * FLANG_TARGET_SIZEOF_UCHAR); |
| 100 | + }; |
| 101 | + } |
| 102 | + template <> |
| 103 | +@@ -259,7 +260,7 @@ constexpr TypeBuilderFunc getModel<void **>() { |
| 104 | + template <> |
| 105 | + constexpr TypeBuilderFunc getModel<long>() { |
| 106 | + return [](mlir::MLIRContext *context) -> mlir::Type { |
| 107 | +- return mlir::IntegerType::get(context, 8 * sizeof(long)); |
| 108 | ++ return mlir::IntegerType::get(context, 8 * FLANG_TARGET_SIZEOF_LONG); |
| 109 | + }; |
| 110 | + } |
| 111 | + template <> |
| 112 | +@@ -280,7 +281,7 @@ constexpr TypeBuilderFunc getModel<const long *>() { |
| 113 | + template <> |
| 114 | + constexpr TypeBuilderFunc getModel<long long>() { |
| 115 | + return [](mlir::MLIRContext *context) -> mlir::Type { |
| 116 | +- return mlir::IntegerType::get(context, 8 * sizeof(long long)); |
| 117 | ++ return mlir::IntegerType::get(context, 8 * FLANG_TARGET_SIZEOF_LONGLONG); |
| 118 | + }; |
| 119 | + } |
| 120 | + template <> |
| 121 | +@@ -308,13 +309,13 @@ constexpr TypeBuilderFunc getModel<const long long *>() { |
| 122 | + template <> |
| 123 | + constexpr TypeBuilderFunc getModel<unsigned long>() { |
| 124 | + return [](mlir::MLIRContext *context) -> mlir::Type { |
| 125 | +- return mlir::IntegerType::get(context, 8 * sizeof(unsigned long)); |
| 126 | ++ return mlir::IntegerType::get(context, 8 * FLANG_TARGET_SIZEOF_ULONG); |
| 127 | + }; |
| 128 | + } |
| 129 | + template <> |
| 130 | + constexpr TypeBuilderFunc getModel<unsigned long long>() { |
| 131 | + return [](mlir::MLIRContext *context) -> mlir::Type { |
| 132 | +- return mlir::IntegerType::get(context, 8 * sizeof(unsigned long long)); |
| 133 | ++ return mlir::IntegerType::get(context, 8 * FLANG_TARGET_SIZEOF_ULONGLONG); |
| 134 | + }; |
| 135 | + } |
| 136 | + template <> |
| 137 | +@@ -434,13 +435,13 @@ constexpr TypeBuilderFunc getModel<const std::complex<double> *>() { |
| 138 | + template <> |
| 139 | + constexpr TypeBuilderFunc getModel<c_float_complex_t>() { |
| 140 | + return [](mlir::MLIRContext *context) -> mlir::Type { |
| 141 | +- return fir::ComplexType::get(context, sizeof(float)); |
| 142 | ++ return fir::ComplexType::get(context, FLANG_TARGET_SIZEOF_FLOAT); |
| 143 | + }; |
| 144 | + } |
| 145 | + template <> |
| 146 | + constexpr TypeBuilderFunc getModel<c_double_complex_t>() { |
| 147 | + return [](mlir::MLIRContext *context) -> mlir::Type { |
| 148 | +- return fir::ComplexType::get(context, sizeof(double)); |
| 149 | ++ return fir::ComplexType::get(context, FLANG_TARGET_SIZEOF_DOUBLE); |
| 150 | + }; |
| 151 | + } |
| 152 | + template <> |
| 153 | +diff --git a/flang/include/flang/Optimizer/Support/DataLayout.h b/flang/include/flang/Optimizer/Support/DataLayout.h |
| 154 | +index d21576bb95f7..5372039d8702 100644 |
| 155 | +--- a/flang/include/flang/Optimizer/Support/DataLayout.h |
| 156 | ++++ b/flang/include/flang/Optimizer/Support/DataLayout.h |
| 157 | +@@ -23,6 +23,22 @@ namespace llvm { |
| 158 | + class DataLayout; |
| 159 | + } |
| 160 | + |
| 161 | ++constexpr size_t FLANG_TARGET_SIZEOF_UINT = 4; |
| 162 | ++constexpr size_t FLANG_TARGET_SIZEOF_INT = 4; |
| 163 | ++constexpr size_t FLANG_TARGET_SIZEOF_SHORT = 2; |
| 164 | ++constexpr size_t FLANG_TARGET_SIZEOF_CHAR = 1; |
| 165 | ++constexpr size_t FLANG_TARGET_SIZEOF_SCHAR = 1; |
| 166 | ++constexpr size_t FLANG_TARGET_SIZEOF_UCHAR = 1; |
| 167 | ++constexpr size_t FLANG_TARGET_SIZEOF_CHAR16 = 2; |
| 168 | ++constexpr size_t FLANG_TARGET_SIZEOF_CHAR32 = 4; |
| 169 | ++constexpr size_t FLANG_TARGET_SIZEOF_LONG = 4; |
| 170 | ++constexpr size_t FLANG_TARGET_SIZEOF_LONGLONG = 8; |
| 171 | ++constexpr size_t FLANG_TARGET_SIZEOF_ULONG = 4; |
| 172 | ++constexpr size_t FLANG_TARGET_SIZEOF_ULONGLONG = 8; |
| 173 | ++constexpr size_t FLANG_TARGET_SIZEOF_SIZE_T = 4; |
| 174 | ++constexpr size_t FLANG_TARGET_SIZEOF_FLOAT = 4; |
| 175 | ++constexpr size_t FLANG_TARGET_SIZEOF_DOUBLE = 8; |
| 176 | ++ |
| 177 | + namespace fir::support { |
| 178 | + /// Create an mlir::DataLayoutSpecInterface attribute from an llvm::DataLayout |
| 179 | + /// and set it on the provided mlir::ModuleOp. |
| 180 | +diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp |
| 181 | +index f9ea92a843b2..ca72d67400b0 100644 |
| 182 | +--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp |
| 183 | ++++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp |
| 184 | +@@ -909,7 +909,8 @@ getMalloc(fir::AllocMemOp op, mlir::ConversionPatternRewriter &rewriter) { |
| 185 | + return mlir::SymbolRefAttr::get(userMalloc); |
| 186 | + mlir::OpBuilder moduleBuilder( |
| 187 | + op->getParentOfType<mlir::ModuleOp>().getBodyRegion()); |
| 188 | +- auto indexType = mlir::IntegerType::get(op.getContext(), 64); |
| 189 | ++ auto indexType = |
| 190 | ++ mlir::IntegerType::get(op.getContext(), 8 * FLANG_TARGET_SIZEOF_SIZE_T); |
| 191 | + auto mallocDecl = moduleBuilder.create<mlir::LLVM::LLVMFuncOp>( |
| 192 | + op.getLoc(), mallocName, |
| 193 | + mlir::LLVM::LLVMFunctionType::get(getLlvmPtrType(op.getContext()), |
| 194 | +@@ -976,8 +977,11 @@ struct AllocMemOpConversion : public fir::FIROpConversion<fir::AllocMemOp> { |
| 195 | + size = rewriter.create<mlir::LLVM::MulOp>( |
| 196 | + loc, ity, size, integerCast(loc, rewriter, ity, opnd)); |
| 197 | + heap->setAttr("callee", getMalloc(heap, rewriter)); |
| 198 | ++ auto szt_ty = mlir::IntegerType::get(rewriter.getContext(), |
| 199 | ++ 8 * FLANG_TARGET_SIZEOF_SIZE_T); |
| 200 | ++ auto size_szt = integerCast(loc, rewriter, szt_ty, size); |
| 201 | + rewriter.replaceOpWithNewOp<mlir::LLVM::CallOp>( |
| 202 | +- heap, ::getLlvmPtrType(heap.getContext()), size, heap->getAttrs()); |
| 203 | ++ heap, ::getLlvmPtrType(heap.getContext()), size_szt, heap->getAttrs()); |
| 204 | + return mlir::success(); |
| 205 | + } |
| 206 | + |
0 commit comments