[llvm-commits] [llvm] r158314 - /llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp

Hal Finkel hfinkel at anl.gov
Mon Jun 11 09:46:59 PDT 2012


Roman has suggested that I move this into Support/Host.cpp (putting
this in sys::getHostCPUName certainly seems to make sense). Without
objection, I'll do that. Should I move the corresponding Darwin
CPU-detection functionality there as well?

 -Hal

On Mon, 11 Jun 2012 15:43:14 -0000
Hal Finkel <hfinkel at anl.gov> wrote:

> Author: hfinkel
> Date: Mon Jun 11 10:43:13 2012
> New Revision: 158314
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=158314&view=rev
> Log:
> Add local CPU detection for Linux PPC.
> 
> This functionality mirrors that available on PPC/Darwin.
> 
> Modified:
>     llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp
> 
> Modified: llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp?rev=158314&r1=158313&r2=158314&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp (original) +++
> llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp Mon Jun 11 10:43:13
> 2012 @@ -14,8 +14,12 @@ #include "PPCSubtarget.h"
>  #include "PPCRegisterInfo.h"
>  #include "PPC.h"
> +#include "llvm/ADT/StringRef.h"
> +#include "llvm/ADT/StringSwitch.h"
>  #include "llvm/GlobalValue.h"
>  #include "llvm/Target/TargetMachine.h"
> +#include "llvm/Support/DataStream.h"
> +#include "llvm/Support/Debug.h"
>  #include "llvm/Support/TargetRegistry.h"
>  #include <cstdlib>
>  
> @@ -60,6 +64,95 @@
>    
>    return "generic";
>  }
> +#elif defined(__linux__) && (defined(__ppc__) ||
> defined(__powerpc__)) +static const char *GetCurrentPowerPCCPU() {
> +  // Access to the Processor Version Register (PVR) on PowerPC is
> privileged,
> +  // and so we must use an operating-system interface to determine
> the current
> +  // processor type. On Linux, this is exposed through
> the /proc/cpuinfo file.
> +  const char *generic = "generic";
> +
> +  // Note: We cannot mmap /proc/cpuinfo here and then process the
> resulting
> +  // memory buffer because the 'file' has 0 size (it can be read
> from only
> +  // as a stream).
> +
> +  std::string Err;
> +  DataStreamer *DS = getDataFileStreamer("/proc/cpuinfo", &Err);
> +  if (!DS) {
> +    DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << Err << "\n");
> +    return generic;
> +  }
> +
> +  // The cpu line is second (after the 'processor: 0' line), so if
> this
> +  // buffer is too small then something has changed (or is wrong).
> +  char buffer[1024];
> +  size_t CPUInfoSize = DS->GetBytes((unsigned char*) buffer,
> sizeof(buffer));
> +  delete DS;
> +
> +  const char *CPUInfoStart = buffer;
> +  const char *CPUInfoEnd = buffer + CPUInfoSize;
> +
> +  const char *CIP = CPUInfoStart;
> +
> +  const char *CPUStart = 0;
> +  size_t CPULen = 0;
> +
> +  // We need to find the first line which starts with cpu, spaces,
> and a colon.
> +  // After the colon, there may be some additional spaces and then
> the cpu type.
> +  while (CIP < CPUInfoEnd && CPUStart == 0) {
> +    if (CIP < CPUInfoEnd && *CIP == '\n')
> +      ++CIP;
> +
> +    if (CIP < CPUInfoEnd && *CIP == 'c') {
> +      ++CIP;
> +      if (CIP < CPUInfoEnd && *CIP == 'p') {
> +        ++CIP;
> +        if (CIP < CPUInfoEnd && *CIP == 'u') {
> +          ++CIP;
> +          while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
> +            ++CIP;
> +  
> +          if (CIP < CPUInfoEnd && *CIP == ':') {
> +            ++CIP;
> +            while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
> +              ++CIP;
> +  
> +            if (CIP < CPUInfoEnd) {
> +              CPUStart = CIP;
> +              while (CIP < CPUInfoEnd && (*CIP != ' ' && *CIP !=
> '\t' &&
> +                                          *CIP != ',' && *CIP !=
> '\n'))
> +                ++CIP;
> +              CPULen = CIP - CPUStart;
> +            }
> +          }
> +        }
> +      }
> +    }
> +
> +    if (CPUStart == 0)
> +      while (CIP < CPUInfoEnd && *CIP != '\n')
> +        ++CIP;
> +  }
> +
> +  if (CPUStart == 0)
> +    return generic;
> +
> +  return StringSwitch<const char *>(StringRef(CPUStart, CPULen))
> +    .Case("604e", "604e")
> +    .Case("604", "604")
> +    .Case("7400", "7400")
> +    .Case("7410", "7400")
> +    .Case("7447", "7400")
> +    .Case("7455", "7450")
> +    .Case("G4", "g4")
> +    .Case("POWER4", "g4")
> +    .Case("PPC970FX", "970")
> +    .Case("PPC970MP", "970")
> +    .Case("G5", "g5")
> +    .Case("POWER5", "g5")
> +    .Case("POWER6", "pwr6")
> +    .Case("POWER7", "pwr7")
> +    .Default(generic);
> +}
>  #endif
>  
>  
> @@ -84,7 +177,8 @@
>    std::string CPUName = CPU;
>    if (CPUName.empty())
>      CPUName = "generic";
> -#if defined(__APPLE__)
> +#if defined(__APPLE__) || \
> +      (defined(__linux__) && (defined(__ppc__) ||
> defined(__powerpc__))) if (CPUName == "generic")
>      CPUName = GetCurrentPowerPCCPU();
>  #endif
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits



-- 
Hal Finkel
Postdoctoral Appointee
Leadership Computing Facility
Argonne National Laboratory



More information about the llvm-commits mailing list