Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Support] Add llvm::support::endian::writeNext #88685

Merged

Conversation

MaskRay
Copy link
Member

@MaskRay MaskRay commented Apr 15, 2024

writeNext overloads increase the pointer argument like readNext.
Code like the following

endian::write32<ELFT::Endianness>(p, 42);
p += 4;
endian::write32<ELFT::Endianness>(p, 43);
p += 4;

can be simplified to:

endian::writeNext<uint32_t, ELFT::Endianness>(p, 42);
endian::writeNext<uint32_t, ELFT::Endianness>(p, 43);

Created using spr 1.3.5-bogner
@llvmbot
Copy link
Collaborator

llvmbot commented Apr 15, 2024

@llvm/pr-subscribers-llvm-support

Author: Fangrui Song (MaskRay)

Changes

writeNext overloads increase the pointer argument like readNext.
Code like the following

endian::write32&lt;ELFT::Endianness&gt;(p, 42);
p += 4;
endian::write32&lt;ELFT::Endianness&gt;(p, 43);
p += 4;

can be simplified to:

endian::writeNext&lt;uint32_t, ELFT::Endianness&gt;(p, 42);
endian::writeNext&lt;uint32_t, ELFT::Endianness&gt;(p, 43);

Full diff: https://github.com/llvm/llvm-project/pull/88685.diff

2 Files Affected:

  • (modified) llvm/include/llvm/Support/Endian.h (+15)
  • (modified) llvm/unittests/Support/EndianTest.cpp (+23)
diff --git a/llvm/include/llvm/Support/Endian.h b/llvm/include/llvm/Support/Endian.h
index 4c0405cf1e2f69..1cdb5ca0d5eaa1 100644
--- a/llvm/include/llvm/Support/Endian.h
+++ b/llvm/include/llvm/Support/Endian.h
@@ -102,6 +102,21 @@ inline void write(void *memory, value_type value) {
   write<value_type, alignment>(memory, value, endian);
 }
 
+/// Write a value of a particular endianness, and increment the buffer past that
+/// value.
+template <typename value_type, std::size_t alignment = unaligned,
+          typename CharT>
+inline void writeNext(CharT *&memory, value_type value, endianness endian) {
+  write(memory, value, endian);
+  memory += sizeof(value_type);
+}
+
+template <typename value_type, endianness endian,
+          std::size_t alignment = unaligned, typename CharT>
+inline void writeNext(CharT *&memory, value_type value) {
+  writeNext<value_type, alignment, CharT>(memory, value, endian);
+}
+
 template <typename value_type>
 using make_unsigned_t = std::make_unsigned_t<value_type>;
 
diff --git a/llvm/unittests/Support/EndianTest.cpp b/llvm/unittests/Support/EndianTest.cpp
index ab7dfc3800691d..bba1a56168f709 100644
--- a/llvm/unittests/Support/EndianTest.cpp
+++ b/llvm/unittests/Support/EndianTest.cpp
@@ -36,6 +36,29 @@ TEST(Endian, Read) {
                                                                   1)));
 }
 
+TEST(Endian, WriteNext) {
+  unsigned char bigval[] = {0x00, 0x00}, *p = bigval;
+  endian::writeNext<int16_t, llvm::endianness::big>(p, short(0xaabb));
+  EXPECT_EQ(bigval[0], 0xaa);
+  EXPECT_EQ(bigval[1], 0xbb);
+  EXPECT_EQ(p, bigval + 2);
+
+  char littleval[8] = {}, *q = littleval;
+  endian::writeNext<uint32_t, llvm::endianness::little>(q, 0x44556677);
+  EXPECT_EQ(littleval[0], 0x77);
+  EXPECT_EQ(littleval[1], 0x66);
+  EXPECT_EQ(littleval[2], 0x55);
+  EXPECT_EQ(littleval[3], 0x44);
+  EXPECT_EQ(q, littleval + 4);
+
+  endian::writeNext<uint32_t>(q, 0x11223344, llvm::endianness::little);
+  EXPECT_EQ(littleval[4], 0x44);
+  EXPECT_EQ(littleval[5], 0x33);
+  EXPECT_EQ(littleval[6], 0x22);
+  EXPECT_EQ(littleval[7], 0x11);
+  EXPECT_EQ(q, littleval + 8);
+}
+
 TEST(Endian, ReadBitAligned) {
   // Simple test to make sure we properly pull out the 0x0 word.
   unsigned char littleval[] = {0x3f, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff};

Copy link
Contributor

@kazutakahirata kazutakahirata left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks!

Copy link
Collaborator

@dwblaikie dwblaikie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good stuff - thanks!

@MaskRay MaskRay merged commit 51d85b7 into main Apr 15, 2024
6 checks passed
@MaskRay MaskRay deleted the users/MaskRay/spr/support-add-llvmsupportendianwritenext branch April 15, 2024 17:02
aniplcc pushed a commit to aniplcc/llvm-project that referenced this pull request Apr 15, 2024
`writeNext` overloads increase the pointer argument like `readNext`.
Code like the following
```
endian::write32<ELFT::Endianness>(p, 42);
p += 4;
endian::write32<ELFT::Endianness>(p, 43);
p += 4;
```

can be simplified to:
```
endian::writeNext<uint32_t, ELFT::Endianness>(p, 42);
endian::writeNext<uint32_t, ELFT::Endianness>(p, 43);
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants