Skip to content

Commit 1d00ccb

Browse files
committed
Add support for inlining method calls
The compiler is now able to inline calls to static and instance methods. For each method we calculate a rough weight/cost, and calls are inlined into their callers until the maximum weight is reached. Inlining is done bottom-up using Tarjan's strongly connected components algorithm, reducing the amount of duplicate inlining work. Inlining is also done in a deterministic order as to ensure incremental compilation caches can be reused as much as possible. The current inlining threshold is on the conservative end as to not increase compile times and compile-time memory usage too much. Over time we may relax this based on user reports and any extra optimization passes we might add. If a method is annotated with the `inline` keyword, it's _always_ inlined into the caller regardless of it or the caller's weight. This is meant to be used when you want to guarantee a method is inlined, such as for the various operator methods of Int, Float, Bool, etc. Because of this guarantee one should use it sparingly, as to not increase the compile time and executable size too much. This fixes #343. Changelog: added
1 parent 9f68de6 commit 1d00ccb

38 files changed

+2642
-629
lines changed

ast/src/lexer.rs

+6
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ pub enum TokenKind {
166166
While,
167167
Whitespace,
168168
Extern,
169+
Inline,
169170
}
170171

171172
impl TokenKind {
@@ -268,6 +269,7 @@ impl TokenKind {
268269
TokenKind::Nil => "the 'nil' keyword",
269270
TokenKind::Replace => "a '=:'",
270271
TokenKind::Extern => "the 'extern' keyword",
272+
TokenKind::Inline => "the 'inline' keyword",
271273
}
272274
}
273275
}
@@ -335,6 +337,7 @@ impl Token {
335337
| TokenKind::Case
336338
| TokenKind::Enum
337339
| TokenKind::Extern
340+
| TokenKind::Inline
338341
)
339342
}
340343

@@ -997,6 +1000,7 @@ impl Lexer {
9971000
"return" => TokenKind::Return,
9981001
"static" => TokenKind::Static,
9991002
"extern" => TokenKind::Extern,
1003+
"inline" => TokenKind::Inline,
10001004
_ => TokenKind::Identifier,
10011005
},
10021006
7 => match value.as_str() {
@@ -1337,6 +1341,7 @@ mod tests {
13371341
assert!(tok(TokenKind::While, "", 1..=1, 1..=1).is_keyword());
13381342
assert!(tok(TokenKind::Recover, "", 1..=1, 1..=1).is_keyword());
13391343
assert!(tok(TokenKind::Nil, "", 1..=1, 1..=1).is_keyword());
1344+
assert!(tok(TokenKind::Inline, "", 1..=1, 1..=1).is_keyword());
13401345
}
13411346

13421347
#[test]
@@ -1978,6 +1983,7 @@ mod tests {
19781983
assert_token!("return", Return, "return", 1..=1, 1..=6);
19791984
assert_token!("static", Static, "static", 1..=1, 1..=6);
19801985
assert_token!("extern", Extern, "extern", 1..=1, 1..=6);
1986+
assert_token!("inline", Inline, "inline", 1..=1, 1..=6);
19811987

19821988
assert_token!("builtin", Builtin, "builtin", 1..=1, 1..=7);
19831989
assert_token!("recover", Recover, "recover", 1..=1, 1..=7);

ast/src/nodes.rs

+1
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,7 @@ pub enum MethodKind {
417417

418418
#[derive(Debug, PartialEq, Eq)]
419419
pub struct DefineMethod {
420+
pub inline: bool,
420421
pub public: bool,
421422
pub kind: MethodKind,
422423
pub operator: bool,

0 commit comments

Comments
 (0)