diff --git a/projects/clr/rocclr/compiler/lib/backends/common/Disassembler.cpp b/projects/clr/rocclr/compiler/lib/backends/common/Disassembler.cpp index 8030a52c6b..1c7f70e151 100644 --- a/projects/clr/rocclr/compiler/lib/backends/common/Disassembler.cpp +++ b/projects/clr/rocclr/compiler/lib/backends/common/Disassembler.cpp @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +#if defined(LEGACY_COMPLIB) #include "Disassembler.h" #include "lib/MC/MCDisassembler/EDDisassembler.h" #include "lib/MC/MCDisassembler/EDInst.h" @@ -341,3 +342,4 @@ int Disassembler::disassembleEnhanced(const std::string &TS, return 0; } +#endif // LEGACY_COMPLIB \ No newline at end of file diff --git a/projects/clr/rocclr/compiler/lib/backends/common/codegen.cpp b/projects/clr/rocclr/compiler/lib/backends/common/codegen.cpp index f89f3191b1..bb646cedfd 100644 --- a/projects/clr/rocclr/compiler/lib/backends/common/codegen.cpp +++ b/projects/clr/rocclr/compiler/lib/backends/common/codegen.cpp @@ -14,8 +14,15 @@ #ifdef _MSC_VER #pragma warning(default:4146) #endif +#if defined(LEGACY_COMPLIB) #include "llvm/DataLayout.h" #include "llvm/Module.h" +#include "llvm/ExecutionEngine/ObjectImage.h" +#else +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Module.h" +#include "llvm/Object/ObjectFile.h" +#endif #include "llvm/Support/CodeGen.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FormattedStream.h" @@ -27,7 +34,6 @@ #include "llvm/Target/TargetOptions.h" #include "llvm/ExecutionEngine/JITEventListener.h" #include "llvm/ExecutionEngine/MCJIT.h" -#include "llvm/ExecutionEngine/ObjectImage.h" #include #include #include @@ -96,7 +102,11 @@ void OCLMCJITMemoryManager::reserveMemory(uint64_t Size) { } uint8_t *OCLMCJITMemoryManager:: -allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) { +allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID +#if !defined(LEGACY_COMPLIB) + , llvm::StringRef SectionName +#endif + ) { // The recording memory manager is just a local copy of the remote target. // The alignment requirement is just stored here for later use. Regular // heap storage is sufficient here, but we're using mapped memory to work @@ -112,9 +122,11 @@ allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) { } uint8_t *OCLMCJITMemoryManager:: -allocateDataSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID, bool isReasOnly) { - bool IsReadOnly = false; +allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, +#if !defined(LEGACY_COMPLIB) + llvm::StringRef SectionName, +#endif + bool isReadOnly) { // The recording memory manager is just a local copy of the remote target. // The alignment requirement is just stored here for later use. Regular // heap storage is sufficient here, but we're using mapped memory to work @@ -144,7 +156,11 @@ uint8_t * OCLMCJITMemoryManager::reservedAlloc(uintptr_t Size, unsigned Alignmen } llvm::sys::MemoryBlock OCLMCJITMemoryManager::allocateSection(uintptr_t Size) { +#if defined(LEGACY_COMPLIB) llvm::error_code ec; +#else + std::error_code ec; +#endif llvm::sys::MemoryBlock MB = llvm::sys::Memory::allocateMappedMemory(Size, &Near, @@ -162,6 +178,18 @@ llvm::sys::MemoryBlock OCLMCJITMemoryManager::allocateSection(uintptr_t Size) { return MB; } +#if !defined(LEGACY_COMPLIB) +void OCLMCJITMemoryManager::reserveAllocationSpace(uintptr_t CodeSize, + uintptr_t DataSizeRO, + uintptr_t DataSizeRW) { + uint64_t GOTTableReserveSize = 4096; + uint64_t Size = (uint64_t)CodeSize + (uint64_t)DataSizeRO + + (uint64_t)DataSizeRW + GOTTableReserveSize; + if ((uint64_t)allocPtr + (uint64_t)Size > (uint64_t)allocMaxPtr) + reserveMemory(Size); +} +#endif // !LEGACY_COMPLIB + void OCLMCJITMemoryManager::setMemoryWritable() { assert(!"Unexpected"); } @@ -256,7 +284,13 @@ public: output_ = &output; } - virtual void NotifyObjectEmitted(const llvm::ObjectImage &Obj) { + virtual void NotifyObjectEmitted +#if defined(LEGACY_COMPLIB) + (const llvm::ObjectImage &Obj) +#else + (const llvm::object::ObjectFile &Obj, const llvm::RuntimeDyld::LoadedObjectInfo &L) +#endif + override { encodeObjectImage(Obj.getData(), *output_); } @@ -330,12 +364,25 @@ jitCodeGen(llvm::Module* Composite, OclJITEventListener Listener(output); llvm::InitializeNativeTargetAsmParser(); llvm::InitializeNativeTargetAsmPrinter(); - llvm::JITMemoryManager* MemMgr = new OCLMCJITMemoryManager(); + OCLMCJITMemoryManager* MemMgr = new OCLMCJITMemoryManager(); +#if defined(LEGACY_COMPLIB) llvm::EngineBuilder builder(Composite); +#else + // FIXME: this llvm::Module* actually seems to be got from unique_ptr::get() + // somewhere, but acl functions use Module* instead of std::unique_ptr + // llvm::EngineBuilder does std::move on this pointer further so Module* can be + // deleted twice... llvm::EngineBuilder builder(Composite); + std::unique_ptr MPtr(Composite); + llvm::EngineBuilder builder(std::move(MPtr)); +#endif builder.setOptLevel(OLvl); builder.setErrorStr(&ErrStr); +#if defined(LEGACY_COMPLIB) builder.setJITMemoryManager(MemMgr); builder.setUseMCJIT(true); +#else + builder.setMCJITMemoryManager(MemMgr); +#endif // builder.setRelocationModel(llvm::Reloc::PIC_) // builder.setCodeModel(llvm::CodeModel::Large) #ifndef ANDROID @@ -393,14 +440,22 @@ llvmCodeGen( #ifdef __linux__ TheTriple.setOS(Triple::Linux); #else +#if defined(LEGACY_COMPLIB) TheTriple.setOS(Triple::MinGW32); +#else + TheTriple.setOS(Triple::Win32); +#endif #endif } TheTriple.setEnvironment(Triple::AMDOpenCL); // FIXME: need to make AMDOpenCL be the same as ELF if (OptionsObj->oVariables->UseJIT) +#if defined(LEGACY_COMPLIB) TheTriple.setEnvironment(Triple::ELF); +#else + TheTriple.setObjectFormat(Triple::ELF); +#endif mod.setTargetTriple(TheTriple.getTriple()); // Allocate target machine. First, check whether the user has explicitly @@ -560,10 +615,14 @@ llvmCodeGen( PassManager Passes; // Add the target data from the target machine, if it exists, or the module. +#if defined(LEGACY_COMPLIB) if (const DataLayout *TD = Target.getDataLayout()) Passes.add(new DataLayout(*TD)); else Passes.add(new DataLayout(&mod)); +#else + Passes.add(new DataLayoutPass()); +#endif // Override default to generate verbose assembly, if the device is not the GPU. // The GPU sets this in AMDILTargetMachine.cpp. diff --git a/projects/clr/rocclr/compiler/lib/backends/common/codegen.hpp b/projects/clr/rocclr/compiler/lib/backends/common/codegen.hpp index cb17a11251..9528d4f67d 100644 --- a/projects/clr/rocclr/compiler/lib/backends/common/codegen.hpp +++ b/projects/clr/rocclr/compiler/lib/backends/common/codegen.hpp @@ -4,7 +4,11 @@ #ifndef _BE_CODEGEN_HPP_ #define _BE_CODEGEN_HPP_ #include "compiler_stage.hpp" +#if defined(LEGACY_COMPLIB) #include "llvm/ExecutionEngine/JITMemoryManager.h" +#else +#include "llvm/ExecutionEngine/RTDyldMemoryManager.h" +#endif namespace amdcl { @@ -89,7 +93,13 @@ namespace amdcl //!--------------------------------------------------------------------------!// // JIT Memory manager //!--------------------------------------------------------------------------!// -class OCLMCJITMemoryManager : public llvm::JITMemoryManager { +class OCLMCJITMemoryManager : public +#if defined(LEGACY_COMPLIB) + llvm::JITMemoryManager +#else + llvm::RTDyldMemoryManager +#endif +{ public: typedef std::pair Allocation; @@ -121,17 +131,34 @@ public: virtual void reserveMemory(uint64_t size); +#if defined(LEGACY_COMPLIB) uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID); uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, bool isReadOnly); + bool applyPermissions(std::string *ErrMsg) { return false; } + +#else + virtual bool needsToReserveAllocationSpace() override { return true; } + + virtual void reserveAllocationSpace(uintptr_t CodeSize, uintptr_t DataSizeRO, + uintptr_t DataSizeRW) override; + + uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID, llvm::StringRef SectionName) override; + + uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID, llvm::StringRef SectionName, + bool isReadOnly) override; + + bool finalizeMemory(std::string *ErrMsg = nullptr) override { return false; } +#endif + void *getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure = true); - bool applyPermissions(std::string *ErrMsg) { return false; } - // The following obsolete JITMemoryManager calls are stubbed out for // this model. void setMemoryWritable(); diff --git a/projects/clr/rocclr/compiler/lib/backends/common/compiler_stage.cpp b/projects/clr/rocclr/compiler/lib/backends/common/compiler_stage.cpp index 321dae92ba..2585a96b40 100644 --- a/projects/clr/rocclr/compiler/lib/backends/common/compiler_stage.cpp +++ b/projects/clr/rocclr/compiler/lib/backends/common/compiler_stage.cpp @@ -3,8 +3,13 @@ // #include "compiler_stage.hpp" #include "utils/libUtils.h" +#if defined(LEGACY_COMPLIB) #include "llvm/Assembly/Parser.h" #include "llvm/LLVMContext.h" +#else +#include "llvm/AsmParser/Parser.h" +#include "llvm/IR/LLVMContext.h" +#endif using namespace amdcl; @@ -84,9 +89,14 @@ LLVMCompilerStage::loadBitcode(std::string& llvmBinary) reinterpret_cast(llvmBinary.data() + llvmBinary.length()))) { llvm::SMDiagnostic diags; +#if defined(LEGACY_COMPLIB) return ParseAssemblyString(llvmBinary.c_str(), llvmbinary_, diags, Context()); - +#else + llvmbinary_ = llvm::parseAssemblyString(llvmBinary.c_str(), diags, Context()).release(); + return llvmbinary_; +#endif } +#if defined(LEGACY_COMPLIB) // Use getMemBuffer() ? if (llvm::MemoryBuffer *Buffer = llvm::MemoryBuffer::getMemBufferCopy( @@ -97,5 +107,13 @@ LLVMCompilerStage::loadBitcode(std::string& llvmBinary) delete Buffer; return M; } +#else + if (std::unique_ptr Buffer = + llvm::MemoryBuffer::getMemBufferCopy( + llvm::StringRef(llvmBinary), "input.bc")) { + llvm::ErrorOr M = llvm::parseBitcodeFile(Buffer->getMemBufferRef(), Context()); + if( M ) return M.get(); + } +#endif return NULL; } diff --git a/projects/clr/rocclr/compiler/lib/backends/common/frontend_clang.cpp b/projects/clr/rocclr/compiler/lib/backends/common/frontend_clang.cpp index ecbc29646a..08690a4cdd 100644 --- a/projects/clr/rocclr/compiler/lib/backends/common/frontend_clang.cpp +++ b/projects/clr/rocclr/compiler/lib/backends/common/frontend_clang.cpp @@ -106,10 +106,9 @@ int amdcl::ClangOCLFrontend::compileCommand(const std::string& src) { // file itself is not passed to the ClangOCLFE library. It is a passed // as a string for compilation. - llvm::MemoryBuffer *srcBuffer = + std::unique_ptr srcBufferPtr = llvm::MemoryBuffer::getMemBuffer(src, inpCLFileName.c_str(), true); - llvm::OwningPtr srcBufferPtr(srcBuffer); ClangOptions.Src.swap(srcBufferPtr); assert(ClangOptions.Src.get() && "ClangOCLFE: Memory Buffer" " initialization error\n"); diff --git a/projects/clr/rocclr/compiler/lib/backends/common/linker.cpp b/projects/clr/rocclr/compiler/lib/backends/common/linker.cpp index 78429ceb8f..a27cfece89 100644 --- a/projects/clr/rocclr/compiler/lib/backends/common/linker.cpp +++ b/projects/clr/rocclr/compiler/lib/backends/common/linker.cpp @@ -12,14 +12,34 @@ #include "utils/libUtils.h" #include "utils/options.hpp" #include "utils/target_mappings.h" -#include "llvm/LLVMContext.h" #include "acl.h" +#if defined(LEGACY_COMPLIB) #include "llvm/Instructions.h" #include "llvm/Linker.h" +#include "llvm/LLVMContext.h" #include "llvm/GlobalValue.h" #include "llvm/GlobalVariable.h" +#include "llvm/Analysis/Verifier.h" +#include "llvm/Support/CallSite.h" +#include "llvm/Support/system_error.h" +#include "llvm/DataLayout.h" +#include "llvm/ValueSymbolTable.h" +#ifdef _DEBUG +#include "llvm/Assembly/Writer.h" +#endif +#else +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/CallSite.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/GlobalValue.h" +#include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/ValueSymbolTable.h" +#include "llvm/IR/Verifier.h" +#include "llvm/Linker/Linker.h" +#endif #include "llvm/AMDFixupKernelModule.h" #include "llvm/AMDResolveLinker.h" @@ -29,7 +49,6 @@ #include "llvm/Analysis/AMDLocalArrayUsage.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/Passes.h" -#include "llvm/Analysis/Verifier.h" #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/CodeGen/LinkAllAsmWriterComponents.h" @@ -42,7 +61,6 @@ #include "llvm/MC/SubtargetFeature.h" -#include "llvm/Support/CallSite.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/FileUtilities.h" #include "llvm/Support/FormattedStream.h" @@ -53,26 +71,19 @@ #include "llvm/Support/PluginLoader.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Signals.h" -#include "llvm/Support/system_error.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" -#include "llvm/DataLayout.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/Scalar.h" -#include "llvm/ValueSymbolTable.h" #include "llvm/AMDLLVMContextHook.h" #if defined(LEGACY_COMPLIB) #include "llvm/AMDILFuncSupport.h" #endif -#ifdef _DEBUG -#include "llvm/Assembly/Writer.h" -#endif - // need to undef DEBUG before using DEBUG macro in llvm/Support/Debug.h #ifdef DEBUG #undef DEBUG @@ -120,6 +131,7 @@ inline llvm::Module* return 0; } +#if defined(LEGACY_COMPLIB) llvm::Module* M; std::string ErrorMessage; OwningPtr Buffer; @@ -132,8 +144,18 @@ inline llvm::Module* } return M; +#else + ErrorOr> FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename); + if (!FileOrErr) { + llvm::ErrorOr M = llvm::parseBitcodeFile(FileOrErr.get()->getMemBufferRef(), Context); + if (M) return M.get(); + } + + return nullptr; +#endif } +#if defined(LEGACY_COMPLIB) inline llvm::Module* LoadLibrary(const std::string& libFile, LLVMContext& Context, MemoryBuffer** Buffer) { if (!sys::fs::exists(libFile)) { @@ -172,9 +194,11 @@ inline llvm::Module* } return M; } +#endif // Load bitcode libary from an array of const char. This assumes that // the array has a valid ending zero ! +#if defined(LEGACY_COMPLIB) llvm::Module* LoadLibrary(const char* libBC, size_t libBCSize, LLVMContext& Context, MemoryBuffer** Buffer) @@ -192,7 +216,22 @@ llvm::Module* } return M; } +#else +llvm::Module* + LoadLibrary(const char* libBC, size_t libBCSize, + LLVMContext& Context) + { + llvm::ErrorOr M(nullptr); + std::string ErrorMessage; + auto Buffer = MemoryBuffer::getMemBuffer(StringRef(libBC, libBCSize), ""); + if ( Buffer ) { + M = llvm::getLazyBitcodeModule(std::move(Buffer), Context); + if (!M) return nullptr; + } + return *M; + } +#endif static std::set *getAmdRtFunctions() { @@ -300,12 +339,21 @@ amdcl::OCLLinker::linkLLVMModules(std::vector &libs) char buf[128]; sprintf(buf, "_original%d.bc", (int)i); std::string fileName = Options()->getDumpFileName(buf); +#if defined(LEGACY_COMPLIB) llvm::raw_fd_ostream outs(fileName.c_str(), MyErrorInfo, llvm::raw_fd_ostream::F_Binary); if (MyErrorInfo.empty()) llvm::WriteBitcodeToFile(libs[i], outs); else printf(MyErrorInfo.c_str()); +#else + std::error_code EC; + llvm::raw_fd_ostream outs(fileName.c_str(), EC, llvm::sys::fs::F_None); + if (!EC) + llvm::WriteBitcodeToFile(libs[i], outs); + else + printf(EC.message().c_str()); +#endif } } @@ -480,6 +528,7 @@ amdcl::OCLLinker::link(llvm::Module* input, std::vector &libs) } if (Options()->isDumpFlagSet(amd::option::DUMP_BC_ORIGINAL)) { +#if defined(LEGACY_COMPLIB) std::string MyErrorInfo; std::string fileName = Options()->getDumpFileName("_original.bc"); llvm::raw_fd_ostream outs(fileName.c_str(), MyErrorInfo, llvm::raw_fd_ostream::F_Binary); @@ -487,6 +536,15 @@ amdcl::OCLLinker::link(llvm::Module* input, std::vector &libs) WriteBitcodeToFile(LLVMBinary(), outs); else printf(MyErrorInfo.c_str()); +#else + std::string fileName = Options()->getDumpFileName("_original.bc"); + std::error_code EC; + llvm::raw_fd_ostream outs(fileName.c_str(), EC, llvm::sys::fs::F_None); + if (!EC) + WriteBitcodeToFile(LLVMBinary(), outs); + else + printf(EC.message().c_str()); +#endif } std::vector LibMs; @@ -506,8 +564,12 @@ amdcl::OCLLinker::link(llvm::Module* input, std::vector &libs) return 1; } for (int i=0; i < sz; i++) { +#if defined(LEGACY_COMPLIB) llvm::MemoryBuffer* Buffer = 0; llvm::Module* Library = amd::LoadLibrary(LibDescs[i].start, LibDescs[i].size, Context(), &Buffer); +#else + llvm::Module *Library = amd::LoadLibrary(LibDescs[i].start, LibDescs[i].size, Context()); +#endif DEBUG(llvm::dbgs() << "Loaded library " << i << "\n"); if ( !Library ) { BuildLog() += "Internal Error: cannot load library!\n"; @@ -530,7 +592,11 @@ amdcl::OCLLinker::link(llvm::Module* input, std::vector &libs) // Find the first library whose target triple is not empty. if (LibTargetTriple.empty() && !Library->getTargetTriple().empty()) { LibTargetTriple = Library->getTargetTriple(); +#if defined(LEGACY_COMPLIB) LibDataLayout = Library->getDataLayout(); +#else + LibDataLayout = Library->getDataLayoutStr(); +#endif } LibMs.push_back(Library); } @@ -543,8 +609,13 @@ amdcl::OCLLinker::link(llvm::Module* input, std::vector &libs) continue; assert (LibMs[i]->getTargetTriple() == LibTargetTriple && "Library target triple should match"); +#if defined(LEGACY_COMPLIB) assert (LibMs[i]->getDataLayout() == LibDataLayout && "Library data layout should match"); +#else + assert (LibMs[i]->getDataLayoutStr() == LibDataLayout && + "Library data layout should match"); +#endif } #endif @@ -658,12 +729,22 @@ amdcl::OCLLinker::link(llvm::Module* input, std::vector &libs) if (Options()->isDumpFlagSet(amd::option::DUMP_BC_LINKED)) { std::string MyErrorInfo; std::string fileName = Options()->getDumpFileName("_linked.bc"); +#if defined(LEGACY_COMPLIB) llvm::raw_fd_ostream outs(fileName.c_str(), MyErrorInfo, llvm::raw_fd_ostream::F_Binary); // FIXME: Need to add this to the elf binary! if (MyErrorInfo.empty()) WriteBitcodeToFile(LLVMBinary(), outs); else printf(MyErrorInfo.c_str()); +#else + std::error_code EC; + llvm::raw_fd_ostream outs(fileName.c_str(), EC, llvm::sys::fs::F_None); + // FIXME: Need to add this to the elf binary! + if (!EC) + WriteBitcodeToFile(LLVMBinary(), outs); + else + printf(EC.message().c_str()); +#endif } // Check if kernels containing local arrays are called by other kernels. diff --git a/projects/clr/rocclr/compiler/lib/backends/common/opt_level.cpp b/projects/clr/rocclr/compiler/lib/backends/common/opt_level.cpp index 6b30744096..95dd4840d9 100644 --- a/projects/clr/rocclr/compiler/lib/backends/common/opt_level.cpp +++ b/projects/clr/rocclr/compiler/lib/backends/common/opt_level.cpp @@ -9,8 +9,10 @@ #include "utils/target_mappings.h" #include "utils/libUtils.h" #include "llvm/Analysis/Passes.h" +#if defined(LEGACY_COMPLIB) #include "llvm/DataLayout.h" #include "llvm/Module.h" +#endif #include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/LinkAllPasses.h" #include "llvm/Support/TargetRegistry.h" @@ -23,9 +25,17 @@ void OptLevel::setup(bool isGPU, uint32_t OptLevel) { // Add an appropriate DataLayout instance for this module. +#if defined(LEGACY_COMPLIB) Passes().add(new DataLayout(module_)); +#else + Passes().add(new DataLayoutPass()); +#endif fpasses_ = new FunctionPassManager(module_); +#if defined(LEGACY_COMPLIB) fpasses_->add(new DataLayout(module_)); +#else + fpasses_->add(new DataLayoutPass()); +#endif PassManagerBuilder Builder; Builder.OptLevel = OptLevel; @@ -75,8 +85,10 @@ OptLevel::setup(bool isGPU, uint32_t OptLevel) Builder.SizeLevel = 0; Builder.DisableUnitAtATime = false; Builder.DisableUnrollLoops = OptLevel == 0; +#if defined(LEGACY_COMPLIB) if (Options()->libraryType_ != amd::GPU_Library_HSAIL) Builder.DisableSimplifyLibCalls = true; +#endif Builder.AMDpopulateFunctionPassManager(*fpasses_, &module_->getContext()); Builder.AMDpopulateModulePassManager(passes_, &module_->getContext(), module_); } @@ -136,9 +148,8 @@ OptLevel::run(aclBinary *elf) } } std::unique_ptr TM(Machine); -// This is for llvm 3.6 -// if (TM.get()) -// TM->addAnalysisPasses(passes_); + if (TM.get()) + TM->addAnalysisPasses(passes_); #endif if (Options()->oVariables->OptPrintLiveness) { diff --git a/projects/clr/rocclr/compiler/lib/backends/common/optimizer.cpp b/projects/clr/rocclr/compiler/lib/backends/common/optimizer.cpp index 42cb9c52ed..3acaa32484 100644 --- a/projects/clr/rocclr/compiler/lib/backends/common/optimizer.cpp +++ b/projects/clr/rocclr/compiler/lib/backends/common/optimizer.cpp @@ -9,7 +9,12 @@ #include "utils/libUtils.h" #include "utils/options.hpp" +#if defined(LEGACY_COMPLIB) #include "llvm/DataLayout.h" +#else +#include "llvm/IR/DataLayout.h" +#include "llvm/Support/FileSystem.h" +#endif #include "llvm/Analysis/Passes.h" #include "llvm/Support/raw_ostream.h" #include "llvm/LinkAllPasses.h" @@ -42,7 +47,11 @@ int CPUOptimizer::preOptimizer(llvm::Module* M) { llvm::PassManager Passes; +#if defined(LEGACY_COMPLIB) Passes.add(new llvm::DataLayout(M)); +#else + Passes.add(new llvm::DataLayoutPass()); +#endif Passes.add(createAMDExportKernelNaturePass()); @@ -87,14 +96,24 @@ CPUOptimizer::optimize(llvm::Module *input) return 1; } if (Options()->isDumpFlagSet(amd::option::DUMP_BC_OPTIMIZED)) { - std::string MyErrorInfo; std::string fileName = Options()->getDumpFileName("_optimized.bc"); +#if defined(LEGACY_COMPLIB) + std::string MyErrorInfo; raw_fd_ostream outs (fileName.c_str(), MyErrorInfo, raw_fd_ostream::F_Binary); // FIXME: Need to add this to the elf binary! if (MyErrorInfo.empty()) WriteBitcodeToFile(LLVMBinary(), outs); else printf(MyErrorInfo.c_str()); +#else + std::error_code EC; + llvm::raw_fd_ostream outs(fileName.c_str(), EC, llvm::sys::fs::F_None); + // FIXME: Need to add this to the elf binary! + if (!EC) + WriteBitcodeToFile(LLVMBinary(), outs); + else + printf(EC.message().c_str()); +#endif } return ret; } @@ -139,14 +158,24 @@ GPUOptimizer::optimize(llvm::Module *input) return 1; } if (Options()->isDumpFlagSet(amd::option::DUMP_BC_OPTIMIZED)) { - std::string MyErrorInfo; std::string fileName = Options()->getDumpFileName("_optimized.bc"); +#if defined(LEGACY_COMPLIB) + std::string MyErrorInfo; raw_fd_ostream outs (fileName.c_str(), MyErrorInfo, raw_fd_ostream::F_Binary); // FIXME: Need to add this to the elf binary! if (MyErrorInfo.empty()) WriteBitcodeToFile(LLVMBinary(), outs); else printf(MyErrorInfo.c_str()); +#else + std::error_code EC; + llvm::raw_fd_ostream outs(fileName.c_str(), EC, llvm::sys::fs::F_None); + // FIXME: Need to add this to the elf binary! + if (!EC) + WriteBitcodeToFile(LLVMBinary(), outs); + else + printf(EC.message().c_str()); +#endif } return ret; } diff --git a/projects/clr/rocclr/compiler/lib/backends/common/spir.cpp b/projects/clr/rocclr/compiler/lib/backends/common/spir.cpp index 1ac9dbc231..216f9b683e 100644 --- a/projects/clr/rocclr/compiler/lib/backends/common/spir.cpp +++ b/projects/clr/rocclr/compiler/lib/backends/common/spir.cpp @@ -16,19 +16,29 @@ #include #include +#if defined(LEGACY_COMPLIB) #include "llvm/DataLayout.h" #include "llvm/Module.h" +#include "llvm/Analysis/Verifier.h" +#include "llvm/Assembly/PrintModulePass.h" +#else +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Verifier.h" +#endif #include "llvm/Pass.h" #include "llvm/PassManager.h" #include "llvm/ADT/SmallString.h" -#include "llvm/Analysis/Verifier.h" #include "llvm/Analysis/SPIRVerifier.h" -#include "llvm/Assembly/PrintModulePass.h" #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/Bitcode/BitstreamWriter.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Scalar.h" +#if defined(LEGACY_COMPLIB) +#define LLVMReturnStatusAction ReturnStatusAction +#endif + using namespace llvm; using namespace amdcl; @@ -47,7 +57,12 @@ amdcl::SPIR::loadSPIR(std::string &spirBinary) log_ += errors; return NULL; } +#if defined(LEGACY_COMPLIB) verifyModule(*bc, ReturnStatusAction, &errors); +#else + raw_string_ostream errorsOS(errors); + verifyModule(*bc, &errorsOS); +#endif if (!errors.empty()) { log_ += errors; errors.clear(); @@ -55,7 +70,7 @@ amdcl::SPIR::loadSPIR(std::string &spirBinary) FunctionPassManager FPM(bc); if (Options()->oVariables->verifyHWSpir) { if (!isHSAILTarget(Elf()->target)) { - verifySPIRModule(*bc, ReturnStatusAction, State, false, &errors); + verifySPIRModule(*bc, LLVMReturnStatusAction, State, false, &errors); } if (!errors.empty()) { log_ += errors; @@ -66,7 +81,7 @@ amdcl::SPIR::loadSPIR(std::string &spirBinary) } if (Options()->oVariables->verifyLWSpir) { if (!isHSAILTarget(Elf()->target)) { - verifySPIRModule(*bc, ReturnStatusAction, State, true, &errors); + verifySPIRModule(*bc, LLVMReturnStatusAction, State, true, &errors); } if (!errors.empty()) { log_ += errors; @@ -92,7 +107,11 @@ amdcl::SPIR::loadBitcode(std::string &binary) bc->setTargetTriple(familySet[Elf()->target.arch_id].triple); llvm::PassManager SPIRPasses; +#if defined(LEGACY_COMPLIB) SPIRPasses.add(new llvm::DataLayout(bc)); +#else + SPIRPasses.add(new llvm::DataLayoutPass()); +#endif SPIRPasses.add(createSPIRLoader(/*demangleBuiltin=*/ true)); SPIRPasses.run(*bc); return bc; diff --git a/projects/clr/rocclr/compiler/lib/backends/common/v0_8/if_acl.cpp b/projects/clr/rocclr/compiler/lib/backends/common/v0_8/if_acl.cpp index f0459d82a6..b910ad34c6 100644 --- a/projects/clr/rocclr/compiler/lib/backends/common/v0_8/if_acl.cpp +++ b/projects/clr/rocclr/compiler/lib/backends/common/v0_8/if_acl.cpp @@ -33,18 +33,25 @@ #include "utils/versions.hpp" #include "sync.hpp" -#include "llvm/LLVMContext.h" #include "llvm/Analysis/Passes.h" #if defined(LEGACY_COMPLIB) #include "Disassembler.h" +#include "llvm/LLVMContext.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/Support/IRReader.h" #include "llvm/Support/raw_ostream.h" #include "llvm/ADT/OwningPtr.h" +#include "llvm/ExecutionEngine/ObjectImage.h" +#include "llvm/ExecutionEngine/ObjectBuffer.h" +#else +#include "llvm/ADT/DenseMap.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/Object/ObjectFile.h" #endif #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/Support/CommandLine.h" @@ -58,11 +65,8 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Bitcode/BitstreamWriter.h" #include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/Support/IRReader.h" #include "llvm/Transforms/Scalar.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" -#include "llvm/ExecutionEngine/ObjectImage.h" -#include "llvm/ExecutionEngine/ObjectBuffer.h" #include "llvm/ExecutionEngine/JITEventListener.h" #include "llvm/ExecutionEngine/RuntimeDyld.h" #include @@ -84,7 +88,11 @@ if_aclCompilerInit(aclCompiler *cl, aclBinary *bin, llvm::TimePassesIsEnabled = false; if (cl->llvm_shutdown == NULL) { cl->llvm_shutdown = reinterpret_cast - (new llvm::llvm_shutdown_obj(false)); + (new llvm::llvm_shutdown_obj( +#if defined(LEGACY_COMPLIB) + false +#endif + )); } // Initialize targets first. llvm::InitializeAllTargets(); @@ -103,9 +111,11 @@ if_aclCompilerInit(aclCompiler *cl, aclBinary *bin, llvm::initializeIPA(Registry); llvm::initializeCodeGen(Registry); llvm::initializeTarget(Registry); +#if defined(LEGACY_COMPLIB) llvm::initializeVerifierPass(Registry); llvm::initializeDominatorTreePass(Registry); llvm::initializePreVerifierPass(Registry); +#endif amdcl::release_global_lock(); if (error) (*error) = ACL_SUCCESS; return reinterpret_cast(cl); @@ -285,21 +295,37 @@ RSLLVMIRToModule( std::string llvmBinary(source, data_size); std::string ErrorMessage; llvm::LLVMContext * Context = reinterpret_cast(ctx); +#if defined(LEGACY_COMPLIB) llvm::MemoryBuffer *Buffer = llvm::MemoryBuffer::getMemBufferCopy( llvm::StringRef(llvmBinary), "input.bc"); llvm::Module *M = NULL; +#else + std::unique_ptr Buffer = + llvm::MemoryBuffer::getMemBufferCopy(llvm::StringRef(llvmBinary), "input.bc"); + llvm::ErrorOr ErrOrM(nullptr); +#endif if (llvm::isBitcode((const unsigned char *)Buffer->getBufferStart(), (const unsigned char *)Buffer->getBufferEnd())) { +#if defined(LEGACY_COMPLIB) M = llvm::ParseBitcodeFile(Buffer, *Context, &ErrorMessage); +#else + ErrOrM = llvm::parseBitcodeFile(Buffer->getMemBufferRef(), *Context); +#endif } +#if defined(LEGACY_COMPLIB) if (M == NULL) { +#else + if (!ErrOrM || ErrOrM.get() == nullptr) { +#endif if (error != NULL) (*error) = ACL_INVALID_BINARY; return NULL; } - +#if !defined(LEGACY_COMPLIB) + llvm::Module *M = ErrOrM.get(); +#endif amdcl::CompilerStage *cs = reinterpret_cast(ald); aclDevType arch_id = cs->Elf()->target.arch_id; if ((arch_id != aclAMDIL) && (arch_id != aclHSAIL)) { @@ -1322,15 +1348,22 @@ if_aclCompile(aclCompiler *cl, if (isHSAILTarget(bin->target)) { #ifndef DEBUG // Do not install signal handlers for the pretty stack trace. - llvm::DisablePrettyStackTrace = true; +#if defined(LEGACY_COMPLIB) + llvm::DisablePrettyStackTrace = true; +#endif #else +#if !defined(LEGACY_COMPLIB) + llvm::EnablePrettyStackTrace(); +#endif llvm::sys::PrintStackTraceOnErrorSignal(); #endif } else #endif { llvm::InitializeAllAsmParsers(); +#if defined(LEGACY_COMPLIB) llvm::DisablePrettyStackTrace = true; +#endif llvm::PassRegistry &Registry = *llvm::PassRegistry::getPassRegistry(); llvm::initializeSPIRVerifierPass(Registry); } @@ -2923,6 +2956,7 @@ if_aclDbgRemoveArgument(aclCompiler *cl, return error_code; } +#if defined(LEGACY_COMPLIB) static OCLMCJITMemoryManager* memMgr = NULL; OCLMCJITMemoryManager* createJITMemoryManager() { @@ -2931,11 +2965,42 @@ OCLMCJITMemoryManager* createJITMemoryManager() { } return memMgr; } +#else +typedef llvm::DenseMap MemMgrTableT; +typedef llvm::DenseMap DyLdTableT; +static MemMgrTableT MemMgrTable; +static DyLdTableT DyLdTable; + +static llvm::RuntimeDyld* GetOrCreateDyld(llvm::object::ObjectFile* obj) { + DyLdTableT::iterator DI = DyLdTable.find(obj); + if (DI != DyLdTable.end()) + return DI->second; + OCLMCJITMemoryManager *memMgr = new OCLMCJITMemoryManager(); + MemMgrTable.insert(std::make_pair(obj, memMgr)); + llvm::RuntimeDyld *rtdyld = new llvm::RuntimeDyld(memMgr); + DyLdTable.insert(std::make_pair(obj, rtdyld)); + return rtdyld; +} + +static void ReleaseDyld(llvm::object::ObjectFile* obj) { + DyLdTableT::iterator DI = DyLdTable.find(obj); + if (DI != DyLdTable.end()) { + delete DI->second; + DyLdTable.erase(DI); + } + MemMgrTableT::iterator MI = MemMgrTable.find(obj); + if (MI != MemMgrTable.end()) { + delete MI->second; + MemMgrTable.erase(MI); + } +} +#endif aclJITObjectImage ACL_API_ENTRY if_aclJITObjectImageCreate(const void* buffer, size_t length, aclBinary* bin, acl_error* error_code) { llvm::StringRef dataString((const char*)buffer, length); +#if defined(LEGACY_COMPLIB) llvm::MemoryBuffer* memBuf = llvm::MemoryBuffer::getMemBufferCopy(dataString); llvm::ObjectBuffer* objBuf = new llvm::ObjectBuffer(memBuf); llvm::RuntimeDyld rtdyld(createJITMemoryManager()); @@ -2951,21 +3016,59 @@ if_aclJITObjectImageCreate(const void* buffer, size_t length, out.close(); } return objectImage; +#else + std::unique_ptr memBuf = llvm::MemoryBuffer::getMemBufferCopy(dataString); + llvm::ErrorOr> objBuf = + llvm::object::ObjectFile::createObjectFile(memBuf->getMemBufferRef()); + llvm::RuntimeDyld *rtdyld = GetOrCreateDyld(objBuf->get()); + + auto objectImage = rtdyld->loadObject(*(objBuf.get())); + rtdyld->resolveRelocations(); + + amd::option::Options* options = (amd::option::Options*)bin->options; + if (options->isDumpFlagSet(amd::option::DUMP_O)) { + llvm::StringRef finalData = objBuf.get()->getData(); + std::string finalDataString = finalData.str(); + std::string objname = options->getDumpFileName(".elf"); + std::ofstream out(objname.c_str(), + (std::fstream::binary | std::fstream::trunc)); + out << finalDataString; + out.close(); + } + + memBuf.release(); + llvm::object::ObjectFile* result = objBuf.get().release(); + + return result; +#endif } aclJITObjectImage ACL_API_ENTRY if_aclJITObjectImageCopy(const void* buffer, size_t length, acl_error* error_code) { llvm::StringRef dataString((const char*)buffer, length); +#if defined(LEGACY_COMPLIB) llvm::MemoryBuffer* memBuf = llvm::MemoryBuffer::getMemBufferCopy(dataString); llvm::ObjectBuffer* objBuf = new llvm::ObjectBuffer(memBuf); llvm::RuntimeDyld rtdyld(createJITMemoryManager()); llvm::ObjectImage* objectImage = rtdyld.loadObject(objBuf); rtdyld.resolveRelocations(); return objectImage; +#else + std::unique_ptr memBuf = llvm::MemoryBuffer::getMemBufferCopy(dataString); + auto objBuf = llvm::object::ObjectFile::createObjectFile(memBuf->getMemBufferRef()); + llvm::RuntimeDyld *rtdyld = GetOrCreateDyld(objBuf->get()); + auto objectImage = rtdyld->loadObject(*(objBuf.get())); + rtdyld->resolveRelocations(); + memBuf.release(); + llvm::object::ObjectFile* result = objBuf.get().release(); + + return result; +#endif } acl_error ACL_API_ENTRY if_aclJITObjectImageDestroy(aclJITObjectImage image) { +#if defined(LEGACY_COMPLIB) llvm::ObjectImage* objectImage(reinterpret_cast(image)); llvm::object::section_iterator end = objectImage->end_sections(); llvm::error_code err; @@ -2976,29 +3079,41 @@ if_aclJITObjectImageDestroy(aclJITObjectImage image) { sectionRef.getAddress(address); memMgr->deallocateSection((uint8_t*)address); } +#else + llvm::object::ObjectFile* objectImage(reinterpret_cast(image)); + ReleaseDyld(objectImage); +#endif delete objectImage; return ACL_SUCCESS; } size_t ACL_API_ENTRY if_aclJITObjectImageSize(aclJITObjectImage image, acl_error* error_code) { +#if defined(LEGACY_COMPLIB) return (reinterpret_cast(image))->getData().size(); +#else + return (reinterpret_cast(image))->getData().size(); +#endif } const char* ACL_API_ENTRY if_aclJITObjectImageData(aclJITObjectImage image, acl_error* error_code) { +#if defined(LEGACY_COMPLIB) return (reinterpret_cast(image))->getData().data(); +#else + return (reinterpret_cast(image))->getData().data(); +#endif } acl_error ACL_API_ENTRY if_aclJITObjectImageFinalize(aclJITObjectImage image) { - // TODO: Implement return ACL_SUCCESS; } size_t ACL_API_ENTRY if_aclJITObjectImageGetGlobalsSize(aclJITObjectImage image, acl_error* error_code) { size_t totalSize = 0; +#if defined(LEGACY_COMPLIB) llvm::ObjectImage* objectImage(reinterpret_cast(image)); llvm::object::section_iterator end = objectImage->end_sections(); llvm::error_code err; @@ -3017,12 +3132,22 @@ if_aclJITObjectImageGetGlobalsSize(aclJITObjectImage image, acl_error* error_cod totalSize += (size_t)size; } } +#else + llvm::object::ObjectFile* objectImage(reinterpret_cast(image)); + for (auto iter: objectImage->sections()) { + uint64_t size = iter.getSize(); + if ((iter.isBSS() || iter.isData()) && !iter.isText()) { + totalSize += (size_t)iter.getSize(); + } + } +#endif return totalSize; } acl_error ACL_API_ENTRY if_aclJITObjectImageIterateSymbols(aclJITObjectImage image, JITSymbolCallback jit_callback, void* data) { +#if defined(LEGACY_COMPLIB) llvm::ObjectImage* objectImage(reinterpret_cast(image)); llvm::object::symbol_iterator end = objectImage->end_symbols(); llvm::StringRef name; @@ -3035,6 +3160,19 @@ if_aclJITObjectImageIterateSymbols(aclJITObjectImage image, symRef.getAddress(address); jit_callback(name.str().c_str(), (const void*)address, data); } +#else + llvm::object::ObjectFile* objectImage = reinterpret_cast(image); + llvm::RuntimeDyld *rtdyld = GetOrCreateDyld(objectImage); + std::error_code err; + llvm::StringRef name; + for (const llvm::object::SymbolRef &S: objectImage->symbols()) { + std::error_code err = S.getName(name); + assert (!err); + uint64_t address; + address = (uint64_t) rtdyld->getSymbolLoadAddress(name); + jit_callback(name.data(), (const void*)address, data); + } +#endif return ACL_SUCCESS; }