| 
									
										
										
										
											2020-10-10 14:16:11 +02:00
										 |  |  | # typed: true | 
					
						
							| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 15:44:50 +01:00
										 |  |  | require "utils/popen" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-09 03:23:53 +02:00
										 |  |  | # Helper module for querying hardware information. | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  | module Hardware | 
					
						
							| 
									
										
										
										
											2020-08-09 03:23:53 +02:00
										 |  |  |   # Helper module for querying CPU information. | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  |   class CPU | 
					
						
							| 
									
										
										
										
											2013-08-11 19:11:58 -07:00
										 |  |  |     INTEL_32BIT_ARCHS = [:i386].freeze | 
					
						
							|  |  |  |     INTEL_64BIT_ARCHS = [:x86_64].freeze | 
					
						
							| 
									
										
										
										
											2022-11-15 05:22:42 +00:00
										 |  |  |     INTEL_ARCHS       = (INTEL_32BIT_ARCHS + INTEL_64BIT_ARCHS).freeze | 
					
						
							| 
									
										
										
										
											2018-04-14 03:01:33 +02:00
										 |  |  |     PPC_32BIT_ARCHS   = [:ppc, :ppc32, :ppc7400, :ppc7450, :ppc970].freeze | 
					
						
							| 
									
										
										
										
											2020-04-30 16:50:13 +10:00
										 |  |  |     PPC_64BIT_ARCHS   = [:ppc64, :ppc64le, :ppc970].freeze | 
					
						
							| 
									
										
										
										
											2022-11-15 05:22:42 +00:00
										 |  |  |     PPC_ARCHS         = (PPC_32BIT_ARCHS + PPC_64BIT_ARCHS).freeze | 
					
						
							| 
									
										
										
										
											2022-09-29 16:33:44 +08:00
										 |  |  |     ARM_64BIT_ARCHS   = [:arm64, :aarch64].freeze | 
					
						
							| 
									
										
										
										
											2022-11-15 05:22:42 +00:00
										 |  |  |     ARM_ARCHS         = ARM_64BIT_ARCHS | 
					
						
							| 
									
										
										
										
											2020-12-08 16:28:45 +00:00
										 |  |  |     ALL_ARCHS = [ | 
					
						
							| 
									
										
										
										
											2022-11-15 05:22:42 +00:00
										 |  |  |       *INTEL_ARCHS, | 
					
						
							|  |  |  |       *PPC_ARCHS, | 
					
						
							|  |  |  |       *ARM_ARCHS, | 
					
						
							| 
									
										
										
										
											2020-12-08 16:28:45 +00:00
										 |  |  |     ].freeze | 
					
						
							| 
									
										
										
										
											2013-08-11 19:11:58 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-05 14:58:17 +01:00
										 |  |  |     INTEL_64BIT_OLDEST_CPU = :core2 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  |     class << self | 
					
						
							| 
									
										
										
										
											2016-07-06 10:43:54 +01:00
										 |  |  |       def optimization_flags | 
					
						
							| 
									
										
										
										
											2020-04-30 16:50:13 +10:00
										 |  |  |         @optimization_flags ||= { | 
					
						
							| 
									
										
										
										
											2020-07-08 20:53:10 +02:00
										 |  |  |           native:             arch_flag("native"), | 
					
						
							| 
									
										
										
										
											2020-12-22 19:06:59 +11:00
										 |  |  |           ivybridge:          "-march=ivybridge", | 
					
						
							| 
									
										
										
										
											2020-07-10 10:32:30 -07:00
										 |  |  |           sandybridge:        "-march=sandybridge", | 
					
						
							| 
									
										
										
										
											2023-12-23 04:02:41 +00:00
										 |  |  |           westmere:           "-march=westmere", | 
					
						
							| 
									
										
										
										
											2020-12-22 19:06:59 +11:00
										 |  |  |           nehalem:            "-march=nehalem", | 
					
						
							| 
									
										
										
										
											2020-07-08 20:53:10 +02:00
										 |  |  |           core2:              "-march=core2", | 
					
						
							|  |  |  |           core:               "-march=prescott", | 
					
						
							| 
									
										
										
										
											2023-12-23 04:02:41 +00:00
										 |  |  |           arm_vortex_tempest: "", # TODO: -mcpu=apple-m1 when we've patched all our GCCs to support it | 
					
						
							| 
									
										
										
										
											2020-07-08 20:53:10 +02:00
										 |  |  |           armv6:              "-march=armv6", | 
					
						
							|  |  |  |           armv8:              "-march=armv8-a", | 
					
						
							|  |  |  |           ppc64:              "-mcpu=powerpc64", | 
					
						
							|  |  |  |           ppc64le:            "-mcpu=powerpc64le", | 
					
						
							| 
									
										
										
										
											2020-04-30 16:50:13 +10:00
										 |  |  |         }.freeze | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |       alias generic_optimization_flags optimization_flags | 
					
						
							| 
									
										
										
										
											2016-07-06 10:43:54 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |       sig { returns(Symbol) } | 
					
						
							| 
									
										
										
										
											2016-07-06 10:43:54 +01:00
										 |  |  |       def arch_32_bit | 
					
						
							| 
									
										
										
										
											2017-11-29 11:44:59 -08:00
										 |  |  |         if arm? | 
					
						
							|  |  |  |           :arm | 
					
						
							|  |  |  |         elsif intel? | 
					
						
							|  |  |  |           :i386 | 
					
						
							| 
									
										
										
										
											2020-04-30 16:50:13 +10:00
										 |  |  |         elsif ppc32? | 
					
						
							| 
									
										
										
										
											2017-11-29 11:44:59 -08:00
										 |  |  |           :ppc32 | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           :dunno | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2016-07-06 10:43:54 +01:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |       sig { returns(Symbol) } | 
					
						
							| 
									
										
										
										
											2016-07-06 10:43:54 +01:00
										 |  |  |       def arch_64_bit | 
					
						
							| 
									
										
										
										
											2017-11-29 11:44:59 -08:00
										 |  |  |         if arm? | 
					
						
							|  |  |  |           :arm64 | 
					
						
							|  |  |  |         elsif intel? | 
					
						
							|  |  |  |           :x86_64 | 
					
						
							| 
									
										
										
										
											2020-04-30 16:50:13 +10:00
										 |  |  |         elsif ppc64le? | 
					
						
							|  |  |  |           :ppc64le | 
					
						
							|  |  |  |         elsif ppc64? | 
					
						
							| 
									
										
										
										
											2017-11-29 11:44:59 -08:00
										 |  |  |           :ppc64 | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           :dunno | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def arch | 
					
						
							|  |  |  |         case bits | 
					
						
							|  |  |  |         when 32
 | 
					
						
							|  |  |  |           arch_32_bit | 
					
						
							|  |  |  |         when 64
 | 
					
						
							|  |  |  |           arch_64_bit | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           :dunno | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |       sig { returns(Symbol) } | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  |       def type | 
					
						
							| 
									
										
										
										
											2016-07-16 21:05:07 +01:00
										 |  |  |         case RUBY_PLATFORM | 
					
						
							|  |  |  |         when /x86_64/, /i\d86/ then :intel | 
					
						
							| 
									
										
										
										
											2019-02-21 21:14:04 -08:00
										 |  |  |         when /arm/, /aarch64/ then :arm | 
					
						
							| 
									
										
										
										
											2020-04-30 16:50:13 +10:00
										 |  |  |         when /ppc|powerpc/ then :ppc | 
					
						
							| 
									
										
										
										
											2016-07-16 21:05:07 +01:00
										 |  |  |         else :dunno | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2013-03-17 13:30:12 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |       sig { returns(Symbol) } | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  |       def family | 
					
						
							|  |  |  |         :dunno | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2013-03-17 13:30:12 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  |       def cores | 
					
						
							| 
									
										
										
										
											2017-11-29 11:44:59 -08:00
										 |  |  |         return @cores if @cores | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-29 11:44:59 -08:00
										 |  |  |         @cores = Utils.popen_read("getconf", "_NPROCESSORS_ONLN").chomp.to_i | 
					
						
							|  |  |  |         @cores = 1 unless $CHILD_STATUS.success? | 
					
						
							|  |  |  |         @cores | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2013-03-17 13:30:12 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  |       def bits | 
					
						
							| 
									
										
										
										
											2017-11-29 11:44:59 -08:00
										 |  |  |         @bits ||= case RUBY_PLATFORM | 
					
						
							| 
									
										
										
										
											2020-04-30 16:50:13 +10:00
										 |  |  |         when /x86_64/, /ppc64|powerpc64/, /aarch64|arm64/ then 64
 | 
					
						
							| 
									
										
										
										
											2017-11-29 11:44:59 -08:00
										 |  |  |         when /i\d86/, /ppc/, /arm/ then 32
 | 
					
						
							| 
									
										
										
										
											2016-07-16 21:05:07 +01:00
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |       sig { returns(T::Boolean) } | 
					
						
							| 
									
										
										
										
											2016-07-16 21:05:07 +01:00
										 |  |  |       def sse4? | 
					
						
							|  |  |  |         RUBY_PLATFORM.to_s.include?("x86_64") | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2013-03-17 13:30:12 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  |       def is_32_bit? | 
					
						
							|  |  |  |         bits == 32
 | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2013-03-17 13:30:12 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  |       def is_64_bit? | 
					
						
							|  |  |  |         bits == 64
 | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2013-11-26 20:23:19 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  |       def intel? | 
					
						
							|  |  |  |         type == :intel | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2013-11-26 20:23:19 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  |       def ppc? | 
					
						
							|  |  |  |         type == :ppc | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2015-02-23 21:38:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-30 16:50:13 +10:00
										 |  |  |       def ppc32? | 
					
						
							|  |  |  |         ppc? && is_32_bit? | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def ppc64le? | 
					
						
							|  |  |  |         ppc? && is_64_bit? && little_endian? | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def ppc64? | 
					
						
							|  |  |  |         ppc? && is_64_bit? && big_endian? | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-29 20:02:39 -06:00
										 |  |  |       def arm? | 
					
						
							|  |  |  |         type == :arm | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-30 16:50:13 +10:00
										 |  |  |       def little_endian? | 
					
						
							|  |  |  |         !big_endian? | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def big_endian? | 
					
						
							|  |  |  |         [1].pack("I") == [1].pack("N") | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-18 14:18:46 -08:00
										 |  |  |       def virtualized? | 
					
						
							|  |  |  |         false | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  |       def features | 
					
						
							|  |  |  |         [] | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2015-02-23 21:38:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  |       def feature?(name) | 
					
						
							|  |  |  |         features.include?(name) | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2020-04-30 16:50:13 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |       def arch_flag(arch) | 
					
						
							|  |  |  |         return "-mcpu=#{arch}" if ppc? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         "-march=#{arch}" | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2020-07-13 11:00:14 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |       sig { returns(T::Boolean) } | 
					
						
							| 
									
										
										
										
											2020-11-12 17:06:47 +00:00
										 |  |  |       def in_rosetta2? | 
					
						
							| 
									
										
										
										
											2020-07-13 11:00:14 -07:00
										 |  |  |         false | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2015-02-23 21:38:36 -05:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2013-03-17 13:30:12 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-20 20:10:54 +00:00
										 |  |  |   class << self | 
					
						
							|  |  |  |     def cores_as_words | 
					
						
							|  |  |  |       case Hardware::CPU.cores | 
					
						
							|  |  |  |       when 1 then "single" | 
					
						
							|  |  |  |       when 2 then "dual" | 
					
						
							|  |  |  |       when 4 then "quad" | 
					
						
							|  |  |  |       when 6 then "hexa" | 
					
						
							|  |  |  |       when 8 then "octa" | 
					
						
							|  |  |  |       when 12 then "dodeca" | 
					
						
							| 
									
										
										
										
											2013-06-06 16:02:27 -05:00
										 |  |  |       else | 
					
						
							| 
									
										
										
										
											2018-12-20 20:10:54 +00:00
										 |  |  |         Hardware::CPU.cores | 
					
						
							| 
									
										
										
										
											2013-06-06 16:02:27 -05:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2018-12-20 20:10:54 +00:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-28 19:31:21 +00:00
										 |  |  |     def oldest_cpu(_version = nil) | 
					
						
							| 
									
										
										
										
											2018-12-20 20:10:54 +00:00
										 |  |  |       if Hardware::CPU.intel? | 
					
						
							|  |  |  |         if Hardware::CPU.is_64_bit? | 
					
						
							| 
									
										
										
										
											2021-04-05 14:58:17 +01:00
										 |  |  |           Hardware::CPU::INTEL_64BIT_OLDEST_CPU | 
					
						
							| 
									
										
										
										
											2018-12-20 20:10:54 +00:00
										 |  |  |         else | 
					
						
							|  |  |  |           :core | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       elsif Hardware::CPU.arm? | 
					
						
							|  |  |  |         if Hardware::CPU.is_64_bit? | 
					
						
							|  |  |  |           :armv8 | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           :armv6 | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2020-05-01 23:21:28 +10:00
										 |  |  |       elsif Hardware::CPU.ppc? && Hardware::CPU.is_64_bit? | 
					
						
							|  |  |  |         if Hardware::CPU.little_endian? | 
					
						
							|  |  |  |           :ppc64le | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           :ppc64 | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2018-05-15 17:20:51 -07:00
										 |  |  |       else | 
					
						
							| 
									
										
										
										
											2018-12-20 20:10:54 +00:00
										 |  |  |         Hardware::CPU.family | 
					
						
							| 
									
										
										
										
											2018-05-15 17:20:51 -07:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2013-06-06 16:02:27 -05:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2018-12-20 20:10:54 +00:00
										 |  |  |     alias generic_oldest_cpu oldest_cpu | 
					
						
							| 
									
										
										
										
											2023-06-13 19:22:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-20 23:44:25 +01:00
										 |  |  |     # Returns a Rust flag to set the target CPU if necessary. | 
					
						
							|  |  |  |     # Defaults to nil. | 
					
						
							| 
									
										
										
										
											2023-06-17 12:14:21 +01:00
										 |  |  |     sig { returns(T.nilable(String)) } | 
					
						
							| 
									
										
										
										
											2023-06-17 10:38:32 +01:00
										 |  |  |     def rustflags_target_cpu | 
					
						
							| 
									
										
										
										
											2023-06-24 11:09:28 +01:00
										 |  |  |       # Rust already defaults to the oldest supported cpu for each target-triplet | 
					
						
							|  |  |  |       # so it's safe to ignore generic archs such as :armv6 here. | 
					
						
							| 
									
										
										
										
											2023-06-20 23:44:25 +01:00
										 |  |  |       # Rust defaults to apple-m1 since Rust 1.71 for aarch64-apple-darwin. | 
					
						
							|  |  |  |       @target_cpu ||= case (cpu = oldest_cpu) | 
					
						
							|  |  |  |       when :core | 
					
						
							|  |  |  |         :prescott | 
					
						
							| 
									
										
										
										
											2023-12-23 04:02:41 +00:00
										 |  |  |       when :native, :ivybridge, :sandybridge, :westmere, :nehalem, :core2 | 
					
						
							| 
									
										
										
										
											2023-06-20 23:44:25 +01:00
										 |  |  |         cpu | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |       return if @target_cpu.blank? | 
					
						
							| 
									
										
										
										
											2023-06-20 23:48:10 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-20 23:44:25 +01:00
										 |  |  |       "--codegen target-cpu=#{@target_cpu}" | 
					
						
							| 
									
										
										
										
											2023-06-13 19:22:12 +01:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2013-06-06 16:02:27 -05:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2009-09-02 13:17:15 -06:00
										 |  |  | end | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | require "extend/os/hardware" |