| ... | ... | @@ -197,7 +197,7 @@ pub fn main() anyerror!void { |
| 197 | 197 | .llvm_tblgen_exe = llvm_tblgen_exe, |
| 198 | 198 | .llvm_src_root = llvm_src_root, |
| 199 | 199 | .zig_src_dir = zig_src_dir, |
| 200 | | .root_progress = &root_progress, |
| 200 | .root_progress = root_progress, |
| 201 | 201 | .llvm_target = llvm_target, |
| 202 | 202 | }); |
| 203 | 203 | } |
| ... | ... | @@ -385,11 +385,19 @@ fn processOneTarget(job: Job) anyerror!void { |
| 385 | 385 | }, |
| 386 | 386 | ); |
| 387 | 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 | 389 | for (implies.items) |imply| { |
| 390 | 390 | const other_key = imply.Object.get("def").?.String; |
| 391 | | const other_obj = &root_map.getEntry(other_key).?.value.Object; |
| 392 | | try dependencies.append(other_obj); |
| 391 | try deps_set.put(other_key, {}); |
| 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 | 402 | std.sort.sort(*json.ObjectMap, dependencies.items, {}, objectLessThan); |
| 395 | 403 | |
| ... | ... | @@ -427,24 +435,29 @@ fn processOneTarget(job: Job) anyerror!void { |
| 427 | 435 | ); |
| 428 | 436 | |
| 429 | 437 | for (all_cpus.items) |obj| { |
| 430 | | var cpu_features = std.ArrayList(*json.ObjectMap).init(arena); |
| 431 | | |
| 432 | 438 | const llvm_name = obj.get("Name").?.String; |
| 439 | var deps_set = std.StringHashMap(void).init(arena); |
| 440 | |
| 433 | 441 | const features = obj.get("Features").?.Array; |
| 434 | 442 | for (features.items) |feature| { |
| 435 | 443 | const feature_key = feature.Object.get("def").?.String; |
| 436 | | const feature_obj = &root_map.getEntry(feature_key).?.value.Object; |
| 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); |
| 444 | try deps_set.put(feature_key, {}); |
| 440 | 445 | } |
| 441 | 446 | const tune_features = obj.get("TuneFeatures").?.Array; |
| 442 | 447 | for (tune_features.items) |feature| { |
| 443 | 448 | const feature_key = feature.Object.get("def").?.String; |
| 444 | | const feature_obj = &root_map.getEntry(feature_key).?.value.Object; |
| 445 | | const feature_llvm_name = feature_obj.get("Name").?.String; |
| 446 | | if (feature_llvm_name.len == 0) continue; |
| 447 | | try cpu_features.append(feature_obj); |
| 449 | try deps_set.put(feature_key, {}); |
| 450 | } |
| 451 | try pruneFeatures(arena, root_map, &deps_set); |
| 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 | 462 | std.sort.sort(*json.ObjectMap, cpu_features.items, {}, objectLessThan); |
| 450 | 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 | 507 | \\ |
| 495 | 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 | 512 | , .{arg0}) catch std.process.exit(1); |
| 498 | 513 | std.process.exit(code); |
| 499 | 514 | } |
| ... | ... | @@ -533,3 +548,41 @@ fn hasSuperclass(obj: *json.ObjectMap, class_name: []const u8) bool { |
| 533 | 548 | } |
| 534 | 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 | } |