Skip to content

Commit c883463

Browse files
committed
Implement feature extraction from TargetMachine
Add the `LLVMRustHasFeature` function to check whether a `TargetMachine` has a given feature.
1 parent 64a35f9 commit c883463

File tree

4 files changed

+83
-0
lines changed

4 files changed

+83
-0
lines changed

mk/rustllvm.mk

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ $$(RT_OUTPUT_DIR_$(1))/$$(call CFG_STATIC_LIB_NAME_$(1),rustllvm): \
4343
@$$(call E, link: $$@)
4444
$$(Q)$$(call CFG_CREATE_ARCHIVE_$(1),$$@) $$^
4545

46+
RUSTLLVM_COMPONENTS_$(1) = $$(shell echo $$(LLVM_ALL_COMPONENTS_$(1)) |\
47+
tr 'a-z-' 'A-Z_'| sed -e 's/^ //;s/\([^ ]*\)/\-DLLVM_COMPONENT_\1/g')
48+
4649
# On MSVC we need to double-escape arguments that llvm-config printed which
4750
# start with a '/'. The shell we're running in will auto-translate the argument
4851
# `/foo` to `C:/msys64/foo` but we really want it to be passed through as `/foo`
@@ -51,6 +54,7 @@ $(1)/rustllvm/%.o: $(S)src/rustllvm/%.cpp $$(MKFILE_DEPS) $$(LLVM_CONFIG_$(1))
5154
@$$(call E, compile: $$@)
5255
$$(Q)$$(call CFG_COMPILE_CXX_$(1), $$@,) \
5356
$$(subst /,//,$$(LLVM_CXXFLAGS_$(1))) \
57+
$$(RUSTLLVM_COMPONENTS_$(1)) \
5458
$$(EXTRA_RUSTLLVM_CXXFLAGS_$(1)) \
5559
$$(RUSTLLVM_INCS_$(1)) \
5660
$$<

src/librustc_llvm/build.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,13 @@ fn main() {
100100
}
101101
cfg.flag(flag);
102102
}
103+
104+
for component in &components[..] {
105+
let mut flag = String::from("-DLLVM_COMPONENT_");
106+
flag.push_str(&component.to_uppercase());
107+
cfg.flag(&flag);
108+
}
109+
103110
cfg.file("../rustllvm/ExecutionEngineWrapper.cpp")
104111
.file("../rustllvm/PassWrapper.cpp")
105112
.file("../rustllvm/RustWrapper.cpp")

src/librustc_llvm/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2013,6 +2013,9 @@ extern {
20132013
pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> PassRef;
20142014
pub fn LLVMRustAddPass(PM: PassManagerRef, Pass: PassRef);
20152015

2016+
pub fn LLVMRustHasFeature(T: TargetMachineRef,
2017+
s: *const c_char) -> bool;
2018+
20162019
pub fn LLVMRustCreateTargetMachine(Triple: *const c_char,
20172020
CPU: *const c_char,
20182021
Features: *const c_char,

src/rustllvm/PassWrapper.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,75 @@ LLVMRustAddPass(LLVMPassManagerRef PM, Pass *pass) {
9797
pm->add(pass);
9898
}
9999

100+
#ifdef LLVM_COMPONENT_X86
101+
#define SUBTARGET_X86 SUBTARGET(X86)
102+
#else
103+
#define SUBTARGET_X86
104+
#endif
105+
106+
#ifdef LLVM_COMPONENT_ARM
107+
#define SUBTARGET_ARM SUBTARGET(ARM)
108+
#else
109+
#define SUBTARGET_ARM
110+
#endif
111+
112+
#ifdef LLVM_COMPONENT_AARCH64
113+
#define SUBTARGET_AARCH64 SUBTARGET(AArch64)
114+
#else
115+
#define SUBTARGET_AARCH64
116+
#endif
117+
118+
#ifdef LLVM_COMPONENT_MIPS
119+
#define SUBTARGET_MIPS SUBTARGET(Mips)
120+
#else
121+
#define SUBTARGET_MIPS
122+
#endif
123+
124+
#ifdef LLVM_COMPONENT_POWERPC
125+
#define SUBTARGET_PPC SUBTARGET(PPC)
126+
#else
127+
#define SUBTARGET_PPC
128+
#endif
129+
130+
#define GEN_SUBTARGETS \
131+
SUBTARGET_X86 \
132+
SUBTARGET_ARM \
133+
SUBTARGET_AARCH64 \
134+
SUBTARGET_MIPS \
135+
SUBTARGET_PPC
136+
137+
#define SUBTARGET(x) namespace llvm { \
138+
extern const SubtargetFeatureKV x##FeatureKV[]; \
139+
extern const SubtargetFeatureKV x##SubTypeKV[]; \
140+
}
141+
142+
GEN_SUBTARGETS
143+
#undef SUBTARGET
144+
145+
extern "C" bool
146+
LLVMRustHasFeature(LLVMTargetMachineRef TM,
147+
const char *feature) {
148+
TargetMachine *Target = unwrap(TM);
149+
const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
150+
const FeatureBitset &Bits = MCInfo->getFeatureBits();
151+
const llvm::SubtargetFeatureKV *FeatureEntry;
152+
153+
#define SUBTARGET(x) \
154+
if (MCInfo->isCPUStringValid(x##SubTypeKV[0].Key)) { \
155+
FeatureEntry = x##FeatureKV; \
156+
} else
157+
158+
GEN_SUBTARGETS {
159+
return false;
160+
}
161+
#undef SUBTARGET
162+
163+
while (strcmp(feature, FeatureEntry->Key) != 0)
164+
FeatureEntry++;
165+
166+
return (Bits & FeatureEntry->Value) == FeatureEntry->Value;
167+
}
168+
100169
extern "C" LLVMTargetMachineRef
101170
LLVMRustCreateTargetMachine(const char *triple,
102171
const char *cpu,

0 commit comments

Comments
 (0)