<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Mar 23, 2016 at 8:36 AM, Davide Italiano <span dir="ltr"><<a href="mailto:davide@freebsd.org" target="_blank">davide@freebsd.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span>On Tue, Mar 22, 2016 at 1:52 PM, Rui Ueyama via llvm-commits<br>
<<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:<br>
> Author: ruiu<br>
> Date: Tue Mar 22 15:52:10 2016<br>
> New Revision: 264091<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=264091&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=264091&view=rev</a><br>
> Log:<br>
> ELF: Create LTO.{cpp,h} and move LTO-related code to that file.<br>
><br>
> The code for LTO has been growing, so now is probably a good time to<br>
> move it to its own file. SymbolTable.cpp is for symbol table, and<br>
> because compiling bitcode files are semantically not a part of<br>
> symbol table, this is I think a good thing to do.<br>
><br>
<br>
</span>Sorry for noticing this late, but I realized you renamed codegen -> compile.<br>
Is there any particular reason? I prefer the old one. If you have<br>
other suggestions, I'm happy to hear.<br></blockquote><div><br></div><div>I just though that compile is more preferable since it's a plain English word (at least than codegen.) It's not a strong preference or anything, but is codegen a good name for a function? (I mean would you say "I codegen this and this" for example?)</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
--<br>
Davide<br>
<div><div><br>
> <a href="http://reviews.llvm.org/D18370" rel="noreferrer" target="_blank">http://reviews.llvm.org/D18370</a><br>
><br>
> Added:<br>
> lld/trunk/ELF/LTO.cpp<br>
> lld/trunk/ELF/LTO.h<br>
> Modified:<br>
> lld/trunk/ELF/CMakeLists.txt<br>
> lld/trunk/ELF/SymbolTable.cpp<br>
> lld/trunk/ELF/SymbolTable.h<br>
><br>
> Modified: lld/trunk/ELF/CMakeLists.txt<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/CMakeLists.txt?rev=264091&r1=264090&r2=264091&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/CMakeLists.txt?rev=264091&r1=264090&r2=264091&view=diff</a><br>
> ==============================================================================<br>
> --- lld/trunk/ELF/CMakeLists.txt (original)<br>
> +++ lld/trunk/ELF/CMakeLists.txt Tue Mar 22 15:52:10 2016<br>
> @@ -9,6 +9,7 @@ add_lld_library(lldELF<br>
> ICF.cpp<br>
> InputFiles.cpp<br>
> InputSection.cpp<br>
> + LTO.cpp<br>
> LinkerScript.cpp<br>
> MarkLive.cpp<br>
> OutputSections.cpp<br>
><br>
> Added: lld/trunk/ELF/LTO.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LTO.cpp?rev=264091&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LTO.cpp?rev=264091&view=auto</a><br>
> ==============================================================================<br>
> --- lld/trunk/ELF/LTO.cpp (added)<br>
> +++ lld/trunk/ELF/LTO.cpp Tue Mar 22 15:52:10 2016<br>
> @@ -0,0 +1,140 @@<br>
> +//===- LTO.cpp ------------------------------------------------------------===//<br>
> +//<br>
> +// The LLVM Linker<br>
> +//<br>
> +// This file is distributed under the University of Illinois Open Source<br>
> +// License. See LICENSE.TXT for details.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +<br>
> +#include "LTO.h"<br>
> +#include "Config.h"<br>
> +#include "Error.h"<br>
> +#include "InputFiles.h"<br>
> +#include "Symbols.h"<br>
> +#include "llvm/Analysis/TargetLibraryInfo.h"<br>
> +#include "llvm/Analysis/TargetTransformInfo.h"<br>
> +#include "llvm/Bitcode/ReaderWriter.h"<br>
> +#include "llvm/IR/LegacyPassManager.h"<br>
> +#include "llvm/Linker/IRMover.h"<br>
> +#include "llvm/Support/StringSaver.h"<br>
> +#include "llvm/Support/TargetRegistry.h"<br>
> +#include "llvm/Target/TargetMachine.h"<br>
> +#include "llvm/Transforms/IPO.h"<br>
> +#include "llvm/Transforms/IPO/PassManagerBuilder.h"<br>
> +<br>
> +using namespace llvm;<br>
> +using namespace llvm::object;<br>
> +using namespace llvm::ELF;<br>
> +<br>
> +using namespace lld;<br>
> +using namespace lld::elf;<br>
> +<br>
> +// This is for use when debugging LTO.<br>
> +static void saveLtoObjectFile(StringRef Buffer) {<br>
> + std::error_code EC;<br>
> + raw_fd_ostream OS(Config->OutputFile.str() + ".lto.o", EC,<br>
> + sys::fs::OpenFlags::F_None);<br>
> + check(EC);<br>
> + OS << Buffer;<br>
> +}<br>
> +<br>
> +// This is for use when debugging LTO.<br>
> +static void saveBCFile(Module &M, StringRef Suffix) {<br>
> + std::error_code EC;<br>
> + raw_fd_ostream OS(Config->OutputFile.str() + Suffix.str(), EC,<br>
> + sys::fs::OpenFlags::F_None);<br>
> + check(EC);<br>
> + WriteBitcodeToFile(&M, OS, /* ShouldPreserveUseListOrder */ true);<br>
> +}<br>
> +<br>
> +// Run LTO passes.<br>
> +// FIXME: Reduce code duplication by sharing this code with the gold plugin.<br>
> +static void runLTOPasses(Module &M, TargetMachine &TM) {<br>
> + legacy::PassManager LtoPasses;<br>
> + LtoPasses.add(createTargetTransformInfoWrapperPass(TM.getTargetIRAnalysis()));<br>
> + PassManagerBuilder PMB;<br>
> + PMB.LibraryInfo = new TargetLibraryInfoImpl(Triple(TM.getTargetTriple()));<br>
> + PMB.Inliner = createFunctionInliningPass();<br>
> + PMB.VerifyInput = true;<br>
> + PMB.VerifyOutput = true;<br>
> + PMB.LoopVectorize = true;<br>
> + PMB.SLPVectorize = true;<br>
> + PMB.OptLevel = 2; // FIXME: This should be an option.<br>
> + PMB.populateLTOPassManager(LtoPasses);<br>
> + LtoPasses.run(M);<br>
> +<br>
> + if (Config->SaveTemps)<br>
> + saveBCFile(M, ".lto.opt.bc");<br>
> +}<br>
> +<br>
> +void BitcodeCompiler::add(BitcodeFile &F) {<br>
> + std::unique_ptr<IRObjectFile> Obj =<br>
> + check(IRObjectFile::create(F.MB, Context));<br>
> + std::vector<GlobalValue *> Keep;<br>
> + unsigned BodyIndex = 0;<br>
> + ArrayRef<SymbolBody *> Bodies = F.getSymbols();<br>
> +<br>
> + for (const BasicSymbolRef &Sym : Obj->symbols()) {<br>
> + GlobalValue *GV = Obj->getSymbolGV(Sym.getRawDataRefImpl());<br>
> + assert(GV);<br>
> + if (GV->hasAppendingLinkage()) {<br>
> + Keep.push_back(GV);<br>
> + continue;<br>
> + }<br>
> + if (!BitcodeFile::shouldSkip(Sym))<br>
> + if (SymbolBody *B = Bodies[BodyIndex++])<br>
> + if (&B->repl() == B && isa<DefinedBitcode>(B))<br>
> + Keep.push_back(GV);<br>
> + }<br>
> +<br>
> + Mover.move(Obj->takeModule(), Keep,<br>
> + [](GlobalValue &, IRMover::ValueAdder) {});<br>
> +}<br>
> +<br>
> +// Merge all the bitcode files we have seen, codegen the result<br>
> +// and return the resulting ObjectFile.<br>
> +template <class ELFT><br>
> +std::unique_ptr<elf::ObjectFile<ELFT>> BitcodeCompiler::compile() {<br>
> + if (Config->SaveTemps)<br>
> + saveBCFile(Combined, ".lto.bc");<br>
> +<br>
> + StringRef TripleStr = Combined.getTargetTriple();<br>
> + Triple TheTriple(TripleStr);<br>
> +<br>
> + // FIXME: Should we have a default triple? The gold plugin uses<br>
> + // sys::getDefaultTargetTriple(), but that is probably wrong given that this<br>
> + // might be a cross linker.<br>
> +<br>
> + std::string ErrMsg;<br>
> + const Target *TheTarget = TargetRegistry::lookupTarget(TripleStr, ErrMsg);<br>
> + if (!TheTarget)<br>
> + fatal("target not found: " + ErrMsg);<br>
> +<br>
> + TargetOptions Options;<br>
> + Reloc::Model R = Config->Pic ? Reloc::PIC_ : Reloc::Static;<br>
> + std::unique_ptr<TargetMachine> TM(<br>
> + TheTarget->createTargetMachine(TripleStr, "", "", Options, R));<br>
> +<br>
> + runLTOPasses(Combined, *TM);<br>
> +<br>
> + raw_svector_ostream OS(OwningData);<br>
> + legacy::PassManager CodeGenPasses;<br>
> + if (TM->addPassesToEmitFile(CodeGenPasses, OS,<br>
> + TargetMachine::CGFT_ObjectFile))<br>
> + fatal("failed to setup codegen");<br>
> + CodeGenPasses.run(Combined);<br>
> + MB = MemoryBuffer::getMemBuffer(OwningData,<br>
> + "LLD-INTERNAL-combined-lto-object", false);<br>
> + if (Config->SaveTemps)<br>
> + saveLtoObjectFile(MB->getBuffer());<br>
> +<br>
> + std::unique_ptr<InputFile> IF = createObjectFile(*MB);<br>
> + auto *OF = cast<ObjectFile<ELFT>>(IF.release());<br>
> + return std::unique_ptr<ObjectFile<ELFT>>(OF);<br>
> +}<br>
> +<br>
> +template std::unique_ptr<elf::ObjectFile<ELF32LE>> BitcodeCompiler::compile();<br>
> +template std::unique_ptr<elf::ObjectFile<ELF32BE>> BitcodeCompiler::compile();<br>
> +template std::unique_ptr<elf::ObjectFile<ELF64LE>> BitcodeCompiler::compile();<br>
> +template std::unique_ptr<elf::ObjectFile<ELF64BE>> BitcodeCompiler::compile();<br>
><br>
> Added: lld/trunk/ELF/LTO.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LTO.h?rev=264091&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LTO.h?rev=264091&view=auto</a><br>
> ==============================================================================<br>
> --- lld/trunk/ELF/LTO.h (added)<br>
> +++ lld/trunk/ELF/LTO.h Tue Mar 22 15:52:10 2016<br>
> @@ -0,0 +1,51 @@<br>
> +//===- LTO.h ----------------------------------------------------*- C++ -*-===//<br>
> +//<br>
> +// The LLVM Linker<br>
> +//<br>
> +// This file is distributed under the University of Illinois Open Source<br>
> +// License. See LICENSE.TXT for details.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +//<br>
> +// This file provides a way to combine bitcode files into one ELF<br>
> +// file by compiling them using LLVM.<br>
> +//<br>
> +// If LTO is in use, your input files are not in regular ELF files<br>
> +// but instead LLVM bitcode files. In that case, the linker has to<br>
> +// convert bitcode files into the native format so that we can create<br>
> +// an ELF file that contains native code. This file provides that<br>
> +// functionality.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +<br>
> +#ifndef LLD_ELF_LTO_H<br>
> +#define LLD_ELF_LTO_H<br>
> +<br>
> +#include "lld/Core/LLVM.h"<br>
> +#include "llvm/ADT/SmallString.h"<br>
> +#include "llvm/IR/LLVMContext.h"<br>
> +#include "llvm/IR/Module.h"<br>
> +#include "llvm/Linker/IRMover.h"<br>
> +<br>
> +namespace lld {<br>
> +namespace elf {<br>
> +<br>
> +class BitcodeFile;<br>
> +template <class ELFT> class ObjectFile;<br>
> +<br>
> +class BitcodeCompiler {<br>
> +public:<br>
> + void add(BitcodeFile &F);<br>
> + template <class ELFT> std::unique_ptr<ObjectFile<ELFT>> compile();<br>
> +<br>
> +private:<br>
> + llvm::LLVMContext Context;<br>
> + llvm::Module Combined{"ld-temp.o", Context};<br>
> + llvm::IRMover Mover{Combined};<br>
> + SmallString<0> OwningData;<br>
> + std::unique_ptr<MemoryBuffer> MB;<br>
> +};<br>
> +}<br>
> +}<br>
> +<br>
> +#endif<br>
><br>
> Modified: lld/trunk/ELF/SymbolTable.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=264091&r1=264090&r2=264091&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=264091&r1=264090&r2=264091&view=diff</a><br>
> ==============================================================================<br>
> --- lld/trunk/ELF/SymbolTable.cpp (original)<br>
> +++ lld/trunk/ELF/SymbolTable.cpp Tue Mar 22 15:52:10 2016<br>
> @@ -18,16 +18,8 @@<br>
> #include "Config.h"<br>
> #include "Error.h"<br>
> #include "Symbols.h"<br>
> -#include "llvm/Analysis/TargetLibraryInfo.h"<br>
> -#include "llvm/Analysis/TargetTransformInfo.h"<br>
> #include "llvm/Bitcode/ReaderWriter.h"<br>
> -#include "llvm/IR/LegacyPassManager.h"<br>
> -#include "llvm/Linker/IRMover.h"<br>
> #include "llvm/Support/StringSaver.h"<br>
> -#include "llvm/Support/TargetRegistry.h"<br>
> -#include "llvm/Target/TargetMachine.h"<br>
> -#include "llvm/Transforms/IPO.h"<br>
> -#include "llvm/Transforms/IPO/PassManagerBuilder.h"<br>
><br>
> using namespace llvm;<br>
> using namespace llvm::object;<br>
> @@ -101,131 +93,17 @@ void SymbolTable<ELFT>::addFile(std::uni<br>
> resolve(B);<br>
> }<br>
><br>
> -// This is for use when debugging LTO.<br>
> -static void saveLtoObjectFile(StringRef Buffer) {<br>
> - std::error_code EC;<br>
> - raw_fd_ostream OS(Config->OutputFile.str() + ".lto.o", EC,<br>
> - sys::fs::OpenFlags::F_None);<br>
> - check(EC);<br>
> - OS << Buffer;<br>
> -}<br>
> -<br>
> -// This is for use when debugging LTO.<br>
> -static void saveBCFile(Module &M, StringRef Suffix) {<br>
> - std::error_code EC;<br>
> - raw_fd_ostream OS(Config->OutputFile.str() + Suffix.str(), EC,<br>
> - sys::fs::OpenFlags::F_None);<br>
> - check(EC);<br>
> - WriteBitcodeToFile(&M, OS, /* ShouldPreserveUseListOrder */ true);<br>
> -}<br>
> -<br>
> -static void runLTOPasses(Module &M, TargetMachine &TM) {<br>
> - // Run LTO passes.<br>
> - // FIXME: Reduce code duplication by sharing this code with the gold plugin.<br>
> - legacy::PassManager LtoPasses;<br>
> - LtoPasses.add(<br>
> - createTargetTransformInfoWrapperPass(TM.getTargetIRAnalysis()));<br>
> - PassManagerBuilder PMB;<br>
> - PMB.LibraryInfo = new TargetLibraryInfoImpl(Triple(TM.getTargetTriple()));<br>
> - PMB.Inliner = createFunctionInliningPass();<br>
> - PMB.VerifyInput = true;<br>
> - PMB.VerifyOutput = true;<br>
> - PMB.LoopVectorize = true;<br>
> - PMB.SLPVectorize = true;<br>
> - PMB.OptLevel = 2; // FIXME: This should be an option.<br>
> - PMB.populateLTOPassManager(LtoPasses);<br>
> - LtoPasses.run(M);<br>
> -<br>
> - if (Config->SaveTemps)<br>
> - saveBCFile(M, ".lto.opt.bc");<br>
> -}<br>
> -<br>
> -// Codegen the module M and returns the resulting InputFile.<br>
> -template <class ELFT><br>
> -std::unique_ptr<InputFile> SymbolTable<ELFT>::codegen(Module &M) {<br>
> - StringRef TripleStr = M.getTargetTriple();<br>
> - Triple TheTriple(TripleStr);<br>
> -<br>
> - // FIXME: Should we have a default triple? The gold plugin uses<br>
> - // sys::getDefaultTargetTriple(), but that is probably wrong given that this<br>
> - // might be a cross linker.<br>
> -<br>
> - std::string ErrMsg;<br>
> - const Target *TheTarget = TargetRegistry::lookupTarget(TripleStr, ErrMsg);<br>
> - if (!TheTarget)<br>
> - fatal("target not found: " + ErrMsg);<br>
> -<br>
> - TargetOptions Options;<br>
> - Reloc::Model R = Config->Pic ? Reloc::PIC_ : Reloc::Static;<br>
> - std::unique_ptr<TargetMachine> TM(<br>
> - TheTarget->createTargetMachine(TripleStr, "", "", Options, R));<br>
> -<br>
> - runLTOPasses(M, *TM);<br>
> -<br>
> - raw_svector_ostream OS(OwningLTOData);<br>
> - legacy::PassManager CodeGenPasses;<br>
> - if (TM->addPassesToEmitFile(CodeGenPasses, OS,<br>
> - TargetMachine::CGFT_ObjectFile))<br>
> - fatal("failed to setup codegen");<br>
> - CodeGenPasses.run(M);<br>
> - LtoBuffer = MemoryBuffer::getMemBuffer(<br>
> - OwningLTOData, "LLD-INTERNAL-combined-lto-object", false);<br>
> - if (Config->SaveTemps)<br>
> - saveLtoObjectFile(LtoBuffer->getBuffer());<br>
> - return createObjectFile(*LtoBuffer);<br>
> -}<br>
> -<br>
> -static void addBitcodeFile(IRMover &Mover, BitcodeFile &F,<br>
> - LLVMContext &Context) {<br>
> -<br>
> - std::unique_ptr<IRObjectFile> Obj =<br>
> - check(IRObjectFile::create(F.MB, Context));<br>
> - std::vector<GlobalValue *> Keep;<br>
> - unsigned BodyIndex = 0;<br>
> - ArrayRef<SymbolBody *> Bodies = F.getSymbols();<br>
> -<br>
> - for (const BasicSymbolRef &Sym : Obj->symbols()) {<br>
> - GlobalValue *GV = Obj->getSymbolGV(Sym.getRawDataRefImpl());<br>
> - assert(GV);<br>
> - if (GV->hasAppendingLinkage()) {<br>
> - Keep.push_back(GV);<br>
> - continue;<br>
> - }<br>
> - if (BitcodeFile::shouldSkip(Sym))<br>
> - continue;<br>
> - SymbolBody *B = Bodies[BodyIndex++];<br>
> - if (!B || &B->repl() != B)<br>
> - continue;<br>
> - auto *DB = dyn_cast<DefinedBitcode>(B);<br>
> - if (!DB)<br>
> - continue;<br>
> - Keep.push_back(GV);<br>
> - }<br>
> -<br>
> - Mover.move(Obj->takeModule(), Keep,<br>
> - [](GlobalValue &, IRMover::ValueAdder) {});<br>
> -}<br>
> -<br>
> -// Merge all the bitcode files we have seen, codegen the result and return<br>
> -// the resulting ObjectFile.<br>
> -template <class ELFT><br>
> -elf::ObjectFile<ELFT> *SymbolTable<ELFT>::createCombinedLtoObject() {<br>
> - LLVMContext Context;<br>
> - Module Combined("ld-temp.o", Context);<br>
> - IRMover Mover(Combined);<br>
> - for (const std::unique_ptr<BitcodeFile> &F : BitcodeFiles)<br>
> - addBitcodeFile(Mover, *F, Context);<br>
> - if (Config->SaveTemps)<br>
> - saveBCFile(Combined, ".lto.bc");<br>
> - std::unique_ptr<InputFile> F = codegen(Combined);<br>
> - ObjectFiles.emplace_back(cast<ObjectFile<ELFT>>(F.release()));<br>
> - return &*ObjectFiles.back();<br>
> -}<br>
> -<br>
> template <class ELFT> void SymbolTable<ELFT>::addCombinedLtoObject() {<br>
> if (BitcodeFiles.empty())<br>
> return;<br>
> - ObjectFile<ELFT> *Obj = createCombinedLtoObject();<br>
> +<br>
> + // Compile bitcode files.<br>
> + Lto.reset(new BitcodeCompiler);<br>
> + for (const std::unique_ptr<BitcodeFile> &F : BitcodeFiles)<br>
> + Lto->add(*F);<br>
> + std::unique_ptr<ObjectFile<ELFT>> Obj = Lto->compile<ELFT>();<br>
> +<br>
> + // Replace bitcode symbols.<br>
> llvm::DenseSet<StringRef> DummyGroups;<br>
> Obj->parse(DummyGroups);<br>
> for (SymbolBody *Body : Obj->getNonLocalSymbols()) {<br>
> @@ -234,6 +112,7 @@ template <class ELFT> void SymbolTable<E<br>
> continue;<br>
> Sym->Body = Body;<br>
> }<br>
> + ObjectFiles.push_back(std::move(Obj));<br>
> }<br>
><br>
> // Add an undefined symbol.<br>
><br>
> Modified: lld/trunk/ELF/SymbolTable.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=264091&r1=264090&r2=264091&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=264091&r1=264090&r2=264091&view=diff</a><br>
> ==============================================================================<br>
> --- lld/trunk/ELF/SymbolTable.h (original)<br>
> +++ lld/trunk/ELF/SymbolTable.h Tue Mar 22 15:52:10 2016<br>
> @@ -11,6 +11,7 @@<br>
> #define LLD_ELF_SYMBOL_TABLE_H<br>
><br>
> #include "InputFiles.h"<br>
> +#include "LTO.h"<br>
> #include "llvm/ADT/MapVector.h"<br>
><br>
> namespace llvm {<br>
> @@ -74,8 +75,6 @@ private:<br>
> std::unique_ptr<InputFile> codegen(llvm::Module &M);<br>
> std::string conflictMsg(SymbolBody *Old, SymbolBody *New);<br>
><br>
> - SmallString<0> OwningLTOData;<br>
> - std::unique_ptr<MemoryBuffer> LtoBuffer;<br>
> ObjectFile<ELFT> *createCombinedLtoObject();<br>
><br>
> // The order the global symbols are in is not defined. We can use an arbitrary<br>
> @@ -101,6 +100,8 @@ private:<br>
><br>
> // Set of .so files to not link the same shared object file more than once.<br>
> llvm::DenseSet<StringRef> SoNames;<br>
> +<br>
> + std::unique_ptr<BitcodeCompiler> Lto;<br>
> };<br>
><br>
> } // namespace elf<br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
<br>
</div></div><span><font color="#888888">--<br>
Davide<br>
<br>
"There are no solved problems; there are only problems that are more<br>
or less solved" -- Henri Poincare<br>
</font></span></blockquote></div><br></div></div>