#include <algorithm>
#include <atomic>
#include <cassert>
+#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <functional>
+#include <limits>
+#include <memory>
#include <sstream>
#include <string>
return Error::success();
}
+/// Return the difference (in bytes) between \p Begin and \p End.
+template <typename Ty = char>
+ptrdiff_t getPtrDiff(const void *End, const void *Begin) {
+ return reinterpret_cast<const Ty *>(End) -
+ reinterpret_cast<const Ty *>(Begin);
+}
+
+/// Return \p Ptr advanced by \p Offset bytes.
+template <typename Ty> Ty *advanceVoidPtr(Ty *Ptr, int64_t Offset) {
+ static_assert(std::is_void<Ty>::value);
+ return const_cast<char *>(reinterpret_cast<const char *>(Ptr) + Offset);
+}
+
+/// Return \p Ptr aligned to \p Alignment bytes.
+template <typename Ty> Ty *alignPtr(Ty *Ptr, int64_t Alignment) {
+ size_t Space = std::numeric_limits<size_t>::max();
+ return std::align(Alignment, sizeof(char), Ptr, Space);
+}
+
} // namespace target
} // namespace omp
} // namespace llvm
GlobalTy &ImageGlobal) override {
// The global's address in AMDGPU is computed as the image begin + the ELF
// symbol value. Notice we do not add the ELF section offset.
- ImageGlobal.setPtr((char *)Image.getStart() + Symbol.st_value);
+ ImageGlobal.setPtr(advanceVoidPtr(Image.getStart(), Symbol.st_value));
// Set the global's size.
ImageGlobal.setSize(Symbol.st_size);
// Initialize implicit arguments.
utils::AMDGPUImplicitArgsTy *ImplArgs =
reinterpret_cast<utils::AMDGPUImplicitArgsTy *>(
- static_cast<char *>(AllArgs) + KernelArgsSize);
+ advanceVoidPtr(AllArgs, KernelArgsSize));
// Initialize the implicit arguments to zero.
std::memset(ImplArgs, 0, ImplicitArgsSize);
#include "GlobalHandler.h"
#include "ELFSymbols.h"
#include "PluginInterface.h"
+#include "Utilities.h"
#include <cstring>
// The global's address is computed as the image begin + the ELF section
// offset + the ELF symbol value.
- ImageGlobal.setPtr((char *)Image.getStart() + Section.sh_offset +
- Symbol.st_value);
+ ImageGlobal.setPtr(
+ advanceVoidPtr(Image.getStart(), Section.sh_offset + Symbol.st_value));
// Set the global's size.
ImageGlobal.setSize(Symbol.st_size);
Expected<std::unique_ptr<Module>>
createModuleFromImage(__tgt_device_image *Image, LLVMContext &Context) {
StringRef Data((const char *)Image->ImageStart,
- (char *)Image->ImageEnd - (char *)Image->ImageStart);
+ target::getPtrDiff(Image->ImageEnd, Image->ImageStart));
std::unique_ptr<MemoryBuffer> MB = MemoryBuffer::getMemBuffer(
Data, /* BufferName */ "", /* RequiresNullTerminator */ false);
return createModuleFromMemoryBuffer(MB, Context);
}
StringRef Data(reinterpret_cast<const char *>(Image->ImageStart),
- reinterpret_cast<char *>(Image->ImageEnd) -
- reinterpret_cast<char *>(Image->ImageStart));
+ target::getPtrDiff(Image->ImageEnd, Image->ImageStart));
std::unique_ptr<MemoryBuffer> MB = MemoryBuffer::getMemBuffer(
Data, /* BufferName */ "", /* RequiresNullTerminator */ false);
if (!MB)
/// Get the image size.
size_t getSize() const {
- return ((char *)TgtImage->ImageEnd) - ((char *)TgtImage->ImageStart);
+ return getPtrDiff(TgtImage->ImageEnd, TgtImage->ImageStart);
}
/// Get a memory buffer reference to the whole image.
--It;
// Evaluate whether the buffer is contained in the pinned allocation.
- return ((const char *)It->first + It->second > (const char *)Buffer);
+ return (advanceVoidPtr(It->first, It->second) > (const char *)Buffer);
}
/// Return the execution mode used for kernel \p Name.