17
17
#include " rust-compile-intrinsic.h"
18
18
#include " rust-compile-context.h"
19
19
#include " rust-compile-type.h"
20
+ #include " rust-compile-expr.h"
20
21
#include " rust-compile-fnparam.h"
21
22
#include " rust-builtins.h"
22
23
#include " rust-diagnostics.h"
28
29
#include " fold-const.h"
29
30
#include " langhooks.h"
30
31
32
+ #include " print-tree.h"
33
+
31
34
namespace Rust {
32
35
namespace Compile {
33
36
@@ -44,6 +47,15 @@ wrapping_op_handler (Context *ctx, TyTy::FnType *fntype, tree_code op);
44
47
static tree
45
48
copy_nonoverlapping_handler (Context *ctx, TyTy::FnType *fntype);
46
49
50
+ enum class Prefetch
51
+ {
52
+ Read,
53
+ Write
54
+ };
55
+
56
+ static tree
57
+ prefetch_data_handler (Context *ctx, TyTy::FnType *fntype, Prefetch kind);
58
+
47
59
static inline tree
48
60
rotate_left_handler (Context *ctx, TyTy::FnType *fntype)
49
61
{
@@ -70,18 +82,32 @@ wrapping_mul_handler (Context *ctx, TyTy::FnType *fntype)
70
82
{
71
83
return wrapping_op_handler (ctx, fntype, MULT_EXPR);
72
84
}
85
+ static inline tree
86
+ prefetch_read_data (Context *ctx, TyTy::FnType *fntype)
87
+ {
88
+ return prefetch_data_handler (ctx, fntype, Prefetch::Read);
89
+ }
90
+ static inline tree
91
+ prefetch_write_data (Context *ctx, TyTy::FnType *fntype)
92
+ {
93
+ return prefetch_data_handler (ctx, fntype, Prefetch::Write);
94
+ }
73
95
74
96
static const std::map<std::string,
75
97
std::function<tree (Context *, TyTy::FnType *)>>
76
- generic_intrinsics = {{" offset" , &offset_handler},
77
- {" size_of" , &sizeof_handler},
78
- {" transmute" , &transmute_handler},
79
- {" rotate_left" , &rotate_left_handler},
80
- {" rotate_right" , &rotate_right_handler},
81
- {" wrapping_add" , &wrapping_add_handler},
82
- {" wrapping_sub" , &wrapping_sub_handler},
83
- {" wrapping_mul" , &wrapping_mul_handler},
84
- {" copy_nonoverlapping" , ©_nonoverlapping_handler}};
98
+ generic_intrinsics = {
99
+ {" offset" , &offset_handler},
100
+ {" size_of" , &sizeof_handler},
101
+ {" transmute" , &transmute_handler},
102
+ {" rotate_left" , &rotate_left_handler},
103
+ {" rotate_right" , &rotate_right_handler},
104
+ {" wrapping_add" , &wrapping_add_handler},
105
+ {" wrapping_sub" , &wrapping_sub_handler},
106
+ {" wrapping_mul" , &wrapping_mul_handler},
107
+ {" copy_nonoverlapping" , ©_nonoverlapping_handler},
108
+ {" prefetch_read_data" , &prefetch_read_data},
109
+ {" prefetch_write_data" , &prefetch_write_data},
110
+ };
85
111
86
112
Intrinsics::Intrinsics (Context *ctx) : ctx (ctx) {}
87
113
@@ -515,5 +541,58 @@ copy_nonoverlapping_handler (Context *ctx, TyTy::FnType *fntype)
515
541
return fndecl;
516
542
}
517
543
544
+ static tree
545
+ prefetch_data_handler (Context *ctx, TyTy::FnType *fntype, Prefetch kind)
546
+ {
547
+ rust_assert (fntype->get_params ().size () == 2 );
548
+
549
+ tree lookup = NULL_TREE;
550
+ if (check_for_cached_intrinsic (ctx, fntype, &lookup))
551
+ return lookup;
552
+
553
+ auto fndecl = compile_intrinsic_function (ctx, fntype);
554
+
555
+ // prefetching isn't pure and shouldn't be discarded after GIMPLE
556
+ TREE_READONLY (fndecl) = 0 ;
557
+ TREE_SIDE_EFFECTS (fndecl) = 1 ;
558
+
559
+ std::vector<Bvariable *> args;
560
+ compile_fn_params (ctx, fntype, fndecl, &args);
561
+
562
+ if (!ctx->get_backend ()->function_set_parameters (fndecl, args))
563
+ return error_mark_node;
564
+
565
+ enter_intrinsic_block (ctx, fndecl);
566
+
567
+ auto addr = ctx->get_backend ()->var_expression (args[0 ], Location ());
568
+ auto locality = ctx->get_backend ()->var_expression (args[1 ], Location ());
569
+
570
+ mpz_t zero;
571
+ mpz_t one;
572
+ mpz_init_set_ui (zero, 0 );
573
+ mpz_init_set_ui (one, 1 );
574
+
575
+ auto rw_flag_value = kind == Prefetch::Write ? one : zero;
576
+ auto rw_flag
577
+ = ctx->get_backend ()->integer_constant_expression (integer_type_node,
578
+ rw_flag_value);
579
+ auto prefetch_raw = NULL_TREE;
580
+ auto ok
581
+ = BuiltinsContext::get ().lookup_simple_builtin (" prefetch" , &prefetch_raw);
582
+ rust_assert (ok);
583
+ auto prefetch
584
+ = build_fold_addr_expr_loc (Location ().gcc_location (), prefetch_raw);
585
+
586
+ auto prefetch_call
587
+ = ctx->get_backend ()->call_expression (prefetch, {addr, rw_flag, locality},
588
+ nullptr , Location ());
589
+
590
+ ctx->add_statement (prefetch_call);
591
+
592
+ finalize_intrinsic_block (ctx, fndecl);
593
+
594
+ return fndecl;
595
+ }
596
+
518
597
} // namespace Compile
519
598
} // namespace Rust
0 commit comments