From 51a66e0589ee6911d11c0382795d8daa68435e34 Mon Sep 17 00:00:00 2001 From: "Zwolski, Antoni" Date: Mon, 2 Dec 2024 13:42:05 +0100 Subject: [PATCH] CMPLRLLVM-63534: Remove usage of deprecated getPointerTo --- .../ClangOffloadWrapper.cpp | 373 +++++++++--------- .../Offloading/SYCLOffloadWrapper.cpp | 2 +- 2 files changed, 187 insertions(+), 188 deletions(-) diff --git a/clang/tools/clang-offload-wrapper/ClangOffloadWrapper.cpp b/clang/tools/clang-offload-wrapper/ClangOffloadWrapper.cpp index 8079f9fa22e1b..ac0fd951d6f04 100644 --- a/clang/tools/clang-offload-wrapper/ClangOffloadWrapper.cpp +++ b/clang/tools/clang-offload-wrapper/ClangOffloadWrapper.cpp @@ -409,7 +409,7 @@ class BinaryWrapper { std::pair addStructArrayToModule(ArrayRef ArrayData, Type *ElemTy) { - auto *PtrTy = ElemTy->getPointerTo(); + auto *PtrTy = llvm::PointerType::getUnqual(C); if (ArrayData.size() == 0) { auto *NullPtr = Constant::getNullValue(PtrTy); @@ -442,8 +442,8 @@ class BinaryWrapper { StructType *getEntryTy() { if (!EntryTy) EntryTy = StructType::create("__tgt_offload_entry", PointerType::getUnqual(C), - PointerType::getUnqual(C), getSizeTTy(), - Type::getInt32Ty(C), Type::getInt32Ty(C)); + PointerType::getUnqual(C), getSizeTTy(), + Type::getInt32Ty(C), Type::getInt32Ty(C)); return EntryTy; } @@ -917,8 +917,7 @@ class BinaryWrapper { PropRegistry = MySymPropReader->getPropRegistry(); } else { if (PropRegistryFile.empty()) { - auto *NullPtr = - Constant::getNullValue(getSyclPropSetTy()->getPointerTo()); + auto *NullPtr = Constant::getNullValue(llvm::PointerType::getUnqual(C)); return std::pair(NullPtr, NullPtr); } // load the property registry file @@ -956,7 +955,7 @@ class BinaryWrapper { } public: - MemoryBuffer *addELFNotes(MemoryBuffer *Buf, StringRef OriginalFileName); + MemoryBuffer *addELFNotes(MemoryBuffer *Buf, StringRef OriginalFileName); private: /// Creates binary descriptor for the given device images. Binary descriptor @@ -1145,8 +1144,8 @@ class BinaryWrapper { #if LLVM_ENABLE_EXCEPTIONS } catch (const std::exception &ex) { return createStringError(inconvertibleErrorCode(), - std::string("Failed to compress the device image: \n") + - std::string(ex.what())); + std::string("Failed to compress the device image: \n") + + std::string(ex.what())); } #endif if (Verbose) @@ -1402,210 +1401,210 @@ class BinaryWrapper { } }; - // The whole function body is misaligned just to simplify - // conflict resolutions with llorg. +// The whole function body is misaligned just to simplify +// conflict resolutions with llorg. MemoryBuffer *BinaryWrapper::addELFNotes( MemoryBuffer *Buf, - StringRef OriginalFileName) { - // Cannot add notes, if llvm-objcopy is not available. - // - // I did not find a clean way to add a new notes section into an existing - // ELF file. llvm-objcopy seems to recreate a new ELF from scratch, - // and we just try to use llvm-objcopy here. - if (ObjcopyPath.empty()) - return Buf; + StringRef OriginalFileName) { + // Cannot add notes, if llvm-objcopy is not available. + // + // I did not find a clean way to add a new notes section into an existing + // ELF file. llvm-objcopy seems to recreate a new ELF from scratch, + // and we just try to use llvm-objcopy here. + if (ObjcopyPath.empty()) + return Buf; - StringRef ToolNameRef(ToolName); + StringRef ToolNameRef(ToolName); - // Helpers to emit warnings. - auto warningOS = [ToolNameRef]() -> raw_ostream & { - return WithColor::warning(errs(), ToolNameRef); - }; - auto handleErrorAsWarning = [&warningOS](Error E) { - logAllUnhandledErrors(std::move(E), warningOS()); - }; + // Helpers to emit warnings. + auto warningOS = [ToolNameRef]() -> raw_ostream & { + return WithColor::warning(errs(), ToolNameRef); + }; + auto handleErrorAsWarning = [&warningOS](Error E) { + logAllUnhandledErrors(std::move(E), warningOS()); + }; - Expected> BinOrErr = - ObjectFile::createELFObjectFile(Buf->getMemBufferRef(), - /*InitContent=*/false); - if (Error E = BinOrErr.takeError()) { - consumeError(std::move(E)); - // This warning is questionable, but let it be here, - // assuming that most OpenMP offload models use ELF offload images. - warningOS() << OriginalFileName - << " is not an ELF image, so notes cannot be added to it.\n"; - return Buf; - } + Expected> BinOrErr = + ObjectFile::createELFObjectFile(Buf->getMemBufferRef(), + /*InitContent=*/false); + if (Error E = BinOrErr.takeError()) { + consumeError(std::move(E)); + // This warning is questionable, but let it be here, + // assuming that most OpenMP offload models use ELF offload images. + warningOS() << OriginalFileName + << " is not an ELF image, so notes cannot be added to it.\n"; + return Buf; + } - // If we fail to add the note section, we just pass through the original - // ELF image for wrapping. At some point we should enforce the note section - // and start emitting errors vs warnings. - endianness Endianness; - if (isa(BinOrErr->get()) || - isa(BinOrErr->get())) { - Endianness = endianness::little; - } else if (isa(BinOrErr->get()) || - isa(BinOrErr->get())) { - Endianness = endianness::big; - } else { - warningOS() << OriginalFileName - << " is an ELF image of unrecognized format.\n"; - return Buf; - } + // If we fail to add the note section, we just pass through the original + // ELF image for wrapping. At some point we should enforce the note section + // and start emitting errors vs warnings. + endianness Endianness; + if (isa(BinOrErr->get()) || + isa(BinOrErr->get())) { + Endianness = endianness::little; + } else if (isa(BinOrErr->get()) || + isa(BinOrErr->get())) { + Endianness = endianness::big; + } else { + warningOS() << OriginalFileName + << " is an ELF image of unrecognized format.\n"; + return Buf; + } - // Create temporary file for the data of a new SHT_NOTE section. - // We fill it in with data and then pass to llvm-objcopy invocation - // for reading. - Twine NotesFileModel = OriginalFileName + Twine(".elfnotes.%%%%%%%.tmp"); - Expected NotesTemp = - sys::fs::TempFile::create(NotesFileModel); - if (Error E = NotesTemp.takeError()) { - handleErrorAsWarning(createFileError(NotesFileModel, std::move(E))); - return Buf; - } - TempFiles.push_back(NotesTemp->TmpName); + // Create temporary file for the data of a new SHT_NOTE section. + // We fill it in with data and then pass to llvm-objcopy invocation + // for reading. + Twine NotesFileModel = OriginalFileName + Twine(".elfnotes.%%%%%%%.tmp"); + Expected NotesTemp = + sys::fs::TempFile::create(NotesFileModel); + if (Error E = NotesTemp.takeError()) { + handleErrorAsWarning(createFileError(NotesFileModel, std::move(E))); + return Buf; + } + TempFiles.push_back(NotesTemp->TmpName); - // Create temporary file for the updated ELF image. - // This is an empty file that we pass to llvm-objcopy invocation - // for writing. - Twine ELFFileModel = OriginalFileName + Twine(".elfwithnotes.%%%%%%%.tmp"); + // Create temporary file for the updated ELF image. + // This is an empty file that we pass to llvm-objcopy invocation + // for writing. + Twine ELFFileModel = OriginalFileName + Twine(".elfwithnotes.%%%%%%%.tmp"); Expected ELFTemp = sys::fs::TempFile::create(ELFFileModel); - if (Error E = ELFTemp.takeError()) { - handleErrorAsWarning(createFileError(ELFFileModel, std::move(E))); - return Buf; - } - TempFiles.push_back(ELFTemp->TmpName); - - // Keep the new ELF image file to reserve the name for the future - // llvm-objcopy invocation. - std::string ELFTmpFileName = ELFTemp->TmpName; - if (Error E = ELFTemp->keep(ELFTmpFileName)) { - handleErrorAsWarning(createFileError(ELFTmpFileName, std::move(E))); - return Buf; - } + if (Error E = ELFTemp.takeError()) { + handleErrorAsWarning(createFileError(ELFFileModel, std::move(E))); + return Buf; + } + TempFiles.push_back(ELFTemp->TmpName); + + // Keep the new ELF image file to reserve the name for the future + // llvm-objcopy invocation. + std::string ELFTmpFileName = ELFTemp->TmpName; + if (Error E = ELFTemp->keep(ELFTmpFileName)) { + handleErrorAsWarning(createFileError(ELFTmpFileName, std::move(E))); + return Buf; + } - // Write notes to the *elfnotes*.tmp file. - raw_fd_ostream NotesOS(NotesTemp->FD, false); + // Write notes to the *elfnotes*.tmp file. + raw_fd_ostream NotesOS(NotesTemp->FD, false); - struct NoteTy { - // Note name is a null-terminated "LLVMOMPOFFLOAD". - std::string Name; - // Note type defined in llvm/include/llvm/BinaryFormat/ELF.h. - uint32_t Type = 0; - // Each note has type-specific associated data. - std::string Desc; + struct NoteTy { + // Note name is a null-terminated "LLVMOMPOFFLOAD". + std::string Name; + // Note type defined in llvm/include/llvm/BinaryFormat/ELF.h. + uint32_t Type = 0; + // Each note has type-specific associated data. + std::string Desc; - NoteTy(std::string &&Name, uint32_t Type, std::string &&Desc) - : Name(std::move(Name)), Type(Type), Desc(std::move(Desc)) {} - }; + NoteTy(std::string &&Name, uint32_t Type, std::string &&Desc) + : Name(std::move(Name)), Type(Type), Desc(std::move(Desc)) {} + }; - // So far we emit just three notes. - SmallVector Notes; - // Version of the offload image identifying the structure of the ELF image. - // Version 1.0 does not have any specific requirements. - // We may come up with some structure that has to be honored by all - // offload implementations in future (e.g. to let libomptarget - // get some information from the offload image). - Notes.emplace_back("LLVMOMPOFFLOAD", ELF::NT_LLVM_OPENMP_OFFLOAD_VERSION, - OPENMP_OFFLOAD_IMAGE_VERSION); - // This is a producer identification string. We are LLVM! - Notes.emplace_back("LLVMOMPOFFLOAD", ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER, - "LLVM"); - // This is a producer version. Use the same format that is used - // by clang to report the LLVM version. - Notes.emplace_back("LLVMOMPOFFLOAD", - ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER_VERSION, - LLVM_VERSION_STRING + // So far we emit just three notes. + SmallVector Notes; + // Version of the offload image identifying the structure of the ELF image. + // Version 1.0 does not have any specific requirements. + // We may come up with some structure that has to be honored by all + // offload implementations in future (e.g. to let libomptarget + // get some information from the offload image). + Notes.emplace_back("LLVMOMPOFFLOAD", ELF::NT_LLVM_OPENMP_OFFLOAD_VERSION, + OPENMP_OFFLOAD_IMAGE_VERSION); + // This is a producer identification string. We are LLVM! + Notes.emplace_back("LLVMOMPOFFLOAD", ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER, + "LLVM"); + // This is a producer version. Use the same format that is used + // by clang to report the LLVM version. + Notes.emplace_back("LLVMOMPOFFLOAD", + ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER_VERSION, + LLVM_VERSION_STRING #ifdef LLVM_REVISION - " " LLVM_REVISION + " " LLVM_REVISION #endif - ); - - // Return the amount of padding required for a blob of N bytes - // to be aligned to Alignment bytes. - auto getPadAmount = [](uint32_t N, uint32_t Alignment) -> uint32_t { - uint32_t Mod = (N % Alignment); - if (Mod == 0) - return 0; - return Alignment - Mod; - }; - auto emitPadding = [&getPadAmount](raw_ostream &OS, uint32_t Size) { - for (uint32_t I = 0; I < getPadAmount(Size, 4); ++I) - OS << '\0'; - }; + ); + + // Return the amount of padding required for a blob of N bytes + // to be aligned to Alignment bytes. + auto getPadAmount = [](uint32_t N, uint32_t Alignment) -> uint32_t { + uint32_t Mod = (N % Alignment); + if (Mod == 0) + return 0; + return Alignment - Mod; + }; + auto emitPadding = [&getPadAmount](raw_ostream &OS, uint32_t Size) { + for (uint32_t I = 0; I < getPadAmount(Size, 4); ++I) + OS << '\0'; + }; - // Put notes into the file. - for (auto &N : Notes) { - assert(!N.Name.empty() && "We should not create notes with empty names."); - // Name must be null-terminated. - if (N.Name.back() != '\0') - N.Name += '\0'; - uint32_t NameSz = N.Name.size(); - uint32_t DescSz = N.Desc.size(); - // A note starts with three 4-byte values: - // NameSz - // DescSz - // Type - // These three fields are endian-sensitive. - support::endian::write(NotesOS, NameSz, Endianness); - support::endian::write(NotesOS, DescSz, Endianness); - support::endian::write(NotesOS, N.Type, Endianness); - // Next, we have a null-terminated Name padded to a 4-byte boundary. - NotesOS << N.Name; - emitPadding(NotesOS, NameSz); - if (DescSz == 0) - continue; - // Finally, we have a descriptor, which is an arbitrary flow of bytes. - NotesOS << N.Desc; - emitPadding(NotesOS, DescSz); - } - NotesOS.flush(); + // Put notes into the file. + for (auto &N : Notes) { + assert(!N.Name.empty() && "We should not create notes with empty names."); + // Name must be null-terminated. + if (N.Name.back() != '\0') + N.Name += '\0'; + uint32_t NameSz = N.Name.size(); + uint32_t DescSz = N.Desc.size(); + // A note starts with three 4-byte values: + // NameSz + // DescSz + // Type + // These three fields are endian-sensitive. + support::endian::write(NotesOS, NameSz, Endianness); + support::endian::write(NotesOS, DescSz, Endianness); + support::endian::write(NotesOS, N.Type, Endianness); + // Next, we have a null-terminated Name padded to a 4-byte boundary. + NotesOS << N.Name; + emitPadding(NotesOS, NameSz); + if (DescSz == 0) + continue; + // Finally, we have a descriptor, which is an arbitrary flow of bytes. + NotesOS << N.Desc; + emitPadding(NotesOS, DescSz); + } + NotesOS.flush(); - // Keep the notes file. - std::string NotesTmpFileName = NotesTemp->TmpName; - if (Error E = NotesTemp->keep(NotesTmpFileName)) { - handleErrorAsWarning(createFileError(NotesTmpFileName, std::move(E))); - return Buf; - } + // Keep the notes file. + std::string NotesTmpFileName = NotesTemp->TmpName; + if (Error E = NotesTemp->keep(NotesTmpFileName)) { + handleErrorAsWarning(createFileError(NotesTmpFileName, std::move(E))); + return Buf; + } - // Run llvm-objcopy like this: - // llvm-objcopy --add-section=.note.openmp= \ + // Run llvm-objcopy like this: + // llvm-objcopy --add-section=.note.openmp= \ // - // - // This will add a SHT_NOTE section on top of the original ELF. - std::vector Args; - Args.push_back(ObjcopyPath); - std::string Option("--add-section=.note.openmp=" + NotesTmpFileName); - Args.push_back(Option); - Args.push_back("--no-verify-note-sections"); - Args.push_back(OriginalFileName); - Args.push_back(ELFTmpFileName); - bool ExecutionFailed = false; - std::string ErrMsg; - (void)sys::ExecuteAndWait(ObjcopyPath, Args, - /*Env=*/std::nullopt, /*Redirects=*/{}, - /*SecondsToWait=*/0, - /*MemoryLimit=*/0, &ErrMsg, &ExecutionFailed); - - if (ExecutionFailed) { - warningOS() << ErrMsg << "\n"; - return Buf; - } + // + // This will add a SHT_NOTE section on top of the original ELF. + std::vector Args; + Args.push_back(ObjcopyPath); + std::string Option("--add-section=.note.openmp=" + NotesTmpFileName); + Args.push_back(Option); + Args.push_back("--no-verify-note-sections"); + Args.push_back(OriginalFileName); + Args.push_back(ELFTmpFileName); + bool ExecutionFailed = false; + std::string ErrMsg; + (void)sys::ExecuteAndWait(ObjcopyPath, Args, + /*Env=*/std::nullopt, /*Redirects=*/{}, + /*SecondsToWait=*/0, + /*MemoryLimit=*/0, &ErrMsg, &ExecutionFailed); + + if (ExecutionFailed) { + warningOS() << ErrMsg << "\n"; + return Buf; + } - // Substitute the original ELF with new one. - ErrorOr> BufOrErr = - MemoryBuffer::getFile(ELFTmpFileName); - if (!BufOrErr) { + // Substitute the original ELF with new one. + ErrorOr> BufOrErr = + MemoryBuffer::getFile(ELFTmpFileName); + if (!BufOrErr) { handleErrorAsWarning( createFileError(ELFTmpFileName, BufOrErr.getError())); - return Buf; - } - - AutoGcBufs.emplace_back(std::move(*BufOrErr)); - return AutoGcBufs.back().get(); + return Buf; } + AutoGcBufs.emplace_back(std::move(*BufOrErr)); + return AutoGcBufs.back().get(); +} + llvm::raw_ostream &operator<<(llvm::raw_ostream &Out, const BinaryWrapper::Image &Img) { Out << "\n{\n"; diff --git a/llvm/lib/Frontend/Offloading/SYCLOffloadWrapper.cpp b/llvm/lib/Frontend/Offloading/SYCLOffloadWrapper.cpp index c836d470c6f08..5cd54df70e3ed 100644 --- a/llvm/lib/Frontend/Offloading/SYCLOffloadWrapper.cpp +++ b/llvm/lib/Frontend/Offloading/SYCLOffloadWrapper.cpp @@ -358,7 +358,7 @@ struct Wrapper { std::pair addStructArrayToModule(ArrayRef ArrayData, Type *ElemTy) { if (ArrayData.empty()) { - auto *PtrTy = ElemTy->getPointerTo(); + auto *PtrTy = llvm::PointerType::getUnqual(ElemTy->getContext()); auto *NullPtr = Constant::getNullValue(PtrTy); return std::make_pair(NullPtr, NullPtr); }