23struct DecompressionAnalyzer {
31 DecompressionAnalyzer(
const Graph& graph,
Zone* phase_zone)
40 for (int32_t next_block_id = graph.block_count() - 1; next_block_id >= 0;) {
41 BlockIndex block_index = BlockIndex(next_block_id);
43 const Block& block = graph.Get(block_index);
45 ProcessBlock<true>(block, &next_block_id);
47 ProcessBlock<false>(block, &next_block_id);
53 bool NeedsDecompression(
const Operation& op) {
54 return NeedsDecompression(graph.Index(op));
56 bool MarkAsNeedsDecompression(
OpIndex op) {
57 return (needs_decompression[op] =
true);
60 template <
bool is_loop>
61 void ProcessBlock(
const Block& block, int32_t* next_block_id) {
63 if (is_loop && op.Is<PhiOp>() && NeedsDecompression(op)) {
64 const PhiOp& phi = op.Cast<PhiOp>();
65 if (!NeedsDecompression(phi.input(1))) {
66 Block* backedge = block.LastPredecessor();
68 std::max<int32_t>(*next_block_id, backedge->index().id());
74 void ProcessOperation(
const Operation& op);
75 void MarkAddressingBase(
OpIndex base_idx);
78void DecompressionAnalyzer::ProcessOperation(
const Operation& op) {
80 case Opcode::kStore: {
81 auto& store = op.Cast<StoreOp>();
82 MarkAsNeedsDecompression(store.base());
83 if (store.index().valid()) {
84 MarkAsNeedsDecompression(store.index().value());
86 if (!store.stored_rep.IsCompressibleTagged()) {
87 MarkAsNeedsDecompression(store.value());
91 case Opcode::kFrameState:
96 auto& phi = op.Cast<PhiOp>();
97 if (NeedsDecompression(op)) {
98 for (OpIndex input : phi.inputs()) {
99 MarkAsNeedsDecompression(input);
106 case Opcode::kComparison: {
107 auto& comp = op.Cast<ComparisonOp>();
108 if (comp.rep == WordRepresentation::Word64()) {
109 MarkAsNeedsDecompression(comp.left());
110 MarkAsNeedsDecompression(comp.right());
114 case Opcode::kWordBinop: {
115 auto& binary_op = op.Cast<WordBinopOp>();
116 if (binary_op.rep == WordRepresentation::Word64()) {
117 MarkAsNeedsDecompression(binary_op.left());
118 MarkAsNeedsDecompression(binary_op.right());
122 case Opcode::kShift: {
123 auto& shift_op = op.Cast<
ShiftOp>();
124 if (shift_op.rep == WordRepresentation::Word64()) {
125 MarkAsNeedsDecompression(shift_op.left());
129 case Opcode::kChange: {
130 auto& change = op.Cast<ChangeOp>();
131 if (change.to == WordRepresentation::Word64() && NeedsDecompression(op)) {
132 MarkAsNeedsDecompression(change.input());
136 case Opcode::kTaggedBitcast: {
137 auto& bitcast = op.Cast<TaggedBitcastOp>();
138 if (bitcast.kind != TaggedBitcastOp::Kind::kSmi &&
139 NeedsDecompression(op)) {
140 MarkAsNeedsDecompression(bitcast.input());
146 case Opcode::kConstant:
147 if (!NeedsDecompression(op)) {
151 case Opcode::kLoad: {
152 if (!NeedsDecompression(op)) {
155 const LoadOp& load = op.Cast<LoadOp>();
157 graph.Get(load.base()).saturated_use_count.IsOne()) {
162 MarkAddressingBase(load.base());
164 MarkAsNeedsDecompression(load.base());
165 if (load.index().valid()) {
166 MarkAsNeedsDecompression(load.index().value());
172 for (OpIndex input : op.inputs()) {
173 MarkAsNeedsDecompression(input);
182void DecompressionAnalyzer::MarkAddressingBase(
OpIndex base_idx) {
185 if (
const LoadOp* load =
base.TryCast<LoadOp>();
186 load && load->loaded_rep.IsCompressibleTagged()) {
191 if (
base.Is<PhiOp>()) {
192 bool keep_compressed =
true;
193 for (OpIndex input_idx :
base.inputs()) {
194 const Operation& input = graph.Get(input_idx);
195 if (!input.Is<LoadOp>() || !
base.IsOnlyUserOf(input, graph) ||
196 !input.Cast<LoadOp>().loaded_rep.IsCompressibleTagged()) {
197 keep_compressed =
false;
201 if (keep_compressed)
return;
203 MarkAsNeedsDecompression(base_idx);
212 DecompressionAnalyzer analyzer(graph,
phase_zone);
214 for (
OpIndex op_idx : analyzer.candidates) {
216 if (analyzer.NeedsDecompression(op))
continue;
218 case Opcode::kConstant: {
232 case Opcode::kLoad: {
234 if (load.loaded_rep.IsCompressibleTagged()) {
242 case Opcode::kTaggedBitcast: {
static constexpr RegisterRepresentation Compressed()
static constexpr RegisterRepresentation Word32()
static constexpr RegisterRepresentation WordPtr()
static constexpr RegisterRepresentation Tagged()
#define DECOMPRESS_POINTER_BY_ADDRESSING_MODE
FixedOpIndexSidetable< uint8_t > needs_decompression
ZoneVector< OpIndex > candidates
void RunDecompressionOptimization(Graph &graph, Zone *phase_zone)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
underlying_operation_t< Op > & Cast()