<commit_before>#include <iostream>
#include <string>

#include "Target.h"
#include "Debug.h"
#include "LLVM_Headers.h"
#include "Util.h"

namespace Halide {

using std::string;
using std::vector;

namespace {
#ifndef __arm__

#ifdef _MSC_VER
static void cpuid(int info[4], int infoType, int extra) {
    __cpuidex(info, infoType, extra);
}

#else
// CPU feature detection code taken from ispc
// (https://github.com/ispc/ispc/blob/master/builtins/dispatch.ll)

#ifdef _LP64
static void cpuid(int info[4], int infoType, int extra) {
    __asm__ __volatile__ (
        "cpuid                 \n\t"
        : "=a" (info[0]), "=b" (info[1]), "=c" (info[2]), "=d" (info[3])
        : "0" (infoType), "2" (extra));
}
#else
static void cpuid(int info[4], int infoType, int extra) {
    // We save %ebx in case it's the PIC register
    __asm__ __volatile__ (
        "mov{l}\t{%%}ebx, %1  \n\t"
        "cpuid                 \n\t"
        "xchg{l}\t{%%}ebx, %1  \n\t"
        : "=a" (info[0]), "=r" (info[1]), "=c" (info[2]), "=d" (info[3])
        : "0" (infoType), "2" (extra));
}
#endif
#endif
#endif
}

Target get_host_target() {
    Target::OS os = Target::OSUnknown;
    #ifdef __linux__
    os = Target::Linux;
    #endif
    #ifdef _MSC_VER
    os = Target::Windows;
    #endif
    #ifdef __APPLE__
    os = Target::OSX;
    #endif

    bool use_64_bits = (sizeof(size_t) == 8);
    int bits = use_64_bits ? 64 : 32;

    #ifdef __arm__
    Target::Arch arch = Target::ARM;
    return Target(os, arch, bits, 0);
    #else

    Target::Arch arch = Target::X86;

    int info[4];
    cpuid(info, 1, 0);
    bool have_sse41 = info[2] & (1 << 19);
    bool have_sse2 = info[3] & (1 << 26);
    bool have_avx = info[2] & (1 << 28);
    bool have_f16 = info[2] & (1 << 29);
    bool have_rdrand = info[2] & (1 << 30);

    assert(have_sse2 && "The x86 backend assumes at least sse2 support");

    uint64_t features = 0;
    if (have_sse41) features |= Target::SSE41;
    if (have_avx)   features |= Target::AVX;

    if (use_64_bits && have_avx && have_f16 && have_rdrand) {
        // So far, so good.  AVX2?
        // Call cpuid with eax=7, ecx=0
        int info2[4];
        cpuid(info2, 7, 0);
        bool have_avx2 = info[1] & (1 << 5);
        if (have_avx2) {
            features |= Target::AVX2;
        }
    }

    return Target(os, arch, bits, features);
#endif
}

namespace {
string get_env(const char *name) {
#ifdef _WIN32
    char buf[128];
    size_t read = 0;
    getenv_s(&read, buf, name);
    if (read) {
        return string(buf);
    } else {
        return "";
    }
#else
    char *buf = getenv(name);
    if (buf) {
        return string(buf);
    } else {
        return "";
    }
#endif
}
}

Target get_target_from_environment() {
    string target = get_env("HL_TARGET");
    if (target.empty()) {
        return get_host_target();
    } else {
        return parse_target_string(target);
    }
}

Target get_jit_target_from_environment() {
    Target host = get_host_target();
    string target = get_env("HL_JIT_TARGET");
    if (target.empty()) {
        return host;
    } else {
        Target t = parse_target_string(target);
        assert(t.os == host.os && t.arch == host.arch && t.bits == host.bits &&
               "HL_JIT_TARGET must match the host OS, architecture, and bit width");
        return t;
    }
}

Target parse_target_string(const std::string &target) {
    //Internal::debug(0) << "Getting host target \n";

    Target t = get_host_target();

    if (target.empty()) return t;

    //Internal::debug(0) << "Got host target \n";
    if (!t.merge_string(target)) {
        std::cerr << "Did not understand HL_TARGET=" << target << "\n"
                  << "Expected format is arch-os-feature1-feature2-... "
                  << "Where arch is x86-32, x86-64, arm-32, arm-64, "
                  << "and os is linux, windows, osx, nacl, ios, or android. "
                  << "If arch or os are omitted, they default to the host. "
                  << "Features include sse41, avx, avx2, cuda, opencl, and gpu_debug.\n"
                  << "HL_TARGET can also include \"host\", which sets the "
                  << "host's architecture, os, and feature set, with the "
                  << "exception of the GPU runtimes, which default to off\n";

        assert(false);
    }

    return t;
}

bool Target::merge_string(const std::string &target) {
    string rest = target;
    vector<string> tokens;
    size_t first_dash;<commit_msg>Target defaults to host os and arch only (but not feature set).<commit_after>#include <iostream>
#include <string>

#include "Target.h"
#include "Debug.h"
#include "LLVM_Headers.h"
#include "Util.h"

namespace Halide {

using std::string;
using std::vector;

namespace {
#ifndef __arm__

#ifdef _MSC_VER
static void cpuid(int info[4], int infoType, int extra) {
    __cpuidex(info, infoType, extra);
}

#else
// CPU feature detection code taken from ispc
// (https://github.com/ispc/ispc/blob/master/builtins/dispatch.ll)

#ifdef _LP64
static void cpuid(int info[4], int infoType, int extra) {
    __asm__ __volatile__ (
        "cpuid                 \n\t"
        : "=a" (info[0]), "=b" (info[1]), "=c" (info[2]), "=d" (info[3])
        : "0" (infoType), "2" (extra));
}
#else
static void cpuid(int info[4], int infoType, int extra) {
    // We save %ebx in case it's the PIC register
    __asm__ __volatile__ (
        "mov{l}\t{%%}ebx, %1  \n\t"
        "cpuid                 \n\t"
        "xchg{l}\t{%%}ebx, %1  \n\t"
        : "=a" (info[0]), "=r" (info[1]), "=c" (info[2]), "=d" (info[3])
        : "0" (infoType), "2" (extra));
}
#endif
#endif
#endif
}

Target get_host_target() {
    Target::OS os = Target::OSUnknown;
    #ifdef __linux__
    os = Target::Linux;
    #endif
    #ifdef _MSC_VER
    os = Target::Windows;
    #endif
    #ifdef __APPLE__
    os = Target::OSX;
    #endif

    bool use_64_bits = (sizeof(size_t) == 8);
    int bits = use_64_bits ? 64 : 32;

    #ifdef __arm__
    Target::Arch arch = Target::ARM;
    return Target(os, arch, bits, 0);
    #else

    Target::Arch arch = Target::X86;

    int info[4];
    cpuid(info, 1, 0);
    bool have_sse41 = info[2] & (1 << 19);
    bool have_sse2 = info[3] & (1 << 26);
    bool have_avx = info[2] & (1 << 28);
    bool have_f16 = info[2] & (1 << 29);
    bool have_rdrand = info[2] & (1 << 30);

    assert(have_sse2 && "The x86 backend assumes at least sse2 support");

    uint64_t features = 0;
    if (have_sse41) features |= Target::SSE41;
    if (have_avx)   features |= Target::AVX;

    if (use_64_bits && have_avx && have_f16 && have_rdrand) {
        // So far, so good.  AVX2?
        // Call cpuid with eax=7, ecx=0
        int info2[4];
        cpuid(info2, 7, 0);
        bool have_avx2 = info[1] & (1 << 5);
        if (have_avx2) {
            features |= Target::AVX2;
        }
    }

    return Target(os, arch, bits, features);
#endif
}

namespace {
string get_env(const char *name) {
#ifdef _WIN32
    char buf[128];
    size_t read = 0;
    getenv_s(&read, buf, name);
    if (read) {
        return string(buf);
    } else {
        return "";
    }
#else
    char *buf = getenv(name);
    if (buf) {
        return string(buf);
    } else {
        return "";
    }
#endif
}
}

Target get_target_from_environment() {
    string target = get_env("HL_TARGET");
    if (target.empty()) {
        return get_host_target();
    } else {
        return parse_target_string(target);
    }
}

Target get_jit_target_from_environment() {
    Target host = get_host_target();
    string target = get_env("HL_JIT_TARGET");
    if (target.empty()) {
        return host;
    } else {
        Target t = parse_target_string(target);
        assert(t.os == host.os && t.arch == host.arch && t.bits == host.bits &&
               "HL_JIT_TARGET must match the host OS, architecture, and bit width");
        return t;
    }
}

Target parse_target_string(const std::string &target) {
    //Internal::debug(0) << "Getting host target \n";

    Target host = get_host_target();

    if (target.empty()) {
        // If nothing is specified, use the host target.
        return host;
    }

    // Default to the host OS and architecture.
    Target t;
    t.os = host.os;
    t.arch = host.arch;
    t.bits = host.bits;

    //Internal::debug(0) << "Got host target \n";
    if (!t.merge_string(target)) {
        std::cerr << "Did not understand HL_TARGET=" << target << "\n"
                  << "Expected format is arch-os-feature1-feature2-... "
                  << "Where arch is x86-32, x86-64, arm-32, arm-64, "
                  << "and os is linux, windows, osx, nacl, ios, or android. "
                  << "If arch or os are omitted, they default to the host. "
                  << "Features include sse41, avx, avx2, cuda, opencl, and gpu_debug.\n"
                  << "HL_TARGET can also begin with \"host\", which sets the "
                  << "host's architecture, os, and feature set, with the "
                  << "exception of the GPU runtimes, which default to off\n";

        assert(false);
    }

    return t;
}

bool Target::merge_string(const std::string &target) {
    string rest = target;
    vector<string> tokens;
    size_t first_dash;
{'fraction_non_alphanumeric': 0.15156098087933456, 'fraction_numerical': 0.024413957005509343, 'mean_word_length': 2.3579978237214365, 'pattern_counts': {'":': 0, '<': 85, '<?xml version=': 0, '>': 9, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5236646', 'n_tokens_mistral': 3397, 'n_tokens_neox': 3240, 'n_words': 890}