From e7964ae3ebbe92acb62f87a5c263f6d8de298087 Mon Sep 17 00:00:00 2001 From: foreman Date: Thu, 28 Aug 2014 01:17:39 -0400 Subject: [PATCH] P4 to Git Change 1070977 by ssahasra@ssahasra_opencl_windows on 2014/08/28 01:10:11 ECR #333753 - unify online/offline linkers The code for "FixUpModule" from the online linker is now moved to a common file under llvm/lib. This replaces the copy present in llvm/tools/llvm-link, thus unifying the two linkers. Reviewed by Stanislav Mekhanoshin, Yaxun Liu (Sam) Passes smoke, smoke_clang and precheckin. Also passes OpenCL 2.0 conformance tests. Affected files ... ... //depot/stg/opencl/drivers/opencl/compiler/lib/backends/common/linker.cpp#109 edit ... //depot/stg/opencl/drivers/opencl/compiler/llvm/include/llvm/AMDFixupKernelModule.h#1 add ... //depot/stg/opencl/drivers/opencl/compiler/llvm/include/llvm/AMDUtils.h#1 add ... //depot/stg/opencl/drivers/opencl/compiler/llvm/lib/Linker/AMDFixupKernelModule.cpp#1 add ... //depot/stg/opencl/drivers/opencl/compiler/llvm/lib/Transforms/Utils/AMDUtils.cpp#1 add ... //depot/stg/opencl/drivers/opencl/compiler/llvm/tools/llvm-link/AMDFixUpModule.cpp#12 delete ... //depot/stg/opencl/drivers/opencl/compiler/llvm/tools/llvm-link/llvm-link.cpp#48 edit [ROCm/clr commit: 7f55691ebc863d94b0c686e9ce6031247c77c80e] --- .../compiler/lib/backends/common/linker.cpp | 233 +----------------- 1 file changed, 7 insertions(+), 226 deletions(-) diff --git a/projects/clr/rocclr/compiler/lib/backends/common/linker.cpp b/projects/clr/rocclr/compiler/lib/backends/common/linker.cpp index 47e90ad82a..894af82335 100644 --- a/projects/clr/rocclr/compiler/lib/backends/common/linker.cpp +++ b/projects/clr/rocclr/compiler/lib/backends/common/linker.cpp @@ -20,8 +20,10 @@ #include "llvm/GlobalValue.h" #include "llvm/GlobalVariable.h" +#include "llvm/AMDFixupKernelModule.h" #include "llvm/AMDResolveLinker.h" #include "llvm/AMDPrelinkOpt.h" +#include "llvm/AMDUtils.h" #include "llvm/ADT/Triple.h" #include "llvm/ADT/StringMap.h" #include "llvm/Analysis/AMDLocalArrayUsage.h" @@ -695,144 +697,6 @@ void amdcl::OCLLinker::fixupOldTriple(llvm::Module *module) } } -static unsigned getSPIRVersion(const llvm::Module *M) { - const llvm::NamedMDNode *SPIRVersion - = M->getNamedMetadata("opencl.spir.version"); - - if (!SPIRVersion) return 0; // not SPIR - - // When multiple llvm modules are linked together to create a single module - // Metadata's of llvm modules are added into destination module and - // it results in a more than one SPIR MDNode value. - // Marking this fix as temporary and it will be tracked in bugzilla id 9775 - // FIXME: Uncomment the line below - // assert(SPIRVersion->getNumOperands() == 1); - assert(SPIRVersion->getNumOperands() > 0); - if (SPIRVersion->getNumOperands() > 1) { - DEBUG_WITH_TYPE("linkTriple", - llvm::dbgs() << "[CheckSPIRVersion] " - "Too many arguments to SPIR version MDNode\n"); - } - - const llvm::MDNode *VersionMD = SPIRVersion->getOperand(0); - assert(VersionMD->getNumOperands() == 2); - - const llvm::ConstantInt *CMajor - = llvm::cast(VersionMD->getOperand(0)); - assert(CMajor->getType()->getIntegerBitWidth() == 32); - unsigned VersionMajor = CMajor->getZExtValue(); - - const llvm::ConstantInt *CMinor - = llvm::cast(VersionMD->getOperand(1)); - assert(CMinor->getType()->getIntegerBitWidth() == 32); - unsigned VersionMinor = CMinor->getZExtValue(); - - return (VersionMajor * 100) + (VersionMinor * 10); -} - -//Modify module for targets before linking. -//Report error by buildLog. -//Return false on error. -static bool fixUpModule(llvm::Module *M, - llvm::StringRef TargetTriple, - llvm::StringRef TargetLayout, - bool RunSPIRLoader, - bool DemangleBuiltins, - bool RunEDGAdapter, - bool SetSPIRCallingConv, - bool RunX86Adpater) { - llvm::PassManager Passes; - - DEBUG_WITH_TYPE("linkTriple", llvm::dbgs() << - "[fixUpModule] module triple: " << M->getTargetTriple() << - " target triple: " << TargetTriple); - llvm::Triple triple(M->getTargetTriple()); -#if OPENCL_MAJOR < 2 - if (triple.getArch() == llvm::Triple::spir || - triple.getArch() == llvm::Triple::spir64 || - triple.getArch() == llvm::Triple::x86 || - triple.getArch() == llvm::Triple::x86_64 || - M->getTargetTriple().empty()) -#endif - { - M->setTargetTriple(TargetTriple); - M->setDataLayout(TargetLayout); - } -#if OPENCL_MAJOR < 2 - if (M->getTargetTriple() != TargetTriple) { - //ToDo: There is bug 9996 in compiler library about converting BIF30 to BIF21 - //which causes regressions in ocltst if the following check is enabled. - //Fix the bugs then enable the following check - #if 0 - llvm::dbgs() << "Internal Error: Inconsistent module and library target\n"; - return false; - #else - llvm::dbgs() << "WARNING: Inconsistent module and library target\n"; - return true; - #endif - } -#endif - - Passes.add(new llvm::DataLayout(M)); - - Passes.add(llvm::createAMDLowerAtomicsPass()); - - if (getSPIRVersion(M) >= 200) { - Passes.add(llvm::createAMDPrintfRuntimeBinding()); - Passes.add(llvm::createAMDLowerPipeBuiltinsPass()); - Passes.add(llvm::createAMDLowerEnqueueKernelPass()); - Passes.add(llvm::createAMDGenerateDevEnqMetadataPass()); - } - - if (RunEDGAdapter) { - assert(!RunSPIRLoader); - Passes.add(llvm::createAMDEDGToIA64TranslatorPass(SetSPIRCallingConv)); - } - - if (RunSPIRLoader) { - assert(!RunEDGAdapter); - Passes.add(llvm::createSPIRLoader(DemangleBuiltins)); - } - - if (RunX86Adpater) { - // One of them should run before the AMDX86Adapter Pass. - assert(RunSPIRLoader || RunEDGAdapter); - Passes.add(llvm::createAMDX86AdapterPass()); - } - - Passes.run(*M); - return true; -} - -static bool isSPIRTriple(const llvm::Triple &Triple) { - return Triple.getArch() == llvm::Triple::spir - || Triple.getArch() == llvm::Triple::spir64; -} - -static bool isAMDILTriple(const llvm::Triple &Triple) { - return Triple.getArch() == llvm::Triple::amdil - || Triple.getArch() == llvm::Triple::amdil64; -} - -static bool isX86Triple(const llvm::Triple &Triple) { - return Triple.getArch() == llvm::Triple::x86 - || Triple.getArch() == llvm::Triple::x86_64; -} - -static bool isHSAILTriple(const llvm::Triple &Triple) { - return Triple.getArch() == llvm::Triple::hsail - || Triple.getArch() == llvm::Triple::hsail_64; -} - -static void CheckSPIRVersionForTarget(const llvm::Module *M, - const llvm::Triple &TargetTriple) { - unsigned SPIRVersion = getSPIRVersion(M); - if (SPIRVersion >= 200) - assert(!isAMDILTriple(TargetTriple)); - else - assert(SPIRVersion == 120); -} - // On 64 bit device, aclBinary target is set to 64 bit by default. When 32 bit // LLVM or SPIR binary is loaded, aclBinary target needs to be modified to // match LLVM or SPIR bitness. @@ -918,7 +782,7 @@ checkAndFixAclBinaryTarget(llvm::Module* module, aclBinary* elf, #endif } - int +int amdcl::OCLLinker::link(llvm::Module* input, std::vector &libs) { bool IsGPUTarget = isGpuTarget(Elf()->target); @@ -1037,96 +901,13 @@ amdcl::OCLLinker::link(llvm::Module* input, std::vector &libs) #endif - // Under various situations, the LLVM dialect used in the kernel - // module does not match the dialect used in the builtin library. We - // need to fix-up the kernel module to eliminate this mismatch. - // - // SPIRLoader is required to consume a SPIR kernel: - // SPIR 1.2 on all targets. - // SPIR 2.0 on x86 and HSAIL only. - // - // The AMDIL libary is compiled by EDG, and hence it does not use - // the SPIR mangling scheme. To allow a SPIR 1.2 kernel to link with - // this library, the SPIRLoader must fix the mangling in the kernel. - // - // EDGAdapter is required to consume a non-SPIR (EDG) kernel on x86 - // and HSAIL targets. The builtins library for these targets are - // built by Clang, but OpenCL 1.2 kernels are compiled by EDG. - // - // A non-SPIR kernel module is not expected on the HSAIL target in a - // normal OpenCL 2.0 build. We should actually flag an error if this - // occurs, but we let it through to facilitate custom builds created - // to test this combination. In this situation, the EDGAdapter must - // additionally set the calling conventions correctly, because the - // HSAIL library is in SPIR format. - // - // RunX86Adpater is required to run only on the CPU path. It is - // expected to the solve the link issues between the user kernel - // (SPIR/EDG) vs. Clang compiled x86 builtins library. + if (!llvm::fixupKernelModule(LLVMBinary(), LibTargetTriple, LibDataLayout)) + return 1; - // Enabled for: - bool RunSPIRLoader = false; // SPIR -> x86/HSAIL/AMDIL - bool DemangleBuiltins = false; // SPIR -> AMDIL - bool RunEDGAdapter = false; // EDG -> x86/HSAIL - bool SetSPIRCallingConv = false; // EDG -> HSAIL - bool RunX86Adapter = false; // SPIR/EDG -> x86 - bool LowerToPreciseFunctions = false; - - llvm::Triple ModuleTriple(LLVMBinary()->getTargetTriple()); - llvm::Triple TargetTriple(LibTargetTriple); - - - if (isSPIRTriple(ModuleTriple)) { - CheckSPIRVersionForTarget(LLVMBinary(), TargetTriple); - RunSPIRLoader = true; -#if OPENCL_MAJOR >= 2 // this will become default - DemangleBuiltins |= isAMDILTriple(TargetTriple); -#ifdef BUILD_HSA_TARGET // special case for HSA build - DemangleBuiltins |= isHSAILTriple(TargetTriple); -#endif - // Never demangle for x86 target on 200 build. -#else // OpenCL 1.2 build (this will go away) - DemangleBuiltins = true; -#endif - } else { -#if OPENCL_MAJOR >= 2 - // Decide if we need to adapt the non-SPIR (EDG) kernel module. - // - // FIXME: Remove the #ifdef when x86 and HSAIL libraries are - // always built by Clang. -#ifndef BUILD_HSA_TARGET - // Run the adapter for HSAIL, only if this is an ORCA build! - // - // On an HSA build, the HSAIL library is always built with EDG. - // This assumption must match the settings in - // "opencl/library/hsa/hsail/build/Makefile.hsail" - RunEDGAdapter |= isHSAILTriple(TargetTriple); -#endif - // HSAIL requires SPIR calling conventions since the library is in - // SPIR format. This doesn't matter if the EDGAdapter is not run. - SetSPIRCallingConv = isHSAILTriple(TargetTriple); - - // Run the EDG Adapter if OPENCL_MAJOR >= 2 and for x86 target. - RunEDGAdapter |= isX86Triple(TargetTriple); -#endif // OPENCL_MAJOR >= 2 - } - -// X86Adapter should run for both EDG generated LLVM IR and SPIR for x86 path. -// FIXME: Remove the #ifdef when x86 is always built by Clang on -// OpenCL 1.2 builds. -#if OPENCL_MAJOR >=2 - RunX86Adapter = isX86Triple(TargetTriple); // For HSAIL targets, when the option -cl-fp32-correctly-rounded-divide-sqrt // lower divide and sqrt functions to precise HSAIL builtin library functions. - LowerToPreciseFunctions = (isHSAILTriple(TargetTriple) - && Options()->oVariables->FP32RoundDivideSqrt); -#endif - - if (!fixUpModule(LLVMBinary(), LibTargetTriple, LibDataLayout, - RunSPIRLoader, DemangleBuiltins, - RunEDGAdapter, SetSPIRCallingConv, - RunX86Adapter)) - return 1; + bool LowerToPreciseFunctions = (isHSAILTriple(llvm::Triple(LibTargetTriple)) && + Options()->oVariables->FP32RoundDivideSqrt); // Before doing anything else, quickly optimize Module if (Options()->oVariables->OptLevel) {