Skip to content
This repository was archived by the owner on Apr 28, 2023. It is now read-only.

Commit ed0d65d

Browse files
Introduce CPUID
This commit introduces and uses cpuid information to pass the proper llc `mcpu` flag.
1 parent 0079a95 commit ed0d65d

File tree

3 files changed

+156
-2
lines changed

3 files changed

+156
-2
lines changed

tc/core/flags.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ DEFINE_bool(llvm_dump_after_opt, false, "Print IR after optimization");
5959
DEFINE_bool(llvm_dump_asm, false, "Print asm");
6060
DEFINE_string(
6161
llvm_dump_asm_options,
62-
"-march=x86-64 -mcpu=broadwell -filetype=asm",
62+
"-filetype=asm",
6363
"Options used when dumping asm");
6464

6565
DEFINE_uint32(

tc/core/polyhedral/codegen_llvm.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "tc/core/polyhedral/schedule_isl_conversion.h"
4343
#include "tc/core/polyhedral/scop.h"
4444
#include "tc/core/scope_guard.h"
45+
#include "tc/core/utils/cpu.h"
4546
#include "tc/core/utils/system.h"
4647
#include "tc/external/isl.h"
4748
#include "tc/tc_config.h"
@@ -661,7 +662,7 @@ std::unique_ptr<llvm::Module> emitLLVMKernel(
661662
}
662663
utils::checkedSystemCall(
663664
std::string(TC_STRINGIFY(TC_LLVM_BIN_DIR)) + "/llc",
664-
{FLAGS_llvm_dump_asm_options, optFile, std::string("-o ") + asmFile});
665+
{FLAGS_llvm_dump_asm_options, utils::CPUID::llcFlags(), optFile, std::string("-o ") + asmFile});
665666
{
666667
std::ifstream is(asmFile);
667668
std::string str(

tc/core/utils/cpu.h

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/**
2+
* Copyright (c) 2017-present, Facebook, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
#pragma once
17+
18+
#include <unordered_map>
19+
20+
#include <cpuid.h>
21+
22+
#include "tc/core/flags.h"
23+
#include "tc/core/utils/cpu.h"
24+
25+
namespace tc {
26+
namespace utils {
27+
28+
#define INTEL_ebx 0x756e6547
29+
#define INTEL_ecx 0x6c65746e
30+
#define INTEL_edx 0x49656e69
31+
32+
/**
33+
* We start with a reasonable subset of the processors listed in the result
34+
* of running the command:
35+
* llvm-as < /dev/null | llc -march=x86-64 -mcpu=help
36+
*/
37+
struct CPUID {
38+
public:
39+
CPUID() : eax(0), ebx(0), ecx(0), edx(0) {
40+
__get_cpuid(1, &eax, &ebx, &ecx, &edx);
41+
}
42+
43+
static bool isIntel() {
44+
unsigned int a, b, c, d;
45+
__get_cpuid(0, &a, &b, &c, &d);
46+
return b == INTEL_ebx && c == INTEL_ecx && d == INTEL_edx;
47+
}
48+
49+
using Stepping = unsigned char;
50+
using Model = unsigned char;
51+
using Family = unsigned char;
52+
using ProcessorType = unsigned char;
53+
using ExtendedModel = unsigned char;
54+
using ExtendedFamily = unsigned short;
55+
struct FullModel {
56+
FullModel(Model m, ExtendedModel em) {
57+
val = (em << 4) + m;
58+
}
59+
operator unsigned short() {
60+
return val;
61+
}
62+
operator const unsigned short&() const {
63+
return val;
64+
}
65+
unsigned short val;
66+
};
67+
68+
static const std::unordered_map<unsigned short, std::string>&
69+
intelFamily6ExtendedFamily0() {
70+
static std::unordered_map<unsigned short, std::string> m{
71+
{FullModel(0xD, 0x3), "broadwell"}, // client
72+
{FullModel(0x7, 0x4), "broadwell"}, // client
73+
{FullModel(0xF, 0x4), "broadwell"}, // server
74+
{FullModel(0x6, 0x5), "broadwell"}, // server
75+
{FullModel(0x6, 0x6), "cannonlake"}, // client
76+
{FullModel(0x6, 0x4), "haswell"}, // client
77+
{FullModel(0x5, 0x4), "haswell"}, // client
78+
{FullModel(0xC, 0x3), "haswell"}, // client
79+
{FullModel(0xF, 0x3), "haswell"}, // server
80+
{FullModel(0xA, 0x3), "ivybridge"}, // client
81+
{FullModel(0xE, 0x3), "ivybridge"}, // server
82+
{FullModel(0xA, 0x2), "sandybridge"}, // client
83+
{FullModel(0xD, 0x2), "sandybridge"}, // server
84+
{FullModel(0xE, 0x4), "skylake"}, // client
85+
{FullModel(0xE, 0x5), "skylake"}, // client
86+
{FullModel(0x5, 0x5), "skylake-avx512"}, // server
87+
{FullModel(0x5, 0x2), "westmere"}, // client
88+
{FullModel(0xC, 0x2), "westmere"}, // server
89+
{FullModel(0xF, 0x2), "westmere"}, // server
90+
};
91+
return m;
92+
};
93+
94+
static std::tuple<
95+
Stepping,
96+
Model,
97+
Family,
98+
ProcessorType,
99+
ExtendedModel,
100+
ExtendedFamily>
101+
parseCPU() {
102+
CPUID id;
103+
return std::make_tuple(
104+
static_cast<Stepping>(id.eax & 0x0000000F), // 3:0
105+
static_cast<Model>((id.eax >> 4) & 0x0000000F), // 7:4
106+
static_cast<Family>((id.eax >> 8) & 0x0000000F), // 11:8
107+
static_cast<ProcessorType>((id.eax >> 12) & 0x00000003), // 13:12
108+
static_cast<ExtendedModel>((id.eax >> 16) & 0x0000000F), // 19:16
109+
static_cast<ExtendedFamily>((id.eax >> 20) & 0x000000FF) // 27:20
110+
);
111+
}
112+
113+
#define INTEL_FAMILY_6 0x6
114+
#define INTEL_EXTENDED_FAMILY_0 0x0
115+
static std::string mcpu() {
116+
if (FLAGS_mcpu.size() > 0) {
117+
return FLAGS_mcpu;
118+
}
119+
120+
TC_CHECK(CPUID::isIntel());
121+
auto parsedCPU = CPUID::parseCPU();
122+
auto model = std::get<1>(parsedCPU);
123+
auto family = std::get<2>(parsedCPU);
124+
auto extendedModel = std::get<4>(parsedCPU);
125+
auto extendedFamily = std::get<5>(parsedCPU);
126+
if (family == INTEL_FAMILY_6 && extendedFamily == INTEL_EXTENDED_FAMILY_0) {
127+
if (intelFamily6ExtendedFamily0().count(FullModel(model, extendedModel)) >
128+
0) {
129+
return intelFamily6ExtendedFamily0().at(
130+
FullModel(model, extendedModel));
131+
}
132+
LOG(ERROR) << "FullModel: "
133+
<< (unsigned short)FullModel(model, extendedModel)
134+
<< " -> unspecified x86-64";
135+
return "x86-64";
136+
}
137+
TC_CHECK(false) << "Unsupported family/model/extendedmodel: " << family
138+
<< "/" << model << "/" << extendedModel;
139+
return "";
140+
}
141+
142+
static std::string llcFlags() {
143+
return std::string("-march=x86-64 -mcpu=") + CPUID::mcpu();
144+
}
145+
146+
public:
147+
unsigned int eax;
148+
unsigned int ebx;
149+
unsigned int ecx;
150+
unsigned int edx;
151+
};
152+
} // namespace utils
153+
} // namespace tc

0 commit comments

Comments
 (0)