struct FieldInfo* createFieldInfo(const tree field_decl) { struct FieldInfo* fi = (struct FieldInfo*) xcalloc(1, sizeof(struct FieldInfo)); fi->isSpecial = DECL_ARTIFICIAL(field_decl); fi->isBitField = DECL_BIT_FIELD(field_decl); const char* fieldName; if (fi->isSpecial) fieldName = fieldNames[FIELD_BASE]; else if (DECL_NAME(field_decl)) fieldName = IDENTIFIER_POINTER(DECL_NAME(field_decl)); else fieldName = fieldNames[FIELD_NONAME]; fi->name = xstrdup(fieldName); fi->size = TREE_INT_CST_LOW(DECL_SIZE(field_decl)); // Offset calculation is a little bit wierd. According to GCC docs: // "... DECL_FIELD_OFFSET is position, counting in bytes, of the // DECL_OFFSET_ALIGN-bit sized word ..." and ".. DECL_FIELD_BIT_OFFSET is the // bit offset of the first bit of the field within this word" fi->offset = TREE_INT_CST_LOW(DECL_FIELD_OFFSET(field_decl)) * BITS_PER_UNIT + TREE_INT_CST_LOW(DECL_FIELD_BIT_OFFSET(field_decl)); fi->align = DECL_ALIGN(field_decl); return fi; }
static tree find_earlier_clone (struct clone_info* info) { int i; if (info->which_thunks_ok == NO_THUNKS || info->next_clone == 0) return NULL_TREE; if (info->which_thunks_ok == ALL_THUNKS) return info->clones [0]; if (info->which_thunks_ok == IN_CHARGE_1) for (i = 0; i < info->next_clone; i++) if ((TREE_INT_CST_LOW (info->in_charge_value [i]) & 1) == (TREE_INT_CST_LOW (info->in_charge_value [info->next_clone]) & 1)) return info->clones [i]; if (info->which_thunks_ok == IN_CHARGE_0) for (i = 0; i < info->next_clone; i++) if ((TREE_INT_CST_LOW (info->in_charge_value [i]) == 0) == (TREE_INT_CST_LOW (info->in_charge_value [info->next_clone]) == 0)) return info->clones [i]; return NULL_TREE; }
static void pp_c_integer_constant (c_pretty_printer *pp, tree i) { tree type = TREE_TYPE (i); if (TREE_INT_CST_HIGH (i) == 0) pp_wide_integer (pp, TREE_INT_CST_LOW (i)); else { if (tree_int_cst_sgn (i) < 0) { pp_character (pp, '-'); i = build_int_cst_wide (NULL_TREE, -TREE_INT_CST_LOW (i), ~TREE_INT_CST_HIGH (i) + !TREE_INT_CST_LOW (i)); } sprintf (pp_buffer (pp)->digit_buffer, HOST_WIDE_INT_PRINT_DOUBLE_HEX, TREE_INT_CST_HIGH (i), TREE_INT_CST_LOW (i)); pp_string (pp, pp_buffer (pp)->digit_buffer); } if (TYPE_UNSIGNED (type)) pp_character (pp, 'u'); if (type == long_integer_type_node || type == long_unsigned_type_node) pp_character (pp, 'l'); else if (type == long_long_integer_type_node || type == long_long_unsigned_type_node) pp_string (pp, "ll"); }
static int encode_derived (gfc_expr *source, unsigned char *buffer, size_t buffer_size) { gfc_constructor *ctr; gfc_component *cmp; int ptr; tree type; type = gfc_typenode_for_spec (&source->ts); ctr = source->value.constructor; cmp = source->ts.derived->components; for (;ctr; ctr = ctr->next, cmp = cmp->next) { gcc_assert (cmp); if (!ctr->expr) continue; ptr = TREE_INT_CST_LOW(DECL_FIELD_OFFSET(cmp->backend_decl)) + TREE_INT_CST_LOW(DECL_FIELD_BIT_OFFSET(cmp->backend_decl))/8; if (ctr->expr->expr_type == EXPR_NULL) memset (&buffer[ptr], 0, int_size_in_bytes (TREE_TYPE (cmp->backend_decl))); else gfc_target_encode_expr (ctr->expr, &buffer[ptr], buffer_size - ptr); } return int_size_in_bytes (type); }
static void test_string_literals (gimple *stmt) { gcall *call = check_for_named_call (stmt, "__emit_string_literal_range", 4); if (!call) return; /* We expect an ADDR_EXPR with a STRING_CST inside it for the initial arg. */ tree t_addr_string = gimple_call_arg (call, 0); if (TREE_CODE (t_addr_string) != ADDR_EXPR) { error_at (call->location, "string literal required for arg 1"); return; } tree t_string = TREE_OPERAND (t_addr_string, 0); if (TREE_CODE (t_string) != STRING_CST) { error_at (call->location, "string literal required for arg 1"); return; } tree t_caret_idx = gimple_call_arg (call, 1); if (TREE_CODE (t_caret_idx) != INTEGER_CST) { error_at (call->location, "integer constant required for arg 2"); return; } int caret_idx = TREE_INT_CST_LOW (t_caret_idx); tree t_start_idx = gimple_call_arg (call, 2); if (TREE_CODE (t_start_idx) != INTEGER_CST) { error_at (call->location, "integer constant required for arg 3"); return; } int start_idx = TREE_INT_CST_LOW (t_start_idx); tree t_end_idx = gimple_call_arg (call, 3); if (TREE_CODE (t_end_idx) != INTEGER_CST) { error_at (call->location, "integer constant required for arg 4"); return; } int end_idx = TREE_INT_CST_LOW (t_end_idx); /* A STRING_CST doesn't have a location, but the ADDR_EXPR does. */ location_t strloc = EXPR_LOCATION (t_addr_string); location_t loc; substring_loc substr_loc (strloc, TREE_TYPE (t_string), caret_idx, start_idx, end_idx); const char *err = substr_loc.get_location (&loc); if (err) error_at (strloc, "unable to read substring location: %s", err); else emit_warning (loc); }
static unsigned HOST_WIDE_INT alloc_object_size (const_gimple call, int object_size_type) { tree callee, bytes = NULL_TREE; tree alloc_size; int arg1 = -1, arg2 = -1; gcc_assert (is_gimple_call (call)); callee = gimple_call_fndecl (call); if (!callee) return unknown[object_size_type]; alloc_size = lookup_attribute ("alloc_size", TYPE_ATTRIBUTES (TREE_TYPE (callee))); if (alloc_size && TREE_VALUE (alloc_size)) { tree p = TREE_VALUE (alloc_size); arg1 = TREE_INT_CST_LOW (TREE_VALUE (p))-1; if (TREE_CHAIN (p)) arg2 = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (p)))-1; } if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL) switch (DECL_FUNCTION_CODE (callee)) { case BUILT_IN_CALLOC: arg2 = 1; /* fall through */ case BUILT_IN_MALLOC: case BUILT_IN_ALLOCA: case BUILT_IN_ALLOCA_WITH_ALIGN: arg1 = 0; default: break; } if (arg1 < 0 || arg1 >= (int)gimple_call_num_args (call) || TREE_CODE (gimple_call_arg (call, arg1)) != INTEGER_CST || (arg2 >= 0 && (arg2 >= (int)gimple_call_num_args (call) || TREE_CODE (gimple_call_arg (call, arg2)) != INTEGER_CST))) return unknown[object_size_type]; if (arg2 >= 0) bytes = size_binop (MULT_EXPR, fold_convert (sizetype, gimple_call_arg (call, arg1)), fold_convert (sizetype, gimple_call_arg (call, arg2))); else if (arg1 >= 0) bytes = fold_convert (sizetype, gimple_call_arg (call, arg1)); if (bytes && host_integerp (bytes, 1)) return tree_low_cst (bytes, 1); return unknown[object_size_type]; }
/* Non-altivec vectors bigger than 8 bytes are returned by sret. */ bool llvm_rs6000_should_return_vector_as_shadow(tree type, bool isBuiltin ATTRIBUTE_UNUSED) { if (!TARGET_64BIT && TREE_CODE(type) == VECTOR_TYPE && TYPE_SIZE(type) && TREE_CODE(TYPE_SIZE(type))==INTEGER_CST && TREE_INT_CST_LOW(TYPE_SIZE(type))>64 && TREE_INT_CST_LOW(TYPE_SIZE(type))!=128) return true; return false; }
Uint UI_From_gnu (tree Input) { tree gnu_type = TREE_TYPE (Input), gnu_base, gnu_temp; /* UI_Base is defined so that 5 Uint digits is sufficient to hold the largest possible signed 64-bit value. */ const int Max_For_Dint = 5; int v[Max_For_Dint], i; Vector_Template temp; Int_Vector vec; #if HOST_BITS_PER_WIDE_INT == 64 /* On 64-bit hosts, host_integerp tells whether the input fits in a signed 64-bit integer. Then a truncation tells whether it fits in a signed 32-bit integer. */ if (host_integerp (Input, 0)) { HOST_WIDE_INT hw_input = TREE_INT_CST_LOW (Input); if (hw_input == (int) hw_input) return UI_From_Int (hw_input); } else return No_Uint; #else /* On 32-bit hosts, host_integerp tells whether the input fits in a signed 32-bit integer. Then a sign test tells whether it fits in a signed 64-bit integer. */ if (host_integerp (Input, 0)) return UI_From_Int (TREE_INT_CST_LOW (Input)); else if (TREE_INT_CST_HIGH (Input) < 0 && TYPE_UNSIGNED (gnu_type) && !(TREE_CODE (gnu_type) == INTEGER_TYPE && TYPE_IS_SIZETYPE (gnu_type))) return No_Uint; #endif gnu_base = build_int_cst (gnu_type, UI_Base); gnu_temp = Input; for (i = Max_For_Dint - 1; i >= 0; i--) { v[i] = tree_low_cst (fold_build1 (ABS_EXPR, gnu_type, fold_build2 (TRUNC_MOD_EXPR, gnu_type, gnu_temp, gnu_base)), 0); gnu_temp = fold_build2 (TRUNC_DIV_EXPR, gnu_type, gnu_temp, gnu_base); } temp.Low_Bound = 1, temp.High_Bound = Max_For_Dint; vec.Array = v, vec.Bounds = &temp; return Vector_To_Uint (vec, tree_int_cst_sgn (Input) < 0); }
/* (Generic) vectors 4 bytes long are returned as an int. Vectors 8 bytes long are returned as 2 ints. */ tree llvm_rs6000_should_return_vector_as_scalar(tree type, bool isBuiltin ATTRIBUTE_UNUSED) { if (!TARGET_64BIT && TREE_CODE(type) == VECTOR_TYPE && TYPE_SIZE(type) && TREE_CODE(TYPE_SIZE(type))==INTEGER_CST) { if (TREE_INT_CST_LOW(TYPE_SIZE(type))==32) return uint32_type_node; else if (TREE_INT_CST_LOW(TYPE_SIZE(type))==64) return uint64_type_node; } return 0; }
static size_t expr_to_char (gfc_expr *e, unsigned char *data, unsigned char *chk, size_t len) { int i; int ptr; gfc_constructor *ctr; gfc_component *cmp; unsigned char *buffer; if (e == NULL) return 0; /* Take a derived type, one component at a time, using the offsets from the backend declaration. */ if (e->ts.type == BT_DERIVED) { ctr = e->value.constructor; cmp = e->ts.derived->components; for (;ctr; ctr = ctr->next, cmp = cmp->next) { gcc_assert (cmp && cmp->backend_decl); if (!ctr->expr) continue; ptr = TREE_INT_CST_LOW(DECL_FIELD_OFFSET(cmp->backend_decl)) + TREE_INT_CST_LOW(DECL_FIELD_BIT_OFFSET(cmp->backend_decl))/8; expr_to_char (ctr->expr, &data[ptr], &chk[ptr], len); } return len; } /* Otherwise, use the target-memory machinery to write a bitwise image, appropriate to the target, in a buffer and check off the initialized part of the buffer. */ len = gfc_target_expr_size (e); buffer = (unsigned char*)alloca (len); len = gfc_target_encode_expr (e, buffer, len); for (i = 0; i < (int)len; i++) { if (chk[i] && (buffer[i] != data[i])) { gfc_error ("Overlapping unequal initializers in EQUIVALENCE " "at %L", &e->where); return 0; } chk[i] = 0xFF; } memcpy (data, buffer, len); return len; }
/* * Return a new REAL_CST node whose type is TYPE * and whose value is the integer value of the * INTEGER_CST node I. */ REAL_VALUE_TYPE real_value_from_int_cst (tree i) { REAL_VALUE_TYPE d; #ifdef REAL_ARITHMETIC REAL_VALUE_FROM_INT (d, TREE_INT_CST_LOW (i), TREE_INT_CST_HIGH (i)); #else /* not REAL_ARITHMETIC */ #define MASK ((unsigned)1 << (HOST_BITS_PER_INT - 1)) if (TREE_INT_CST_HIGH (i) < 0) { d = (double) (~ TREE_INT_CST_HIGH (i)); d *= ((double) (1 << (HOST_BITS_PER_INT / 2)) * (double) (1 << (HOST_BITS_PER_INT / 2))); /* * The following four lines are equivalent * to converting ~ TREE_INT_CST_LOW (i) from * unsigned to double, but that is broken in * some compilers. */ if (((~ TREE_INT_CST_LOW (i)) & MASK) != 0) d += ((double) MASK + (double) ((~ MASK) & ~ TREE_INT_CST_LOW (i))); else d += (double) (unsigned) (~ TREE_INT_CST_LOW (i)); d = (- d - 1.0); } else { d = (double) TREE_INT_CST_HIGH (i); d *= ((double) (1 << (HOST_BITS_PER_INT / 2)) * (double) (1 << (HOST_BITS_PER_INT / 2))); if ((TREE_INT_CST_LOW (i) & MASK) != 0) d += ((double) MASK + (double) ((~ MASK) & TREE_INT_CST_LOW (i))); else d += (double) (unsigned) TREE_INT_CST_LOW (i); } #undef MASK #endif /* not REAL_ARITHMETIC */ return (d); } /* end real_value_from_int_cst */
hashval_t hash_type_name (tree t) { gcc_checking_assert (TYPE_MAIN_VARIANT (t) == t); /* If not in LTO, all main variants are unique, so we can do pointer hash. */ if (!in_lto_p) return htab_hash_pointer (t); /* Anonymous types are unique. */ if (type_in_anonymous_namespace_p (t)) return htab_hash_pointer (t); /* For polymorphic types, we can simply hash the virtual table. */ if (TYPE_BINFO (t) && BINFO_VTABLE (TYPE_BINFO (t))) { tree v = BINFO_VTABLE (TYPE_BINFO (t)); hashval_t hash = 0; if (TREE_CODE (v) == POINTER_PLUS_EXPR) { hash = TREE_INT_CST_LOW (TREE_OPERAND (v, 1)); v = TREE_OPERAND (TREE_OPERAND (v, 0), 0); } v = DECL_ASSEMBLER_NAME (v); hash = iterative_hash_hashval_t (hash, htab_hash_pointer (v)); return hash; } /* Rest is not implemented yet. */ gcc_unreachable (); }
/* * Create a type of integers to be the TYPE_DOMAIN * of an ARRAY_TYPE. MAXVAL should be the maximum * value in the domain (one less than the length of * the array). */ tree build_index_type (tree maxval) { register tree itype = make_node (INTEGER_TYPE); TYPE_PRECISION (itype) = BITS_PER_WORD; TYPE_MIN_VALUE (itype) = build_int_2 (0, 0); TREE_TYPE (TYPE_MIN_VALUE (itype)) = sizetype; TYPE_MAX_VALUE (itype) = convert (sizetype, maxval); TYPE_MODE (itype) = SImode; TYPE_SIZE (itype) = TYPE_SIZE (sizetype); TYPE_SIZE_UNIT (itype) = TYPE_SIZE_UNIT (sizetype); TYPE_ALIGN (itype) = TYPE_ALIGN (sizetype); if (TREE_CODE (maxval) == INTEGER_CST) { int maxint = TREE_INT_CST_LOW (maxval); return (type_hash_canon (maxint > 0 ? maxint : - maxint, itype)); } else { return (itype); } } /* end build_index_type */
tree gfc_conv_string_init (tree length, gfc_expr * expr) { gfc_char_t *s; HOST_WIDE_INT len; int slen; tree str; bool free_s = false; gcc_assert (expr->expr_type == EXPR_CONSTANT); gcc_assert (expr->ts.type == BT_CHARACTER); gcc_assert (INTEGER_CST_P (length)); gcc_assert (TREE_INT_CST_HIGH (length) == 0); len = TREE_INT_CST_LOW (length); slen = expr->value.character.length; if (len > slen) { s = gfc_get_wide_string (len); memcpy (s, expr->value.character.string, slen * sizeof (gfc_char_t)); gfc_wide_memset (&s[slen], ' ', len - slen); free_s = true; } else s = expr->value.character.string; str = gfc_build_wide_string_const (expr->ts.kind, len, s); if (free_s) free (s); return str; }
const char* XIL_DecodeAttribute(tree attr, const char **text_value, int *int_value) { tree purpose = TREE_PURPOSE(attr); if (!purpose || TREE_CODE(purpose) != IDENTIFIER_NODE) { TREE_UNEXPECTED(attr); return NULL; } const char *name = IDENTIFIER_POINTER(purpose); tree value = TREE_VALUE(attr); if (!value) return name; if (TREE_CODE(value) != TREE_LIST) { TREE_UNEXPECTED(attr); return name; } value = TREE_VALUE(value); if (TREE_CODE(value) == STRING_CST) { if (text_value) *text_value = TREE_STRING_POINTER(value); } else if (TREE_CODE(value) == INTEGER_CST) { if (int_value) *int_value = TREE_INT_CST_LOW(value); } return name; }
/* Ditto, but narrowest signed type. */ static enum integer_type_kind narrowest_signed_type (unsigned HOST_WIDE_INT low, unsigned HOST_WIDE_INT high, unsigned int flags) { enum integer_type_kind itk; if ((flags & CPP_N_WIDTH) == CPP_N_SMALL) itk = itk_int; else if ((flags & CPP_N_WIDTH) == CPP_N_MEDIUM) itk = itk_long; else itk = itk_long_long; for (; itk < itk_none; itk += 2 /* skip signed types */) { tree upper = TYPE_MAX_VALUE (integer_types[itk]); if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) > high || ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) == high && TREE_INT_CST_LOW (upper) >= low)) return itk; } return itk_none; }
int gfc_interpret_derived (unsigned char *buffer, size_t buffer_size, gfc_expr *result) { gfc_component *cmp; gfc_constructor *head = NULL, *tail = NULL; int ptr; tree type; /* The attributes of the derived type need to be bolted to the floor. */ result->expr_type = EXPR_STRUCTURE; type = gfc_typenode_for_spec (&result->ts); cmp = result->ts.derived->components; /* Run through the derived type components. */ for (;cmp; cmp = cmp->next) { if (head == NULL) head = tail = gfc_get_constructor (); else { tail->next = gfc_get_constructor (); tail = tail->next; } /* The constructor points to the component. */ tail->n.component = cmp; tail->expr = gfc_constant_result (cmp->ts.type, cmp->ts.kind, &result->where); tail->expr->ts = cmp->ts; /* Copy shape, if needed. */ if (cmp->as && cmp->as->rank) { int n; tail->expr->expr_type = EXPR_ARRAY; tail->expr->rank = cmp->as->rank; tail->expr->shape = gfc_get_shape (tail->expr->rank); for (n = 0; n < tail->expr->rank; n++) { mpz_init_set_ui (tail->expr->shape[n], 1); mpz_add (tail->expr->shape[n], tail->expr->shape[n], cmp->as->upper[n]->value.integer); mpz_sub (tail->expr->shape[n], tail->expr->shape[n], cmp->as->lower[n]->value.integer); } } ptr = TREE_INT_CST_LOW (DECL_FIELD_OFFSET (cmp->backend_decl)); gfc_target_interpret_expr (&buffer[ptr], buffer_size - ptr, tail->expr); result->value.constructor = head; } return int_size_in_bytes (type); }
tree gfc_conv_string_init (tree length, gfc_expr * expr) { char *s; HOST_WIDE_INT len; int slen; tree str; gcc_assert (expr->expr_type == EXPR_CONSTANT); gcc_assert (expr->ts.type == BT_CHARACTER && expr->ts.kind == 1); gcc_assert (INTEGER_CST_P (length)); gcc_assert (TREE_INT_CST_HIGH (length) == 0); len = TREE_INT_CST_LOW (length); slen = expr->value.character.length; if (len > slen) { s = gfc_getmem (len); memcpy (s, expr->value.character.string, slen); memset (&s[slen], ' ', len - slen); str = gfc_build_string_const (len, s); gfc_free (s); } else str = gfc_build_string_const (len, expr->value.character.string); return str; }
/* Output a declaration. Used for function locals, and struct/union members. */ void xml_generic_decl(tree decl, int indent, const char *tag, FILE *out) { fprintf(out, "%s<%s", spc(indent), tag); xml_location(decl, out); fprintf(out, ">\n"); indent += INDENT; xml_decl_binding(decl, indent, "binding", out); fprintf(out, "%s<type", spc(indent)); if (DECL_SIZE(decl)) fprintf(out, " size='%lu'", TREE_INT_CST_LOW(DECL_SIZE(decl))); if (DECL_ALIGN(decl)) fprintf(out, " alignment='%d'", DECL_ALIGN(decl)); fprintf(out, ">\n"); /* Output the type. */ xml_type(TREE_TYPE(decl), decl, indent + INDENT, out); fprintf(out, "%s</type>\n", spc(indent)); if (TREE_CODE(decl) == VAR_DECL && DECL_INITIAL(decl)) { fprintf(out, "%s<initial>\n", spc(indent)); xml_expr(DECL_INITIAL(decl), indent + INDENT, out); fprintf(out, "%s</initial>\n", spc(indent)); } indent -= INDENT; fprintf(out, "%s</%s>\n", spc(indent), tag); }
void i386_nlm_encode_section_info (tree decl, rtx rtl, int first) { default_encode_section_info (decl, rtl, first); if (first && TREE_CODE (decl) == FUNCTION_DECL && *IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)) != '*' && !strchr (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), '@')) { tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl)); tree newid; if (lookup_attribute ("stdcall", type_attributes)) newid = gen_stdcall_or_fastcall_decoration (decl, '_'); else if (lookup_attribute ("fastcall", type_attributes)) newid = gen_stdcall_or_fastcall_decoration (decl, FASTCALL_PREFIX); else if ((newid = lookup_attribute ("regparm", type_attributes)) != NULL_TREE) newid = gen_regparm_prefix (decl, TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (newid)))); if (newid != NULL_TREE) { rtx rtlname = XEXP (rtl, 0); if (GET_CODE (rtlname) == MEM) rtlname = XEXP (rtlname, 0); XSTR (rtlname, 0) = IDENTIFIER_POINTER (newid); /* These attributes must be present on first declaration, change_decl_assembler_name will warn if they are added later and the decl has been referenced, but duplicate_decls should catch the mismatch before this is called. */ change_decl_assembler_name (decl, newid); } } }
tree c_finish_oacc_wait (location_t loc, tree parms, tree clauses) { const int nparms = list_length (parms); tree stmt, t; vec<tree, va_gc> *args; vec_alloc (args, nparms + 2); stmt = builtin_decl_explicit (BUILT_IN_GOACC_WAIT); if (find_omp_clause (clauses, OMP_CLAUSE_ASYNC)) t = OMP_CLAUSE_ASYNC_EXPR (clauses); else t = build_int_cst (integer_type_node, GOMP_ASYNC_SYNC); args->quick_push (t); args->quick_push (build_int_cst (integer_type_node, nparms)); for (t = parms; t; t = TREE_CHAIN (t)) { if (TREE_CODE (OMP_CLAUSE_WAIT_EXPR (t)) == INTEGER_CST) args->quick_push (build_int_cst (integer_type_node, TREE_INT_CST_LOW (OMP_CLAUSE_WAIT_EXPR (t)))); else args->quick_push (OMP_CLAUSE_WAIT_EXPR (t)); } stmt = build_call_expr_loc_vec (loc, stmt, args); add_stmt (stmt); vec_free (args); return stmt; }
/// HandleReturnType - This is invoked by the target-independent code for the /// return type. It potentially breaks down the argument and invokes methods /// on the client that indicate how its pieces should be handled. This /// handles things like returning structures via hidden parameters. void DefaultABI::HandleReturnType(tree type, tree fn, bool isBuiltin) { unsigned Offset = 0; const Type *Ty = ConvertType(type); if (Ty->isVectorTy()) { // Vector handling is weird on x86. In particular builtin and // non-builtin function of the same return types can use different // calling conventions. tree ScalarType = LLVM_SHOULD_RETURN_VECTOR_AS_SCALAR(type, isBuiltin); if (ScalarType) C.HandleAggregateResultAsScalar(ConvertType(ScalarType)); else if (LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW(type, isBuiltin)) C.HandleScalarShadowResult(Ty->getPointerTo(), false); else C.HandleScalarResult(Ty); } else if (Ty->isSingleValueType() || Ty->isVoidTy()) { // Return scalar values normally. C.HandleScalarResult(Ty); } else if (doNotUseShadowReturn(type, fn, C.getCallingConv())) { tree SingleElt = LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR(type); if (SingleElt && TYPE_SIZE(SingleElt) && TREE_CODE(TYPE_SIZE(SingleElt)) == INTEGER_CST && TREE_INT_CST_LOW(TYPE_SIZE_UNIT(type)) == TREE_INT_CST_LOW(TYPE_SIZE_UNIT(SingleElt))) { C.HandleAggregateResultAsScalar(ConvertType(SingleElt)); } else { // Otherwise return as an integer value large enough to hold the entire // aggregate. if (const Type *AggrTy = LLVM_AGGR_TYPE_FOR_STRUCT_RETURN(type, C.getCallingConv())) C.HandleAggregateResultAsAggregate(AggrTy); else if (const Type* ScalarTy = LLVM_SCALAR_TYPE_FOR_STRUCT_RETURN(type, &Offset)) C.HandleAggregateResultAsScalar(ScalarTy, Offset); else { assert(0 && "Unable to determine how to return this aggregate!"); abort(); } } } else { // If the function is returning a struct or union, we pass the pointer to // the struct as the first argument to the function. // FIXME: should return the hidden first argument for some targets // (e.g. ELF i386). C.HandleAggregateShadowResult(Ty->getPointerTo(), false); } }
/* Non-Altivec vectors are passed in integer regs. */ bool llvm_rs6000_should_pass_vector_in_integer_regs(tree type) { if (!TARGET_64BIT && TREE_CODE(type) == VECTOR_TYPE && TYPE_SIZE(type) && TREE_CODE(TYPE_SIZE(type))==INTEGER_CST && TREE_INT_CST_LOW(TYPE_SIZE(type)) != 128) return true; return false; }
void copy_ref_info (tree new_ref, tree old_ref) { tree new_ptr_base = NULL_TREE; gcc_assert (TREE_CODE (new_ref) == MEM_REF || TREE_CODE (new_ref) == TARGET_MEM_REF); TREE_SIDE_EFFECTS (new_ref) = TREE_SIDE_EFFECTS (old_ref); TREE_THIS_VOLATILE (new_ref) = TREE_THIS_VOLATILE (old_ref); new_ptr_base = TREE_OPERAND (new_ref, 0); /* We can transfer points-to information from an old pointer or decl base to the new one. */ if (new_ptr_base && TREE_CODE (new_ptr_base) == SSA_NAME && !SSA_NAME_PTR_INFO (new_ptr_base)) { tree base = get_base_address (old_ref); if (!base) ; else if ((TREE_CODE (base) == MEM_REF || TREE_CODE (base) == TARGET_MEM_REF) && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME && SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0))) { struct ptr_info_def *new_pi; unsigned int align, misalign; duplicate_ssa_name_ptr_info (new_ptr_base, SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0))); new_pi = SSA_NAME_PTR_INFO (new_ptr_base); /* We have to be careful about transferring alignment information. */ if (get_ptr_info_alignment (new_pi, &align, &misalign) && TREE_CODE (old_ref) == MEM_REF && !(TREE_CODE (new_ref) == TARGET_MEM_REF && (TMR_INDEX2 (new_ref) || (TMR_STEP (new_ref) && (TREE_INT_CST_LOW (TMR_STEP (new_ref)) < align))))) { unsigned int inc = (mem_ref_offset (old_ref) - mem_ref_offset (new_ref)).low; adjust_ptr_info_misalignment (new_pi, inc); } else mark_ptr_info_alignment_unknown (new_pi); } else if (TREE_CODE (base) == VAR_DECL || TREE_CODE (base) == PARM_DECL || TREE_CODE (base) == RESULT_DECL) { struct ptr_info_def *pi = get_ptr_info (new_ptr_base); pt_solution_set_var (&pi->pt, base); } } }
int myprof_get_type_size ( tree t ) { int ret=0; if ( TYPE_SIZE_UNIT(t) != NULL ) ret = TREE_INT_CST_LOW ( TYPE_SIZE_UNIT(t) ); return ret; }
static bool get_nonnull_operand (tree arg_num_expr, unsigned HOST_WIDE_INT *valp) { /* Verify the arg number is a constant. */ if (!tree_fits_uhwi_p (arg_num_expr)) return false; *valp = TREE_INT_CST_LOW (arg_num_expr); return true; }
static tree tree_get_random_const(tree type) { unsigned long long mask; mask = 1ULL << (TREE_INT_CST_LOW(TYPE_SIZE(type)) - 1); mask = 2 * (mask - 1) + 1; if (TYPE_UNSIGNED(type)) return build_int_cstu(type, mask & get_random_const()); return build_int_cst(type, mask & get_random_const()); }
int oacc_get_ifn_dim_arg (const gimple *stmt) { gcc_checking_assert (gimple_call_internal_fn (stmt) == IFN_GOACC_DIM_SIZE || gimple_call_internal_fn (stmt) == IFN_GOACC_DIM_POS); tree arg = gimple_call_arg (stmt, 0); HOST_WIDE_INT axis = TREE_INT_CST_LOW (arg); gcc_checking_assert (axis >= 0 && axis < GOMP_DIM_MAX); return (int) axis; }
static int get_type_size( tree t ) { int ret = 0; if ( TYPE_SIZE_UNIT(t) != NULL ) { ret = TREE_INT_CST_LOW( TYPE_SIZE_UNIT(t) ); } return ret; }
static bool get_nonnull_operand (tree arg_num_expr, unsigned HOST_WIDE_INT *valp) { /* Verify the arg number is a constant. */ if (TREE_CODE (arg_num_expr) != INTEGER_CST || TREE_INT_CST_HIGH (arg_num_expr) != 0) return false; *valp = TREE_INT_CST_LOW (arg_num_expr); return true; }