diff options
Diffstat (limited to 'utils')
-rw-r--r-- | utils/FileCheck/CMakeLists.txt | 2 | ||||
-rw-r--r-- | utils/FileUpdate/CMakeLists.txt | 2 | ||||
-rw-r--r-- | utils/KillTheDoctor/CMakeLists.txt | 2 | ||||
-rw-r--r-- | utils/TableGen/AsmWriterEmitter.cpp | 249 | ||||
-rw-r--r-- | utils/TableGen/AsmWriterEmitter.h | 1 | ||||
-rw-r--r-- | utils/TableGen/CMakeLists.txt | 2 | ||||
-rw-r--r-- | utils/TableGen/ClangSACheckersEmitter.cpp | 1 | ||||
-rw-r--r-- | utils/TableGen/X86RecognizableInstr.cpp | 4 | ||||
-rw-r--r-- | utils/buildit/GNUmakefile | 6 | ||||
-rwxr-xr-x | utils/buildit/build_llvm | 8 | ||||
-rw-r--r-- | utils/count/CMakeLists.txt | 2 | ||||
-rwxr-xr-x | utils/llvmbuild | 740 | ||||
-rw-r--r-- | utils/not/CMakeLists.txt | 2 | ||||
-rw-r--r-- | utils/valgrind/i386-pc-linux-gnu.supp | 8 |
14 files changed, 1015 insertions, 14 deletions
diff --git a/utils/FileCheck/CMakeLists.txt b/utils/FileCheck/CMakeLists.txt index 54db453..fa56f92 100644 --- a/utils/FileCheck/CMakeLists.txt +++ b/utils/FileCheck/CMakeLists.txt @@ -1,4 +1,4 @@ -add_executable(FileCheck +add_llvm_utility(FileCheck FileCheck.cpp ) diff --git a/utils/FileUpdate/CMakeLists.txt b/utils/FileUpdate/CMakeLists.txt index 5dda49e..655aaec 100644 --- a/utils/FileUpdate/CMakeLists.txt +++ b/utils/FileUpdate/CMakeLists.txt @@ -1,4 +1,4 @@ -add_executable(FileUpdate +add_llvm_utility(FileUpdate FileUpdate.cpp ) diff --git a/utils/KillTheDoctor/CMakeLists.txt b/utils/KillTheDoctor/CMakeLists.txt index 99c671e..37c2b7c 100644 --- a/utils/KillTheDoctor/CMakeLists.txt +++ b/utils/KillTheDoctor/CMakeLists.txt @@ -1,4 +1,4 @@ -add_executable(KillTheDoctor +add_llvm_utility(KillTheDoctor KillTheDoctor.cpp ) diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp index 448ebad..cd31e0c 100644 --- a/utils/TableGen/AsmWriterEmitter.cpp +++ b/utils/TableGen/AsmWriterEmitter.cpp @@ -542,7 +542,255 @@ void AsmWriterEmitter::EmitGetInstructionName(raw_ostream &O) { << "}\n\n#endif\n"; } +void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + CodeGenTarget Target(Records); + Record *AsmWriter = Target.getAsmWriter(); + + O << "\n#ifdef PRINT_ALIAS_INSTR\n"; + O << "#undef PRINT_ALIAS_INSTR\n\n"; + + // Enumerate the register classes. + const std::vector<CodeGenRegisterClass> &RegisterClasses = + Target.getRegisterClasses(); + + O << "namespace { // Register classes\n"; + O << " enum RegClass {\n"; + + // Emit the register enum value for each RegisterClass. + for (unsigned I = 0, E = RegisterClasses.size(); I != E; ++I) { + if (I != 0) O << ",\n"; + O << " RC_" << RegisterClasses[I].TheDef->getName(); + } + + O << "\n };\n"; + O << "} // end anonymous namespace\n\n"; + + // Emit a function that returns 'true' if a regsiter is part of a particular + // register class. I.e., RAX is part of GR64 on X86. + O << "static bool regIsInRegisterClass" + << "(unsigned RegClass, unsigned Reg) {\n"; + + // Emit the switch that checks if a register belongs to a particular register + // class. + O << " switch (RegClass) {\n"; + O << " default: break;\n"; + + for (unsigned I = 0, E = RegisterClasses.size(); I != E; ++I) { + const CodeGenRegisterClass &RC = RegisterClasses[I]; + + // Give the register class a legal C name if it's anonymous. + std::string Name = RC.TheDef->getName(); + O << " case RC_" << Name << ":\n"; + + // Emit the register list now. + unsigned IE = RC.Elements.size(); + if (IE == 1) { + O << " if (Reg == " << getQualifiedName(RC.Elements[0]) << ")\n"; + O << " return true;\n"; + } else { + O << " switch (Reg) {\n"; + O << " default: break;\n"; + + for (unsigned II = 0; II != IE; ++II) { + Record *Reg = RC.Elements[II]; + O << " case " << getQualifiedName(Reg) << ":\n"; + } + + O << " return true;\n"; + O << " }\n"; + } + + O << " break;\n"; + } + + O << " }\n\n"; + O << " return false;\n"; + O << "}\n\n"; + + // Emit the method that prints the alias instruction. + std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); + bool isMC = AsmWriter->getValueAsBit("isMCAsmWriter"); + const char *MachineInstrClassName = isMC ? "MCInst" : "MachineInstr"; + + O << "bool " << Target.getName() << ClassName + << "::printAliasInstr(const " << MachineInstrClassName + << " *MI, raw_ostream &OS) {\n"; + + std::vector<Record*> AllInstAliases = + Records.getAllDerivedDefinitions("InstAlias"); + + // Create a map from the qualified name to a list of potential matches. + std::map<std::string, std::vector<CodeGenInstAlias*> > AliasMap; + for (std::vector<Record*>::iterator + I = AllInstAliases.begin(), E = AllInstAliases.end(); I != E; ++I) { + CodeGenInstAlias *Alias = new CodeGenInstAlias(*I, Target); + const Record *R = *I; + const DagInit *DI = R->getValueAsDag("ResultInst"); + const DefInit *Op = dynamic_cast<const DefInit*>(DI->getOperator()); + AliasMap[getQualifiedName(Op->getDef())].push_back(Alias); + } + + if (AliasMap.empty() || !isMC) { + // FIXME: Support MachineInstr InstAliases? + O << " return true;\n"; + O << "}\n\n"; + O << "#endif // PRINT_ALIAS_INSTR\n"; + return; + } + + O << " StringRef AsmString;\n"; + O << " std::map<StringRef, unsigned> OpMap;\n"; + O << " switch (MI->getOpcode()) {\n"; + O << " default: return true;\n"; + + for (std::map<std::string, std::vector<CodeGenInstAlias*> >::iterator + I = AliasMap.begin(), E = AliasMap.end(); I != E; ++I) { + std::vector<CodeGenInstAlias*> &Aliases = I->second; + + std::map<std::string, unsigned> CondCount; + std::map<std::string, std::string> BodyMap; + + std::string AsmString = ""; + + for (std::vector<CodeGenInstAlias*>::iterator + II = Aliases.begin(), IE = Aliases.end(); II != IE; ++II) { + const CodeGenInstAlias *CGA = *II; + AsmString = CGA->AsmString; + unsigned Indent = 8; + unsigned LastOpNo = CGA->ResultInstOperandIndex.size(); + + std::string Cond; + raw_string_ostream CondO(Cond); + + CondO << "if (MI->getNumOperands() == " << LastOpNo; + + std::map<StringRef, unsigned> OpMap; + bool CantHandle = false; + + for (unsigned i = 0, e = LastOpNo; i != e; ++i) { + const CodeGenInstAlias::ResultOperand &RO = CGA->ResultOperands[i]; + + switch (RO.Kind) { + default: assert(0 && "unexpected InstAlias operand kind"); + case CodeGenInstAlias::ResultOperand::K_Record: { + const Record *Rec = RO.getRecord(); + StringRef ROName = RO.getName(); + + if (Rec->isSubClassOf("RegisterClass")) { + CondO << " &&\n"; + CondO.indent(Indent) << "MI->getOperand(" << i << ").isReg() &&\n"; + if (OpMap.find(ROName) == OpMap.end()) { + OpMap[ROName] = i; + CondO.indent(Indent) + << "regIsInRegisterClass(RC_" + << CGA->ResultOperands[i].getRecord()->getName() + << ", MI->getOperand(" << i << ").getReg())"; + } else { + CondO.indent(Indent) + << "MI->getOperand(" << i + << ").getReg() == MI->getOperand(" + << OpMap[ROName] << ").getReg()"; + } + } else { + assert(Rec->isSubClassOf("Operand") && "Unexpected operand!"); + // FIXME: We need to handle these situations. + CantHandle = true; + break; + } + + break; + } + case CodeGenInstAlias::ResultOperand::K_Imm: + CondO << " &&\n"; + CondO.indent(Indent) << "MI->getOperand(" << i << ").getImm() == "; + CondO << CGA->ResultOperands[i].getImm(); + break; + case CodeGenInstAlias::ResultOperand::K_Reg: + CondO << " &&\n"; + CondO.indent(Indent) << "MI->getOperand(" << i << ").getReg() == "; + CondO << Target.getName() << "::" + << CGA->ResultOperands[i].getRegister()->getName(); + break; + } + + if (CantHandle) break; + } + + if (CantHandle) continue; + + CondO << ")"; + + std::string Body; + raw_string_ostream BodyO(Body); + + BodyO << " // " << CGA->Result->getAsString() << "\n"; + BodyO << " AsmString = \"" << AsmString << "\";\n"; + + for (std::map<StringRef, unsigned>::iterator + III = OpMap.begin(), IIE = OpMap.end(); III != IIE; ++III) + BodyO << " OpMap[\"" << III->first << "\"] = " + << III->second << ";\n"; + + ++CondCount[CondO.str()]; + BodyMap[CondO.str()] = BodyO.str(); + } + + std::string Code; + raw_string_ostream CodeO(Code); + + bool EmitElse = false; + for (std::map<std::string, unsigned>::iterator + II = CondCount.begin(), IE = CondCount.end(); II != IE; ++II) { + if (II->second != 1) continue; + CodeO << " "; + if (EmitElse) CodeO << "} else "; + CodeO << II->first << " {\n"; + CodeO << BodyMap[II->first]; + EmitElse = true; + } + + if (CodeO.str().empty()) continue; + + O << " case " << I->first << ":\n"; + O << CodeO.str(); + O << " }\n"; + O << " break;\n"; + } + + O << " }\n\n"; + + // Code that prints the alias, replacing the operands with the ones from the + // MCInst. + O << " if (AsmString.empty()) return true;\n"; + O << " std::pair<StringRef, StringRef> ASM = AsmString.split(' ');\n"; + O << " OS << '\\t' << ASM.first;\n"; + + O << " if (!ASM.second.empty()) {\n"; + O << " OS << '\\t';\n"; + O << " for (StringRef::iterator\n"; + O << " I = ASM.second.begin(), E = ASM.second.end(); I != E; ) {\n"; + O << " if (*I == '$') {\n"; + O << " StringRef::iterator Start = ++I;\n"; + O << " while (I != E &&\n"; + O << " ((*I >= 'a' && *I <= 'z') ||\n"; + O << " (*I >= 'A' && *I <= 'Z') ||\n"; + O << " (*I >= '0' && *I <= '9') ||\n"; + O << " *I == '_'))\n"; + O << " ++I;\n"; + O << " StringRef Name(Start, I - Start);\n"; + O << " printOperand(MI, OpMap[Name], OS);\n"; + O << " } else {\n"; + O << " OS << *I++;\n"; + O << " }\n"; + O << " }\n"; + O << " }\n\n"; + + O << " return false;\n"; + O << "}\n\n"; + + O << "#endif // PRINT_ALIAS_INSTR\n"; +} void AsmWriterEmitter::run(raw_ostream &O) { EmitSourceFileHeader("Assembly Writer Source Fragment", O); @@ -550,5 +798,6 @@ void AsmWriterEmitter::run(raw_ostream &O) { EmitPrintInstruction(O); EmitGetRegisterName(O); EmitGetInstructionName(O); + EmitPrintAliasInstruction(O); } diff --git a/utils/TableGen/AsmWriterEmitter.h b/utils/TableGen/AsmWriterEmitter.h index 9f7d776..5e8d6f5 100644 --- a/utils/TableGen/AsmWriterEmitter.h +++ b/utils/TableGen/AsmWriterEmitter.h @@ -38,6 +38,7 @@ private: void EmitPrintInstruction(raw_ostream &o); void EmitGetRegisterName(raw_ostream &o); void EmitGetInstructionName(raw_ostream &o); + void EmitPrintAliasInstruction(raw_ostream &O); AsmWriterInst *getAsmWriterInstByID(unsigned ID) const { assert(ID < NumberedInstructions.size()); diff --git a/utils/TableGen/CMakeLists.txt b/utils/TableGen/CMakeLists.txt index e24314c..514b191 100644 --- a/utils/TableGen/CMakeLists.txt +++ b/utils/TableGen/CMakeLists.txt @@ -3,7 +3,7 @@ set(LLVM_REQUIRES_RTTI 1) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LLVM_TOOLS_BINARY_DIR}) -add_executable(tblgen +add_llvm_utility(tblgen ARMDecoderEmitter.cpp AsmMatcherEmitter.cpp AsmWriterEmitter.cpp diff --git a/utils/TableGen/ClangSACheckersEmitter.cpp b/utils/TableGen/ClangSACheckersEmitter.cpp index 3e49ab1..8865db3 100644 --- a/utils/TableGen/ClangSACheckersEmitter.cpp +++ b/utils/TableGen/ClangSACheckersEmitter.cpp @@ -148,6 +148,7 @@ void ClangSACheckersEmitter::run(raw_ostream &OS) { // Create a pseudo-group to hold this checker. std::string fullName = getCheckerFullName(R); GroupInfo &info = groupInfoByName[fullName]; + info.Hidden = R->getValueAsBit("Hidden"); recordGroupMap[R] = &info; info.Checkers.push_back(R); } else { diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp index ccd3efd..b0839c3 100644 --- a/utils/TableGen/X86RecognizableInstr.cpp +++ b/utils/TableGen/X86RecognizableInstr.cpp @@ -34,7 +34,9 @@ using namespace llvm; MAP(E8, 39) \ MAP(F0, 40) \ MAP(F8, 41) \ - MAP(F9, 42) + MAP(F9, 42) \ + MAP(D0, 45) \ + MAP(D1, 46) // A clone of X86 since we can't depend on something that is generated. namespace X86Local { diff --git a/utils/buildit/GNUmakefile b/utils/buildit/GNUmakefile index 54577e2..5140e15 100644 --- a/utils/buildit/GNUmakefile +++ b/utils/buildit/GNUmakefile @@ -80,6 +80,10 @@ EmbeddedSim: export MACOSX_DEPLOYMENT_TARGET=`sw_vers -productVersion`; \ $(MAKE) IOS_SIM_BUILD=yes PREFIX=$(SDKROOT)/usr/local install +Embedded: + ARM_PLATFORM=`xcodebuild -version -sdk iphoneos PlatformPath` && \ + $(MAKE) DSTROOT=$(DSTROOT)$$ARM_PLATFORM install + # installhdrs does nothing, because the headers aren't useful until # the compiler is installed. installhdrs: @@ -128,4 +132,4 @@ clean: $(OBJROOT) $(SYMROOT) $(DSTROOT): mkdir -p $@ -.PHONY: install installsrc clean EmbeddedHosted EmbeddedSim +.PHONY: install installsrc clean EmbeddedHosted EmbeddedSim Embedded diff --git a/utils/buildit/build_llvm b/utils/buildit/build_llvm index 5e8369c..38b0bfd 100755 --- a/utils/buildit/build_llvm +++ b/utils/buildit/build_llvm @@ -267,8 +267,9 @@ fi # The Hello dylib is an example of how to build a pass. # The BugpointPasses module is only used to test bugpoint. # These unversioned dylibs cause verification failures, so do not install them. -rm $DEST_DIR$DEST_ROOT/lib/libLLVMHello.dylib -rm $DEST_DIR$DEST_ROOT/lib/libBugpointPasses.dylib +# (The wildcards are used to match a "lib" prefix if it is present.) +rm $DEST_DIR$DEST_ROOT/lib/*LLVMHello.dylib +rm $DEST_DIR$DEST_ROOT/lib/*BugpointPasses.dylib # Compress manpages MDIR=$DEST_DIR$DEST_ROOT/share/man/man1 @@ -341,6 +342,9 @@ else fi rm -f lib/libLTO.a lib/libLTO.la +# Omit lto.h from the result. Clang will supply. +find $DEST_DIR$DEST_ROOT -name lto.h -delete + ################################################################################ # Remove debugging information from DEST_DIR. diff --git a/utils/count/CMakeLists.txt b/utils/count/CMakeLists.txt index e124f61..4e0d371 100644 --- a/utils/count/CMakeLists.txt +++ b/utils/count/CMakeLists.txt @@ -1,3 +1,3 @@ -add_executable(count +add_llvm_utility(count count.c ) diff --git a/utils/llvmbuild b/utils/llvmbuild new file mode 100755 index 0000000..fb8500d --- /dev/null +++ b/utils/llvmbuild @@ -0,0 +1,740 @@ +#!/usr/bin/python3 +##===- utils/llvmbuild - Build the LLVM project ----------------*-python-*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## +# +# This script builds many different flavors of the LLVM ecosystem. It +# will build LLVM, Clang, llvm-gcc, and dragonegg as well as run tests +# on them. This script is convenient to use to check builds and tests +# before committing changes to the upstream repository +# +# A typical source setup uses three trees and looks like this: +# +# official +# dragonegg +# trunk +# gcc +# trunk +# llvm +# trunk +# tools +# clang +# tags +# RELEASE_28 +# tools +# clang +# llvm-gcc +# trunk +# tags +# RELEASE_28 +# staging +# dragonegg +# trunk +# gcc +# trunk +# llvm +# trunk +# tools +# clang +# tags +# RELEASE_28 +# tools +# clang +# llvm-gcc +# trunk +# tags +# RELEASE_28 +# commit +# dragonegg +# trunk +# gcc +# trunk +# llvm +# trunk +# tools +# clang +# tags +# RELEASE_28 +# tools +# clang +# llvm-gcc +# trunk +# tags +# RELEASE_28 +# +# "gcc" above is the upstream FSF gcc and "gcc/trunk" refers to the +# 4.5 branch as discussed in the dragonegg build guide. +# +# In a typical workflow, the "official" tree always contains unchanged +# sources from the main LLVM project repositories. The "staging" tree +# is where local work is done. A set of changes resides there waiting +# to be moved upstream. The "commit" tree is where changes from +# "staging" make their way upstream. Individual incremental changes +# from "staging" are applied to "commit" and committed upstream after +# a successful build and test run. A successful build is one in which +# testing results in no more failures than seen in the testing of the +# "official" tree. +# +# A build may be invoked as such: +# +# llvmbuild --src=~/llvm/commit --src=~/llvm/staging +# --src=~/llvm/official --branch=trunk --branch=tags/RELEASE_28 +# --build=debug --build=release --build=paranoid +# --prefix=/home/greened/install --builddir=/home/greened/build +# +# This will build the LLVM ecosystem, including LLVM, Clang, llvm-gcc, +# gcc 4.5 and dragonegg, putting build results in ~/build and +# installing tools in ~/install. llvmbuild creates separate build and +# install directories for each source/branch/build flavor. In the +# above example, llvmbuild will build debug, release and paranoid +# (debug+checks) flavors of the trunk and RELEASE_28 branches from +# each source tree (official, staging and commit) for a total of +# eighteen builds. All builds will be run in parallel. +# +# The user may control parallelism via the --jobs and --threads +# switches. --jobs tells llvmbuild the maximum total number of builds +# to activate in parallel. The user may think of it as equivalent to +# the GNU make -j switch. --threads tells llvmbuild how many worker +# threads to use to accomplish those builds. If --threads is less +# than --jobs, --threads workers will be launched and each one will +# pick a source/branch/flavor combination to build. Then llvmbuild +# will invoke GNU make with -j (--jobs / --threads) to use up the +# remaining job capacity. Once a worker is finished with a build, it +# will pick another combination off the list and start building it. +# +##===----------------------------------------------------------------------===## + +import optparse +import os +import sys +import threading +import queue +import logging +import traceback +import subprocess +import re + +# TODO: Use shutil.which when it is available (3.2 or later) +def find_executable(executable, path=None): + """Try to find 'executable' in the directories listed in 'path' (a + string listing directories separated by 'os.pathsep'; defaults to + os.environ['PATH']). Returns the complete filename or None if not + found + """ + if path is None: + path = os.environ['PATH'] + paths = path.split(os.pathsep) + extlist = [''] + if os.name == 'os2': + (base, ext) = os.path.splitext(executable) + # executable files on OS/2 can have an arbitrary extension, but + # .exe is automatically appended if no dot is present in the name + if not ext: + executable = executable + ".exe" + elif sys.platform == 'win32': + pathext = os.environ['PATHEXT'].lower().split(os.pathsep) + (base, ext) = os.path.splitext(executable) + if ext.lower() not in pathext: + extlist = pathext + for ext in extlist: + execname = executable + ext + if os.path.isfile(execname): + return execname + else: + for p in paths: + f = os.path.join(p, execname) + if os.path.isfile(f): + return f + else: + return None + +def is_executable(fpath): + return os.path.exists(fpath) and os.access(fpath, os.X_OK) + +def add_options(parser): + parser.add_option("-v", "--verbose", action="store_true", + default=False, + help=("Output informational messages" + " [default: %default]")) + parser.add_option("--src", action="append", + help=("Top-level source directory [default: %default]")) + parser.add_option("--build", action="append", + help=("Build types to run [default: %default]")) + parser.add_option("--branch", action="append", + help=("Source branch to build [default: %default]")) + parser.add_option("--cc", default=find_executable("cc"), + help=("The C compiler to use [default: %default]")) + parser.add_option("--cxx", default=find_executable("c++"), + help=("The C++ compiler to use [default: %default]")) + parser.add_option("--threads", default=4, type="int", + help=("The number of worker threads to use " + "[default: %default]")) + parser.add_option("--jobs", "-j", default=8, type="int", + help=("The number of simultaneous build jobs " + "[default: %default]")) + parser.add_option("--prefix", + help=("Root install directory [default: %default]")) + parser.add_option("--builddir", + help=("Root build directory [default: %default]")) + parser.add_option("--extra-llvm-config-flags", default="", + help=("Extra flags to pass to llvm configure [default: %default]")) + parser.add_option("--extra-llvm-gcc-config-flags", default="", + help=("Extra flags to pass to llvm-gcc configure [default: %default]")) + parser.add_option("--extra-gcc-config-flags", default="", + help=("Extra flags to pass to gcc configure [default: %default]")) + parser.add_option("--force-configure", default=False, action="store_true", + help=("Force reconfigure of all components")) + return + +def check_options(parser, options, valid_builds): + # See if we're building valid flavors. + for build in options.build: + if (build not in valid_builds): + parser.error("'" + build + "' is not a valid build flavor " + + str(valid_builds)) + + # See if we can find source directories. + for src in options.src: + for component in ["llvm", "llvm-gcc", "gcc", "dragonegg"]: + compsrc = src + "/" + component + if (not os.path.isdir(compsrc)): + parser.error("'" + compsrc + "' does not exist") + if (options.branch is not None): + for branch in options.branch: + if (not os.path.isdir(os.path.join(compsrc, branch))): + parser.error("'" + os.path.join(compsrc, branch) + + "' does not exist") + + # See if we can find the compilers + options.cc = find_executable(options.cc) + options.cxx = find_executable(options.cxx) + + return + +# Find a unique short name for the given set of paths. This searches +# back through path components until it finds unique component names +# among all given paths. +def get_path_abbrevs(paths): + # Find the number of common starting characters in the last component + # of the paths. + unique_paths = list(paths) + + class NotFoundException(Exception): pass + + # Find a unique component of each path. + unique_bases = unique_paths[:] + found = 0 + while len(unique_paths) > 0: + bases = [os.path.basename(src) for src in unique_paths] + components = { c for c in bases } + # Account for single entry in paths. + if len(components) > 1 or len(components) == len(bases): + # We found something unique. + for c in components: + if bases.count(c) == 1: + index = bases.index(c) + unique_bases[index] = c + # Remove the corresponding path from the set under + # consideration. + unique_paths[index] = None + unique_paths = [ p for p in unique_paths if p is not None ] + unique_paths = [os.path.dirname(src) for src in unique_paths] + + if len(unique_paths) > 0: + raise NotFoundException() + + abbrevs = dict(zip(paths, [base for base in unique_bases])) + + return abbrevs + +# Given a set of unique names, find a short character sequence that +# uniquely identifies them. +def get_short_abbrevs(unique_bases): + # Find a unique start character for each path base. + my_unique_bases = unique_bases[:] + unique_char_starts = unique_bases[:] + while len(my_unique_bases) > 0: + for start, char_tuple in enumerate(zip(*[base + for base in my_unique_bases])): + chars = { c for c in char_tuple } + # Account for single path. + if len(chars) > 1 or len(chars) == len(char_tuple): + # We found something unique. + for c in chars: + if char_tuple.count(c) == 1: + index = char_tuple.index(c) + unique_char_starts[index] = start + # Remove the corresponding path from the set under + # consideration. + my_unique_bases[index] = None + my_unique_bases = [ b for b in my_unique_bases + if b is not None ] + break + + if len(my_unique_bases) > 0: + raise NotFoundException() + + abbrevs = [abbrev[start_index:start_index+3] + for abbrev, start_index + in zip([base for base in unique_bases], + [index for index in unique_char_starts])] + + abbrevs = dict(zip(unique_bases, abbrevs)) + + return abbrevs + +class Builder(threading.Thread): + class ExecutableNotFound(Exception): pass + class FileNotExecutable(Exception): pass + + def __init__(self, work_queue, jobs, + build_abbrev, source_abbrev, branch_abbrev, + options): + super().__init__() + self.work_queue = work_queue + self.jobs = jobs + self.cc = options.cc + self.cxx = options.cxx + self.build_abbrev = build_abbrev + self.source_abbrev = source_abbrev + self.branch_abbrev = branch_abbrev + self.build_prefix = options.builddir + self.install_prefix = options.prefix + self.options = options + self.component_abbrev = dict( + llvm="llvm", + llvm_gcc="lgcc", + llvm2="llv2", + gcc="ugcc", + dagonegg="degg") + def run(self): + while True: + try: + source, branch, build = self.work_queue.get() + self.dobuild(source, branch, build) + except: + traceback.print_exc() + finally: + self.work_queue.task_done() + + def execute(self, command, execdir, env, component): + prefix = self.component_abbrev[component.replace("-", "_")] + pwd = os.getcwd() + if not os.path.exists(execdir): + os.makedirs(execdir) + + execenv = os.environ.copy() + + for key, value in env.items(): + execenv[key] = value + + self.logger.debug("[" + prefix + "] " + "env " + str(env) + " " + + " ".join(command)); + + try: + proc = subprocess.Popen(command, + cwd=execdir, + env=execenv, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + + line = proc.stdout.readline() + while line: + self.logger.info("[" + prefix + "] " + + str(line, "utf-8").rstrip()) + line = proc.stdout.readline() + + except: + traceback.print_exc() + + # Get a list of C++ include directories to pass to clang. + def get_includes(self): + # Assume we're building with g++ for now. + command = [self.cxx] + command += ["-v", "-x", "c++", "/dev/null", "-fsyntax-only"] + includes = [] + self.logger.debug(command) + try: + proc = subprocess.Popen(command, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + + gather = False + line = proc.stdout.readline() + while line: + self.logger.debug(line) + if re.search("End of search list", str(line)) is not None: + self.logger.debug("Stop Gather") + gather = False + if gather: + includes.append(str(line, "utf-8").strip()) + if re.search("#include <...> search starts", str(line)) is not None: + self.logger.debug("Start Gather") + gather = True + line = proc.stdout.readline() + except: + traceback.print_exc() + self.logger.debug(includes) + return includes + + def dobuild(self, source, branch, build): + build_suffix = "" + + ssabbrev = get_short_abbrevs([ab for ab in self.source_abbrev.values()]) + + if branch is not None: + sbabbrev = get_short_abbrevs([ab for ab in self.branch_abbrev.values()]) + + prefix = "[" + ssabbrev[self.source_abbrev[source]] + "-" + sbabbrev[self.branch_abbrev[branch]] + "-" + self.build_abbrev[build] + "]" + self.install_prefix += "/" + self.source_abbrev[source] + "/" + branch + "/" + build + build_suffix += self.source_abbrev[source] + "/" + branch + "/" + build + else: + prefix = "[" + ssabbrev[self.source_abbrev[source]] + "-" + self.build_abbrev[build] + "]" + self.install_prefix += "/" + self.source_abbrev[source] + "/" + build + build_suffix += "/" + self.source_abbrev[source] + "/" + build + + self.logger = logging.getLogger(prefix) + + self.logger.debug(self.install_prefix) + + # Assume we're building with gcc for now. + cxxincludes = self.get_includes() + cxxroot = cxxincludes[0] + cxxarch = os.path.basename(cxxincludes[1]) + + configure_flags = dict( + llvm=dict(debug=["--prefix=" + self.install_prefix, + "--with-extra-options=-Werror", + "--with-cxx-include-root=" + cxxroot, + "--with-cxx-include-arch=" + cxxarch], + release=["--prefix=" + self.install_prefix, + "--with-extra-options=-Werror", + "--enable-optimized", + "--with-cxx-include-root=" + cxxroot, + "--with-cxx-include-arch=" + cxxarch], + paranoid=["--prefix=" + self.install_prefix, + "--with-extra-options=-Werror", + "--enable-expensive-checks", + "--with-cxx-include-root=" + cxxroot, + "--with-cxx-include-arch=" + cxxarch]), + llvm_gcc=dict(debug=["--prefix=" + self.install_prefix, + "--enable-checking", + "--program-prefix=llvm-", + "--enable-llvm=" + self.build_prefix + "/llvm/" + build_suffix, +# Fortran install seems to be broken. +# "--enable-languages=c,c++,fortran"], + "--enable-languages=c,c++"], + release=["--prefix=" + self.install_prefix, + "--program-prefix=llvm-", + "--enable-llvm=" + self.build_prefix + "/llvm/" + build_suffix, +# Fortran install seems to be broken. +# "--enable-languages=c,c++,fortran"], + "--enable-languages=c,c++"], + paranoid=["--prefix=" + self.install_prefix, + "--enable-checking", + "--program-prefix=llvm-", + "--enable-llvm=" + self.build_prefix + "/llvm/" + build_suffix, +# Fortran install seems to be broken. +# "--enable-languages=c,c++,fortran"]), + "--enable-languages=c,c++"]), + llvm2=dict(debug=["--prefix=" + self.install_prefix, + "--with-extra-options=-Werror", + "--with-llvmgccdir=" + self.install_prefix + "/bin", + "--with-cxx-include-root=" + cxxroot, + "--with-cxx-include-arch=" + cxxarch], + release=["--prefix=" + self.install_prefix, + "--with-extra-options=-Werror", + "--enable-optimized", + "--with-llvmgccdir=" + self.install_prefix + "/bin", + "--with-cxx-include-root=" + cxxroot, + "--with-cxx-include-arch=" + cxxarch], + paranoid=["--prefix=" + self.install_prefix, + "--with-extra-options=-Werror", + "--enable-expensive-checks", + "--with-llvmgccdir=" + self.install_prefix + "/bin", + "--with-cxx-include-root=" + cxxroot, + "--with-cxx-include-arch=" + cxxarch]), + gcc=dict(debug=["--prefix=" + self.install_prefix, + "--enable-checking"], + release=["--prefix=" + self.install_prefix], + paranoid=["--prefix=" + self.install_prefix, + "--enable-checking"]), + dragonegg=dict(debug=[], + release=[], + paranoid=[])) + + configure_env = dict( + llvm=dict(debug=dict(CC=self.cc, + CXX=self.cxx), + release=dict(CC=self.cc, + CXX=self.cxx), + paranoid=dict(CC=self.cc, + CXX=self.cxx)), + llvm_gcc=dict(debug=dict(CC=self.cc, + CXX=self.cxx), + release=dict(CC=self.cc, + CXX=self.cxx), + paranoid=dict(CC=self.cc, + CXX=self.cxx)), + llvm2=dict(debug=dict(CC=self.cc, + CXX=self.cxx), + release=dict(CC=self.cc, + CXX=self.cxx), + paranoid=dict(CC=self.cc, + CXX=self.cxx)), + gcc=dict(debug=dict(CC=self.cc, + CXX=self.cxx), + release=dict(CC=self.cc, + CXX=self.cxx), + paranoid=dict(CC=self.cc, + CXX=self.cxx)), + dragonegg=dict(debug=dict(CC=self.cc, + CXX=self.cxx), + release=dict(CC=self.cc, + CXX=self.cxx), + paranoid=dict(CC=self.cc, + CXX=self.cxx))) + + make_flags = dict( + llvm=dict(debug=["-j" + str(self.jobs)], + release=["-j" + str(self.jobs)], + paranoid=["-j" + str(self.jobs)]), + llvm_gcc=dict(debug=["-j" + str(self.jobs), + "bootstrap"], + release=["-j" + str(self.jobs), + "bootstrap"], + paranoid=["-j" + str(self.jobs), + "bootstrap"]), + llvm2=dict(debug=["-j" + str(self.jobs)], + release=["-j" + str(self.jobs)], + paranoid=["-j" + str(self.jobs)]), + gcc=dict(debug=["-j" + str(self.jobs), + "bootstrap"], + release=["-j" + str(self.jobs), + "bootstrap"], + paranoid=["-j" + str(self.jobs), + "bootstrap"]), + dragonegg=dict(debug=["-j" + str(self.jobs)], + release=["-j" + str(self.jobs)], + paranoid=["-j" + str(self.jobs)])) + + make_env = dict( + llvm=dict(debug=dict(), + release=dict(), + paranoid=dict()), + llvm_gcc=dict(debug=dict(), + release=dict(), + paranoid=dict()), + llvm2=dict(debug=dict(), + release=dict(), + paranoid=dict()), + gcc=dict(debug=dict(), + release=dict(), + paranoid=dict()), + dragonegg=dict(debug=dict(GCC=self.install_prefix + "/bin/gcc", + LLVM_CONFIG=self.install_prefix + "/bin/llvm-config"), + release=dict(GCC=self.install_prefix + "/bin/gcc", + LLVM_CONFIG=self.install_prefix + "/bin/llvm-config"), + paranoid=dict(GCC=self.install_prefix + "/bin/gcc", + LLVM_CONFIG=self.install_prefix + "/bin/llvm-config"))) + + make_install_flags = dict( + llvm=dict(debug=["install"], + release=["install"], + paranoid=["install"]), + llvm_gcc=dict(debug=["install"], + release=["install"], + paranoid=["install"]), + llvm2=dict(debug=["install"], + release=["install"], + paranoid=["install"]), + gcc=dict(debug=["install"], + release=["install"], + paranoid=["install"]), + dragonegg=dict(debug=["install"], + release=["install"], + paranoid=["install"])) + + make_install_env = dict( + llvm=dict(debug=dict(), + release=dict(), + paranoid=dict()), + llvm_gcc=dict(debug=dict(), + release=dict(), + paranoid=dict()), + llvm2=dict(debug=dict(), + release=dict(), + paranoid=dict()), + gcc=dict(debug=dict(), + release=dict(), + paranoid=dict()), + dragonegg=dict(debug=dict(), + release=dict(), + paranoid=dict())) + + make_check_flags = dict( + llvm=dict(debug=["check"], + release=["check"], + paranoid=["check"]), + llvm_gcc=dict(debug=["check"], + release=["check"], + paranoid=["check"]), + llvm2=dict(debug=["check"], + release=["check"], + paranoid=["check"]), + gcc=dict(debug=["check"], + release=["check"], + paranoid=["check"]), + dragonegg=dict(debug=["check"], + release=["check"], + paranoid=["check"])) + + make_check_env = dict( + llvm=dict(debug=dict(), + release=dict(), + paranoid=dict()), + llvm_gcc=dict(debug=dict(), + release=dict(), + paranoid=dict()), + llvm2=dict(debug=dict(), + release=dict(), + paranoid=dict()), + gcc=dict(debug=dict(), + release=dict(), + paranoid=dict()), + dragonegg=dict(debug=dict(), + release=dict(), + paranoid=dict())) + + for component in ["llvm", "llvm-gcc", "llvm2", "gcc", "dragonegg"]: + comp = component[:] + + srcdir = source + "/" + comp.rstrip("2") + builddir = self.build_prefix + "/" + comp + "/" + build_suffix + installdir = self.install_prefix + + if (branch is not None): + srcdir += "/" + branch + + comp_key = comp.replace("-", "_") + + config_args = configure_flags[comp_key][build][:] + config_args.extend(getattr(self.options, + "extra_" + comp_key + + "_config_flags").split()) + + self.logger.info("Configuring " + component + " in " + builddir) + self.configure(component, srcdir, builddir, + config_args, + configure_env[comp_key][build]) + + self.logger.info("Building " + component + " in " + builddir) + self.make(component, srcdir, builddir, + make_flags[comp_key][build], + make_env[comp_key][build]) + + self.logger.info("Installing " + component + " in " + installdir) + self.make(component, srcdir, builddir, + make_install_flags[comp_key][build], + make_install_env[comp_key][build]) + + self.logger.info("Testing " + component + " in " + builddir) + self.make(component, srcdir, builddir, + make_check_flags[comp_key][build], + make_check_env[comp_key][build]) + + + def configure(self, component, srcdir, builddir, flags, env): + self.logger.debug("Configure " + str(flags)) + + configure_files = dict( + llvm=[(srcdir + "/configure", builddir + "/Makefile")], + llvm_gcc=[(srcdir + "/configure", builddir + "/Makefile"), + (srcdir + "/gcc/configure", builddir + "/gcc/Makefile")], + llvm2=[(srcdir + "/configure", builddir + "/Makefile")], + gcc=[(srcdir + "/configure", builddir + "/Makefile"), + (srcdir + "/gcc/configure", builddir + "/gcc/Makefile")], + dragonegg=[()]) + + + doconfig = False + for conf, mf in configure_files[component.replace("-", "_")]: + if not os.path.exists(conf): + return + if os.path.exists(conf) and os.path.exists(mf): + confstat = os.stat(conf) + makestat = os.stat(mf) + if confstat.st_mtime > makestat.st_mtime: + doconfig = True + break + else: + doconfig = True + break + + if not doconfig and not self.options.force_configure: + return + + program = srcdir + "/configure" + if not is_executable(program): + return + + args = [program] + args += ["--verbose"] + args += flags + self.execute(args, builddir, env, component) + + def make(self, component, srcdir, builddir, flags, env): + program = find_executable("make") + if program is None: + raise ExecutableNotFound + + if not is_executable(program): + raise FileNotExecutable + + args = [program] + args += flags + self.execute(args, builddir, env, component) + +# Global constants +build_abbrev = dict(debug="dbg", release="opt", paranoid="par") + +# Parse options +parser = optparse.OptionParser(version="%prog 1.0") +add_options(parser) +(options, args) = parser.parse_args() +check_options(parser, options, build_abbrev.keys()); + +if options.verbose: + logging.basicConfig(level=logging.DEBUG, + format='%(name)-13s: %(message)s') +else: + logging.basicConfig(level=logging.INFO, + format='%(name)-13s: %(message)s') + +source_abbrev = get_path_abbrevs(set(options.src)) +branch_abbrev = get_path_abbrevs(set(options.branch)) + +work_queue = queue.Queue() + +for t in range(options.threads): + jobs = options.jobs // options.threads + builder = Builder(work_queue, jobs, + build_abbrev, source_abbrev, branch_abbrev, + options) + builder.daemon = True + builder.start() + +for build in set(options.build): + for source in set(options.src): + if options.branch is not None: + for branch in set(options.branch): + work_queue.put((source, branch, build)) + else: + work_queue.put((source, None, build)) + +work_queue.join() diff --git a/utils/not/CMakeLists.txt b/utils/not/CMakeLists.txt index 155d2e3..f4c0229 100644 --- a/utils/not/CMakeLists.txt +++ b/utils/not/CMakeLists.txt @@ -1,4 +1,4 @@ -add_executable(not +add_llvm_utility(not not.cpp ) diff --git a/utils/valgrind/i386-pc-linux-gnu.supp b/utils/valgrind/i386-pc-linux-gnu.supp index c9f68a0..0509791 100644 --- a/utils/valgrind/i386-pc-linux-gnu.supp +++ b/utils/valgrind/i386-pc-linux-gnu.supp @@ -12,19 +12,19 @@ { ADDRESS_IN_RANGE/Invalid read of size 4 Memcheck:Addr4 - obj:/usr/bin/python2.5 + obj:/usr/bin/python* } { ADDRESS_IN_RANGE/Invalid read of size 4 Memcheck:Value4 - obj:/usr/bin/python2.5 + obj:/usr/bin/python* } { ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value Memcheck:Cond - obj:/usr/bin/python2.5 + obj:/usr/bin/python* } { @@ -37,5 +37,5 @@ We don't care if python leaks Memcheck:Leak fun:malloc - obj:/usr/bin/python2.5 + obj:/usr/bin/python* } |