aboutsummaryrefslogtreecommitdiff
path: root/llvm/utils
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/utils')
-rw-r--r--llvm/utils/TableGen/Basic/DirectiveEmitter.cpp22
-rw-r--r--llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp13
-rw-r--r--llvm/utils/TableGen/Common/CodeGenRegisters.cpp30
-rw-r--r--llvm/utils/TableGen/Common/CodeGenRegisters.h4
-rw-r--r--llvm/utils/TableGen/RegisterInfoEmitter.cpp2
-rw-r--r--llvm/utils/gn/secondary/libcxx/include/BUILD.gn1
-rw-r--r--llvm/utils/gn/secondary/lld/MachO/BUILD.gn1
-rwxr-xr-xllvm/utils/llvm-original-di-preservation.py154
-rwxr-xr-xllvm/utils/release/export.sh2
9 files changed, 171 insertions, 58 deletions
diff --git a/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp b/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp
index 177eece..f0e2369 100644
--- a/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp
+++ b/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp
@@ -106,8 +106,16 @@ static void generateEnumClass(ArrayRef<const Record *> Records, raw_ostream &OS,
bool ExportEnums) {
OS << "\n";
OS << "enum class " << Enum << " {\n";
- for (const Record *R : Records) {
- OS << " " << getIdentifierName(R, Prefix) << ",\n";
+ if (!Records.empty()) {
+ std::string N;
+ for (auto [I, R] : llvm::enumerate(Records)) {
+ N = getIdentifierName(R, Prefix);
+ OS << " " << N << ",\n";
+ // Make the sentinel names less likely to conflict with actual names...
+ if (I == 0)
+ OS << " First_ = " << N << ",\n";
+ }
+ OS << " Last_ = " << N << ",\n";
}
OS << "};\n";
OS << "\n";
@@ -282,6 +290,7 @@ static void emitDirectivesDecl(const RecordKeeper &Records, raw_ostream &OS) {
if (DirLang.hasEnableBitmaskEnumInNamespace())
OS << "#include \"llvm/ADT/BitmaskEnum.h\"\n";
+ OS << "#include \"llvm/ADT/Sequence.h\"\n";
OS << "#include \"llvm/ADT/StringRef.h\"\n";
OS << "#include \"llvm/Frontend/Directive/Spelling.h\"\n";
OS << "#include \"llvm/Support/Compiler.h\"\n";
@@ -375,6 +384,15 @@ static void emitDirectivesDecl(const RecordKeeper &Records, raw_ostream &OS) {
for (auto Ns : reverse(Namespaces))
OS << "} // namespace " << Ns << "\n";
+ // These specializations need to be in ::llvm.
+ for (StringRef Enum : {"Association", "Category", "Directive", "Clause"}) {
+ OS << "\n";
+ OS << "template <> struct enum_iteration_traits<"
+ << DirLang.getCppNamespace() << "::" << Enum << "> {\n";
+ OS << " static constexpr bool is_iterable = true;\n";
+ OS << "};\n";
+ }
+
OS << "} // namespace llvm\n";
OS << "#endif // LLVM_" << Lang << "_INC\n";
diff --git a/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp b/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp
index 652bea9..7f90d6b 100644
--- a/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp
+++ b/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp
@@ -236,8 +236,19 @@ public:
for (RuntimeLibcall &LibCall : RuntimeLibcallDefList)
Def2RuntimeLibcall[LibCall.getDef()] = &LibCall;
- ArrayRef<const Record *> AllRuntimeLibcallImpls =
+ ArrayRef<const Record *> AllRuntimeLibcallImplsRaw =
Records.getAllDerivedDefinitions("RuntimeLibcallImpl");
+
+ SmallVector<const Record *, 1024> AllRuntimeLibcallImpls(
+ AllRuntimeLibcallImplsRaw);
+
+ // Sort by libcall impl name, not the enum name. This keeps the order
+ // suitable for using the name table for libcall recognition binary search.
+ llvm::sort(AllRuntimeLibcallImpls, [](const Record *A, const Record *B) {
+ return A->getValueAsString("LibCallFuncName") <
+ B->getValueAsString("LibCallFuncName");
+ });
+
RuntimeLibcallImplDefList.reserve(AllRuntimeLibcallImpls.size());
size_t LibCallImplEnumVal = 1;
diff --git a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
index c43cc9a..28b542f 100644
--- a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
@@ -701,11 +701,13 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank,
Orders.resize(1 + AltOrders->size());
// Default allocation order always contains all registers.
+ MemberBV.resize(RegBank.getRegisters().size());
Artificial = true;
for (const Record *Element : *Elements) {
Orders[0].push_back(Element);
const CodeGenRegister *Reg = RegBank.getReg(Element);
Members.push_back(Reg);
+ MemberBV.set(CodeGenRegBank::getRegIndex(Reg));
Artificial &= Reg->Artificial;
if (!Reg->getSuperRegs().empty())
RegsWithSuperRegsTopoSigs.set(Reg->getTopoSig());
@@ -767,9 +769,11 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank,
RegsWithSuperRegsTopoSigs(RegBank.getNumTopoSigs()), EnumValue(-1),
RSI(Props.RSI), CopyCost(0), Allocatable(true), AllocationPriority(0),
GlobalPriority(false), TSFlags(0) {
+ MemberBV.resize(RegBank.getRegisters().size());
Artificial = true;
GeneratePressureSet = false;
for (const auto R : Members) {
+ MemberBV.set(CodeGenRegBank::getRegIndex(R));
if (!R->getSuperRegs().empty())
RegsWithSuperRegsTopoSigs.set(R->getTopoSig());
Artificial &= R->Artificial;
@@ -833,7 +837,7 @@ bool CodeGenRegisterClass::hasType(const ValueTypeByHwMode &VT) const {
}
bool CodeGenRegisterClass::contains(const CodeGenRegister *Reg) const {
- return llvm::binary_search(Members, Reg, deref<std::less<>>());
+ return MemberBV.test(CodeGenRegBank::getRegIndex(Reg));
}
unsigned CodeGenRegisterClass::getWeight(const CodeGenRegBank &RegBank) const {
@@ -2295,9 +2299,6 @@ void CodeGenRegBank::inferSubClassWithSubReg(CodeGenRegisterClass *RC) {
SRSets[I].push_back(R);
}
- for (auto I : SRSets)
- sortAndUniqueRegisters(I.second);
-
// Find matching classes for all SRSets entries. Iterate in SubRegIndex
// numerical order to visit synthetic indices last.
for (const CodeGenSubRegIndex &SubIdx : SubRegIndices) {
@@ -2332,8 +2333,7 @@ void CodeGenRegBank::inferMatchingSuperRegClass(
CodeGenRegisterClass *RC,
std::list<CodeGenRegisterClass>::iterator FirstSubRegRC) {
DenseSet<const CodeGenSubRegIndex *> ImpliedSubRegIndices;
- std::vector<std::pair<const CodeGenRegister *, const CodeGenRegister *>>
- SubToSuperRegs;
+ std::vector<const CodeGenRegister *> SubRegs;
BitVector TopoSigs(getNumTopoSigs());
// Iterate subregister indices in topological order to visit larger indices
@@ -2351,15 +2351,14 @@ void CodeGenRegBank::inferMatchingSuperRegClass(
// Build list of (Sub, Super) pairs for this SubIdx, sorted by Sub. Note
// that the list may contain entries with the same Sub but different Supers.
- SubToSuperRegs.clear();
+ SubRegs.clear();
TopoSigs.reset();
for (const CodeGenRegister *Super : RC->getMembers()) {
const CodeGenRegister *Sub = Super->getSubRegs().find(SubIdx)->second;
assert(Sub && "Missing sub-register");
- SubToSuperRegs.emplace_back(Sub, Super);
+ SubRegs.push_back(Sub);
TopoSigs.set(Sub->getTopoSig());
}
- sort(SubToSuperRegs, on_first<deref<std::less<>>>());
// Iterate over sub-register class candidates. Ignore classes created by
// this loop. They will never be useful.
@@ -2374,16 +2373,10 @@ void CodeGenRegBank::inferMatchingSuperRegClass(
// Topological shortcut: SubRC members have the wrong shape.
if (!TopoSigs.anyCommon(SubRC.getRegsWithSuperRegsTopoSigs()))
continue;
- // Compute the subset of RC that maps into SubRC with a single linear scan
- // through SubToSuperRegs and the members of SubRC.
+ // Compute the subset of RC that maps into SubRC.
CodeGenRegister::Vec SubSetVec;
- auto SubI = SubRC.getMembers().begin(), SubE = SubRC.getMembers().end();
- for (auto &[Sub, Super] : SubToSuperRegs) {
- while (SubI != SubE && **SubI < *Sub)
- ++SubI;
- if (SubI == SubE)
- break;
- if (**SubI == *Sub)
+ for (const auto &[Sub, Super] : zip_equal(SubRegs, RC->getMembers())) {
+ if (SubRC.contains(Sub))
SubSetVec.push_back(Super);
}
@@ -2391,7 +2384,6 @@ void CodeGenRegBank::inferMatchingSuperRegClass(
continue;
// RC injects completely into SubRC.
- sortAndUniqueRegisters(SubSetVec);
if (SubSetVec.size() == RC->getMembers().size()) {
SubRC.addSuperRegClass(SubIdx, RC);
diff --git a/llvm/utils/TableGen/Common/CodeGenRegisters.h b/llvm/utils/TableGen/Common/CodeGenRegisters.h
index bbcd44c..5e6fff0 100644
--- a/llvm/utils/TableGen/Common/CodeGenRegisters.h
+++ b/llvm/utils/TableGen/Common/CodeGenRegisters.h
@@ -315,6 +315,8 @@ inline bool operator==(const CodeGenRegister &A, const CodeGenRegister &B) {
class CodeGenRegisterClass {
CodeGenRegister::Vec Members;
+ // Bit mask of members, indexed by getRegIndex.
+ BitVector MemberBV;
// Allocation orders. Order[0] always contains all registers in Members.
std::vector<SmallVector<const Record *, 16>> Orders;
// Bit mask of sub-classes including this, indexed by their EnumValue.
@@ -752,7 +754,7 @@ public:
CodeGenRegister *getReg(const Record *);
// Get a Register's index into the Registers array.
- unsigned getRegIndex(const CodeGenRegister *Reg) const {
+ static unsigned getRegIndex(const CodeGenRegister *Reg) {
return Reg->EnumValue - 1;
}
diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
index 7d24c0f..2a311b7 100644
--- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
@@ -1644,7 +1644,7 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS) {
for (const CodeGenRegister &Reg : Regs) {
const CodeGenRegisterClass *BaseRC = nullptr;
for (const CodeGenRegisterClass *RC : BaseClasses) {
- if (is_contained(RC->getMembers(), &Reg)) {
+ if (RC->contains(&Reg)) {
BaseRC = RC;
break;
}
diff --git a/llvm/utils/gn/secondary/libcxx/include/BUILD.gn b/llvm/utils/gn/secondary/libcxx/include/BUILD.gn
index 9a34f6b..82ec812 100644
--- a/llvm/utils/gn/secondary/libcxx/include/BUILD.gn
+++ b/llvm/utils/gn/secondary/libcxx/include/BUILD.gn
@@ -1061,6 +1061,7 @@ if (current_toolchain == default_toolchain) {
"__format/indic_conjunct_break_table.h",
"__format/parser_std_format_spec.h",
"__format/range_default_formatter.h",
+ "__format/range_format.h",
"__format/range_formatter.h",
"__format/unicode.h",
"__format/width_estimation_table.h",
diff --git a/llvm/utils/gn/secondary/lld/MachO/BUILD.gn b/llvm/utils/gn/secondary/lld/MachO/BUILD.gn
index db608e3..b118d16 100644
--- a/llvm/utils/gn/secondary/lld/MachO/BUILD.gn
+++ b/llvm/utils/gn/secondary/lld/MachO/BUILD.gn
@@ -37,6 +37,7 @@ static_library("MachO") {
"ICF.cpp",
"InputFiles.cpp",
"InputSection.cpp",
+ "LinkerOptimizationHints.cpp",
"LTO.cpp",
"MapFile.cpp",
"MarkLive.cpp",
diff --git a/llvm/utils/llvm-original-di-preservation.py b/llvm/utils/llvm-original-di-preservation.py
index 03793b1..b5ccd7a 100755
--- a/llvm/utils/llvm-original-di-preservation.py
+++ b/llvm/utils/llvm-original-di-preservation.py
@@ -11,7 +11,6 @@ from json import loads
from collections import defaultdict
from collections import OrderedDict
-
class DILocBug:
def __init__(self, origin, action, bb_name, fn_name, instr):
self.origin = origin
@@ -20,18 +19,35 @@ class DILocBug:
self.fn_name = fn_name
self.instr = instr
- def __str__(self):
+ def key(self):
return self.action + self.bb_name + self.fn_name + self.instr
+ def to_dict(self):
+ result = {
+ "instr": self.instr,
+ "fn_name": self.fn_name,
+ "bb_name": self.bb_name,
+ "action": self.action,
+ }
+ if self.origin:
+ result["origin"] = self.origin
+ return result
+
class DISPBug:
def __init__(self, action, fn_name):
self.action = action
self.fn_name = fn_name
- def __str__(self):
+ def key(self):
return self.action + self.fn_name
+ def to_dict(self):
+ return {
+ "fn_name": self.fn_name,
+ "action": self.action,
+ }
+
class DIVarBug:
def __init__(self, action, name, fn_name):
@@ -39,9 +55,41 @@ class DIVarBug:
self.name = name
self.fn_name = fn_name
- def __str__(self):
+ def key(self):
return self.action + self.name + self.fn_name
+ def to_dict(self):
+ return {
+ "fn_name": self.fn_name,
+ "name": self.name,
+ "action": self.action,
+ }
+
+
+def print_bugs_yaml(name, bugs_dict, indent=2):
+ def get_bug_line(indent_level: int, text: str, margin_mark: bool = False):
+ if margin_mark:
+ return "- ".rjust(indent_level * indent) + text
+ return " " * indent * indent_level + text
+
+ print(f"{name}:")
+ for bugs_file, bugs_pass_dict in sorted(iter(bugs_dict.items())):
+ print(get_bug_line(1, f"{bugs_file}:"))
+ for bugs_pass, bugs_list in sorted(iter(bugs_pass_dict.items())):
+ print(get_bug_line(2, f"{bugs_pass}:"))
+ for bug in bugs_list:
+ bug_dict = bug.to_dict()
+ first_line = True
+ # First item needs a '-' in the margin.
+ for key, val in sorted(iter(bug_dict.items())):
+ if "\n" in val:
+ # Output block text for any multiline string.
+ print(get_bug_line(3, f"{key}: |", first_line))
+ for line in val.splitlines():
+ print(get_bug_line(4, line))
+ else:
+ print(get_bug_line(3, f"{key}: {val}", first_line))
+ first_line = False
# Report the bugs in form of html.
def generate_html_report(
@@ -430,9 +478,16 @@ def get_json_chunk(file, start, size):
# Parse the program arguments.
def parse_program_args(parser):
parser.add_argument("file_name", type=str, help="json file to process")
- parser.add_argument("html_file", type=str, help="html file to output data")
- parser.add_argument(
- "-compress", action="store_true", help="create reduced html report"
+ parser.add_argument("--reduce", action="store_true", help="create reduced report")
+
+ report_type_group = parser.add_mutually_exclusive_group(required=True)
+ report_type_group.add_argument(
+ "--report-html-file", type=str, help="output HTML file for the generated report"
+ )
+ report_type_group.add_argument(
+ "--acceptance-test",
+ action="store_true",
+ help="if set, produce terminal-friendly output and return 0 iff the input file is empty or does not exist",
)
return parser.parse_args()
@@ -442,10 +497,22 @@ def Main():
parser = argparse.ArgumentParser()
opts = parse_program_args(parser)
- if not opts.html_file.endswith(".html"):
+ if opts.report_html_file is not None and not opts.report_html_file.endswith(
+ ".html"
+ ):
print("error: The output file must be '.html'.")
sys.exit(1)
+ if opts.acceptance_test:
+ if os.path.isdir(opts.file_name):
+ print(f"error: Directory passed as input file: '{opts.file_name}'")
+ sys.exit(1)
+ if not os.path.exists(opts.file_name):
+ # We treat an empty input file as a success, as debugify will generate an output file iff any errors are
+ # found, meaning we expect 0 errors to mean that the expected file does not exist.
+ print(f"No errors detected for: {opts.file_name}")
+ sys.exit(0)
+
# Use the defaultdict in order to make multidim dicts.
di_location_bugs = defaultdict(lambda: defaultdict(list))
di_subprogram_bugs = defaultdict(lambda: defaultdict(list))
@@ -489,9 +556,9 @@ def Main():
skipped_lines += 1
continue
- di_loc_bugs = di_location_bugs[bugs_file][bugs_pass]
- di_sp_bugs = di_subprogram_bugs[bugs_file][bugs_pass]
- di_var_bugs = di_variable_bugs[bugs_file][bugs_pass]
+ di_loc_bugs = di_location_bugs.get("bugs_file", {}).get("bugs_pass", [])
+ di_sp_bugs = di_subprogram_bugs.get("bugs_file", {}).get("bugs_pass", [])
+ di_var_bugs = di_variable_bugs.get("bugs_file", {}).get("bugs_pass", [])
# Omit duplicated bugs.
di_loc_set = set()
@@ -515,9 +582,9 @@ def Main():
skipped_bugs += 1
continue
di_loc_bug = DILocBug(origin, action, bb_name, fn_name, instr)
- if not str(di_loc_bug) in di_loc_set:
- di_loc_set.add(str(di_loc_bug))
- if opts.compress:
+ if not di_loc_bug.key() in di_loc_set:
+ di_loc_set.add(di_loc_bug.key())
+ if opts.reduce:
pass_instr = bugs_pass + instr
if not pass_instr in di_loc_pass_instr_set:
di_loc_pass_instr_set.add(pass_instr)
@@ -538,9 +605,9 @@ def Main():
skipped_bugs += 1
continue
di_sp_bug = DISPBug(action, name)
- if not str(di_sp_bug) in di_sp_set:
- di_sp_set.add(str(di_sp_bug))
- if opts.compress:
+ if not di_sp_bug.key() in di_sp_set:
+ di_sp_set.add(di_sp_bug.key())
+ if opts.reduce:
pass_fn = bugs_pass + name
if not pass_fn in di_sp_pass_fn_set:
di_sp_pass_fn_set.add(pass_fn)
@@ -562,9 +629,9 @@ def Main():
skipped_bugs += 1
continue
di_var_bug = DIVarBug(action, name, fn_name)
- if not str(di_var_bug) in di_var_set:
- di_var_set.add(str(di_var_bug))
- if opts.compress:
+ if not di_var_bug.key() in di_var_set:
+ di_var_set.add(di_var_bug.key())
+ if opts.reduce:
pass_var = bugs_pass + name
if not pass_var in di_var_pass_var_set:
di_var_pass_var_set.add(pass_var)
@@ -582,19 +649,40 @@ def Main():
skipped_bugs += 1
continue
- di_location_bugs[bugs_file][bugs_pass] = di_loc_bugs
- di_subprogram_bugs[bugs_file][bugs_pass] = di_sp_bugs
- di_variable_bugs[bugs_file][bugs_pass] = di_var_bugs
-
- generate_html_report(
- di_location_bugs,
- di_subprogram_bugs,
- di_variable_bugs,
- di_location_bugs_summary,
- di_sp_bugs_summary,
- di_var_bugs_summary,
- opts.html_file,
- )
+ if di_loc_bugs:
+ di_location_bugs[bugs_file][bugs_pass] = di_loc_bugs
+ if di_sp_bugs:
+ di_subprogram_bugs[bugs_file][bugs_pass] = di_sp_bugs
+ if di_var_bugs:
+ di_variable_bugs[bugs_file][bugs_pass] = di_var_bugs
+
+ if opts.report_html_file is not None:
+ generate_html_report(
+ di_location_bugs,
+ di_subprogram_bugs,
+ di_variable_bugs,
+ di_location_bugs_summary,
+ di_sp_bugs_summary,
+ di_var_bugs_summary,
+ opts.report_html_file,
+ )
+ else:
+ # Pretty(ish) print the detected bugs, but check if any exist first so that we don't print an empty dict.
+ if di_location_bugs:
+ print_bugs_yaml("DILocation Bugs", di_location_bugs)
+ if di_subprogram_bugs:
+ print_bugs_yaml("DISubprogram Bugs", di_subprogram_bugs)
+ if di_variable_bugs:
+ print_bugs_yaml("DIVariable Bugs", di_variable_bugs)
+
+ if opts.acceptance_test:
+ if any((di_location_bugs, di_subprogram_bugs, di_variable_bugs)):
+ # Add a newline gap after printing at least one error.
+ print()
+ print(f"Errors detected for: {opts.file_name}")
+ sys.exit(1)
+ else:
+ print(f"No errors detected for: {opts.file_name}")
if skipped_lines > 0:
print("Skipped lines: " + str(skipped_lines))
diff --git a/llvm/utils/release/export.sh b/llvm/utils/release/export.sh
index 66bef82..0ac392cb 100755
--- a/llvm/utils/release/export.sh
+++ b/llvm/utils/release/export.sh
@@ -123,7 +123,7 @@ export_sources() {
tar -C test-suite-$release$rc.src --strip-components=1 -xzf -
fi
echo "Creating tarball for test-suite ..."
- tar --sort=name --owner=0 --group=0 \
+ XZ_OPT="-T0" tar --sort=name --owner=0 --group=0 \
--pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime \
-cJf test-suite-$release$rc.src.tar.xz test-suite-$release$rc.src
fi