Skip to content

Commit 5333188

Browse files
committed
Force operator< to be inlined to reduce place time
1 parent fc03207 commit 5333188

File tree

1 file changed

+33
-3
lines changed

1 file changed

+33
-3
lines changed

vpr/src/place/place_delay_model.h

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,20 @@
66
#include "vpr_types.h"
77
#include "router_delay_profiling.h"
88

9+
#ifndef __has_attribute
10+
# define __has_attribute(x) 0 // Compatibility with non-clang compilers.
11+
#endif
12+
13+
#if defined(COMPILER_GCC) && defined(NDEBUG)
14+
# define ALWAYS_INLINE inline __attribute__((__always_inline__))
15+
#elif defined(COMPILER_MSVC) && defined(NDEBUG)
16+
# define ALWAYS_INLINE __forceinline
17+
#elif __has_attribute(always_inline)
18+
# define ALWAYS_INLINE __attribute__((always_inline)) // clang
19+
#else
20+
# define ALWAYS_INLINE inline
21+
#endif
22+
923
//Abstract interface to a placement delay model
1024
class PlaceDelayModel {
1125
public:
@@ -95,13 +109,29 @@ class OverrideDelayModel : public PlaceDelayModel {
95109
short delta_x;
96110
short delta_y;
97111

98-
friend bool operator<(const t_override& lhs, const t_override& rhs) {
99-
return std::tie(lhs.from_type, lhs.to_type, lhs.from_class, lhs.to_class, lhs.delta_x, lhs.delta_y)
100-
< std::tie(rhs.from_type, rhs.to_type, rhs.from_class, rhs.to_class, rhs.delta_x, rhs.delta_y);
112+
//A combination of ALWAYS_INLINE attribute and std::lexicographical_compare
113+
//is required for operator< to be inlined by compiler.
114+
//Proper inlining of the function reduces place time by around 5%.
115+
//For more information: https://github.com/verilog-to-routing/vtr-verilog-to-routing/issues/1225
116+
friend ALWAYS_INLINE bool operator<(const t_override& lhs, const t_override& rhs) {
117+
const short* left = reinterpret_cast<const short*>(&lhs);
118+
const short* right = reinterpret_cast<const short*>(&rhs);
119+
constexpr size_t NUM_T_OVERRIDE_MEMBERS = sizeof(t_override) / sizeof(short);
120+
return std::lexicographical_compare(left, left + NUM_T_OVERRIDE_MEMBERS, right, right + NUM_T_OVERRIDE_MEMBERS);
101121
}
102122
};
103123

104124
vtr::flat_map2<t_override, float> delay_overrides_;
125+
126+
//operator< treats memory layout of t_override as an array of short
127+
//this requires all members of t_override are shorts and there is no padding between members of t_override
128+
static_assert(sizeof(t_override) == sizeof(t_override::from_type) + sizeof(t_override::to_type) + sizeof(t_override::from_class) + sizeof(t_override::to_class) + sizeof(t_override::delta_x) + sizeof(t_override::delta_y), "Expect t_override to have a memory layout equivalent to an array of short (no padding)");
129+
static_assert(sizeof(t_override::from_type) == sizeof(short), "Expect all t_override data members to be shorts");
130+
static_assert(sizeof(t_override::to_type) == sizeof(short), "Expect all t_override data members to be shorts");
131+
static_assert(sizeof(t_override::from_class) == sizeof(short), "Expect all t_override data members to be shorts");
132+
static_assert(sizeof(t_override::to_class) == sizeof(short), "Expect all t_override data members to be shorts");
133+
static_assert(sizeof(t_override::delta_x) == sizeof(short), "Expect all t_override data members to be shorts");
134+
static_assert(sizeof(t_override::delta_y) == sizeof(short), "Expect all t_override data members to be shorts");
105135
};
106136

107137
#endif

0 commit comments

Comments
 (0)