1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
//! Turns the rewrite rules into the table the simplifier matches with.
//!
//! Design: `spec/optimizer/13-rewrite-rules.md`, which asks for the rewrites to be written as
//! rules that a solver can be asked about rather than as `match` arms nobody can check.
//! Everything this script does is in `rucc-rules`: it reads a rule file, builds the trie over the
//! patterns, and emits the table as Rust. What is here is which files to do it to and where to
//! put the answer, and it is the same script `rucc-codegen` runs over its lowering rules.
//!
//! The rule files live in this crate rather than at the root of the repository, which is what
//! makes a published `rucc-opt` build from its own source archive. `rucc-verify` reads them from
//! here too, so there is still one copy of them and one gate over it.
use Path;
use ;
/// Every rule file this crate compiles.
///
/// One per tier of `spec/optimizer/13-rewrite-rules.md` section 13.4, added here when its file is
/// written, and the list is short on purpose: a rule file nobody compiles is a rule file nobody
/// notices has stopped compiling.
///
/// The five rewrite tiers come first, and their order is the order `crate::simplify` tries them
/// in, which is nearly the order the tiers are numbered. Tier one takes an operation away and tier
/// two swaps one for another, so a term both have something to say about is better off losing the
/// operation, and tier four takes one away as well. Tier three is last rather than third because it
/// only rearranges a term so that another rule can be about it, and there is no reason to reach for
/// that while a rule that improves the code still fires. No instruction matches both anyway, since
/// tier three is about a commutative operation with a constant and tier four is about a conversion.
/// Tier five goes between them for no reason at all: it is the only one about a comparison, so
/// there is no term another tier is also about and nothing that depends on whether it is tried
/// first or last.
///
/// The safety set is not a tier and is not in that order, because it is not matched against the
/// IR at all. It is the table `crate::discharge` asks about two safety checks it has already
/// worked out are about one address, per `spec/safe-memory/07-check-elimination.md` section 7.7,
/// and `crate::simplify` names the five tables it uses one by one so that adding a sixth set here
/// does not put it in the simplifier.
const SETS: & = &;
/// A rule file that will not compile stops the build with the message and nothing else.
///
/// A panic here would bury the line and column under a backtrace and the words "build script
/// panicked", and what has gone wrong is a rule somebody is editing.
!