/*! * \brief Init the cache * \param n The size of the cache * \param n_classes The number of classes * \param it An iterator to an element * \param cache The cache to initialize */ static void init(size_t n, size_t n_classes, const LIterator& it, cache_type& cache) { auto one = *it; cache = cache_type(n, etl::dim<0>(one), etl::dim<1>(one), etl::dim<2>(one)); cpp_unused(it); cpp_unused(n_classes); }
/*! * \brief Init the cache * \param n The size of the cache * \param n_classes The number of classes * \param it An iterator to an element * \param cache The cache to initialize */ static void init(size_t n, size_t n_classes, const LIterator& it, cache_type& cache) { cache = cache_type(n); cpp_unused(it); cpp_unused(n_classes); }
EE* eval_expr(Node* expr) { if (is_unary_op(expr)) return ee_new(UNTYPED, mem_asprintf("%s(%s)", unary_op_map(expr->type), eval_Value(node_get_child(expr, 0)))); if (is_binary_op(expr)) return ee_new (UNTYPED, mem_asprintf("%s(%s, %s)", binary_op_map(expr->type), eval_Value(node_get_child(expr, 0)), eval_Value(node_get_child(expr, 1)))); switch(expr->type){ case K_TRUE: return ee_new("Bool", "VALUE_TRUE"); case K_FALSE: return ee_new("Bool", "VALUE_FALSE"); case K_NIL: return ee_new("Nil", "VALUE_NIL"); case K_EOF: return ee_new("Eof", "VALUE_EOF"); case ID: if (context_block != NULL){ // If it's a block param, then OK. if (var_query_kind(expr->text) == VAR_BLOCK_PARAM) return ee_new(var_query_type(expr->text), var_query_c_name(expr->text)); else return ee_new(var_query_type(expr->text), closure_add(expr->text, var_query_c_name(expr->text))); } else return ee_new(var_query_type(expr->text), var_query_c_name(expr->text)); case SYMBOL: return ee_new("Integer", cache_dsym(expr->text + 1)); case INT: return ee_new("Integer", mem_asprintf("int64_to_val(%s)", expr->text)); case DOUBLE: return ee_new("Double", mem_asprintf("double_to_val(%s)", expr->text)); case STRING: { const char* str = expr->text; return ee_new("String", mem_asprintf("string_to_val(\"%s\")", str)); } break; case CHARACTER: { const char* str = expr->text; return ee_new("Integer", mem_asprintf("int64_to_val(%d)", (int) str[1])); } break; case EXPR_ARRAY: { Node* expr_list = node_get_child(expr, 0); return ee_new("Array", mem_asprintf("array1_to_val2(%u %s)", expr_list->children.size, eval_expr_list(expr_list, true))); } case EXPR_MAP: { Node* m_list = node_get_child(expr, 0); bool is_map = false, is_set = false; const char* args = ""; const int num_ms = node_num_children(m_list); assert(num_ms > 0); for (int i = 0; i < num_ms; i++){ Node* m = node_get_child(m_list, i); switch (node_num_children(m)){ case 2: is_map = true; args = mem_asprintf("%s, %s, %s", args, eval_Value(node_get_child(m, 0)), eval_Value(node_get_child(m, 1))); break; case 1: is_set = true; args = mem_asprintf("%s, %s", args, eval_Value(node_get_child(m, 0))); break; default: assert_never(); break; } } if (is_map and is_set){ fatal_node(expr, "invalid curly braces: is this a set or a map?"); } if (is_map) return ee_new("Map", mem_asprintf("ht_new_map(%d%s)", num_ms, args)); if (is_set) return ee_new("Set", mem_asprintf("ht_new_set(%d%s)", num_ms, args)); assert_never(); } break; case EXPR_INDEX: return ee_new(UNTYPED, eval_index(node_get_child(expr, 0), node_get_child(expr, 1), NULL)); case EXPR_CALL: { Node* callee = node_get_node(expr, "callee"); Node* args = node_get_node(expr, "args"); // If callee is a field, then we must check if its a method call. if (callee->type == EXPR_FIELD){ const char* field_name = node_get_string(callee, "name"); Node* left = node_get_child(callee, 0); const char* s = eval_expr_as_id(left); if (s == NULL or var_query(s)) return ee_new(UNTYPED, eval_obj_call(left, field_name, args)); } const char* s = eval_expr_as_id(callee); if (s != NULL){ // Could be a tuple constructor. if (strequal(s, "tuple")){ return ee_new("Tuple", mem_asprintf("tuple_to_val(%u %s)", node_num_children(args), eval_expr_list(args, true))); } // If all of callee can be evaluated as an id, then it must be a static // call. return ee_new(UNTYPED, eval_static_call(s, args)); } return ee_new(UNTYPED, mem_asprintf("func_call%d(%s %s)", node_num_children(args), eval_Value(callee), eval_expr_list(args, true))); } case EXPR_RANGE_BOUNDED: { Node* left = node_get_child(expr, 0); Node* right = node_get_child(expr, 1); return ee_new("Range", mem_asprintf("range_to_val(RANGE_BOUNDED, " "val_to_int64(%s), val_to_int64(%s))", eval_Value(left), eval_Value(right))); } case EXPR_RANGE_BOUNDED_LEFT: return ee_new("Range", mem_asprintf("range_to_val(RANGE_BOUNDED_LEFT, " "val_to_int64(%s), 0)", eval_Value(node_get_child(expr, 0)))); case EXPR_RANGE_BOUNDED_RIGHT: return ee_new("Range", mem_asprintf("range_to_val(RANGE_BOUNDED_RIGHT, " "0, val_to_int64(%s))", eval_Value(node_get_child(expr, 0)))); case EXPR_RANGE_UNBOUNDED: return ee_new("Range", "range_to_val(RANGE_UNBOUNDED, 0, 0)"); case EXPR_FIELD: { // Attempt to evaluate this field as a static symbol. Node* left = node_get_child(expr, 0); const char* s = eval_expr_as_id(left); if (s == NULL or var_query(s)){ // Dynamic field. const char* field = node_get_string(expr, "name"); return ee_new(UNTYPED, mem_asprintf("field_get(%s, %s)", eval_Value(left), cache_dsym(field))); } else { // Could be a global variable. s = eval_expr_as_id(expr); if (context_block != NULL){ return ee_new(var_query_type(s), closure_add(s, var_query_c_name(s))); } else return ee_new(var_query_type(s), var_query_c_name(s)); } } break; case EXPR_AT_VAR: { const char* name = node_get_string(expr, "name"); if (context_ci == NULL){ fatal_node(expr, "'@%s' in something that's not a class", name); } if (context_ci->type != CLASS_FIELD){ fatal_node(expr, "'@%s' in a class that's not a field class", name); } return ee_new(UNTYPED, mem_asprintf("field_get(__self, %s)", cache_dsym(name))); } case C_CODE: { const char* str = util_trim_ends(expr->text); if (strstr(expr->text, "return")){ fatal_warn("careless return in C code may disrupt the stack (use RRETURN)"); } if (context_fi != NULL){ if (context_fi->type == METHOD or context_fi->type == CONSTRUCTOR or context_fi->type == VIRTUAL_GET or context_fi->type == VIRTUAL_SET){ if (strchr(str, '@') != NULL and context_ci->type != CLASS_CDATA) fatal_node(expr, "@ in C code in a class that is not cdata"); str = util_replace(str, '@', "_c_data->"); } } return ee_new(UNTYPED, str); } case EXPR_IS_TYPE: { const char* type = eval_type(node_get_child(expr, 1)); if (var_query(type)){ fatal_node(expr, "type '%s' in 'is' expression is a variable", type); } return ee_new("Bool", mem_asprintf("pack_bool(obj_klass(%s) == %s)", eval_Value(node_get_child(expr, 0)), cache_type(type))); } case EXPR_BLOCK: { fatal_push("in anonymous block"); if (context_block != NULL){ fatal_node(expr, "nested blocks are not implemented yet"); } // Initialize context_block context_block = mem_new(BlockContext); sbuf_init(&(context_block->sbuf_code), ""); sarray_init(&(context_block->closure_names)); sarray_init(&(context_block->closure_exprs)); static int counter = 0; counter++; context_block->func_name = mem_asprintf("ripe_blk%d", counter); Node* param_list = node_get_node(expr, "param_list"); Node* stmt_list = node_get_node(expr, "stmt_list"); var_push(); // Print out the header of the anonymous function sbuf_printf(&(context_block->sbuf_code), "static Value %s(Value __block", context_block->func_name); for (int i = 0; i < node_num_children(param_list); i++){ Node* param = node_get_child(param_list, i); const char* name = node_get_string(param, "name"); const char* c_name = util_c_name(name); if (node_has_string(param, "array")) fatal_node(expr, "array parameters for blocks are not implemented yet"); const char* type = "?"; // TODO: Deal with type. var_add_local2(name, c_name, type, VAR_BLOCK_PARAM); sbuf_printf(&(context_block->sbuf_code), ", Value %s", c_name); } sbuf_printf(&(context_block->sbuf_code), ")\n"); // Generate block code sbuf_printf(&(context_block->sbuf_code), "{\n"); sbuf_printf(&(context_block->sbuf_code), " Func* _c_data = obj_c_data(__block);\n"); sbuf_printf(&(context_block->sbuf_code), " stack_annot_push(\"anonymous function\");\n"); sbuf_printf(&(context_block->sbuf_code), "%s", gen_block(stmt_list)); sbuf_printf(&(context_block->sbuf_code), "}\n"); // Now, print out the block function to WR_HEADER wr_print(WR_HEADER, "%s", context_block->sbuf_code.str); const char* result = mem_asprintf("block_to_val(%s, %d, %d", context_block->func_name, node_num_children(param_list), context_block->closure_names.size); for (uint i = 0; i < context_block->closure_names.size; i++){ const char* evaluated = sarray_get_ptr(&(context_block->closure_exprs), i); result = mem_asprintf("%s, %s", result, evaluated); } result = mem_asprintf("%s)", result); // End EXPR_BLOCK var_pop(); context_block = NULL; fatal_pop(); return ee_new("Function", result); } default: assert_never(); } return NULL; }
/** * initializes cpuinfo-struct * @param print detection-summary is written to stdout when !=0 */ void init_cpuinfo(cpu_info_t *cpuinfo,int print) { unsigned int i; char output[_HW_DETECT_MAX_OUTPUT]; /* initialize data structure */ memset(cpuinfo,0,sizeof(cpu_info_t)); strcpy(cpuinfo->architecture,"unknown\0"); strcpy(cpuinfo->vendor,"unknown\0"); strcpy(cpuinfo->model_str,"unknown\0"); cpuinfo->num_cpus = num_cpus(); get_architecture(cpuinfo->architecture, sizeof(cpuinfo->architecture)); get_cpu_vendor(cpuinfo->vendor, sizeof(cpuinfo->vendor)); get_cpu_name(cpuinfo->model_str, sizeof(cpuinfo->model_str)); cpuinfo->family = get_cpu_family(); cpuinfo->model = get_cpu_model(); cpuinfo->stepping = get_cpu_stepping(); cpuinfo->num_cores_per_package = num_cores_per_package(); cpuinfo->num_threads_per_core = num_threads_per_core(); cpuinfo->num_packages = num_packages(); cpuinfo->clockrate = get_cpu_clockrate(1, 0); /* setup supported feature list*/ if(!strcmp(cpuinfo->architecture,"x86_64")) cpuinfo->features |= X86_64; if (feature_available("SMT")) cpuinfo->features |= SMT; if (feature_available("FPU")) cpuinfo->features |= FPU; if (feature_available("MMX")) cpuinfo->features |= MMX; if (feature_available("MMX_EXT")) cpuinfo->features |= MMX_EXT; if (feature_available("SSE")) cpuinfo->features |= SSE; if (feature_available("SSE2")) cpuinfo->features |= SSE2; if (feature_available("SSE3")) cpuinfo->features |= SSE3; if (feature_available("SSSE3")) cpuinfo->features |= SSSE3; if (feature_available("SSE4.1")) cpuinfo->features |= SSE4_1; if (feature_available("SSE4.2")) cpuinfo->features |= SSE4_2; if (feature_available("SSE4A")) cpuinfo->features |= SSE4A; if (feature_available("ABM")) cpuinfo->features |= ABM; if (feature_available("POPCNT")) cpuinfo->features |= POPCNT; if (feature_available("AVX")) cpuinfo->features |= AVX; if (feature_available("AVX2")) cpuinfo->features |= AVX2; if (feature_available("FMA")) cpuinfo->features |= FMA; if (feature_available("FMA4")) cpuinfo->features |= FMA4; if (feature_available("AES")) cpuinfo->features |= AES; if (feature_available("AVX512")) cpuinfo->features |= AVX512; /* determine cache details */ for (i=0; i<(unsigned int)num_caches(0); i++) { cpuinfo->Cache_shared[cache_level(0,i)-1]=cache_shared(0,i); cpuinfo->Cacheline_size[cache_level(0,i)-1]=cacheline_length(0,i); if (cpuinfo->Cachelevels < (unsigned int)cache_level(0,i)) { cpuinfo->Cachelevels = cache_level(0,i); } switch (cache_type(0,i)) { case UNIFIED_CACHE: { cpuinfo->Cache_unified[cache_level(0,i)-1]=1; cpuinfo->U_Cache_Size[cache_level(0,i)-1]=cache_size(0,i); cpuinfo->U_Cache_Sets[cache_level(0,i)-1]=cache_assoc(0,i); break; } case DATA_CACHE: { cpuinfo->Cache_unified[cache_level(0,i)-1]=0; cpuinfo->D_Cache_Size[cache_level(0,i)-1]=cache_size(0,i); cpuinfo->D_Cache_Sets[cache_level(0,i)-1]=cache_assoc(0,i); break; } case INSTRUCTION_CACHE: { cpuinfo->Cache_unified[cache_level(0,i)-1]=0; cpuinfo->I_Cache_Size[cache_level(0,i)-1]=cache_size(0,i); cpuinfo->I_Cache_Sets[cache_level(0,i)-1]=cache_assoc(0,i); break; } default: break; } } /* print a summary */ if (print) { fflush(stdout); printf("\n system summary:\n"); if(cpuinfo->num_packages) printf(" number of processors: %i\n",cpuinfo->num_packages); if(cpuinfo->num_cores_per_package) printf(" number of cores per package: %i\n",cpuinfo->num_cores_per_package); if(cpuinfo->num_threads_per_core) printf(" number of threads per core: %i\n",cpuinfo->num_threads_per_core); if(cpuinfo->num_cpus) printf(" total number of threads: %i\n",cpuinfo->num_cpus); printf("\n processor characteristics:\n"); printf(" architecture: %s\n",cpuinfo->architecture); printf(" vendor: %s\n",cpuinfo->vendor); printf(" processor-name: %s\n",cpuinfo->model_str); printf(" model: Family %i, Model %i, Stepping %i\n",cpuinfo->family,cpuinfo->model,cpuinfo->stepping); printf(" frequency: %llu MHz\n",cpuinfo->clockrate/1000000); fflush(stdout); printf(" supported features:\n -"); if(cpuinfo->features&X86_64) printf(" X86_64"); if(cpuinfo->features&FPU) printf(" FPU"); if(cpuinfo->features&MMX) printf(" MMX"); if(cpuinfo->features&MMX_EXT) printf(" MMX_EXT"); if(cpuinfo->features&SSE) printf(" SSE"); if(cpuinfo->features&SSE2) printf(" SSE2"); if(cpuinfo->features&SSE3) printf(" SSE3"); if(cpuinfo->features&SSSE3) printf(" SSSE3"); if(cpuinfo->features&SSE4_1) printf(" SSE4.1"); if(cpuinfo->features&SSE4_2) printf(" SSE4.2"); if(cpuinfo->features&SSE4A) printf(" SSE4A"); if(cpuinfo->features&POPCNT) printf(" POPCNT"); if(cpuinfo->features&AVX) printf(" AVX"); if(cpuinfo->features&AVX2) printf(" AVX2"); if(cpuinfo->features&AVX512) printf(" AVX512"); if(cpuinfo->features&FMA) printf(" FMA"); if(cpuinfo->features&FMA4) printf(" FMA4"); if(cpuinfo->features&AES) printf(" AES"); if(cpuinfo->features&SMT) printf(" SMT"); printf(" \n"); if(cpuinfo->Cachelevels) { printf(" Caches:\n"); for(i = 0; i < (unsigned int)num_caches(0); i++) { snprintf(output,sizeof(output),"n/a"); if (cache_info(0, i, output, sizeof(output)) != -1) printf(" - %s\n",output); } } } fflush(stdout); }