Skip to content

Commit

Permalink
Version 3.5.0-101.0.dev
Browse files Browse the repository at this point in the history
Merge b0535bd into dev
  • Loading branch information
Dart CI committed Apr 25, 2024
2 parents b5f51d8 + b0535bd commit f9c9894
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 4 deletions.
1 change: 1 addition & 0 deletions runtime/docs/pragmas.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ understands potential repercussions.
| Pragma | Meaning |
| --- | --- |
| `vm:unsafe:no-interrupts` | Removes all `CheckStackOverflow` instructions from the optimized version of the marked function, which disables stack overflow checking and interruption within that function. This pragma exists mainly for performance evaluation and should not be used in a general-purpose code, because VM relies on these checks for OOB message delivery and GC scheduling. |
| `vm:unsafe:no-bounds-checks` | Removes all array bounds checks from the optimized version of the marked function in AOT mode. This pragma exists for optimizing throughput of extremely tight loops. |

## Pragmas for internal use

Expand Down
13 changes: 12 additions & 1 deletion runtime/vm/compiler/backend/flow_graph.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ static bool ShouldReorderBlocks(const Function& function,
FLAG_reorder_basic_blocks && !function.IsFfiCallbackTrampoline();
}

static bool IsMarkedWithNoBoundsChecks(const Function& function) {
Object& options = Object::Handle();
return Library::FindPragma(dart::Thread::Current(),
/*only_core=*/false, function,
Symbols::vm_unsafe_no_bounds_checks(),
/*multiple=*/false, &options);
}

FlowGraph::FlowGraph(const ParsedFunction& parsed_function,
GraphEntryInstr* graph_entry,
intptr_t max_block_id,
Expand Down Expand Up @@ -70,7 +78,10 @@ FlowGraph::FlowGraph(const ParsedFunction& parsed_function,
loop_invariant_loads_(nullptr),
captured_parameters_(new(zone()) BitVector(zone(), variable_count())),
inlining_id_(-1),
should_print_(false) {
should_print_(false),
should_remove_all_bounds_checks_(
CompilerState::Current().is_aot() &&
IsMarkedWithNoBoundsChecks(parsed_function.function())) {
should_print_ = FlowGraphPrinter::ShouldPrint(parsed_function.function(),
&compiler_pass_filters_);
ComputeLocationsOfFixedParameters(
Expand Down
5 changes: 5 additions & 0 deletions runtime/vm/compiler/backend/flow_graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,10 @@ class FlowGraph : public ZoneAllocated {

bool should_reorder_blocks() const { return should_reorder_blocks_; }

bool should_remove_all_bounds_checks() const {
return should_remove_all_bounds_checks_;
}

//
// High-level utilities.
//
Expand Down Expand Up @@ -735,6 +739,7 @@ class FlowGraph : public ZoneAllocated {

intptr_t inlining_id_;
bool should_print_;
const bool should_remove_all_bounds_checks_;
uint8_t* compiler_pass_filters_ = nullptr;

intptr_t max_argument_slot_count_ = -1;
Expand Down
4 changes: 3 additions & 1 deletion runtime/vm/compiler/backend/il.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6771,7 +6771,9 @@ bool CheckArrayBoundInstr::IsFixedLengthArrayType(intptr_t cid) {
}

Definition* CheckBoundBaseInstr::Canonicalize(FlowGraph* flow_graph) {
return IsRedundant() ? index()->definition() : this;
return (flow_graph->should_remove_all_bounds_checks() || IsRedundant())
? index()->definition()
: this;
}

intptr_t CheckArrayBoundInstr::LengthOffsetFor(intptr_t class_id) {
Expand Down
26 changes: 26 additions & 0 deletions runtime/vm/compiler/backend/redundancy_elimination_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1603,6 +1603,32 @@ ISOLATE_UNIT_TEST_CASE(CheckStackOverflowElimination_NoInterruptsPragma) {
}
}

ISOLATE_UNIT_TEST_CASE(BoundsCheckElimination_Pragma) {
const char* kScript = R"(
import 'dart:typed_data';
@pragma('vm:unsafe:no-bounds-checks')
int test(Uint8List list) {
int result = 0;
for (int i = 0; i < 10; i++) {
result = list[i];
}
return result;
}
)";

const auto& root_library = Library::Handle(LoadTestScript(kScript));
const auto& function = Function::Handle(GetFunction(root_library, "test"));

TestPipeline pipeline(function, CompilerPass::kAOT);
auto flow_graph = pipeline.RunPasses({});
for (auto block : flow_graph->postorder()) {
for (auto instr : block->instructions()) {
EXPECT_PROPERTY(instr, !it.IsCheckBoundBase());
}
}
}

// This test checks that CSE unwraps redefinitions when comparing all
// instructions except loads, which are handled specially.
ISOLATE_UNIT_TEST_CASE(CSE_Redefinitions) {
Expand Down
3 changes: 2 additions & 1 deletion runtime/vm/symbols.h
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,8 @@ class ObjectPointerVisitor;
V(vm_testing_print_flow_graph, "vm:testing:print-flow-graph") \
V(vm_trace_entrypoints, "vm:testing.unsafe.trace-entrypoints-fn") \
V(vm_unsafe_no_interrupts, "vm:unsafe:no-interrupts") \
V(vm_align_loops, "vm:align-loops")
V(vm_align_loops, "vm:align-loops") \
V(vm_unsafe_no_bounds_checks, "vm:unsafe:no-bounds-checks")

// Contains a list of frequently used strings in a canonicalized form. This
// list is kept in the vm_isolate in order to share the copy across isolates
Expand Down
2 changes: 1 addition & 1 deletion tools/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ CHANNEL dev
MAJOR 3
MINOR 5
PATCH 0
PRERELEASE 100
PRERELEASE 101
PRERELEASE_PATCH 0

0 comments on commit f9c9894

Please sign in to comment.