Skip to content

Commit

Permalink
Implement feature extraction from TargetMachine
Browse files Browse the repository at this point in the history
Add the `LLVMRustHasFeature` function to check whether a
`TargetMachine` has a given feature.
  • Loading branch information
ranma42 committed Apr 8, 2016
1 parent 64a35f9 commit c883463
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 0 deletions.
4 changes: 4 additions & 0 deletions mk/rustllvm.mk
Expand Up @@ -43,6 +43,9 @@ $$(RT_OUTPUT_DIR_$(1))/$$(call CFG_STATIC_LIB_NAME_$(1),rustllvm): \
@$$(call E, link: $$@)
$$(Q)$$(call CFG_CREATE_ARCHIVE_$(1),$$@) $$^

RUSTLLVM_COMPONENTS_$(1) = $$(shell echo $$(LLVM_ALL_COMPONENTS_$(1)) |\
tr 'a-z-' 'A-Z_'| sed -e 's/^ //;s/\([^ ]*\)/\-DLLVM_COMPONENT_\1/g')

# On MSVC we need to double-escape arguments that llvm-config printed which
# start with a '/'. The shell we're running in will auto-translate the argument
# `/foo` to `C:/msys64/foo` but we really want it to be passed through as `/foo`
Expand All @@ -51,6 +54,7 @@ $(1)/rustllvm/%.o: $(S)src/rustllvm/%.cpp $$(MKFILE_DEPS) $$(LLVM_CONFIG_$(1))
@$$(call E, compile: $$@)
$$(Q)$$(call CFG_COMPILE_CXX_$(1), $$@,) \
$$(subst /,//,$$(LLVM_CXXFLAGS_$(1))) \
$$(RUSTLLVM_COMPONENTS_$(1)) \
$$(EXTRA_RUSTLLVM_CXXFLAGS_$(1)) \
$$(RUSTLLVM_INCS_$(1)) \
$$<
Expand Down
7 changes: 7 additions & 0 deletions src/librustc_llvm/build.rs
Expand Up @@ -100,6 +100,13 @@ fn main() {
}
cfg.flag(flag);
}

for component in &components[..] {
let mut flag = String::from("-DLLVM_COMPONENT_");
flag.push_str(&component.to_uppercase());
cfg.flag(&flag);
}

cfg.file("../rustllvm/ExecutionEngineWrapper.cpp")
.file("../rustllvm/PassWrapper.cpp")
.file("../rustllvm/RustWrapper.cpp")
Expand Down
3 changes: 3 additions & 0 deletions src/librustc_llvm/lib.rs
Expand Up @@ -2013,6 +2013,9 @@ extern {
pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> PassRef;
pub fn LLVMRustAddPass(PM: PassManagerRef, Pass: PassRef);

pub fn LLVMRustHasFeature(T: TargetMachineRef,
s: *const c_char) -> bool;

pub fn LLVMRustCreateTargetMachine(Triple: *const c_char,
CPU: *const c_char,
Features: *const c_char,
Expand Down
69 changes: 69 additions & 0 deletions src/rustllvm/PassWrapper.cpp
Expand Up @@ -97,6 +97,75 @@ LLVMRustAddPass(LLVMPassManagerRef PM, Pass *pass) {
pm->add(pass);
}

#ifdef LLVM_COMPONENT_X86
#define SUBTARGET_X86 SUBTARGET(X86)
#else
#define SUBTARGET_X86
#endif

#ifdef LLVM_COMPONENT_ARM
#define SUBTARGET_ARM SUBTARGET(ARM)
#else
#define SUBTARGET_ARM
#endif

#ifdef LLVM_COMPONENT_AARCH64
#define SUBTARGET_AARCH64 SUBTARGET(AArch64)
#else
#define SUBTARGET_AARCH64
#endif

#ifdef LLVM_COMPONENT_MIPS
#define SUBTARGET_MIPS SUBTARGET(Mips)
#else
#define SUBTARGET_MIPS
#endif

#ifdef LLVM_COMPONENT_POWERPC
#define SUBTARGET_PPC SUBTARGET(PPC)
#else
#define SUBTARGET_PPC
#endif

#define GEN_SUBTARGETS \
SUBTARGET_X86 \
SUBTARGET_ARM \
SUBTARGET_AARCH64 \
SUBTARGET_MIPS \
SUBTARGET_PPC

#define SUBTARGET(x) namespace llvm { \
extern const SubtargetFeatureKV x##FeatureKV[]; \
extern const SubtargetFeatureKV x##SubTypeKV[]; \
}

GEN_SUBTARGETS
#undef SUBTARGET

extern "C" bool
LLVMRustHasFeature(LLVMTargetMachineRef TM,
const char *feature) {
TargetMachine *Target = unwrap(TM);
const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
const FeatureBitset &Bits = MCInfo->getFeatureBits();
const llvm::SubtargetFeatureKV *FeatureEntry;

#define SUBTARGET(x) \
if (MCInfo->isCPUStringValid(x##SubTypeKV[0].Key)) { \
FeatureEntry = x##FeatureKV; \
} else

GEN_SUBTARGETS {
return false;
}
#undef SUBTARGET

while (strcmp(feature, FeatureEntry->Key) != 0)
FeatureEntry++;

return (Bits & FeatureEntry->Value) == FeatureEntry->Value;
}

extern "C" LLVMTargetMachineRef
LLVMRustCreateTargetMachine(const char *triple,
const char *cpu,
Expand Down

0 comments on commit c883463

Please sign in to comment.