Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
927 changes: 653 additions & 274 deletions cranelift/codegen/src/alias_analysis.rs

Large diffs are not rendered by default.

9 changes: 5 additions & 4 deletions cranelift/codegen/src/egraph/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Support for egraphs represented in the DataFlowGraph.

use crate::FxHashSet;
use crate::alias_analysis::{AliasAnalysis, LastStores, OptResult};
use crate::alias_analysis::{AliasAnalysis, MemoryState, OptResult};
use crate::branch_to_trap::BranchToTrapAnalysis;
use crate::ctxhash::{CtxEq, CtxHash, NullCtx};
use crate::cursor::{Cursor, CursorPosition, FuncCursor};
Expand Down Expand Up @@ -155,7 +155,7 @@ where
/// build a post-dominator tree for dead-store elimination.
cfg: &'opt ControlFlowGraph,
pub(crate) alias_analysis: &'opt mut AliasAnalysis<'analysis>,
pub(crate) alias_analysis_state: &'opt mut LastStores,
pub(crate) alias_analysis_state: &'opt mut MemoryState,
pub(crate) branch_to_trap_analysis: &'opt mut BranchToTrapAnalysis,
ctrl_plane: &'opt mut ControlPlane,
// Held locally during optimization of one node (recursively):
Expand Down Expand Up @@ -923,11 +923,14 @@ impl<'a> EgraphPass<'a> {
{
gvn_map_blocks.pop();
gvn_map.decrement_depth();
self.alias_analysis.pop_scope();
}

gvn_map.increment_depth();
gvn_map_blocks.push(block);

let mut alias_analysis_state = self.alias_analysis.push_scope(&*self.cfg, block);

// Check that `gvn_map_blocks` is the path from this block up to the
// root in the dominator tree.
debug_assert_eq!(gvn_map_blocks, {
Expand All @@ -945,8 +948,6 @@ impl<'a> EgraphPass<'a> {
trace!("Processing block {}", block);
cursor.set_position(CursorPosition::Before(block));

let mut alias_analysis_state = self.alias_analysis.block_starting_state(block);

for &param in cursor.func.dfg.block_params(block) {
trace!("creating initial singleton eclass for blockparam {}", param);
value_to_opt_value[param] = param;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
test optimize precise-output
set opt_level=speed
target aarch64

function %fence_fallback_survives_join(i64, i32) -> i32, i32 {
region0 = 0 "R0"

block0(v0: i64, v1: i32):
v3 = load.i32 notrap aligned region0 v0
brif v1, block1, block2

block1:
jump block3

block2:
jump block3

block3:
v4 = load.i32 notrap aligned region0 v0
return v3, v4
}

; function %fence_fallback_survives_join(i64, i32) -> i32, i32 fast {
; region0 = 0 "R0"
;
; block0(v0: i64, v1: i32):
; v3 = load.i32 notrap aligned region0 v0
; brif v1, block1, block2
;
; block1:
; jump block3
;
; block2:
; jump block3
;
; block3:
; return v3, v3
; }

function %unknown_does_not_take_the_fence_fallback(i64, i32, i32) -> i32, i32 {
region0 = 0 "R0"

block0(v0: i64, v1: i32, v2: i32):
v3 = load.i32 notrap aligned region0 v0
brif v1, block1, block2

block1:
;; This store prevents `block3` from reusing `v3`.
store notrap aligned region0 v2, v0
jump block3

block2:
jump block3

block3:
v4 = load.i32 notrap aligned region0 v0
return v3, v4
}

; function %unknown_does_not_take_the_fence_fallback(i64, i32, i32) -> i32, i32 fast {
; region0 = 0 "R0"
;
; block0(v0: i64, v1: i32, v2: i32):
; v3 = load.i32 notrap aligned region0 v0
; brif v1, block1, block2
;
; block1:
; store.i32 notrap aligned region0 v2, v0
; jump block3
;
; block2:
; jump block3
;
; block3:
; v4 = load.i32 notrap aligned region0 v0
; return v3, v4
; }
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
test optimize precise-output
set opt_level=speed
target aarch64

;; The last-store analysis must not depend on the order in which the worklist
;; happens to visit blocks. These two functions differ only in the order of the
;; `brif`'s two arms, so they must optimize identically.

function %arms_in_order(i64, i32, i32) -> i32, i32 {
region0 = 0 "R0"

block0(v0: i64, v1: i32, v2: i32):
store notrap aligned region0 v1, v0
brif v1, block3, block1

block1:
store notrap aligned region0 v2, v0
jump block3

block3:
v3 = load.i32 notrap aligned region0 v0
jump block4

block4:
v4 = load.i32 notrap aligned region0 v0
return v3, v4
}

; function %arms_in_order(i64, i32, i32) -> i32, i32 fast {
; region0 = 0 "R0"
;
; block0(v0: i64, v1: i32, v2: i32):
; store notrap aligned region0 v1, v0
; brif v1, block3, block1
;
; block1:
; store.i32 notrap aligned region0 v2, v0
; jump block3
;
; block3:
; v3 = load.i32 notrap aligned region0 v0
; jump block4
;
; block4:
; return v3, v3
; }

function %arms_swapped(i64, i32, i32) -> i32, i32 {
region0 = 0 "R0"

block0(v0: i64, v1: i32, v2: i32):
store notrap aligned region0 v1, v0
brif v1, block1, block3

block1:
store notrap aligned region0 v2, v0
jump block3

block3:
v3 = load.i32 notrap aligned region0 v0
jump block4

block4:
v4 = load.i32 notrap aligned region0 v0
return v3, v4
}

; function %arms_swapped(i64, i32, i32) -> i32, i32 fast {
; region0 = 0 "R0"
;
; block0(v0: i64, v1: i32, v2: i32):
; store notrap aligned region0 v1, v0
; brif v1, block1, block3
;
; block1:
; store.i32 notrap aligned region0 v2, v0
; jump block3
;
; block3:
; v3 = load.i32 notrap aligned region0 v0
; jump block4
;
; block4:
; return v3, v3
; }
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
test optimize precise-output
set opt_level=speed
target aarch64

function %single_pred_inherits(i64, i32, i32, i32) -> i32, i32 {
region0 = 0 "R0"

block0(v0: i64, v1: i32, v2: i32, v3: i32):
store notrap aligned region0 v1, v0
jump block1

block1:
brif v2, block2, block3

block3:
jump block2

block2:
v10 = load.i32 notrap aligned region0 v0
jump block4

block4:
;; `block4` has exactly one predecessor, `block2`, so at the fixpoint its
;; region0 slot must equal `block2`'s outgoing value, and `v11` must
;; therefore be forwarded to `v10`.
v11 = load.i32 notrap aligned region0 v0
store notrap aligned region0 v3, v0
brif v1, block1, block5

block5:
return v10, v11
}

; function %single_pred_inherits(i64, i32, i32, i32) -> i32, i32 fast {
; region0 = 0 "R0"
;
; block0(v0: i64, v1: i32, v2: i32, v3: i32):
; store notrap aligned region0 v1, v0
; jump block1
;
; block1:
; brif.i32 v2, block2, block3
;
; block3:
; jump block2
;
; block2:
; v10 = load.i32 notrap aligned region0 v0
; jump block4
;
; block4:
; store.i32 notrap aligned region0 v3, v0
; brif.i32 v1, block1, block5
;
; block5:
; return v10, v10
; }
63 changes: 63 additions & 0 deletions cranelift/filetests/filetests/alias/merge-token-identity.clif
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
test optimize precise-output
set opt_level=speed
target aarch64

;; `v3` and `v4` sit after two independent joins, with `block4`'s store in
;; between.
function %two_independent_joins(i64, i32, i32) -> i32, i32 {
region0 = 0 "R0"

block0(v0: i64, v1: i32, v2: i32):
brif v1, block1, block2

block1:
store notrap aligned region0 v2, v0
jump block3

block2:
jump block3

block3:
v3 = load.i32 notrap aligned region0 v0
brif v1, block4, block5

block4:
store notrap aligned region0 v1, v0
jump block6

block5:
jump block6

block6:
v4 = load.i32 notrap aligned region0 v0
return v3, v4
}

; function %two_independent_joins(i64, i32, i32) -> i32, i32 fast {
; region0 = 0 "R0"
;
; block0(v0: i64, v1: i32, v2: i32):
; brif v1, block1, block2
;
; block1:
; store.i32 notrap aligned region0 v2, v0
; jump block3
;
; block2:
; jump block3
;
; block3:
; v3 = load.i32 notrap aligned region0 v0
; brif.i32 v1, block4, block5
;
; block4:
; store.i32 notrap aligned region0 v1, v0
; jump block6
;
; block5:
; jump block6
;
; block6:
; v4 = load.i32 notrap aligned region0 v0
; return v3, v4
; }
2 changes: 0 additions & 2 deletions tests/disas/gc/array-copy-with-fuel.wat
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,6 @@
;; @002b brif.i32 v6, block4, block7
;;
;; block4:
;; v143 = load.i32 notrap aligned region6 v162
;; v145 = load.i32 notrap aligned region7 v163
;; @002b v89 = icmp.i64 ult v45, v69
;; @002b v94 = iadd.i64 v45, v170
;; @002b v95 = iadd.i64 v69, v170
Expand Down
Loading