From f8080bc73bc69d9eaadb2d84075315b8a4dca0ea Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Sat, 18 Jun 2022 00:53:32 +0200 Subject: [PATCH] Avoid runtime floats in Pulley::PlanMove Using U_mm inside a compilation unit will force the compiler to generate a runtime copy of the function, and we don't want that. But there seems also to be an optimization problem with gcc <= 7.x where even when declaring an inline function constexpr, if called enough times, the compiler will choose _not_ to evaluate the function at compile time and thus avoid our compile-time float->integer conversions... For this reason, split the body of the function in two parts: the actual function that uses AxisUnits at runtime for calling motion.PlanMove, and a wrapper that forces the conversion. By marking this function as always_inline, the body is correctly evaluated at compile time at each call site. --- src/modules/pulley.cpp | 3 +-- src/modules/pulley.h | 12 +++++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/modules/pulley.cpp b/src/modules/pulley.cpp index cfe68cb..3fe0eb9 100644 --- a/src/modules/pulley.cpp +++ b/src/modules/pulley.cpp @@ -3,7 +3,6 @@ #include "buttons.h" #include "globals.h" #include "leds.h" -#include "motion.h" #include "permanent_storage.h" #include "../debug.h" @@ -34,7 +33,7 @@ bool Pulley::Step() { } } -void Pulley::PlanMove(unit::U_mm delta, unit::U_mm_s feed_rate, unit::U_mm_s end_rate) { +void Pulley::PlanMove(mm::P_pos_t delta, mm::P_speed_t feed_rate, mm::P_speed_t end_rate) { mm::motion.PlanMove(delta, feed_rate, end_rate); state = Moving; } diff --git a/src/modules/pulley.h b/src/modules/pulley.h index 73a2f0b..b2c2d2f 100644 --- a/src/modules/pulley.h +++ b/src/modules/pulley.h @@ -1,9 +1,8 @@ /// @file pulley.h #pragma once #include "../config/config.h" -#include "axisunit.h" -#include "../unit.h" #include "movable_base.h" +#include "motion.h" namespace modules { @@ -25,7 +24,14 @@ public: /// @returns true if the pulley is ready to accept new commands (i.e. it has finished the last operation) bool Step(); - void PlanMove(unit::U_mm delta, unit::U_mm_s feed_rate, unit::U_mm_s end_rate = { 0 }); + void PlanMove(mm::P_pos_t delta, mm::P_speed_t feed_rate, mm::P_speed_t end_rate = { 0 }); + + // NOTE: always_inline is required here to force gcc <= 7.x to evaluate each call at compile time + void __attribute__((always_inline)) PlanMove(unit::U_mm delta, unit::U_mm_s feed_rate, unit::U_mm_s end_rate = { 0 }) { + PlanMove(mm::unitToAxisUnit(delta), + mm::unitToAxisUnit(feed_rate), + mm::unitToAxisUnit(end_rate)); + } /// @returns rounded current position (rotation) of the Pulley /// This exists purely to avoid expensive float (long double) computations of distance traveled by the filament