| ... | @@ -197,7 +197,7 @@ pub fn main() anyerror!void { | ... | @@ -197,7 +197,7 @@ pub fn main() anyerror!void { |
| 197 | .llvm_tblgen_exe = llvm_tblgen_exe, | 197 | .llvm_tblgen_exe = llvm_tblgen_exe, |
| 198 | .llvm_src_root = llvm_src_root, | 198 | .llvm_src_root = llvm_src_root, |
| 199 | .zig_src_dir = zig_src_dir, | 199 | .zig_src_dir = zig_src_dir, |
| 200 | .root_progress = &root_progress, | 200 | .root_progress = root_progress, |
| 201 | .llvm_target = llvm_target, | 201 | .llvm_target = llvm_target, |
| 202 | }); | 202 | }); |
| 203 | } | 203 | } |
| ... | @@ -385,11 +385,19 @@ fn processOneTarget(job: Job) anyerror!void { | ... | @@ -385,11 +385,19 @@ fn processOneTarget(job: Job) anyerror!void { |
| 385 | }, | 385 | }, |
| 386 | ); | 386 | ); |
| 387 | const implies = obj.get("Implies").?.Array; | 387 | const implies = obj.get("Implies").?.Array; |
| 388 | var dependencies = std.ArrayList(*json.ObjectMap).init(arena); | 388 | var deps_set = std.StringHashMap(void).init(arena); |
| 389 | for (implies.items) |imply| { | 389 | for (implies.items) |imply| { |
| 390 | const other_key = imply.Object.get("def").?.String; | 390 | const other_key = imply.Object.get("def").?.String; |
| 391 | const other_obj = &root_map.getEntry(other_key).?.value.Object; | 391 | try deps_set.put(other_key, {}); |
| 392 | try dependencies.append(other_obj); | 392 | } |
| | 393 | try pruneFeatures(arena, root_map, &deps_set); |
| | 394 | var dependencies = std.ArrayList(*json.ObjectMap).init(arena); |
| | 395 | { |
| | 396 | var it = deps_set.iterator(); |
| | 397 | while (it.next()) |entry| { |
| | 398 | const other_obj = &root_map.getEntry(entry.key).?.value.Object; |
| | 399 | try dependencies.append(other_obj); |
| | 400 | } |
| 393 | } | 401 | } |
| 394 | std.sort.sort(*json.ObjectMap, dependencies.items, {}, objectLessThan); | 402 | std.sort.sort(*json.ObjectMap, dependencies.items, {}, objectLessThan); |
| 395 | | 403 | |
| ... | @@ -427,24 +435,29 @@ fn processOneTarget(job: Job) anyerror!void { | ... | @@ -427,24 +435,29 @@ fn processOneTarget(job: Job) anyerror!void { |
| 427 | ); | 435 | ); |
| 428 | | 436 | |
| 429 | for (all_cpus.items) |obj| { | 437 | for (all_cpus.items) |obj| { |
| 430 | var cpu_features = std.ArrayList(*json.ObjectMap).init(arena); | | |
| 431 | | | |
| 432 | const llvm_name = obj.get("Name").?.String; | 438 | const llvm_name = obj.get("Name").?.String; |
| | 439 | var deps_set = std.StringHashMap(void).init(arena); |
| | 440 | |
| 433 | const features = obj.get("Features").?.Array; | 441 | const features = obj.get("Features").?.Array; |
| 434 | for (features.items) |feature| { | 442 | for (features.items) |feature| { |
| 435 | const feature_key = feature.Object.get("def").?.String; | 443 | const feature_key = feature.Object.get("def").?.String; |
| 436 | const feature_obj = &root_map.getEntry(feature_key).?.value.Object; | 444 | try deps_set.put(feature_key, {}); |
| 437 | const feature_llvm_name = feature_obj.get("Name").?.String; | | |
| 438 | if (feature_llvm_name.len == 0) continue; | | |
| 439 | try cpu_features.append(feature_obj); | | |
| 440 | } | 445 | } |
| 441 | const tune_features = obj.get("TuneFeatures").?.Array; | 446 | const tune_features = obj.get("TuneFeatures").?.Array; |
| 442 | for (tune_features.items) |feature| { | 447 | for (tune_features.items) |feature| { |
| 443 | const feature_key = feature.Object.get("def").?.String; | 448 | const feature_key = feature.Object.get("def").?.String; |
| 444 | const feature_obj = &root_map.getEntry(feature_key).?.value.Object; | 449 | try deps_set.put(feature_key, {}); |
| 445 | const feature_llvm_name = feature_obj.get("Name").?.String; | 450 | } |
| 446 | if (feature_llvm_name.len == 0) continue; | 451 | try pruneFeatures(arena, root_map, &deps_set); |
| 447 | try cpu_features.append(feature_obj); | 452 | var cpu_features = std.ArrayList(*json.ObjectMap).init(arena); |
| | 453 | { |
| | 454 | var it = deps_set.iterator(); |
| | 455 | while (it.next()) |entry| { |
| | 456 | const feature_obj = &root_map.getEntry(entry.key).?.value.Object; |
| | 457 | const feature_llvm_name = feature_obj.get("Name").?.String; |
| | 458 | if (feature_llvm_name.len == 0) continue; |
| | 459 | try cpu_features.append(feature_obj); |
| | 460 | } |
| 448 | } | 461 | } |
| 449 | std.sort.sort(*json.ObjectMap, cpu_features.items, {}, objectLessThan); | 462 | std.sort.sort(*json.ObjectMap, cpu_features.items, {}, objectLessThan); |
| 450 | const zig_cpu_name = try llvmNameToZigName(arena, llvm_target, llvm_name); | 463 | const zig_cpu_name = try llvmNameToZigName(arena, llvm_target, llvm_name); |
| ... | @@ -494,6 +507,8 @@ fn usageAndExit(file: fs.File, arg0: []const u8, code: u8) noreturn { | ... | @@ -494,6 +507,8 @@ fn usageAndExit(file: fs.File, arg0: []const u8, code: u8) noreturn { |
| 494 | \\ | 507 | \\ |
| 495 | \\Prints to stdout Zig code which you can use to replace the file src/clang_options_data.zig. | 508 | \\Prints to stdout Zig code which you can use to replace the file src/clang_options_data.zig. |
| 496 | \\ | 509 | \\ |
| | 510 | \\On a less beefy system, or when debugging, compile with --single-threaded. |
| | 511 | \\ |
| 497 | , .{arg0}) catch std.process.exit(1); | 512 | , .{arg0}) catch std.process.exit(1); |
| 498 | std.process.exit(code); | 513 | std.process.exit(code); |
| 499 | } | 514 | } |
| ... | @@ -533,3 +548,41 @@ fn hasSuperclass(obj: *json.ObjectMap, class_name: []const u8) bool { | ... | @@ -533,3 +548,41 @@ fn hasSuperclass(obj: *json.ObjectMap, class_name: []const u8) bool { |
| 533 | } | 548 | } |
| 534 | return false; | 549 | return false; |
| 535 | } | 550 | } |
| | 551 | |
| | 552 | fn pruneFeatures( |
| | 553 | arena: *mem.Allocator, |
| | 554 | root_map: *const json.ObjectMap, |
| | 555 | deps_set: *std.StringHashMap(void), |
| | 556 | ) !void { |
| | 557 | // For each element, recursively iterate over the dependencies and add |
| | 558 | // everything we find to a "deletion set". |
| | 559 | // Then, iterate over the deletion set and delete all that stuff from `deps_set`. |
| | 560 | var deletion_set = std.StringHashMap(void).init(arena); |
| | 561 | { |
| | 562 | var it = deps_set.iterator(); |
| | 563 | while (it.next()) |entry| { |
| | 564 | const other_obj = &root_map.getEntry(entry.key).?.value.Object; |
| | 565 | try walkFeatures(root_map, &deletion_set, other_obj); |
| | 566 | } |
| | 567 | } |
| | 568 | { |
| | 569 | var it = deletion_set.iterator(); |
| | 570 | while (it.next()) |entry| { |
| | 571 | _ = deps_set.remove(entry.key); |
| | 572 | } |
| | 573 | } |
| | 574 | } |
| | 575 | |
| | 576 | fn walkFeatures( |
| | 577 | root_map: *const json.ObjectMap, |
| | 578 | deletion_set: *std.StringHashMap(void), |
| | 579 | feature: *json.ObjectMap, |
| | 580 | ) error{OutOfMemory}!void { |
| | 581 | const implies = feature.get("Implies").?.Array; |
| | 582 | for (implies.items) |imply| { |
| | 583 | const other_key = imply.Object.get("def").?.String; |
| | 584 | try deletion_set.put(other_key, {}); |
| | 585 | const other_obj = &root_map.getEntry(other_key).?.value.Object; |
| | 586 | try walkFeatures(root_map, deletion_set, other_obj); |
| | 587 | } |
| | 588 | } |