Index: docs/LangRef.rst =================================================================== --- docs/LangRef.rst +++ docs/LangRef.rst @@ -2064,6 +2064,25 @@ code for the proper architecture. It's possible to override this on the command line with the ``-mtriple`` command line option. +.. _target_devices_triples: + +Devices Triples +--------------- +A module may specify comma-separated list of triples that describes the +OpenMP offloading targets to be supported. The list of triples is denoted +as devices triple, whose syntax is simply: + +.. code-block:: llvm + + target device_triples = "x86_64-mic,i386-pc-linux-gnu" + +The *devices triples* string consists of a series of substrings separated by +','. Each substring which consists of a series of identifiers joined by the +minus sign character ('-'), is in the same format of the *target triple*. + +This information is passed along to the backend so that it generates +code for the proper architecture. + .. _pointeraliasing: Pointer Aliasing Rules Index: include/llvm/Bitcode/LLVMBitCodes.h =================================================================== --- include/llvm/Bitcode/LLVMBitCodes.h +++ include/llvm/Bitcode/LLVMBitCodes.h @@ -118,6 +118,9 @@ // IFUNC: [ifunc value type, addrspace, resolver val#, linkage, visibility] MODULE_CODE_IFUNC = 18, + + // TRIPLE: [strchr x N, ..., strchr x N] + MODULE_CODE_DEVICES = 19, }; /// PARAMATTR blocks have code for defining a parameter attribute set. Index: include/llvm/IR/Module.h =================================================================== --- include/llvm/IR/Module.h +++ include/llvm/IR/Module.h @@ -187,6 +187,8 @@ void *NamedMDSymTab; ///< NamedMDNode names. DataLayout DL; ///< DataLayout associated with the module + std::string TargetDevices; ///< Target devices + friend class Constant; /// @} @@ -232,6 +234,10 @@ /// @returns a string containing the target triple. const std::string &getTargetTriple() const { return TargetTriple; } + /// Get the target device information which is a comma-separated string + /// describing one or more devices. + const std::string &getTargetDevices() const { return TargetDevices; } + /// Get the global data context. /// @returns LLVMContext - a container for LLVM's global information LLVMContext &getContext() const { return Context; } @@ -268,6 +274,9 @@ /// Set the target triple. void setTargetTriple(StringRef T) { TargetTriple = T; } + /// set the target device information. + void setTargetDevices(StringRef T) { TargetDevices = T; } + /// Set the module-scope inline assembly blocks. /// A trailing newline is added if the input doesn't have one. void setModuleInlineAsm(StringRef Asm) { Index: lib/AsmParser/LLLexer.cpp =================================================================== --- lib/AsmParser/LLLexer.cpp +++ lib/AsmParser/LLLexer.cpp @@ -533,6 +533,7 @@ KEYWORD(notail); KEYWORD(target); KEYWORD(triple); + KEYWORD(device_triples); KEYWORD(source_filename); KEYWORD(unwind); KEYWORD(deplibs); // FIXME: Remove in 4.0. Index: lib/AsmParser/LLParser.cpp =================================================================== --- lib/AsmParser/LLParser.cpp +++ lib/AsmParser/LLParser.cpp @@ -322,6 +322,13 @@ return true; M->setTargetTriple(Str); return false; + case lltok::kw_device_triples: + Lex.Lex(); + if (ParseToken(lltok::equal, "expected '=' after target devices") || + ParseStringConstant(Str)) + return true; + M->setTargetDevices(Str); + return false; case lltok::kw_datalayout: Lex.Lex(); if (ParseToken(lltok::equal, "expected '=' after target datalayout") || Index: lib/AsmParser/LLToken.h =================================================================== --- lib/AsmParser/LLToken.h +++ lib/AsmParser/LLToken.h @@ -84,6 +84,7 @@ kw_notail, kw_target, kw_triple, + kw_device_triples, kw_source_filename, kw_unwind, kw_deplibs, // FIXME: Remove in 4.0 Index: lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- lib/Bitcode/Reader/BitcodeReader.cpp +++ lib/Bitcode/Reader/BitcodeReader.cpp @@ -3257,6 +3257,13 @@ TheModule->setTargetTriple(S); break; } + case bitc::MODULE_CODE_DEVICES: { // TRIPLE: [strchr x N, ..., strchr x N] + std::string S; + if (convertToString(Record, 0, S)) + return error("Invalid record"); + TheModule->setTargetDevices(S); + break; + } case bitc::MODULE_CODE_DATALAYOUT: { // DATALAYOUT: [strchr x N] std::string S; if (convertToString(Record, 0, S)) Index: lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- lib/Bitcode/Writer/BitcodeWriter.cpp +++ lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1108,6 +1108,9 @@ if (!M.getTargetTriple().empty()) writeStringRecord(Stream, bitc::MODULE_CODE_TRIPLE, M.getTargetTriple(), 0 /*TODO*/); + if (!M.getTargetDevices().empty()) + writeStringRecord(Stream, bitc::MODULE_CODE_DEVICES, M.getTargetDevices(), + 0 /*TODO*/); const std::string &DL = M.getDataLayoutStr(); if (!DL.empty()) writeStringRecord(Stream, bitc::MODULE_CODE_DATALAYOUT, DL, 0 /*TODO*/); Index: lib/IR/AsmWriter.cpp =================================================================== --- lib/IR/AsmWriter.cpp +++ lib/IR/AsmWriter.cpp @@ -2392,6 +2392,9 @@ if (!M->getTargetTriple().empty()) Out << "target triple = \"" << M->getTargetTriple() << "\"\n"; + if (!M->getTargetDevices().empty()) + Out << "target device_triples = \"" << M->getTargetDevices() << "\"\n"; + if (!M->getModuleInlineAsm().empty()) { Out << '\n'; Index: lib/Transforms/Utils/CloneModule.cpp =================================================================== --- lib/Transforms/Utils/CloneModule.cpp +++ lib/Transforms/Utils/CloneModule.cpp @@ -53,6 +53,7 @@ New->setSourceFileName(M.getSourceFileName()); New->setDataLayout(M.getDataLayout()); New->setTargetTriple(M.getTargetTriple()); + New->setTargetDevices(M.getTargetDevices()); New->setModuleInlineAsm(M.getModuleInlineAsm()); // Loop over all of the global variables, making corresponding globals in the @@ -110,7 +111,7 @@ GA->copyAttributesFrom(&*I); VMap[&*I] = GA; } - + // Now that all of the things that global variable initializer can refer to // have been created, loop through and copy the global variable referrers // over... We also set the attributes on the global now.