about summary refs log tree commit diff
path: root/compiler/rustc_mir_transform/src/cost_checker.rs
diff options
context:
space:
mode:
authorScott McMurray <scottmcm@users.noreply.github.com>2024-06-29 00:48:23 -0700
committerScott McMurray <scottmcm@users.noreply.github.com>2024-07-01 05:17:13 -0700
commit23c8ed14c938ab28873e88321ac0ad75842fa2c1 (patch)
tree57c91418b15de92b69e3c837ac93b00d34b52214 /compiler/rustc_mir_transform/src/cost_checker.rs
parentc3774be7411722d3695de2ab1da9a358d0d5c82c (diff)
downloadrust-23c8ed14c938ab28873e88321ac0ad75842fa2c1.tar.gz
rust-23c8ed14c938ab28873e88321ac0ad75842fa2c1.zip
Avoid MIR bloat in inlining
In 126578 we ended up with more binary size increases than expected.

This change attempts to avoid inlining large things into small things, to avoid that kind of increase, in cases when top-down inlining will still be able to do that inlining later.
Diffstat (limited to 'compiler/rustc_mir_transform/src/cost_checker.rs')
-rw-r--r--compiler/rustc_mir_transform/src/cost_checker.rs31
1 files changed, 31 insertions, 0 deletions
diff --git a/compiler/rustc_mir_transform/src/cost_checker.rs b/compiler/rustc_mir_transform/src/cost_checker.rs
index 7e401b5482f..3333bebff3a 100644
--- a/compiler/rustc_mir_transform/src/cost_checker.rs
+++ b/compiler/rustc_mir_transform/src/cost_checker.rs
@@ -31,6 +31,37 @@ impl<'b, 'tcx> CostChecker<'b, 'tcx> {
         CostChecker { tcx, param_env, callee_body, instance, penalty: 0, bonus: 0 }
     }
 
+    /// Add function-level costs not well-represented by the block-level costs.
+    ///
+    /// Needed because the `CostChecker` is used sometimes for just blocks,
+    /// and even the full `Inline` doesn't call `visit_body`, so there's nowhere
+    /// to put this logic in the visitor.
+    pub fn add_function_level_costs(&mut self) {
+        fn is_call_like(bbd: &BasicBlockData<'_>) -> bool {
+            use TerminatorKind::*;
+            match bbd.terminator().kind {
+                Call { .. } | Drop { .. } | Assert { .. } | InlineAsm { .. } => true,
+
+                Goto { .. }
+                | SwitchInt { .. }
+                | UnwindResume
+                | UnwindTerminate(_)
+                | Return
+                | Unreachable => false,
+
+                Yield { .. } | CoroutineDrop | FalseEdge { .. } | FalseUnwind { .. } => {
+                    unreachable!()
+                }
+            }
+        }
+
+        // If the only has one Call (or similar), inlining isn't increasing the total
+        // number of calls, so give extra encouragement to inlining that.
+        if self.callee_body.basic_blocks.iter().filter(|bbd| is_call_like(bbd)).count() == 1 {
+            self.bonus += CALL_PENALTY;
+        }
+    }
+
     pub fn cost(&self) -> usize {
         usize::saturating_sub(self.penalty, self.bonus)
     }