[PATCH] D80272: [mlir] Support big-endian systems in DenseElementsAttr (multiple word)
Haruki Imai via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed May 20 19:53:22 PDT 2020
imaihal updated this revision to Diff 265407.
imaihal added a comment.
Fixed variable name to meet camelBack style
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D80272/new/
https://reviews.llvm.org/D80272
Files:
mlir/lib/IR/Attributes.cpp
Index: mlir/lib/IR/Attributes.cpp
===================================================================
--- mlir/lib/IR/Attributes.cpp
+++ mlir/lib/IR/Attributes.cpp
@@ -546,25 +546,57 @@
/// Get start position of actual data in `value`. Actual data is
/// stored in last `bitWidth`/CHAR_BIT bytes in big endian.
-static char *getAPIntDataPos(APInt &value, size_t bitWidth) {
+static char *getAPIntDataPosBE(APInt &value, size_t bitWidth, size_t wordNum) {
char *dataPos =
const_cast<char *>(reinterpret_cast<const char *>(value.getRawData()));
- if (llvm::support::endian::system_endianness() ==
- llvm::support::endianness::big)
- dataPos = dataPos + 8 - llvm::divideCeil(bitWidth, CHAR_BIT);
+ unsigned apintBytesPerWord = APInt::APINT_BITS_PER_WORD / CHAR_BIT;
+
+ dataPos = dataPos + apintBytesPerWord * wordNum -
+ llvm::divideCeil(bitWidth, CHAR_BIT);
+
return dataPos;
}
/// Read APInt `value` from appropriate position.
static void readAPInt(APInt &value, size_t bitWidth, char *outData) {
- char *dataPos = getAPIntDataPos(value, bitWidth);
- std::copy_n(dataPos, llvm::divideCeil(bitWidth, CHAR_BIT), outData);
+ char *dataPos =
+ const_cast<char *>(reinterpret_cast<const char *>(value.getRawData()));
+ if (llvm::support::endian::system_endianness() ==
+ llvm::support::endianness::big) {
+ unsigned numFilledWords = bitWidth / APInt::APINT_BITS_PER_WORD;
+ unsigned resBits = bitWidth - numFilledWords * APInt::APINT_BITS_PER_WORD;
+ unsigned apintBytesPerWord = APInt::APINT_BITS_PER_WORD / CHAR_BIT;
+ // Read words filled with 8 bytes data (multiple of `APINT_BITS_PER_WORD`
+ // bits)
+ std::copy_n(dataPos, apintBytesPerWord * numFilledWords, outData);
+ // Then, read the rest bits from apropriate position in big endian
+ dataPos = getAPIntDataPosBE(value, resBits, numFilledWords + 1);
+ std::copy_n(dataPos, llvm::divideCeil(resBits, CHAR_BIT),
+ outData + apintBytesPerWord * numFilledWords);
+ } else {
+ std::copy_n(dataPos, llvm::divideCeil(bitWidth, CHAR_BIT), outData);
+ }
}
/// Write `inData` to appropriate position of APInt `value`.
static void writeAPInt(const char *inData, size_t bitWidth, APInt &value) {
- char *dataPos = getAPIntDataPos(value, bitWidth);
- std::copy_n(inData, llvm::divideCeil(bitWidth, CHAR_BIT), dataPos);
+ char *dataPos =
+ const_cast<char *>(reinterpret_cast<const char *>(value.getRawData()));
+ if (llvm::support::endian::system_endianness() ==
+ llvm::support::endianness::big) {
+ unsigned numFilledWords = bitWidth / APInt::APINT_BITS_PER_WORD;
+ unsigned resBits = bitWidth - numFilledWords * APInt::APINT_BITS_PER_WORD;
+ unsigned apintBytesPerWord = APInt::APINT_BITS_PER_WORD / CHAR_BIT;
+ // Write words filled with 8 bytes data (multiple of `APINT_BITS_PER_WORD`
+ // bits)
+ std::copy_n(inData, apintBytesPerWord * numFilledWords, dataPos);
+ // Then, write the rest bits from apropriate position in big endian
+ dataPos = getAPIntDataPosBE(value, resBits, numFilledWords + 1);
+ std::copy_n(inData + apintBytesPerWord * numFilledWords,
+ llvm::divideCeil(resBits, CHAR_BIT), dataPos);
+ } else {
+ std::copy_n(inData, llvm::divideCeil(bitWidth, CHAR_BIT), dataPos);
+ }
}
/// Writes value to the bit position `bitPos` in array `rawData`.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D80272.265407.patch
Type: text/x-patch
Size: 3385 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200521/61f06456/attachment.bin>
More information about the llvm-commits
mailing list